devise_openid_authenticatable 1.0.0.alpha6 → 1.0.0.alpha7

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -3,3 +3,4 @@ log/
3
3
  Gemfile.lock
4
4
  .bundle
5
5
  spec/scenario/db/*.sqlite3
6
+ spec/scenario/tmp/*
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,8 @@
1
+ == 1.0.0.alpha7
2
+
3
+ * GH-3: Add support for rememberable.
4
+ * This requires an upgrade to rack-openid 1.2.0 or higher.
5
+
1
6
  == 1.0.0.alpha5
2
7
 
3
8
  * GH-5: Don't try to convert returned values to strings from AX providers
@@ -18,4 +23,4 @@
18
23
 
19
24
  == 1.0.0.alpha1
20
25
 
21
- * Initial version, basically just a packaged-up version of my OpenID strategy for Devise
26
+ * Initial version, basically just a packaged-up version of my OpenID strategy for Devise
data/Gemfile CHANGED
@@ -1,9 +1,13 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem 'rails', '3.0.0.rc'
4
- gem "devise", ">= 1.1.1"
3
+ gem 'rails', '3.0.0'
4
+ gem "devise", ">= 1.1.2"
5
5
  gem "rspec", ">= 2.0.0.beta.17"
6
6
  gem "rspec-rails", ">= 2.0.0.beta.17"
7
- gem "rack-openid", ">= 1.0.3"
7
+ gem "rack-openid", ">= 1.2.0"
8
8
  gem "mocha"
9
9
  gem "sqlite3-ruby"
10
+ gem "rots", :git => "http://github.com/roman/rots.git"
11
+ gem "sham_rack"
12
+ gem "webrat"
13
+ gem "ruby-debug"
data/README.md CHANGED
@@ -62,11 +62,14 @@ aren't using database_authenticatable:
62
62
  <p><%= f.submit "Sign in" %></p>
63
63
  <% end -%>
64
64
 
65
- Finally, you'll need to wire up Rack::OpenID in your Rails configuration. If you're using Devise 1.0, you can do:
65
+ Finally, you'll need to wire up Rack::OpenID in your Rails configuration. The way to do this varies depending on which version of Rails you're using. If you're on Rails 2.3 (and Devise 1.0), you must initialize it like this:
66
66
 
67
- config.middleware.use "Rack::OpenID"
67
+ require 'openid/store/memory'
68
+ config.middleware.use "Rack::OpenID", OpenID::Store::Memory.new
68
69
 
69
- If you're using Devise 1.1 or a later version, you'll need to do this instead, to ensure that Rack::OpenID sits above Warden in the Rack middleware stack:
70
+ (Specifying an OpenID store instance is necessary because Rails 2.3 reinitializes the middleware objects on each request, so in order to ensure that the stored OpenID data is persistent between subsequent requests, we initialize the Memory store upfront and pass in the same instance each time. If you prefer to use a different store, such as the Memcached store, feel free to substitute in the appropriate class here.)
71
+
72
+ If you're using Rails 3, you'll need to do this instead, to ensure that Rack::OpenID sits above Warden in the Rack middleware stack:
70
73
 
71
74
  config.middleware.insert_before(Warden::Manager, Rack::OpenID)
72
75
 
data/Rakefile CHANGED
@@ -27,7 +27,7 @@ begin
27
27
  gemspec.homepage = "http://github.com/nbudin/devise_openid_authenticatable"
28
28
  gemspec.authors = ["Nat Budin"]
29
29
  gemspec.add_runtime_dependency "devise", ">= 1.0.6"
30
- gemspec.add_runtime_dependency "rack-openid", ">= 1.0.3"
30
+ gemspec.add_runtime_dependency "rack-openid", ">= 1.2.0"
31
31
  end
32
32
  Jeweler::GemcutterTasks.new
33
33
  rescue LoadError
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.0.alpha6
1
+ 1.0.0.alpha7
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{devise_openid_authenticatable}
8
- s.version = "1.0.0.alpha6"
8
+ s.version = "1.0.0.alpha7"
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"]
12
- s.date = %q{2010-08-19}
12
+ s.date = %q{2010-09-08}
13
13
  s.description = %q{OpenID authentication module for Devise using Rack::OpenID}
14
14
  s.email = %q{natbudin@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -34,6 +34,7 @@ Gem::Specification.new do |s|
34
34
  "spec/scenario/app/controllers/home_controller.rb",
35
35
  "spec/scenario/app/controllers/sessions_controller.rb",
36
36
  "spec/scenario/app/models/user.rb",
37
+ "spec/scenario/app/views/layouts/application.html.erb",
37
38
  "spec/scenario/app/views/sessions/new.html.erb",
38
39
  "spec/scenario/config.ru",
39
40
  "spec/scenario/config/application.rb",
@@ -50,8 +51,7 @@ Gem::Specification.new do |s|
50
51
  "spec/scenario/db/schema.rb",
51
52
  "spec/spec_helper.rb",
52
53
  "spec/strategy_spec.rb",
53
- "spec/support/migrations.rb",
54
- "spec/support/patches.rb"
54
+ "spec/support/migrations.rb"
55
55
  ]
56
56
  s.homepage = %q{http://github.com/nbudin/devise_openid_authenticatable}
57
57
  s.rdoc_options = ["--charset=UTF-8"]
@@ -77,8 +77,7 @@ Gem::Specification.new do |s|
77
77
  "spec/scenario/db/schema.rb",
78
78
  "spec/spec_helper.rb",
79
79
  "spec/strategy_spec.rb",
80
- "spec/support/migrations.rb",
81
- "spec/support/patches.rb"
80
+ "spec/support/migrations.rb"
82
81
  ]
83
82
 
84
83
  if s.respond_to? :specification_version then
@@ -87,14 +86,14 @@ Gem::Specification.new do |s|
87
86
 
88
87
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
89
88
  s.add_runtime_dependency(%q<devise>, [">= 1.0.6"])
90
- s.add_runtime_dependency(%q<rack-openid>, [">= 1.0.3"])
89
+ s.add_runtime_dependency(%q<rack-openid>, [">= 1.2.0"])
91
90
  else
92
91
  s.add_dependency(%q<devise>, [">= 1.0.6"])
93
- s.add_dependency(%q<rack-openid>, [">= 1.0.3"])
92
+ s.add_dependency(%q<rack-openid>, [">= 1.2.0"])
94
93
  end
95
94
  else
96
95
  s.add_dependency(%q<devise>, [">= 1.0.6"])
97
- s.add_dependency(%q<rack-openid>, [">= 1.0.3"])
96
+ s.add_dependency(%q<rack-openid>, [">= 1.2.0"])
98
97
  end
99
98
  end
100
99
 
@@ -1,99 +1,112 @@
1
1
  require 'devise/strategies/base'
2
2
  require 'rack/openid'
3
3
 
4
- module Devise
5
- module Strategies
6
- class OpenidAuthenticatable < Base
4
+ base_class = begin
5
+ Devise::Strategies::Authenticatable
6
+ rescue
7
+ Devise::Strategies::Base
8
+ end
7
9
 
8
- def valid?
9
- valid_mapping? && ( provider_response? || identity_param? )
10
- end
10
+ class Devise::Strategies::OpenidAuthenticatable < base_class
11
11
 
12
- def authenticate!
13
- logger.debug("Authenticating with OpenID for mapping #{mapping.to}")
12
+ def valid?
13
+ valid_mapping? && ( provider_response? || identity_param? )
14
+ end
14
15
 
15
- if provider_response
16
- handle_response!
17
- else # Delegate authentication to Rack::OpenID by throwing a 401
18
- opts = { :identifier => params[scope]["identity_url"] }
19
- opts[:optional] = mapping.to.openid_optional_fields if mapping.to.respond_to?(:openid_optional_fields)
20
- opts[:required] = mapping.to.openid_required_fields if mapping.to.respond_to?(:openid_required_fields)
21
- custom! [401, { Rack::OpenID::AUTHENTICATE_HEADER => Rack::OpenID.build_header(opts) }, "Sign in with OpenID"]
22
- end
23
- end
16
+ def authenticate!
17
+ logger.debug("Authenticating with OpenID for mapping #{mapping.to}")
24
18
 
25
- protected
26
-
27
- # Handles incoming provider response
28
- def handle_response!
29
- logger.debug "Attempting OpenID auth: #{provider_response.inspect}"
30
-
31
- case provider_response.status
32
- when :success
33
- resource = mapping.to.find_by_identity_url(provider_response.identity_url)
34
- if resource.nil? && mapping.to.respond_to?(:create_from_identity_url)
35
- resource = mapping.to.create_from_identity_url(provider_response.identity_url)
36
- end
37
-
38
- if resource
39
- update_resource!(resource)
40
- success!(resource)
41
- else
42
- fail! "This OpenID URL is not associated with any registered user"
43
- end
44
-
45
- when :cancel
46
- fail! "OpenID authentication cancelled"
47
- when :failure
48
- fail! "OpenID authentication failed"
49
- end
50
- end
19
+ if provider_response
20
+ handle_response!
21
+ else # Delegate authentication to Rack::OpenID by throwing a 401
22
+ opts = { :identifier => params[scope]["identity_url"], :return_to => return_url, :method => 'post' }
23
+ opts[:optional] = mapping.to.openid_optional_fields if mapping.to.respond_to?(:openid_optional_fields)
24
+ opts[:required] = mapping.to.openid_required_fields if mapping.to.respond_to?(:openid_required_fields)
25
+ custom! [401, { Rack::OpenID::AUTHENTICATE_HEADER => Rack::OpenID.build_header(opts) }, "Sign in with OpenID"]
26
+ end
27
+ end
51
28
 
52
- private
29
+ protected
53
30
 
54
- def provider_response?
55
- !!provider_response
56
- end
31
+ # Handles incoming provider response
32
+ def handle_response!
33
+ logger.debug "Attempting OpenID auth: #{provider_response.inspect}"
57
34
 
58
- def provider_response
59
- env[Rack::OpenID::RESPONSE]
35
+ case provider_response.status
36
+ when :success
37
+ resource = mapping.to.find_by_identity_url(provider_response.identity_url)
38
+ if resource.nil? && mapping.to.respond_to?(:create_from_identity_url)
39
+ resource = mapping.to.create_from_identity_url(provider_response.identity_url)
60
40
  end
61
41
 
62
- def valid_mapping?
63
- mapping.to.respond_to?(:find_by_identity_url)
42
+ if resource
43
+ update_resource!(resource)
44
+ success!(resource)
45
+ else
46
+ fail! "This OpenID URL is not associated with any registered user"
64
47
  end
65
48
 
66
- def identity_param?
67
- params[scope].try(:[], 'identity_url').present?
68
- end
49
+ when :cancel
50
+ fail! "OpenID authentication cancelled"
51
+ when :failure
52
+ fail! "OpenID authentication failed"
53
+ end
54
+ end
69
55
 
70
- def update_resource!(resource)
71
- return unless resource.respond_to?(:openid_fields=)
72
-
73
- fields = nil
74
- if axr = OpenID::AX::FetchResponse.from_success_response(provider_response)
75
- fields = axr.data
76
- else
77
- provider_response.message.namespaces.each do |uri, ns_alias|
78
- if ns_alias.to_s == "sreg"
79
- fields = provider_response.extension_response(uri, true)
80
- break
81
- end
82
- end
83
- end
56
+ private
57
+
58
+ def provider_response?
59
+ !!provider_response
60
+ end
61
+
62
+ def provider_response
63
+ env[Rack::OpenID::RESPONSE]
64
+ end
65
+
66
+ def valid_mapping?
67
+ mapping.to.respond_to?(:find_by_identity_url)
68
+ end
69
+
70
+ def identity_param?
71
+ params[scope].try(:[], 'identity_url').present?
72
+ end
84
73
 
85
- if fields
86
- resource.openid_fields = fields
87
- resource.save
74
+ def update_resource!(resource)
75
+ return unless resource.respond_to?(:openid_fields=)
76
+
77
+ fields = nil
78
+ if axr = OpenID::AX::FetchResponse.from_success_response(provider_response)
79
+ fields = axr.data
80
+ else
81
+ provider_response.message.namespaces.each do |uri, ns_alias|
82
+ if ns_alias.to_s == "sreg"
83
+ fields = provider_response.extension_response(uri, true)
84
+ break
88
85
  end
89
86
  end
87
+ end
90
88
 
91
- def logger
92
- @logger ||= ((Rails && Rails.logger) || RAILS_DEFAULT_LOGGER)
93
- end
89
+ if fields
90
+ resource.openid_fields = fields
91
+ resource.save
92
+ end
93
+ end
94
94
 
95
+ def logger
96
+ @logger ||= ((Rails && Rails.logger) || RAILS_DEFAULT_LOGGER)
95
97
  end
96
- end
98
+
99
+ def return_url
100
+ return_to = URI.parse(request.url)
101
+ scope_params = params[scope].inject({}) do |return_params, pair|
102
+ param, value = pair
103
+ return_params["#{scope}[#{param}]"] = value
104
+ return_params
105
+ end
106
+ return_to.query = Rack::Utils.build_query(scope_params)
107
+ return_to.to_s
108
+ end
109
+
97
110
  end
98
111
 
99
112
  Warden::Strategies.add :openid_authenticatable, Devise::Strategies::OpenidAuthenticatable
@@ -1,5 +1,5 @@
1
1
  class User < ActiveRecord::Base
2
- devise :openid_authenticatable
2
+ devise :openid_authenticatable, :rememberable
3
3
 
4
4
  def self.create_from_identity_url(identity_url)
5
5
  create do |user|
@@ -0,0 +1,8 @@
1
+ <html>
2
+ <body>
3
+ <p class="alert"><%= alert %></p>
4
+ <p class="notice"><%= notice %></p>
5
+
6
+ <%= yield %>
7
+ </body>
8
+ </html>
@@ -2,6 +2,7 @@ class CreateTables < ActiveRecord::Migration
2
2
  def self.up
3
3
  create_table :users do |t|
4
4
  t.openid_authenticatable
5
+ t.rememberable
5
6
  t.string :email
6
7
  t.timestamps
7
8
  end
data/spec/spec_helper.rb CHANGED
@@ -5,10 +5,44 @@ $:.unshift File.expand_path('../../lib', __FILE__)
5
5
  require "scenario/config/environment"
6
6
  require "rails/test_help"
7
7
  require 'rspec/rails'
8
+ require 'sham_rack'
9
+ require 'rots'
8
10
 
9
11
  Webrat.configure do |config|
10
12
  config.mode = :rails
11
13
  config.open_error_files = false
12
14
  end
13
15
 
16
+ RSpec.configure do |config|
17
+ config.mock_with :mocha
18
+ end
19
+
20
+ # This is mostly copied in from bin/rots; they don't provide a single app class we could just reuse, unfortunately
21
+
22
+ rots_config = YAML.load(<<-ROTS_CONFIG)
23
+ # Default configuration file
24
+ identity: myid
25
+ sreg:
26
+ nickname: jdoe
27
+ fullname: John Doe
28
+ email: jhon@doe.com
29
+ dob: 1985-09-21
30
+ gender: M
31
+ ROTS_CONFIG
32
+
33
+ rots_server_options = {
34
+ :storage => File.join(File.dirname(__FILE__), 'scenario', 'tmp', 'rots')
35
+ }
36
+ rots_server = Rack::Builder.new do
37
+ use Rack::Lint
38
+ map ("/%s" % rots_config['identity']) do
39
+ run Rots::IdentityPageApp.new(rots_config, rots_server_options)
40
+ end
41
+ map "/server" do
42
+ run Rots::ServerApp.new(rots_config, rots_server_options)
43
+ end
44
+ end
45
+
46
+ ShamRack.mount(rots_server, 'openid.example.org')
47
+
14
48
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
@@ -25,7 +25,8 @@ describe Devise::Strategies::OpenidAuthenticatable do
25
25
  ax_info = mock('AXInfo', :data => { "http://axschema.org/contact/email" => ["dimitrij@example.com"] })
26
26
  OpenID::AX::FetchResponse.stubs(:from_success_response).returns(ax_info)
27
27
 
28
- endpoint = mock('EndPoint', :claimed_id => identity)
28
+ endpoint = mock('EndPoint')
29
+ endpoint.stubs(:claimed_id).returns(identity)
29
30
  success = OpenID::Consumer::SuccessResponse.new(endpoint, OpenID::Message.new, "ANY")
30
31
  OpenID::Consumer.any_instance.stubs(:complete_id_res).returns(success)
31
32
  end
@@ -82,13 +83,31 @@ describe Devise::Strategies::OpenidAuthenticatable do
82
83
 
83
84
  describe "POST /users/sign_in (with a valid identity URL param)" do
84
85
  before do
85
- Rack::OpenID.any_instance.stubs(:begin_authentication).returns([302, {'location' => 'http://openid.example.org/auth'}, ''])
86
+ Rack::OpenID.any_instance.stubs(:begin_authentication).returns([302, {'location' => 'http://openid.example.org/server'}, ''])
86
87
  post '/users/sign_in', 'user' => { 'identity_url' => 'http://openid.example.org/myid' }
87
88
  end
88
89
 
89
90
  it 'should forward request to provider' do
90
91
  response.should be_redirect
91
- response.should redirect_to('http://openid.example.org/auth')
92
+ response.should redirect_to('http://openid.example.org/server')
93
+ end
94
+ end
95
+
96
+ describe "POST /users/sign_in (with rememberable)" do
97
+ before do
98
+ post '/users/sign_in', 'user' => { 'identity_url' => 'http://openid.example.org/myid', 'remember_me' => 1 }
99
+ end
100
+
101
+ it 'should forward request to provider, with params preserved' do
102
+ response.should be_redirect
103
+ redirect_uri = URI.parse(response.header['Location'])
104
+ redirect_uri.host.should == "openid.example.org"
105
+ redirect_uri.path.should match(/^\/server/)
106
+
107
+ # Crack open the redirect URI and extract the return parameter from it, then parse it too
108
+ req = Rack::Request.new(Rack::MockRequest.env_for(redirect_uri.to_s))
109
+ return_req = Rack::Request.new(Rack::MockRequest.env_for(req.params['openid.return_to']))
110
+ return_req.params['user']['remember_me'].to_i.should == 1
92
111
  end
93
112
  end
94
113
 
@@ -136,6 +155,26 @@ describe Devise::Strategies::OpenidAuthenticatable do
136
155
  User.first.email.should == 'dimitrij@example.com'
137
156
  end
138
157
  end
158
+
159
+ describe "POST /users/sign_in (from OpenID provider, success, rememberable)" do
160
+
161
+ before do
162
+ stub_completion
163
+ post '/users/sign_in', openid_params.merge("_method"=>"post", "user" => { "remember_me" => 1 })
164
+ end
165
+
166
+ it 'should accept authentication with success' do
167
+ response.should be_redirect
168
+ response.should redirect_to('http://www.example.com/')
169
+ flash[:notice].should match(/success/i)
170
+ end
171
+
172
+ it 'should update user-records with retrieved information and remember token' do
173
+ User.should have(1).record
174
+ User.first.email.should == 'dimitrij@example.com'
175
+ User.first.remember_token.should_not be_nil
176
+ end
177
+ end
139
178
 
140
179
  describe "POST /users/sign_in (from OpenID provider, success, new user)" do
141
180
 
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: -1710980388
4
+ hash: -1710980387
5
5
  prerelease: true
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
9
  - 0
10
- - alpha6
11
- version: 1.0.0.alpha6
10
+ - alpha7
11
+ version: 1.0.0.alpha7
12
12
  platform: ruby
13
13
  authors:
14
14
  - Nat Budin
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-08-19 00:00:00 -04:00
19
+ date: 2010-09-08 00:00:00 -04:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -43,12 +43,12 @@ dependencies:
43
43
  requirements:
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
- hash: 17
46
+ hash: 31
47
47
  segments:
48
48
  - 1
49
+ - 2
49
50
  - 0
50
- - 3
51
- version: 1.0.3
51
+ version: 1.2.0
52
52
  type: :runtime
53
53
  version_requirements: *id002
54
54
  description: OpenID authentication module for Devise using Rack::OpenID
@@ -78,6 +78,7 @@ files:
78
78
  - spec/scenario/app/controllers/home_controller.rb
79
79
  - spec/scenario/app/controllers/sessions_controller.rb
80
80
  - spec/scenario/app/models/user.rb
81
+ - spec/scenario/app/views/layouts/application.html.erb
81
82
  - spec/scenario/app/views/sessions/new.html.erb
82
83
  - spec/scenario/config.ru
83
84
  - spec/scenario/config/application.rb
@@ -95,7 +96,6 @@ files:
95
96
  - spec/spec_helper.rb
96
97
  - spec/strategy_spec.rb
97
98
  - spec/support/migrations.rb
98
- - spec/support/patches.rb
99
99
  has_rdoc: true
100
100
  homepage: http://github.com/nbudin/devise_openid_authenticatable
101
101
  licenses: []
@@ -152,4 +152,3 @@ test_files:
152
152
  - spec/spec_helper.rb
153
153
  - spec/strategy_spec.rb
154
154
  - spec/support/migrations.rb
155
- - spec/support/patches.rb
@@ -1,4 +0,0 @@
1
- # Patch Webrat
2
- Webrat::Methods.module_eval do
3
- undef_method :response
4
- end