devise_openid_authenticatable 1.0.0.alpha3 → 1.0.0.alpha4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: