devise_openid_authenticatable 1.0.0.alpha3 → 1.0.0.alpha4

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -83,8 +83,56 @@ to your user model class:
83
83
  end
84
84
  end
85
85
 
86
- Ideally I'd like to add support for using sreg attributes here as well, to populate other
87
- fields in the user table.
86
+ SReg and AX Extensions
87
+ ----------------------
88
+
89
+ As of version 1.0.0.alpha4, devise_openid_authenticatable now supports the SReg (simple registration) and AX
90
+ (attribute exchange) extensions. This allows OpenID providers to pass you additional user details, such as
91
+ name, email address, gender, nickname, etc.
92
+
93
+ To add SReg and AX support to your User model, you'll need to do two things: first, you need to specify what
94
+ fields you'd like to request from OpenID providers. Second, you need to provide a method for processing
95
+ these fields during authentication.
96
+
97
+ To specify which fields to request, you can implement one (or both) of two class methods:
98
+ openid_required_fields and openid_optional_fields. For example:
99
+
100
+ def self.openid_required_fields
101
+ ["fullname", "email", "http://axschema.org/namePerson", "http://axschema.org/contact/email"]
102
+ end
103
+
104
+ def self.openid_optional_fields
105
+ ["gender", "http://axschema.org/person/gender"]
106
+ end
107
+
108
+ Required fields should be used for fields without which your app can't operate properly. Optional fields
109
+ should be used for fields which are nice to have, but not necessary for your app. Note that just because you
110
+ specify a field as "required" doesn't necessarily mean that the OpenID provider has to give it to you (for
111
+ example, a provider might not have that field for its users).
112
+
113
+ In the above example, we're specifying both SReg fields (fullname, email, and gender) and the equivalent
114
+ AX fields (the ones that look like URLs). A list of defined AX fields and their equivalent SReg fields can
115
+ be found at [http://www.axschema.org/types](http://www.axschema.org/types). It is highly recommended to
116
+ specify both AX and SReg fields, as both are implemented by different common OpenID providers.
117
+
118
+ Once a successful OpenID response comes back, you still need to process the fields that the provider returned
119
+ to your app. To do that, implement an instance method called openid_fields=. This method takes a hash that
120
+ maps each returned field to a string value. For example:
121
+
122
+ def openid_fields=(fields)
123
+ fields.each do |key, value|
124
+ case key.to_s
125
+ when "fullname", "http://axschema.org/namePerson"
126
+ self.name = value
127
+ when "email", "http://axschema.org/contact/email"
128
+ self.email = value
129
+ when "gender", "http://axschema.org/person/gender"
130
+ self.gender = value
131
+ else
132
+ logger.error "Unknown OpenID field: #{key}"
133
+ end
134
+ end
135
+ end
88
136
 
89
137
  See also
90
138
  --------
data/Rakefile CHANGED
@@ -33,7 +33,7 @@ begin
33
33
  gemspec.homepage = "http://github.com/nbudin/devise_cas_authenticatable"
34
34
  gemspec.authors = ["Nat Budin"]
35
35
  gemspec.add_runtime_dependency "devise", ">= 1.0.6"
36
- gemspec.add_runtime_dependency "rack-openid", "~> 1.0.3"
36
+ gemspec.add_runtime_dependency "rack-openid", ">= 1.0.3"
37
37
  end
38
38
  Jeweler::GemcutterTasks.new
39
39
  rescue LoadError
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.0.alpha3
1
+ 1.0.0.alpha4
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{devise_openid_authenticatable}
8
- s.version = "1.0.0.alpha3"
8
+ s.version = "1.0.0.alpha4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Nat Budin"]
@@ -40,14 +40,14 @@ Gem::Specification.new do |s|
40
40
 
41
41
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
42
42
  s.add_runtime_dependency(%q<devise>, [">= 1.0.6"])
43
- s.add_runtime_dependency(%q<rack-openid>, ["~> 1.0.3"])
43
+ s.add_runtime_dependency(%q<rack-openid>, [">= 1.0.3"])
44
44
  else
45
45
  s.add_dependency(%q<devise>, [">= 1.0.6"])
46
- s.add_dependency(%q<rack-openid>, ["~> 1.0.3"])
46
+ s.add_dependency(%q<rack-openid>, [">= 1.0.3"])
47
47
  end
48
48
  else
49
49
  s.add_dependency(%q<devise>, [">= 1.0.6"])
50
- s.add_dependency(%q<rack-openid>, ["~> 1.0.3"])
50
+ s.add_dependency(%q<rack-openid>, [">= 1.0.3"])
51
51
  end
52
52
  end
53
53
 
@@ -10,16 +10,27 @@ module Devise
10
10
  end
11
11
 
12
12
  def authenticate!
13
- RAILS_DEFAULT_LOGGER.info("Authenticating with OpenID for mapping #{mapping.to}")
13
+ logger.debug("Authenticating with OpenID for mapping #{mapping.to}")
14
14
  if resp = env[Rack::OpenID::RESPONSE]
15
- RAILS_DEFAULT_LOGGER.info "Attempting OpenID auth: #{env["rack.openid.response"].inspect}"
15
+ logger.debug "Attempting OpenID auth: #{env["rack.openid.response"].inspect}"
16
16
  case resp.status
17
17
  when :success
18
18
  u = mapping.to.find_by_identity_url(resp.identity_url)
19
+ if u.nil? && mapping.to.respond_to?(:create_from_identity_url)
20
+ u = mapping.to.create_from_identity_url(resp.identity_url)
21
+ end
22
+
19
23
  if u
24
+ if u.respond_to?("openid_fields=")
25
+ openid_fields = parse_openid_fields(resp)
26
+
27
+ if openid_fields
28
+ u.openid_fields = openid_fields
29
+ u.save
30
+ end
31
+ end
32
+
20
33
  success!(u)
21
- elsif mapping.to.respond_to?(:create_from_identity_url)
22
- success!(mapping.to.create_from_identity_url(resp.identity_url))
23
34
  else
24
35
  fail!("This OpenID URL is not associated with any registered user")
25
36
  end
@@ -29,22 +40,43 @@ module Devise
29
40
  fail!("OpenID auth failed")
30
41
  end
31
42
  else
32
- # construct a return URL, preserving all the scope parameters as GET parameters
33
- return_to = URI.parse(request.url)
34
- scope_params = {}
35
- params[scope].each do |k, v|
36
- scope_params["#{scope}[#{k}]"] = v
37
- end
38
- return_to.query = Rack::Utils.build_query(scope_params)
39
-
40
- header_data = Rack::OpenID.build_header(:identifier => params[scope]["identity_url"], :return_to => return_to.to_s,
41
- :method => request.method)
42
- RAILS_DEFAULT_LOGGER.info header_data
43
+ header_params = { :identifier => params[scope]["identity_url"] }
44
+ header_params[:optional] = mapping.to.openid_optional_fields if mapping.to.respond_to?(:openid_optional_fields)
45
+ header_params[:required] = mapping.to.openid_required_fields if mapping.to.respond_to?(:openid_required_fields)
46
+ header_data = Rack::OpenID.build_header(header_params)
47
+ logger.debug header_data
43
48
  custom!([401, {
44
49
  Rack::OpenID::AUTHENTICATE_HEADER => header_data
45
50
  }, "Sign in with OpenID"])
46
51
  end
47
52
  end
53
+
54
+ private
55
+ def parse_openid_fields(resp)
56
+ openid_fields = nil
57
+ axr = OpenID::AX::FetchResponse.from_success_response(resp)
58
+ if axr
59
+ openid_fields = axr.data
60
+ else
61
+ resp.message.namespaces.each do |uri, ns_alias|
62
+ if ns_alias.to_s == "sreg"
63
+ openid_fields = resp.extension_response(uri, true)
64
+ break
65
+ end
66
+ end
67
+ end
68
+
69
+ # Make sure everything is a string
70
+ openid_fields.each do |k, v|
71
+ openid_fields[k] = v.to_s
72
+ end
73
+
74
+ return openid_fields
75
+ end
76
+
77
+ def logger
78
+ @logger ||= ((Rails && Rails.logger) || RAILS_DEFAULT_LOGGER)
79
+ end
48
80
  end
49
81
  end
50
82
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devise_openid_authenticatable
3
3
  version: !ruby/object:Gem::Version
4
- hash: -1710980575
4
+ hash: -1710980386
5
5
  prerelease: true
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
9
  - 0
10
- - alpha3
11
- version: 1.0.0.alpha3
10
+ - alpha4
11
+ version: 1.0.0.alpha4
12
12
  platform: ruby
13
13
  authors:
14
14
  - Nat Budin
@@ -41,7 +41,7 @@ dependencies:
41
41
  requirement: &id002 !ruby/object:Gem::Requirement
42
42
  none: false
43
43
  requirements:
44
- - - ~>
44
+ - - ">="
45
45
  - !ruby/object:Gem::Version
46
46
  hash: 17
47
47
  segments: