authlogic-oid 1.0.0
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/CHANGELOG.rdoc +3 -0
- data/MIT-LICENSE +20 -0
- data/Manifest.txt +38 -0
- data/README.rdoc +87 -0
- data/Rakefile +20 -0
- data/init.rb +1 -0
- data/lib/authlogic_openid/acts_as_authentic.rb +117 -0
- data/lib/authlogic_openid/session.rb +61 -0
- data/lib/authlogic_openid/version.rb +51 -0
- data/lib/authlogic_openid.rb +6 -0
- data/test/acts_as_authentic_test.rb +90 -0
- data/test/fixtures/users.yml +9 -0
- data/test/libs/open_id_authentication/CHANGELOG +35 -0
- data/test/libs/open_id_authentication/README +231 -0
- data/test/libs/open_id_authentication/Rakefile +22 -0
- data/test/libs/open_id_authentication/generators/open_id_authentication_tables/open_id_authentication_tables_generator.rb +11 -0
- data/test/libs/open_id_authentication/generators/open_id_authentication_tables/templates/migration.rb +20 -0
- data/test/libs/open_id_authentication/generators/upgrade_open_id_authentication_tables/templates/migration.rb +26 -0
- data/test/libs/open_id_authentication/generators/upgrade_open_id_authentication_tables/upgrade_open_id_authentication_tables_generator.rb +11 -0
- data/test/libs/open_id_authentication/init.rb +18 -0
- data/test/libs/open_id_authentication/lib/open_id_authentication/association.rb +9 -0
- data/test/libs/open_id_authentication/lib/open_id_authentication/db_store.rb +55 -0
- data/test/libs/open_id_authentication/lib/open_id_authentication/mem_cache_store.rb +73 -0
- data/test/libs/open_id_authentication/lib/open_id_authentication/nonce.rb +5 -0
- data/test/libs/open_id_authentication/lib/open_id_authentication/request.rb +23 -0
- data/test/libs/open_id_authentication/lib/open_id_authentication/timeout_fixes.rb +20 -0
- data/test/libs/open_id_authentication/lib/open_id_authentication.rb +244 -0
- data/test/libs/open_id_authentication/tasks/open_id_authentication_tasks.rake +30 -0
- data/test/libs/open_id_authentication/test/mem_cache_store_test.rb +151 -0
- data/test/libs/open_id_authentication/test/normalize_test.rb +32 -0
- data/test/libs/open_id_authentication/test/open_id_authentication_test.rb +46 -0
- data/test/libs/open_id_authentication/test/status_test.rb +14 -0
- data/test/libs/open_id_authentication/test/test_helper.rb +17 -0
- data/test/libs/rails_trickery.rb +41 -0
- data/test/libs/user.rb +3 -0
- data/test/libs/user_session.rb +2 -0
- data/test/session_test.rb +32 -0
- data/test/test_helper.rb +78 -0
- metadata +113 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
OpenIdAuthentication
|
|
2
|
+
====================
|
|
3
|
+
|
|
4
|
+
Provides a thin wrapper around the excellent ruby-openid gem from JanRan. Be sure to install that first:
|
|
5
|
+
|
|
6
|
+
gem install ruby-openid
|
|
7
|
+
|
|
8
|
+
To understand what OpenID is about and how it works, it helps to read the documentation for lib/openid/consumer.rb
|
|
9
|
+
from that gem.
|
|
10
|
+
|
|
11
|
+
The specification used is http://openid.net/specs/openid-authentication-2_0.html.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
Prerequisites
|
|
15
|
+
=============
|
|
16
|
+
|
|
17
|
+
OpenID authentication uses the session, so be sure that you haven't turned that off. It also relies on a number of
|
|
18
|
+
database tables to store the authentication keys. So you'll have to run the migration to create these before you get started:
|
|
19
|
+
|
|
20
|
+
rake open_id_authentication:db:create
|
|
21
|
+
|
|
22
|
+
Or, use the included generators to install or upgrade:
|
|
23
|
+
|
|
24
|
+
./script/generate open_id_authentication_tables MigrationName
|
|
25
|
+
./script/generate upgrade_open_id_authentication_tables MigrationName
|
|
26
|
+
|
|
27
|
+
Alternatively, you can use the file-based store, which just relies on on tmp/openids being present in RAILS_ROOT. But be aware that this store only works if you have a single application server. And it's not safe to use across NFS. It's recommended that you use the database store if at all possible. To use the file-based store, you'll also have to add this line to your config/environment.rb:
|
|
28
|
+
|
|
29
|
+
OpenIdAuthentication.store = :file
|
|
30
|
+
|
|
31
|
+
This particular plugin also relies on the fact that the authentication action allows for both POST and GET operations.
|
|
32
|
+
If you're using RESTful authentication, you'll need to explicitly allow for this in your routes.rb.
|
|
33
|
+
|
|
34
|
+
The plugin also expects to find a root_url method that points to the home page of your site. You can accomplish this by using a root route in config/routes.rb:
|
|
35
|
+
|
|
36
|
+
map.root :controller => 'articles'
|
|
37
|
+
|
|
38
|
+
This plugin relies on Rails Edge revision 6317 or newer.
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
Example
|
|
42
|
+
=======
|
|
43
|
+
|
|
44
|
+
This example is just to meant to demonstrate how you could use OpenID authentication. You might well want to add
|
|
45
|
+
salted hash logins instead of plain text passwords and other requirements on top of this. Treat it as a starting point,
|
|
46
|
+
not a destination.
|
|
47
|
+
|
|
48
|
+
Note that the User model referenced in the simple example below has an 'identity_url' attribute. You will want to add the same or similar field to whatever
|
|
49
|
+
model you are using for authentication.
|
|
50
|
+
|
|
51
|
+
Also of note is the following code block used in the example below:
|
|
52
|
+
|
|
53
|
+
authenticate_with_open_id do |result, identity_url|
|
|
54
|
+
...
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
In the above code block, 'identity_url' will need to match user.identity_url exactly. 'identity_url' will be a string in the form of 'http://example.com' -
|
|
58
|
+
If you are storing just 'example.com' with your user, the lookup will fail.
|
|
59
|
+
|
|
60
|
+
There is a handy method in this plugin called 'normalize_url' that will help with validating OpenID URLs.
|
|
61
|
+
|
|
62
|
+
OpenIdAuthentication.normalize_url(user.identity_url)
|
|
63
|
+
|
|
64
|
+
The above will return a standardized version of the OpenID URL - the above called with 'example.com' will return 'http://example.com/'
|
|
65
|
+
It will also raise an InvalidOpenId exception if the URL is determined to not be valid.
|
|
66
|
+
Use the above code in your User model and validate OpenID URLs before saving them.
|
|
67
|
+
|
|
68
|
+
config/routes.rb
|
|
69
|
+
|
|
70
|
+
map.root :controller => 'articles'
|
|
71
|
+
map.resource :session
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
app/views/sessions/new.erb
|
|
75
|
+
|
|
76
|
+
<% form_tag(session_url) do %>
|
|
77
|
+
<p>
|
|
78
|
+
<label for="name">Username:</label>
|
|
79
|
+
<%= text_field_tag "name" %>
|
|
80
|
+
</p>
|
|
81
|
+
|
|
82
|
+
<p>
|
|
83
|
+
<label for="password">Password:</label>
|
|
84
|
+
<%= password_field_tag %>
|
|
85
|
+
</p>
|
|
86
|
+
|
|
87
|
+
<p>
|
|
88
|
+
...or use:
|
|
89
|
+
</p>
|
|
90
|
+
|
|
91
|
+
<p>
|
|
92
|
+
<label for="openid_identifier">OpenID:</label>
|
|
93
|
+
<%= text_field_tag "openid_identifier" %>
|
|
94
|
+
</p>
|
|
95
|
+
|
|
96
|
+
<p>
|
|
97
|
+
<%= submit_tag 'Sign in', :disable_with => "Signing in…" %>
|
|
98
|
+
</p>
|
|
99
|
+
<% end %>
|
|
100
|
+
|
|
101
|
+
app/controllers/sessions_controller.rb
|
|
102
|
+
class SessionsController < ApplicationController
|
|
103
|
+
def create
|
|
104
|
+
if using_open_id?
|
|
105
|
+
open_id_authentication
|
|
106
|
+
else
|
|
107
|
+
password_authentication(params[:name], params[:password])
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
protected
|
|
113
|
+
def password_authentication(name, password)
|
|
114
|
+
if @current_user = @account.users.authenticate(params[:name], params[:password])
|
|
115
|
+
successful_login
|
|
116
|
+
else
|
|
117
|
+
failed_login "Sorry, that username/password doesn't work"
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def open_id_authentication
|
|
122
|
+
authenticate_with_open_id do |result, identity_url|
|
|
123
|
+
if result.successful?
|
|
124
|
+
if @current_user = @account.users.find_by_identity_url(identity_url)
|
|
125
|
+
successful_login
|
|
126
|
+
else
|
|
127
|
+
failed_login "Sorry, no user by that identity URL exists (#{identity_url})"
|
|
128
|
+
end
|
|
129
|
+
else
|
|
130
|
+
failed_login result.message
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
private
|
|
137
|
+
def successful_login
|
|
138
|
+
session[:user_id] = @current_user.id
|
|
139
|
+
redirect_to(root_url)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def failed_login(message)
|
|
143
|
+
flash[:error] = message
|
|
144
|
+
redirect_to(new_session_url)
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
If you're fine with the result messages above and don't need individual logic on a per-failure basis,
|
|
151
|
+
you can collapse the case into a mere boolean:
|
|
152
|
+
|
|
153
|
+
def open_id_authentication
|
|
154
|
+
authenticate_with_open_id do |result, identity_url|
|
|
155
|
+
if result.successful? && @current_user = @account.users.find_by_identity_url(identity_url)
|
|
156
|
+
successful_login
|
|
157
|
+
else
|
|
158
|
+
failed_login(result.message || "Sorry, no user by that identity URL exists (#{identity_url})")
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
Simple Registration OpenID Extension
|
|
165
|
+
====================================
|
|
166
|
+
|
|
167
|
+
Some OpenID Providers support this lightweight profile exchange protocol. See more: http://www.openidenabled.com/openid/simple-registration-extension
|
|
168
|
+
|
|
169
|
+
You can support it in your app by changing #open_id_authentication
|
|
170
|
+
|
|
171
|
+
def open_id_authentication(identity_url)
|
|
172
|
+
# Pass optional :required and :optional keys to specify what sreg fields you want.
|
|
173
|
+
# Be sure to yield registration, a third argument in the #authenticate_with_open_id block.
|
|
174
|
+
authenticate_with_open_id(identity_url,
|
|
175
|
+
:required => [ :nickname, :email ],
|
|
176
|
+
:optional => :fullname) do |result, identity_url, registration|
|
|
177
|
+
case result.status
|
|
178
|
+
when :missing
|
|
179
|
+
failed_login "Sorry, the OpenID server couldn't be found"
|
|
180
|
+
when :invalid
|
|
181
|
+
failed_login "Sorry, but this does not appear to be a valid OpenID"
|
|
182
|
+
when :canceled
|
|
183
|
+
failed_login "OpenID verification was canceled"
|
|
184
|
+
when :failed
|
|
185
|
+
failed_login "Sorry, the OpenID verification failed"
|
|
186
|
+
when :successful
|
|
187
|
+
if @current_user = @account.users.find_by_identity_url(identity_url)
|
|
188
|
+
assign_registration_attributes!(registration)
|
|
189
|
+
|
|
190
|
+
if current_user.save
|
|
191
|
+
successful_login
|
|
192
|
+
else
|
|
193
|
+
failed_login "Your OpenID profile registration failed: " +
|
|
194
|
+
@current_user.errors.full_messages.to_sentence
|
|
195
|
+
end
|
|
196
|
+
else
|
|
197
|
+
failed_login "Sorry, no user by that identity URL exists"
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# registration is a hash containing the valid sreg keys given above
|
|
204
|
+
# use this to map them to fields of your user model
|
|
205
|
+
def assign_registration_attributes!(registration)
|
|
206
|
+
model_to_registration_mapping.each do |model_attribute, registration_attribute|
|
|
207
|
+
unless registration[registration_attribute].blank?
|
|
208
|
+
@current_user.send("#{model_attribute}=", registration[registration_attribute])
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def model_to_registration_mapping
|
|
214
|
+
{ :login => 'nickname', :email => 'email', :display_name => 'fullname' }
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
Attribute Exchange OpenID Extension
|
|
218
|
+
===================================
|
|
219
|
+
|
|
220
|
+
Some OpenID providers also support the OpenID AX (attribute exchange) protocol for exchanging identity information between endpoints. See more: http://openid.net/specs/openid-attribute-exchange-1_0.html
|
|
221
|
+
|
|
222
|
+
Accessing AX data is very similar to the Simple Registration process, described above -- just add the URI identifier for the AX field to your :optional or :required parameters. For example:
|
|
223
|
+
|
|
224
|
+
authenticate_with_open_id(identity_url,
|
|
225
|
+
:required => [ :email, 'http://schema.openid.net/birthDate' ]) do |result, identity_url, registration|
|
|
226
|
+
|
|
227
|
+
This would provide the sreg data for :email, and the AX data for 'http://schema.openid.net/birthDate'
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
Copyright (c) 2007 David Heinemeier Hansson, released under the MIT license
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'rake'
|
|
2
|
+
require 'rake/testtask'
|
|
3
|
+
require 'rake/rdoctask'
|
|
4
|
+
|
|
5
|
+
desc 'Default: run unit tests.'
|
|
6
|
+
task :default => :test
|
|
7
|
+
|
|
8
|
+
desc 'Test the open_id_authentication plugin.'
|
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
|
10
|
+
t.libs << 'lib'
|
|
11
|
+
t.pattern = 'test/**/*_test.rb'
|
|
12
|
+
t.verbose = true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
desc 'Generate documentation for the open_id_authentication plugin.'
|
|
16
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
17
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
18
|
+
rdoc.title = 'OpenIdAuthentication'
|
|
19
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
|
20
|
+
rdoc.rdoc_files.include('README')
|
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
22
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
class <%= class_name %> < ActiveRecord::Migration
|
|
2
|
+
def self.up
|
|
3
|
+
create_table :open_id_authentication_associations, :force => true do |t|
|
|
4
|
+
t.integer :issued, :lifetime
|
|
5
|
+
t.string :handle, :assoc_type
|
|
6
|
+
t.binary :server_url, :secret
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
create_table :open_id_authentication_nonces, :force => true do |t|
|
|
10
|
+
t.integer :timestamp, :null => false
|
|
11
|
+
t.string :server_url, :null => true
|
|
12
|
+
t.string :salt, :null => false
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.down
|
|
17
|
+
drop_table :open_id_authentication_associations
|
|
18
|
+
drop_table :open_id_authentication_nonces
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
class <%= class_name %> < ActiveRecord::Migration
|
|
2
|
+
def self.up
|
|
3
|
+
drop_table :open_id_authentication_settings
|
|
4
|
+
drop_table :open_id_authentication_nonces
|
|
5
|
+
|
|
6
|
+
create_table :open_id_authentication_nonces, :force => true do |t|
|
|
7
|
+
t.integer :timestamp, :null => false
|
|
8
|
+
t.string :server_url, :null => true
|
|
9
|
+
t.string :salt, :null => false
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.down
|
|
14
|
+
drop_table :open_id_authentication_nonces
|
|
15
|
+
|
|
16
|
+
create_table :open_id_authentication_nonces, :force => true do |t|
|
|
17
|
+
t.integer :created
|
|
18
|
+
t.string :nonce
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
create_table :open_id_authentication_settings, :force => true do |t|
|
|
22
|
+
t.string :setting
|
|
23
|
+
t.binary :value
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
if config.respond_to?(:gems)
|
|
2
|
+
config.gem 'ruby-openid', :lib => 'openid', :version => '>=2.0.4'
|
|
3
|
+
else
|
|
4
|
+
begin
|
|
5
|
+
require 'openid'
|
|
6
|
+
rescue LoadError
|
|
7
|
+
begin
|
|
8
|
+
gem 'ruby-openid', '>=2.0.4'
|
|
9
|
+
rescue Gem::LoadError
|
|
10
|
+
puts "Install the ruby-openid gem to enable OpenID support"
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
config.to_prepare do
|
|
16
|
+
OpenID::Util.logger = Rails.logger
|
|
17
|
+
ActionController::Base.send :include, OpenIdAuthentication
|
|
18
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require 'openid/store/interface'
|
|
2
|
+
|
|
3
|
+
module OpenIdAuthentication
|
|
4
|
+
class DbStore < OpenID::Store::Interface
|
|
5
|
+
def self.cleanup_nonces
|
|
6
|
+
now = Time.now.to_i
|
|
7
|
+
Nonce.delete_all(["timestamp > ? OR timestamp < ?", now + OpenID::Nonce.skew, now - OpenID::Nonce.skew])
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.cleanup_associations
|
|
11
|
+
now = Time.now.to_i
|
|
12
|
+
Association.delete_all(['issued + lifetime > ?',now])
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def store_association(server_url, assoc)
|
|
16
|
+
remove_association(server_url, assoc.handle)
|
|
17
|
+
Association.create(:server_url => server_url,
|
|
18
|
+
:handle => assoc.handle,
|
|
19
|
+
:secret => assoc.secret,
|
|
20
|
+
:issued => assoc.issued,
|
|
21
|
+
:lifetime => assoc.lifetime,
|
|
22
|
+
:assoc_type => assoc.assoc_type)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def get_association(server_url, handle = nil)
|
|
26
|
+
assocs = if handle.blank?
|
|
27
|
+
Association.find_all_by_server_url(server_url)
|
|
28
|
+
else
|
|
29
|
+
Association.find_all_by_server_url_and_handle(server_url, handle)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
assocs.reverse.each do |assoc|
|
|
33
|
+
a = assoc.from_record
|
|
34
|
+
if a.expires_in == 0
|
|
35
|
+
assoc.destroy
|
|
36
|
+
else
|
|
37
|
+
return a
|
|
38
|
+
end
|
|
39
|
+
end if assocs.any?
|
|
40
|
+
|
|
41
|
+
return nil
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def remove_association(server_url, handle)
|
|
45
|
+
Association.delete_all(['server_url = ? AND handle = ?', server_url, handle]) > 0
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
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
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require 'digest/sha1'
|
|
2
|
+
require 'openid/store/interface'
|
|
3
|
+
|
|
4
|
+
module OpenIdAuthentication
|
|
5
|
+
class MemCacheStore < OpenID::Store::Interface
|
|
6
|
+
def initialize(*addresses)
|
|
7
|
+
@connection = ActiveSupport::Cache::MemCacheStore.new(addresses)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def store_association(server_url, assoc)
|
|
11
|
+
server_key = association_server_key(server_url)
|
|
12
|
+
assoc_key = association_key(server_url, assoc.handle)
|
|
13
|
+
|
|
14
|
+
assocs = @connection.read(server_key) || {}
|
|
15
|
+
assocs[assoc.issued] = assoc_key
|
|
16
|
+
|
|
17
|
+
@connection.write(server_key, assocs)
|
|
18
|
+
@connection.write(assoc_key, assoc, :expires_in => assoc.lifetime)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def get_association(server_url, handle = nil)
|
|
22
|
+
if handle
|
|
23
|
+
@connection.read(association_key(server_url, handle))
|
|
24
|
+
else
|
|
25
|
+
server_key = association_server_key(server_url)
|
|
26
|
+
assocs = @connection.read(server_key)
|
|
27
|
+
return if assocs.nil?
|
|
28
|
+
|
|
29
|
+
last_key = assocs[assocs.keys.sort.last]
|
|
30
|
+
@connection.read(last_key)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def remove_association(server_url, handle)
|
|
35
|
+
server_key = association_server_key(server_url)
|
|
36
|
+
assoc_key = association_key(server_url, handle)
|
|
37
|
+
assocs = @connection.read(server_key)
|
|
38
|
+
|
|
39
|
+
return false unless assocs && assocs.has_value?(assoc_key)
|
|
40
|
+
|
|
41
|
+
assocs = assocs.delete_if { |key, value| value == assoc_key }
|
|
42
|
+
|
|
43
|
+
@connection.write(server_key, assocs)
|
|
44
|
+
@connection.delete(assoc_key)
|
|
45
|
+
|
|
46
|
+
return true
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def use_nonce(server_url, timestamp, salt)
|
|
50
|
+
return false if @connection.read(nonce_key(server_url, salt))
|
|
51
|
+
return false if (timestamp - Time.now.to_i).abs > OpenID::Nonce.skew
|
|
52
|
+
@connection.write(nonce_key(server_url, salt), timestamp, :expires_in => OpenID::Nonce.skew)
|
|
53
|
+
return true
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
def association_key(server_url, handle = nil)
|
|
58
|
+
"openid_association_#{digest(server_url)}_#{digest(handle)}"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def association_server_key(server_url)
|
|
62
|
+
"openid_association_server_#{digest(server_url)}"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def nonce_key(server_url, salt)
|
|
66
|
+
"openid_nonce_#{digest(server_url)}_#{digest(salt)}"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def digest(text)
|
|
70
|
+
Digest::SHA1.hexdigest(text)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module OpenIdAuthentication
|
|
2
|
+
module Request
|
|
3
|
+
def self.included(base)
|
|
4
|
+
base.alias_method_chain :request_method, :openid
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def request_method_with_openid
|
|
8
|
+
if !parameters[:_method].blank? && parameters[:open_id_complete] == '1'
|
|
9
|
+
parameters[:_method].to_sym
|
|
10
|
+
else
|
|
11
|
+
request_method_without_openid
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# In Rails 2.3, the request object has been renamed
|
|
18
|
+
# from AbstractRequest to Request
|
|
19
|
+
if defined? ActionController::Request
|
|
20
|
+
ActionController::Request.send :include, OpenIdAuthentication::Request
|
|
21
|
+
else
|
|
22
|
+
ActionController::AbstractRequest.send :include, OpenIdAuthentication::Request
|
|
23
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# http://trac.openidenabled.com/trac/ticket/156
|
|
2
|
+
module OpenID
|
|
3
|
+
@@timeout_threshold = 20
|
|
4
|
+
|
|
5
|
+
def self.timeout_threshold
|
|
6
|
+
@@timeout_threshold
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.timeout_threshold=(value)
|
|
10
|
+
@@timeout_threshold = value
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class StandardFetcher
|
|
14
|
+
def make_http(uri)
|
|
15
|
+
http = @proxy.new(uri.host, uri.port)
|
|
16
|
+
http.read_timeout = http.open_timeout = OpenID.timeout_threshold
|
|
17
|
+
http
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|