Changeset 9103
- Timestamp:
- 03/27/08 23:26:52 (2 months ago)
- Files:
-
- plugins/open_id_authentication/CHANGELOG (modified) (1 diff)
- plugins/open_id_authentication/generators (added)
- plugins/open_id_authentication/generators/open_id_authentication_tables (added)
- plugins/open_id_authentication/generators/open_id_authentication_tables/open_id_authentication_tables_generator.rb (added)
- plugins/open_id_authentication/generators/open_id_authentication_tables/templates (added)
- plugins/open_id_authentication/generators/open_id_authentication_tables/templates/migration.rb (added)
- plugins/open_id_authentication/generators/upgrade_open_id_authentication_tables (added)
- plugins/open_id_authentication/generators/upgrade_open_id_authentication_tables/templates (added)
- plugins/open_id_authentication/generators/upgrade_open_id_authentication_tables/templates/migration.rb (added)
- plugins/open_id_authentication/generators/upgrade_open_id_authentication_tables/upgrade_open_id_authentication_tables_generator.rb (added)
- plugins/open_id_authentication/init.rb (modified) (1 diff)
- plugins/open_id_authentication/lib/generators (deleted)
- plugins/open_id_authentication/lib/open_id_authentication.rb (modified) (9 diffs)
- plugins/open_id_authentication/lib/open_id_authentication/db_store.rb (modified) (3 diffs)
- plugins/open_id_authentication/lib/open_id_authentication/setting.rb (deleted)
- plugins/open_id_authentication/README (modified) (1 diff)
- plugins/open_id_authentication/tasks/open_id_authentication_tasks.rake (modified) (1 diff)
- plugins/open_id_authentication/test/normalize_test.rb (modified) (2 diffs)
- plugins/open_id_authentication/test/open_id_authentication_test.rb (modified) (4 diffs)
- plugins/open_id_authentication/test/status_test.rb (modified) (1 diff)
- plugins/open_id_authentication/test/test_helper.rb (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
plugins/open_id_authentication/CHANGELOG
r8872 r9103 1 * Updated plugin to use Ruby OpenID 2.x.x [Josh Peek] 2 1 3 * Tied plugin to ruby-openid 1.1.4 gem until we can make it compatible with 2.x [DHH] 2 4 plugins/open_id_authentication/init.rb
r8872 r9103 1 1 begin 2 gem 'ruby-openid', '=1.1.4' 3 require 'openid' 2 require 'openid' 4 3 rescue LoadError 5 puts "Install the ruby-openid gem to enable OpenID support" 4 begin 5 gem 'ruby-openid', '>=2.0.4' 6 rescue Gem::LoadError 7 puts "Install the ruby-openid gem to enable OpenID support" 8 end 6 9 end 7 10 plugins/open_id_authentication/lib/open_id_authentication.rb
r8931 r9103 1 1 require 'uri' 2 require 'openid/extensions/sreg' 3 require 'openid/store/filesystem' 2 4 3 5 module OpenIdAuthentication 4 6 OPEN_ID_AUTHENTICATION_DIR = RAILS_ROOT + "/tmp/openids" 5 7 6 8 def self.store 7 9 @@store 8 10 end 9 11 10 12 def self.store=(value) 11 13 @@store = value 12 14 end 13 15 14 16 self.store = :db 15 17 16 18 def store 17 19 OpenIdAuthentication.store … … 23 25 class Result 24 26 ERROR_MESSAGES = { 25 :missing => "Sorry, the OpenID server couldn't be found", 26 :canceled => "OpenID verification was canceled", 27 :failed => "Sorry, the OpenID verification failed" 27 :missing => "Sorry, the OpenID server couldn't be found", 28 :canceled => "OpenID verification was canceled", 29 :failed => "Sorry, the OpenID verification failed", 30 :setup_needed => "OpenID verification needs setup" 28 31 } 29 32 30 33 def self.[](code) 31 34 new(code) 32 35 end 33 36 34 37 def initialize(code) 35 38 @code = code 36 39 end 37 40 38 41 def ===(code) 39 42 if code == :unsuccessful && unsuccessful? … … 43 46 end 44 47 end 45 48 46 49 ERROR_MESSAGES.keys.each { |state| define_method("#{state}?") { @code == state } } 47 50 … … 53 56 ERROR_MESSAGES.keys.include?(@code) 54 57 end 55 58 56 59 def message 57 60 ERROR_MESSAGES[@code] … … 67 70 raise InvalidOpenId.new("#{url} is not an OpenID URL") 68 71 end 69 70 72 71 73 protected … … 88 90 end 89 91 90 91 92 private 92 93 def begin_open_id_authentication(identity_url, fields = {}) 93 open_id_response = timeout_protection_from_identity_server { open_id_consumer.begin(identity_url) } 94 open_id_request = open_id_consumer.begin(identity_url) 95 add_simple_registration_fields(open_id_request, fields) 96 redirect_to(open_id_redirect_url(open_id_request)) 97 rescue OpenID::OpenIDError, Timeout::Error => e 98 logger.error("[OPENID] #{e}") 99 yield Result[:missing], identity_url, nil 100 end 101 102 def complete_open_id_authentication 103 params_with_path = params.reject { |key, value| request.path_parameters[key] } 104 open_id_response = timeout_protection_from_identity_server { open_id_consumer.complete(params_with_path, requested_url) } 105 identity_url = normalize_url(open_id_response.endpoint.claimed_id) if open_id_response.endpoint.claimed_id 94 106 95 107 case open_id_response.status 96 when OpenID::FAILURE 97 yield Result[:missing], identity_url, nil 98 when OpenID::SUCCESS 99 add_simple_registration_fields(open_id_response, fields) 100 redirect_to(open_id_redirect_url(open_id_response)) 108 when OpenID::Consumer::SUCCESS 109 yield Result[:successful], identity_url, OpenID::SReg::Response.from_success_response(open_id_response) 110 when OpenID::Consumer::CANCEL 111 yield Result[:canceled], identity_url, nil 112 when OpenID::Consumer::FAILURE 113 yield Result[:failed], identity_url, nil 114 when OpenID::Consumer::SETUP_NEEDED 115 yield Result[:setup_needed], open_id_response.setup_url, nil 101 116 end 102 end103 104 def complete_open_id_authentication105 open_id_response = timeout_protection_from_identity_server { open_id_consumer.complete(params) }106 identity_url = normalize_url(open_id_response.identity_url) if open_id_response.identity_url107 108 case open_id_response.status109 when OpenID::CANCEL110 yield Result[:canceled], identity_url, nil111 when OpenID::FAILURE112 logger.info "OpenID authentication failed: #{open_id_response.msg}"113 yield Result[:failed], identity_url, nil114 when OpenID::SUCCESS115 yield Result[:successful], identity_url, open_id_response.extension_response('sreg')116 end117 117 end 118 118 … … 120 120 OpenID::Consumer.new(session, open_id_store) 121 121 end 122 122 123 123 def open_id_store 124 124 case store … … 132 132 end 133 133 134 def add_simple_registration_fields(open_id_request, fields) 135 sreg_request = OpenID::SReg::Request.new 136 sreg_request.request_fields(Array(fields[:required]).map(&:to_s), true) if fields[:required] 137 sreg_request.request_fields(Array(fields[:optional]).map(&:to_s), false) if fields[:optional] 138 sreg_request.policy_url = fields[:policy_url] if fields[:policy_url] 139 open_id_request.add_extension(sreg_request) 140 end 134 141 135 def add_simple_registration_fields(open_id_response, fields)136 open_id_re sponse.add_extension_arg('sreg', 'required', [ fields[:required] ].flatten * ',') if fields[:required]137 open_id_re sponse.add_extension_arg('sreg', 'optional', [ fields[:optional] ].flatten * ',') if fields[:optional]142 def open_id_redirect_url(open_id_request) 143 open_id_request.return_to_args['open_id_complete'] = '1' 144 open_id_request.redirect_url(root_url, requested_url) 138 145 end 139 140 def open_id_redirect_url(open_id_response) 141 open_id_response.redirect_url( 142 request.protocol + request.host_with_port + "/", 143 open_id_response.return_to("#{request.protocol + request.host_with_port + request.relative_url_root + request.path}?open_id_complete=1") 144 ) 146 147 def requested_url 148 "#{request.protocol + request.host_with_port + request.relative_url_root + request.path}" 145 149 end 146 150 … … 152 156 OpenID::FAILURE 153 157 end 154 158 155 159 def msg 156 160 "Identity server timed out" plugins/open_id_authentication/lib/open_id_authentication/db_store.rb
r6514 r9103 1 require 'openid/store/interface' 2 1 3 module OpenIdAuthentication 2 class DbStore < OpenID::Store 3 def self. gc4 class DbStore < OpenID::Store::Interface 5 def self.cleanup_nonces 4 6 now = Time.now.to_i 5 6 # remove old nonces 7 nonces = Nonce.find(:all) 8 nonces.each {|n| n.destroy if now - n.created > 6.hours} unless nonces.nil? 9 10 # remove expired assocs 11 assocs = Association.find(:all) 12 assocs.each { |a| a.destroy if a.from_record.expired? } unless assocs.nil? 7 Nonce.delete_all(["timestamp > ? OR timestamp < ?", now + OpenID::Nonce.skew, now - OpenID::Nonce.skew]) 13 8 end 14 9 15 16 def get_auth_key 17 unless setting = Setting.find_by_setting('auth_key') 18 auth_key = OpenID::Util.random_string(20) 19 setting = Setting.create(:setting => 'auth_key', :value => auth_key) 20 end 21 22 setting.value 10 def self.cleanup_associations 11 now = Time.now.to_i 12 Association.delete_all(['issued + lifetime > ?',now]) 23 13 end 24 14 25 15 def store_association(server_url, assoc) 26 remove_association(server_url, assoc.handle) 16 remove_association(server_url, assoc.handle) 27 17 Association.create(:server_url => server_url, 28 18 :handle => assoc.handle, … … 33 23 end 34 24 35 def get_association(server_url, handle=nil) 36 assocs = handle.blank? ? 37 Association.find_all_by_server_url(server_url) : 25 def get_association(server_url, handle = nil) 26 assocs = if handle.blank? 27 Association.find_all_by_server_url(server_url) 28 else 38 29 Association.find_all_by_server_url_and_handle(server_url, handle) 39 30 end 31 40 32 assocs.reverse.each do |assoc| 41 a = assoc.from_record 42 if a.expire d?33 a = assoc.from_record 34 if a.expires_in == 0 43 35 assoc.destroy 44 36 else … … 46 38 end 47 39 end if assocs.any? 48 40 49 41 return nil 50 42 end 51 43 52 44 def remove_association(server_url, handle) 53 assoc = Association.find_by_server_url_and_handle(server_url, handle) 54 unless assoc.nil? 55 assoc.destroy 56 return true 57 end 58 false 45 Association.delete_all(['server_url = ? AND handle = ?', server_url, handle]) > 0 59 46 end 60 61 def store_nonce(nonce)62 use_nonce(nonce)63 Nonce.create :nonce => nonce, :created => Time.now.to_i64 end65 66 def use_nonce(nonce)67 nonce = Nonce.find_by_nonce(nonce)68 return false if nonce.nil?69 70 age = Time.now.to_i - nonce.created71 nonce.destroy72 47 73 age < 6.hours # max nonce age of 6 hours74 end75 76 def dumb?77 false48 def use_nonce(server_url, timestamp, salt) 49 return false if Nonce.find_by_server_url_and_timestamp_and_salt(server_url, timestamp, salt) 50 return false if (timestamp - Time.now.to_i).abs > OpenID::Nonce.skew 51 Nonce.create(:server_url => server_url, :timestamp => timestamp, :salt => salt) 52 return true 78 53 end 79 54 end plugins/open_id_authentication/README
r8225 r9103 9 9 from that gem. 10 10 11 The specification used is http://openid.net/specs/openid-authentication- 1_1.html (not the 2.0 draft).11 The specification used is http://openid.net/specs/openid-authentication-2_0.html. 12 12 13 13 plugins/open_id_authentication/tasks/open_id_authentication_tasks.rake
r6515 r9103 3 3 desc "Creates authentication tables for use with OpenIdAuthentication" 4 4 task :create => :environment do 5 raise "Task unavailable to this database (no migration support)" unless ActiveRecord::Base.connection.supports_migrations? 5 generate_migration(["open_id_authentication_tables", "add_open_id_authentication_tables"]) 6 end 7 8 desc "Upgrade authentication tables from ruby-openid 1.x.x to 2.x.x" 9 task :upgrade => :environment do 10 generate_migration(["upgrade_open_id_authentication_tables", "upgrade_open_id_authentication_tables"]) 11 end 12 13 def generate_migration(args) 6 14 require 'rails_generator' 7 15 require 'rails_generator/scripts/generate' 8 Rails::Generator::Scripts::Generate.new.run([ "open_id_authentication_tables", "add_open_id_authentication_tables" ]) 16 17 if ActiveRecord::Base.connection.supports_migrations? 18 Rails::Generator::Scripts::Generate.new.run(args) 19 else 20 raise "Task unavailable to this database (no migration support)" 21 end 9 22 end 10 23 11 24 desc "Clear the authentication tables" 12 25 task :clear => :environment do 13 OpenIdAuthentication::DbStore.gc 26 OpenIdAuthentication::DbStore.cleanup_nonces 27 OpenIdAuthentication::DbStore.cleanup_associations 14 28 end 15 29 end plugins/open_id_authentication/test/normalize_test.rb
r8931 r9103 1 require 'test/unit' 2 require 'rubygems' 3 require 'active_support' 4 5 RAILS_ROOT = File.dirname(__FILE__) 6 require File.dirname(__FILE__) + "/../lib/open_id_authentication" 1 require File.dirname(__FILE__) + '/test_helper' 7 2 8 3 class NormalizeTest < Test::Unit::TestCase … … 30 25 end 31 26 end 32 27 33 28 def test_broken_open_id 34 29 assert_raises(InvalidOpenId) { normalize_url(nil) } plugins/open_id_authentication/test/open_id_authentication_test.rb
r7162 r9103 1 require 'test/unit' 2 3 require 'rubygems' 4 gem 'mocha' 5 require 'mocha' 6 7 gem 'ruby-openid' 8 require 'openid' 9 10 RAILS_ROOT = File.dirname(__FILE__) 11 require File.dirname(__FILE__) + "/../lib/open_id_authentication" 1 require File.dirname(__FILE__) + '/test_helper' 12 2 13 3 class OpenIdAuthenticationTest < Test::Unit::TestCase … … 20 10 21 11 def test_authentication_should_fail_when_the_identity_server_is_missing 22 @controller.stubs(:open_id_consumer).returns(stub(:begin => stub(:status => OpenID::FAILURE))) 23 12 open_id_consumer = mock() 13 open_id_consumer.expects(:begin).raises(OpenID::OpenIDError) 14 @controller.stubs(:open_id_consumer).returns(open_id_consumer) 15 24 16 @controller.send(:authenticate_with_open_id, "http://someone.example.com") do |result, identity_url| 25 17 assert result.missing? … … 29 21 30 22 def test_authentication_should_fail_when_the_identity_server_times_out 31 @controller.stubs(:open_id_consumer).returns(stub(:begin => Proc.new { raise Timeout::Error, "Identity Server took too long." })) 23 open_id_consumer = mock() 24 open_id_consumer.expects(:begin).raises(Timeout::Error, "Identity Server took too long.") 25 @controller.stubs(:open_id_consumer).returns(open_id_consumer) 32 26 33 27 @controller.send(:authenticate_with_open_id, "http://someone.example.com") do |result, identity_url| … … 38 32 39 33 def test_authentication_should_begin_when_the_identity_server_is_present 40 @controller.stubs(:open_id_consumer).returns(stub(:begin => stub(:status => OpenID::SUCCESS)))41 @controller.expects(:begin_open_id_authentication) 34 @controller.stubs(:open_id_consumer).returns(stub(:begin => true)) 35 @controller.expects(:begin_open_id_authentication) 42 36 @controller.send(:authenticate_with_open_id, "http://someone.example.com") 43 37 end plugins/open_id_authentication/test/status_test.rb
r6324 r9103 1 require 'test/unit' 2 3 RAILS_ROOT = File.dirname(__FILE__) 4 require File.dirname(__FILE__) + "/../lib/open_id_authentication" 1 require File.dirname(__FILE__) + '/test_helper' 5 2 6 3 class StatusTest < Test::Unit::TestCase