annotate .svn/pristine/47/478eea0d533e8053ee16800d8a6228965a404db6.svn-base @ 1295:622f24f53b42 redmine-2.3

Update to Redmine SVN revision 11972 on 2.3-stable branch
author Chris Cannam
date Fri, 14 Jun 2013 09:02:21 +0100
parents
children
rev   line source
Chris@1295 1 require 'uri'
Chris@1295 2 require 'openid'
Chris@1295 3 require 'rack/openid'
Chris@1295 4
Chris@1295 5 module OpenIdAuthentication
Chris@1295 6 def self.new(app)
Chris@1295 7 store = OpenIdAuthentication.store
Chris@1295 8 if store.nil?
Chris@1295 9 Rails.logger.warn "OpenIdAuthentication.store is nil. Using in-memory store."
Chris@1295 10 end
Chris@1295 11
Chris@1295 12 ::Rack::OpenID.new(app, OpenIdAuthentication.store)
Chris@1295 13 end
Chris@1295 14
Chris@1295 15 def self.store
Chris@1295 16 @@store
Chris@1295 17 end
Chris@1295 18
Chris@1295 19 def self.store=(*store_option)
Chris@1295 20 store, *parameters = *([ store_option ].flatten)
Chris@1295 21
Chris@1295 22 @@store = case store
Chris@1295 23 when :memory
Chris@1295 24 require 'openid/store/memory'
Chris@1295 25 OpenID::Store::Memory.new
Chris@1295 26 when :file
Chris@1295 27 require 'openid/store/filesystem'
Chris@1295 28 OpenID::Store::Filesystem.new(Rails.root.join('tmp/openids'))
Chris@1295 29 when :memcache
Chris@1295 30 require 'memcache'
Chris@1295 31 require 'openid/store/memcache'
Chris@1295 32 OpenID::Store::Memcache.new(MemCache.new(parameters))
Chris@1295 33 else
Chris@1295 34 store
Chris@1295 35 end
Chris@1295 36 end
Chris@1295 37
Chris@1295 38 self.store = nil
Chris@1295 39
Chris@1295 40 class InvalidOpenId < StandardError
Chris@1295 41 end
Chris@1295 42
Chris@1295 43 class Result
Chris@1295 44 ERROR_MESSAGES = {
Chris@1295 45 :missing => "Sorry, the OpenID server couldn't be found",
Chris@1295 46 :invalid => "Sorry, but this does not appear to be a valid OpenID",
Chris@1295 47 :canceled => "OpenID verification was canceled",
Chris@1295 48 :failed => "OpenID verification failed",
Chris@1295 49 :setup_needed => "OpenID verification needs setup"
Chris@1295 50 }
Chris@1295 51
Chris@1295 52 def self.[](code)
Chris@1295 53 new(code)
Chris@1295 54 end
Chris@1295 55
Chris@1295 56 def initialize(code)
Chris@1295 57 @code = code
Chris@1295 58 end
Chris@1295 59
Chris@1295 60 def status
Chris@1295 61 @code
Chris@1295 62 end
Chris@1295 63
Chris@1295 64 ERROR_MESSAGES.keys.each { |state| define_method("#{state}?") { @code == state } }
Chris@1295 65
Chris@1295 66 def successful?
Chris@1295 67 @code == :successful
Chris@1295 68 end
Chris@1295 69
Chris@1295 70 def unsuccessful?
Chris@1295 71 ERROR_MESSAGES.keys.include?(@code)
Chris@1295 72 end
Chris@1295 73
Chris@1295 74 def message
Chris@1295 75 ERROR_MESSAGES[@code]
Chris@1295 76 end
Chris@1295 77 end
Chris@1295 78
Chris@1295 79 # normalizes an OpenID according to http://openid.net/specs/openid-authentication-2_0.html#normalization
Chris@1295 80 def self.normalize_identifier(identifier)
Chris@1295 81 # clean up whitespace
Chris@1295 82 identifier = identifier.to_s.strip
Chris@1295 83
Chris@1295 84 # if an XRI has a prefix, strip it.
Chris@1295 85 identifier.gsub!(/xri:\/\//i, '')
Chris@1295 86
Chris@1295 87 # dodge XRIs -- TODO: validate, don't just skip.
Chris@1295 88 unless ['=', '@', '+', '$', '!', '('].include?(identifier.at(0))
Chris@1295 89 # does it begin with http? if not, add it.
Chris@1295 90 identifier = "http://#{identifier}" unless identifier =~ /^http/i
Chris@1295 91
Chris@1295 92 # strip any fragments
Chris@1295 93 identifier.gsub!(/\#(.*)$/, '')
Chris@1295 94
Chris@1295 95 begin
Chris@1295 96 uri = URI.parse(identifier)
Chris@1295 97 uri.scheme = uri.scheme.downcase if uri.scheme # URI should do this
Chris@1295 98 identifier = uri.normalize.to_s
Chris@1295 99 rescue URI::InvalidURIError
Chris@1295 100 raise InvalidOpenId.new("#{identifier} is not an OpenID identifier")
Chris@1295 101 end
Chris@1295 102 end
Chris@1295 103
Chris@1295 104 return identifier
Chris@1295 105 end
Chris@1295 106
Chris@1295 107 protected
Chris@1295 108 # The parameter name of "openid_identifier" is used rather than
Chris@1295 109 # the Rails convention "open_id_identifier" because that's what
Chris@1295 110 # the specification dictates in order to get browser auto-complete
Chris@1295 111 # working across sites
Chris@1295 112 def using_open_id?(identifier = nil) #:doc:
Chris@1295 113 identifier ||= open_id_identifier
Chris@1295 114 !identifier.blank? || request.env[Rack::OpenID::RESPONSE]
Chris@1295 115 end
Chris@1295 116
Chris@1295 117 def authenticate_with_open_id(identifier = nil, options = {}, &block) #:doc:
Chris@1295 118 identifier ||= open_id_identifier
Chris@1295 119
Chris@1295 120 if request.env[Rack::OpenID::RESPONSE]
Chris@1295 121 complete_open_id_authentication(&block)
Chris@1295 122 else
Chris@1295 123 begin_open_id_authentication(identifier, options, &block)
Chris@1295 124 end
Chris@1295 125 end
Chris@1295 126
Chris@1295 127 private
Chris@1295 128 def open_id_identifier
Chris@1295 129 params[:openid_identifier] || params[:openid_url]
Chris@1295 130 end
Chris@1295 131
Chris@1295 132 def begin_open_id_authentication(identifier, options = {})
Chris@1295 133 options[:identifier] = identifier
Chris@1295 134 value = Rack::OpenID.build_header(options)
Chris@1295 135 response.headers[Rack::OpenID::AUTHENTICATE_HEADER] = value
Chris@1295 136 head :unauthorized
Chris@1295 137 end
Chris@1295 138
Chris@1295 139 def complete_open_id_authentication
Chris@1295 140 response = request.env[Rack::OpenID::RESPONSE]
Chris@1295 141 identifier = response.display_identifier
Chris@1295 142
Chris@1295 143 case response.status
Chris@1295 144 when OpenID::Consumer::SUCCESS
Chris@1295 145 yield Result[:successful], identifier,
Chris@1295 146 OpenID::SReg::Response.from_success_response(response)
Chris@1295 147 when :missing
Chris@1295 148 yield Result[:missing], identifier, nil
Chris@1295 149 when :invalid
Chris@1295 150 yield Result[:invalid], identifier, nil
Chris@1295 151 when OpenID::Consumer::CANCEL
Chris@1295 152 yield Result[:canceled], identifier, nil
Chris@1295 153 when OpenID::Consumer::FAILURE
Chris@1295 154 yield Result[:failed], identifier, nil
Chris@1295 155 when OpenID::Consumer::SETUP_NEEDED
Chris@1295 156 yield Result[:setup_needed], response.setup_url, nil
Chris@1295 157 end
Chris@1295 158 end
Chris@1295 159 end