From 02052abe44a25f0e67e1986239b9307e547d3199 Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Sun, 3 Oct 2010 21:30:28 +0800 Subject: [PATCH 1/4] Pass any AX response to the callback along with the SReg response --- lib/open_id_authentication.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/open_id_authentication.rb b/lib/open_id_authentication.rb index b355049..ed875cd 100644 --- a/lib/open_id_authentication.rb +++ b/lib/open_id_authentication.rb @@ -112,7 +112,8 @@ def complete_open_id_authentication case response.status when OpenID::Consumer::SUCCESS yield Result[:successful], identifier, - OpenID::SReg::Response.from_success_response(response) + OpenID::SReg::Response.from_success_response(response), + OpenID::AX::FetchResponse.from_success_response(response) when :missing yield Result[:missing], identifier, nil when :invalid From 2b019859e326f931627092e34cf09db744f9950e Mon Sep 17 00:00:00 2001 From: mkristian Date: Mon, 22 Aug 2011 21:02:12 +51800 Subject: [PATCH 2/4] it took me a while to figure out this extra feature with the forth parameter 'ax' of the block --- README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README b/README index fe2b37e..225d196 100644 --- a/README +++ b/README @@ -214,9 +214,9 @@ Some OpenID providers also support the OpenID AX (attribute exchange) protocol f Accessing AX data is very similar to the Simple Registration process, described above -- just add the URI identifier for the AX field to your :optional or :required parameters. For example: authenticate_with_open_id(identity_url, - :required => [ :email, 'http://schema.openid.net/birthDate' ]) do |result, identity_url, registration| + :required => [ :email, 'http://schema.openid.net/birthDate' ]) do |result, identity_url, registration, ax| -This would provide the sreg data for :email, and the AX data for 'http://schema.openid.net/birthDate' +This would provide the sreg data for :email via registration, and the AX data for 'http://schema.openid.net/birthDate' via ax. From 82379c858af5e2bd21afd9770a8cdb1a09f47480 Mon Sep 17 00:00:00 2001 From: patricksrobertson Date: Mon, 1 Aug 2011 10:26:05 -0400 Subject: [PATCH 3/4] Gem release 1.0.0. Updated README to markdown, added contribution guidelines and versioning. --- .gitignore | 1 + CONTRIBUTION_GUIDELINES.md | 8 ++ README => README.md | 115 +++++++++++++++----------- lib/open_id_authentication/version.rb | 4 + open_id_authentication.gemspec | 32 +++++++ 5 files changed, 112 insertions(+), 48 deletions(-) create mode 100644 .gitignore create mode 100644 CONTRIBUTION_GUIDELINES.md rename README => README.md (77%) create mode 100644 lib/open_id_authentication/version.rb create mode 100644 open_id_authentication.gemspec diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..86339a0 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.gem \ No newline at end of file diff --git a/CONTRIBUTION_GUIDELINES.md b/CONTRIBUTION_GUIDELINES.md new file mode 100644 index 0000000..b45014c --- /dev/null +++ b/CONTRIBUTION_GUIDELINES.md @@ -0,0 +1,8 @@ +Contributing to open_id_authentication: + +1. Fork the [official repository](http://github.com/Velir/open_id_authentication/tree/master). +2. Make your changes in a topic branch. +3. Send a pull request. + +Notes: +* Please don't update the Gem version. \ No newline at end of file diff --git a/README b/README.md similarity index 77% rename from README rename to README.md index 225d196..c429540 100644 --- a/README +++ b/README.md @@ -12,26 +12,26 @@ The specification used is http://openid.net/specs/openid-authentication-2_0.html Prerequisites -============= +------------- OpenID authentication uses the session, so be sure that you haven't turned that off. Alternatively, you can use the file-based store, which just relies on on tmp/openids being present in RAILS_ROOT. But be aware that this store only works if you have a single application server. And it's not safe to use across NFS. It's recommended that you use the database store if at all possible. To use the file-based store, you'll also have to add this line to your config/environment.rb: - OpenIdAuthentication.store = :file + OpenIdAuthentication.store = :file This particular plugin also relies on the fact that the authentication action allows for both POST and GET operations. If you're using RESTful authentication, you'll need to explicitly allow for this in your routes.rb. The plugin also expects to find a root_url method that points to the home page of your site. You can accomplish this by using a root route in config/routes.rb: - map.root :controller => 'articles' + root :to => "articles#index" This plugin relies on Rails Edge revision 6317 or newer. Example -======= +------- This example is just to meant to demonstrate how you could use OpenID authentication. You might well want to add salted hash logins instead of plain text passwords and other requirements on top of this. Treat it as a starting point, @@ -42,16 +42,16 @@ model you are using for authentication. Also of note is the following code block used in the example below: - authenticate_with_open_id do |result, identity_url| - ... - end + authenticate_with_open_id do |result, identity_url| + ... + end In the above code block, 'identity_url' will need to match user.identity_url exactly. 'identity_url' will be a string in the form of 'http://example.com' - If you are storing just 'example.com' with your user, the lookup will fail. There is a handy method in this plugin called 'normalize_url' that will help with validating OpenID URLs. - OpenIdAuthentication.normalize_url(user.identity_url) + OpenIdAuthentication.normalize_url(user.identity_url) The above will return a standardized version of the OpenID URL - the above called with 'example.com' will return 'http://example.com/' It will also raise an InvalidOpenId exception if the URL is determined to not be valid. @@ -59,49 +59,53 @@ Use the above code in your User model and validate OpenID URLs before saving the config/routes.rb - map.root :controller => 'articles' - map.resource :session - + #config/routes.rb + root :to => "articles#index" + resource :session app/views/sessions/new.erb - <% form_tag(session_url) do %> -

- - <%= text_field_tag "name" %> -

+ #app/views/sessions/new.erb + <% form_tag(session_url) do %> +

+ + <%= text_field_tag "name" %> +

-

- - <%= password_field_tag %> -

+

+ + <%= password_field_tag %> +

-

- ...or use: -

+

+ +

-

- - <%= text_field_tag "openid_identifier" %> -

+

+ + <%= text_field_tag "openid_identifier" %> +

+ +

+ <%= submit_tag 'Sign in', :disable_with => "Signing in…" %> +

+ <% end %> -

- <%= submit_tag 'Sign in', :disable_with => "Signing in…" %> -

- <% end %> app/controllers/sessions_controller.rb - class SessionsController < ApplicationController - def create - if using_open_id? - open_id_authentication - else - password_authentication(params[:name], params[:password]) + + #app/controllers/sessions_controller.rb + class SessionsController < ApplicationController + def create + if using_open_id? + open_id_authentication + else + password_authentication(params[:name], params[:password]) + end end - end - protected + protected def password_authentication(name, password) if @current_user = @account.users.authenticate(params[:name], params[:password]) successful_login @@ -125,7 +129,7 @@ app/controllers/sessions_controller.rb end - private + private def successful_login session[:user_id] = @current_user.id redirect_to(root_url) @@ -135,7 +139,7 @@ app/controllers/sessions_controller.rb flash[:error] = message redirect_to(new_session_url) end - end + end @@ -154,7 +158,7 @@ you can collapse the case into a mere boolean: Simple Registration OpenID Extension -==================================== +------------------------------------ Some OpenID Providers support this lightweight profile exchange protocol. See more: http://www.openidenabled.com/openid/simple-registration-extension @@ -162,7 +166,8 @@ You can support it in your app by changing #open_id_authentication def open_id_authentication(identity_url) # Pass optional :required and :optional keys to specify what sreg fields you want. - # Be sure to yield registration, a third argument in the #authenticate_with_open_id block. + # Be sure to yield registration, a third argument in the + # #authenticate_with_open_id block. authenticate_with_open_id(identity_url, :required => [ :nickname, :email ], :optional => :fullname) do |result, identity_url, registration| @@ -207,17 +212,31 @@ You can support it in your app by changing #open_id_authentication end Attribute Exchange OpenID Extension -=================================== +----------------------------------- Some OpenID providers also support the OpenID AX (attribute exchange) protocol for exchanging identity information between endpoints. See more: http://openid.net/specs/openid-attribute-exchange-1_0.html Accessing AX data is very similar to the Simple Registration process, described above -- just add the URI identifier for the AX field to your :optional or :required parameters. For example: - authenticate_with_open_id(identity_url, - :required => [ :email, 'http://schema.openid.net/birthDate' ]) do |result, identity_url, registration, ax| + authenticate_with_open_id(identity_url, + :required => [ :email, 'http://schema.openid.net/birthDate' ]) do + |result, identity_url, registration, ax| + +This would provide the sreg data for :email via registration, and the AX data for http://schema.openid.net/birthDate via ax. + +Contributing +------------ + +Please see the [contribution guidelines](http://github.com/Velir/open_id_authentication/blob/master/CONTRIBUTION_GUIDELINES.md). + +Credits +------- -This would provide the sreg data for :email via registration, and the AX data for 'http://schema.openid.net/birthDate' via ax. +open_id_authentication was written by David Heinemeier Hansson with a number of other [contributors](https://github.com/Velir/open_id_authentication/contributors). +open_id_authentication maintenance is funded by [Velir](http://velir.com). -Copyright (c) 2007 David Heinemeier Hansson, released under the MIT license \ No newline at end of file +License +------- +Copyright (c) 2007-2011 David Heinemeier Hansson, released under the MIT license \ No newline at end of file diff --git a/lib/open_id_authentication/version.rb b/lib/open_id_authentication/version.rb new file mode 100644 index 0000000..dbc9750 --- /dev/null +++ b/lib/open_id_authentication/version.rb @@ -0,0 +1,4 @@ +module OpenIdAuthentication + VERSION = "1.0.0" +end + \ No newline at end of file diff --git a/open_id_authentication.gemspec b/open_id_authentication.gemspec new file mode 100644 index 0000000..553b43e --- /dev/null +++ b/open_id_authentication.gemspec @@ -0,0 +1,32 @@ +$LOAD_PATH << File.join(File.dirname(__FILE__), 'lib') +require 'open_id_authentication/version' +Gem::Specification.new do |s| + s.name = %q{open_id_authentication} + s.version = OpenIdAuthentication::VERSION + s.summary = %q{open_id_authentication provides a thin wrapper around the excellent rack-openid + gem.} + s.description = %q{open_id_authentication provides a thin wrapper around the excellent rack-openid + gem.} + + s.files = Dir['[A-Z]*', 'lib/**/*.rb'] + s.require_path = 'lib' + + s.authors = ["Patrick Robertson"] + s.email = %q{patrick.robertson@velir.com} + s.homepage = "https://github.com/Velir/open_id_authentication" + + s.platform = Gem::Platform::RUBY + s.rubygems_version = %q{1.2.0} + + if s.respond_to? :specification_version then + s.specification_version = 3 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_runtime_dependency(%q, ["~> 1.3"]) + else + s.add_dependency(%q, ["~> 1.3"]) + end + else + s.add_dependency(%q, ["~> 1.3"]) + end +end \ No newline at end of file From 94ec97b46d711f6ed31e28533fca3b62e030a168 Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Wed, 14 Sep 2011 08:47:16 +0100 Subject: [PATCH 4/4] Provide a Railtie to initialise the plugin when used as a gem --- init.rb | 2 +- lib/open_id_authentication.rb | 109 ++++++++++++++++++++-------------- 2 files changed, 64 insertions(+), 47 deletions(-) diff --git a/init.rb b/init.rb index 84ec11f..40a6629 100644 --- a/init.rb +++ b/init.rb @@ -8,5 +8,5 @@ config.after_initialize do OpenID::Util.logger = Rails.logger - ActionController::Base.send :include, OpenIdAuthentication + ActionController::Base.send :include, OpenIdAuthentication::ControllerMethods end diff --git a/lib/open_id_authentication.rb b/lib/open_id_authentication.rb index ed875cd..4ce7f10 100644 --- a/lib/open_id_authentication.rb +++ b/lib/open_id_authentication.rb @@ -37,6 +37,21 @@ def self.store=(*store_option) self.store = nil + if Rails.version >= '3' + class Railtie < ::Rails::Railtie + config.app_middleware.use OpenIdAuthentication + + config.after_initialize do + OpenID::Util.logger = Rails.logger + end + + ActiveSupport.on_load :action_controller do + ActionController::Base.send :include, ControllerMethods + #ActionController::Base.extend ControllerMethods + end + end + end + class Result ERROR_MESSAGES = { :missing => "Sorry, the OpenID server couldn't be found", @@ -73,57 +88,59 @@ def message end end - protected - # The parameter name of "openid_identifier" is used rather than - # the Rails convention "open_id_identifier" because that's what - # the specification dictates in order to get browser auto-complete - # working across sites - def using_open_id?(identifier = nil) #:doc: - identifier ||= open_id_identifier - !identifier.blank? || request.env[Rack::OpenID::RESPONSE] - end + module ControllerMethods + protected + # The parameter name of "openid_identifier" is used rather than + # the Rails convention "open_id_identifier" because that's what + # the specification dictates in order to get browser auto-complete + # working across sites + def using_open_id?(identifier = nil) #:doc: + identifier ||= open_id_identifier + !identifier.blank? || request.env[Rack::OpenID::RESPONSE] + end - def authenticate_with_open_id(identifier = nil, options = {}, &block) #:doc: - identifier ||= open_id_identifier + def authenticate_with_open_id(identifier = nil, options = {}, &block) #:doc: + identifier ||= open_id_identifier - if request.env[Rack::OpenID::RESPONSE] - complete_open_id_authentication(&block) - else - begin_open_id_authentication(identifier, options, &block) + if request.env[Rack::OpenID::RESPONSE] + complete_open_id_authentication(&block) + else + begin_open_id_authentication(identifier, options, &block) + end end - end - private - def open_id_identifier - params[:openid_identifier] || params[:openid_url] - end + private + def open_id_identifier + params[:openid_identifier] || params[:openid_url] + end - def begin_open_id_authentication(identifier, options = {}) - options[:identifier] = identifier - value = Rack::OpenID.build_header(options) - response.headers[Rack::OpenID::AUTHENTICATE_HEADER] = value - head :unauthorized - end + def begin_open_id_authentication(identifier, options = {}) + options[:identifier] = identifier + value = Rack::OpenID.build_header(options) + response.headers[Rack::OpenID::AUTHENTICATE_HEADER] = value + head :unauthorized + end - def complete_open_id_authentication - response = request.env[Rack::OpenID::RESPONSE] - identifier = response.display_identifier - - case response.status - when OpenID::Consumer::SUCCESS - yield Result[:successful], identifier, - OpenID::SReg::Response.from_success_response(response), - OpenID::AX::FetchResponse.from_success_response(response) - when :missing - yield Result[:missing], identifier, nil - when :invalid - yield Result[:invalid], identifier, nil - when OpenID::Consumer::CANCEL - yield Result[:canceled], identifier, nil - when OpenID::Consumer::FAILURE - yield Result[:failed], identifier, nil - when OpenID::Consumer::SETUP_NEEDED - yield Result[:setup_needed], response.setup_url, nil + def complete_open_id_authentication + response = request.env[Rack::OpenID::RESPONSE] + identifier = response.display_identifier + + case response.status + when OpenID::Consumer::SUCCESS + yield Result[:successful], identifier, + OpenID::SReg::Response.from_success_response(response), + OpenID::AX::FetchResponse.from_success_response(response) + when :missing + yield Result[:missing], identifier, nil + when :invalid + yield Result[:invalid], identifier, nil + when OpenID::Consumer::CANCEL + yield Result[:canceled], identifier, nil + when OpenID::Consumer::FAILURE + yield Result[:failed], identifier, nil + when OpenID::Consumer::SETUP_NEEDED + yield Result[:setup_needed], response.setup_url, nil + end end - end + end end