ruby-openid 1.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/COPYING +21 -0
- data/INSTALL +34 -0
- data/README +67 -0
- data/TODO +9 -0
- data/examples/README +54 -0
- data/examples/cacert.pem +7815 -0
- data/examples/consumer.rb +285 -0
- data/examples/openid-store/associations/http-localhost_3A3000_2Fserver-EMQbAy3NnHVzA.s0u5KAcplKGzo +6 -0
- data/examples/openid-store/auth_key +1 -0
- data/examples/rails_active_record_store/README +59 -0
- data/examples/rails_active_record_store/XX_add_openidstore.rb +30 -0
- data/examples/rails_active_record_store/models/openid_association.rb +12 -0
- data/examples/rails_active_record_store/models/openid_nonce.rb +3 -0
- data/examples/rails_active_record_store/models/openid_setting.rb +2 -0
- data/examples/rails_active_record_store/openid_helper.rb +91 -0
- data/examples/rails_active_record_store/openidstore_test.rb +15 -0
- data/examples/rails_active_record_store/schema.mysql.sql +22 -0
- data/examples/rails_active_record_store/schema.postgresql.sql +21 -0
- data/examples/rails_active_record_store/schema.sqlite.sql +21 -0
- data/examples/rails_openid_login_generator/USAGE +23 -0
- data/examples/rails_openid_login_generator/openid_login_generator.rb +36 -0
- data/examples/rails_openid_login_generator/templates/README +116 -0
- data/examples/rails_openid_login_generator/templates/controller.rb +116 -0
- data/examples/rails_openid_login_generator/templates/controller_test.rb +0 -0
- data/examples/rails_openid_login_generator/templates/helper.rb +2 -0
- data/examples/rails_openid_login_generator/templates/openid_login_system.rb +87 -0
- data/examples/rails_openid_login_generator/templates/user.rb +14 -0
- data/examples/rails_openid_login_generator/templates/user_test.rb +0 -0
- data/examples/rails_openid_login_generator/templates/users.yml +0 -0
- data/examples/rails_openid_login_generator/templates/view_login.rhtml +15 -0
- data/examples/rails_openid_login_generator/templates/view_logout.rhtml +10 -0
- data/examples/rails_openid_login_generator/templates/view_welcome.rhtml +9 -0
- data/examples/rails_server/README +153 -0
- data/examples/rails_server/Rakefile +10 -0
- data/examples/rails_server/app/controllers/application.rb +4 -0
- data/examples/rails_server/app/controllers/login_controller.rb +35 -0
- data/examples/rails_server/app/controllers/server_controller.rb +185 -0
- data/examples/rails_server/app/helpers/application_helper.rb +3 -0
- data/examples/rails_server/app/helpers/login_helper.rb +2 -0
- data/examples/rails_server/app/helpers/server_helper.rb +9 -0
- data/examples/rails_server/app/views/layouts/server.rhtml +61 -0
- data/examples/rails_server/app/views/login/index.rhtml +32 -0
- data/examples/rails_server/app/views/server/decide.rhtml +11 -0
- data/examples/rails_server/config/boot.rb +19 -0
- data/examples/rails_server/config/database.yml +85 -0
- data/examples/rails_server/config/environment.rb +53 -0
- data/examples/rails_server/config/environments/development.rb +19 -0
- data/examples/rails_server/config/environments/production.rb +19 -0
- data/examples/rails_server/config/environments/test.rb +19 -0
- data/examples/rails_server/config/routes.rb +23 -0
- data/examples/rails_server/db/openid-store/associations/http-localhost_2F_7Cnormal-YU.tkND1J4fEZhnuAoT5Zc0yCA0 +6 -0
- data/examples/rails_server/doc/README_FOR_APP +2 -0
- data/examples/rails_server/log/development.log +6059 -0
- data/examples/rails_server/log/production.log +0 -0
- data/examples/rails_server/log/server.log +0 -0
- data/examples/rails_server/log/test.log +0 -0
- data/examples/rails_server/public/404.html +8 -0
- data/examples/rails_server/public/500.html +8 -0
- data/examples/rails_server/public/dispatch.cgi +12 -0
- data/examples/rails_server/public/dispatch.fcgi +26 -0
- data/examples/rails_server/public/dispatch.rb +12 -0
- data/examples/rails_server/public/favicon.ico +0 -0
- data/examples/rails_server/public/images/rails.png +0 -0
- data/examples/rails_server/public/javascripts/controls.js +750 -0
- data/examples/rails_server/public/javascripts/dragdrop.js +584 -0
- data/examples/rails_server/public/javascripts/effects.js +854 -0
- data/examples/rails_server/public/javascripts/prototype.js +1785 -0
- data/examples/rails_server/public/robots.txt +1 -0
- data/examples/rails_server/script/about +3 -0
- data/examples/rails_server/script/breakpointer +3 -0
- data/examples/rails_server/script/console +3 -0
- data/examples/rails_server/script/destroy +3 -0
- data/examples/rails_server/script/generate +3 -0
- data/examples/rails_server/script/performance/benchmarker +3 -0
- data/examples/rails_server/script/performance/profiler +3 -0
- data/examples/rails_server/script/plugin +3 -0
- data/examples/rails_server/script/process/reaper +3 -0
- data/examples/rails_server/script/process/spawner +3 -0
- data/examples/rails_server/script/process/spinner +3 -0
- data/examples/rails_server/script/runner +3 -0
- data/examples/rails_server/script/server +3 -0
- data/examples/rails_server/test/functional/login_controller_test.rb +18 -0
- data/examples/rails_server/test/functional/server_controller_test.rb +18 -0
- data/examples/rails_server/test/test_helper.rb +28 -0
- data/lib/hmac-md5.rb +11 -0
- data/lib/hmac-rmd160.rb +11 -0
- data/lib/hmac-sha1.rb +11 -0
- data/lib/hmac-sha2.rb +25 -0
- data/lib/hmac.rb +112 -0
- data/lib/openid/association.rb +109 -0
- data/lib/openid/consumer.rb +928 -0
- data/lib/openid/dh.rb +48 -0
- data/lib/openid/discovery.rb +89 -0
- data/lib/openid/fetchers.rb +119 -0
- data/lib/openid/filestore.rb +315 -0
- data/lib/openid/htmltokenizer.rb +355 -0
- data/lib/openid/parse.rb +23 -0
- data/lib/openid/server.rb +951 -0
- data/lib/openid/service.rb +135 -0
- data/lib/openid/stores.rb +178 -0
- data/lib/openid/trustroot.rb +100 -0
- data/lib/openid/util.rb +273 -0
- data/test/assoc.rb +38 -0
- data/test/consumer.rb +384 -0
- data/test/dh.rb +20 -0
- data/test/extensions.rb +30 -0
- data/test/linkparse.rb +305 -0
- data/test/runtests.rb +11 -0
- data/test/server2.rb +1053 -0
- data/test/storetestcase.rb +172 -0
- data/test/teststore.rb +23 -0
- data/test/trustroot.rb +113 -0
- data/test/util.rb +56 -0
- metadata +218 -0
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require "cgi"
|
|
3
|
+
require "uri"
|
|
4
|
+
require "pathname"
|
|
5
|
+
|
|
6
|
+
require "webrick"
|
|
7
|
+
include WEBrick
|
|
8
|
+
|
|
9
|
+
require "openid/consumer"
|
|
10
|
+
require "openid/filestore"
|
|
11
|
+
require "openid/util"
|
|
12
|
+
|
|
13
|
+
################ start config ##########################
|
|
14
|
+
# use your desired store implementation here
|
|
15
|
+
store_dir = Pathname.new(Dir.pwd).join("openid-store")
|
|
16
|
+
store = OpenID::FilesystemStore.new(store_dir)
|
|
17
|
+
|
|
18
|
+
$host = "localhost"
|
|
19
|
+
$port = 2000
|
|
20
|
+
################ end config ############################
|
|
21
|
+
|
|
22
|
+
if $port.nil?
|
|
23
|
+
$base_url = "http://#{$host}/"
|
|
24
|
+
else
|
|
25
|
+
$base_url = "http://#{$host}:#{$port}/"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# NOTE: Please note that a Hash is not a valid session storage type, it is just
|
|
29
|
+
# used here to get something that works. In a production environment this
|
|
30
|
+
# should be an object representing the CURRENT USER's session, NOT a global
|
|
31
|
+
# hash. Every user visiting this running consumer.rb will write into this
|
|
32
|
+
# same hash.
|
|
33
|
+
$session = {}
|
|
34
|
+
|
|
35
|
+
$trust_root = $base_url
|
|
36
|
+
$consumer = OpenID::Consumer.new($session, store)
|
|
37
|
+
|
|
38
|
+
server = HTTPServer.new(:Port=>$port)
|
|
39
|
+
class SimpleServlet < HTTPServlet::AbstractServlet
|
|
40
|
+
|
|
41
|
+
def do_GET(req, res)
|
|
42
|
+
@req = req
|
|
43
|
+
@res = res
|
|
44
|
+
|
|
45
|
+
begin
|
|
46
|
+
case req.path
|
|
47
|
+
when "", "/", "/start"
|
|
48
|
+
self.render
|
|
49
|
+
when "/begin"
|
|
50
|
+
self.do_begin
|
|
51
|
+
when "/complete"
|
|
52
|
+
self.do_complete
|
|
53
|
+
when '/policy'
|
|
54
|
+
self.do_policy
|
|
55
|
+
else
|
|
56
|
+
self.redirect(self.build_url("/"))
|
|
57
|
+
end
|
|
58
|
+
ensure
|
|
59
|
+
@req = nil
|
|
60
|
+
@res = nil
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def do_begin
|
|
65
|
+
# First make sure the user entered something
|
|
66
|
+
openid_url = @req.query.fetch("openid_url", "")
|
|
67
|
+
if openid_url.empty?
|
|
68
|
+
self.render("Enter an identity URL to verify",
|
|
69
|
+
css_class="error", form_contents=openid_url)
|
|
70
|
+
return HTTPStatus::Success
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Then ask the openid library to begin the authorization
|
|
74
|
+
request = $consumer.begin(openid_url)
|
|
75
|
+
|
|
76
|
+
# If the URL was unusable (either because of network conditions,
|
|
77
|
+
# a server error, or that the response returned was not an OpenID
|
|
78
|
+
# identity page), the library will return HTTP_FAILURE or PARSE_ERROR.
|
|
79
|
+
# Let the user know that the URL is unusable.
|
|
80
|
+
case request.status
|
|
81
|
+
when OpenID::FAILURE
|
|
82
|
+
self.render("Unable to find openid server for <q>#{openid_url}</q>",
|
|
83
|
+
css_class="error", form_contents=openid_url)
|
|
84
|
+
return HTTPStatus::Success
|
|
85
|
+
|
|
86
|
+
when OpenID::SUCCESS
|
|
87
|
+
# The URL was a valid identity URL. Now we just need to send a redirect
|
|
88
|
+
# to the server using the redirect_url the library created for us.
|
|
89
|
+
|
|
90
|
+
# check to see if we want to make an SREG request. Generally this will
|
|
91
|
+
# not take the form of a checkbox, but will be part of your site policy.
|
|
92
|
+
# For example, you may perform an sreg request if the user appears
|
|
93
|
+
# to be new to the site. The checkbox is here for convenience of
|
|
94
|
+
# testing.
|
|
95
|
+
do_sreg = @req.query.fetch('sreg', nil)
|
|
96
|
+
|
|
97
|
+
if do_sreg and request.uses_extension?('http://openid.net/sreg/1.0')
|
|
98
|
+
policy_url = self.build_url('/policy')
|
|
99
|
+
request.add_extension_arg('sreg','policy_url', policy_url)
|
|
100
|
+
request.add_extension_arg('sreg','required','email,nickname')
|
|
101
|
+
request.add_extension_arg('sreg','optional','fullname,dob,gender,postcode,country')
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
if do_sreg
|
|
105
|
+
extra = {'did_sreg' => 'true'}
|
|
106
|
+
else
|
|
107
|
+
extra = {}
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
return_to = self.build_url("/complete", extra)
|
|
111
|
+
|
|
112
|
+
# build the redirect
|
|
113
|
+
redirect_url = request.redirect_url($trust_root, return_to)
|
|
114
|
+
|
|
115
|
+
# send redirect to the server
|
|
116
|
+
self.redirect(redirect_url)
|
|
117
|
+
else
|
|
118
|
+
# Should never get here
|
|
119
|
+
raise "Not Reached"
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# handle the redirect from the OpenID server
|
|
124
|
+
def do_complete
|
|
125
|
+
# Ask the library to check the response that the server sent
|
|
126
|
+
# us. Status is a code indicating the response type. info is
|
|
127
|
+
# either nil or a string containing more information about
|
|
128
|
+
# the return type.
|
|
129
|
+
response = $consumer.complete(@req.query)
|
|
130
|
+
|
|
131
|
+
css_class = "error"
|
|
132
|
+
|
|
133
|
+
did_sreg = @req.query.fetch('did_sreg', nil)
|
|
134
|
+
sreg_checked = did_sreg ? 'checked="checked"' : ''
|
|
135
|
+
|
|
136
|
+
if response.status == OpenID::FAILURE
|
|
137
|
+
# In the case of failure, if info is non-nil, it is the
|
|
138
|
+
# URL that we were verifying. We include it in the error
|
|
139
|
+
# message to help the user figure out what happened.
|
|
140
|
+
if response.identity_url
|
|
141
|
+
message = "Verification of #{response.identity_url} failed"
|
|
142
|
+
else
|
|
143
|
+
message = 'Verification failed.'
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# add on the failure message for a little debug info
|
|
147
|
+
message += ' '+response.msg.to_s
|
|
148
|
+
|
|
149
|
+
elsif response.status == OpenID::SUCCESS
|
|
150
|
+
# Success means that the transaction completed without
|
|
151
|
+
# error. If info is nil, it means that the user cancelled
|
|
152
|
+
# the verification.
|
|
153
|
+
css_class = "alert"
|
|
154
|
+
|
|
155
|
+
message = "You have successfully verified #{response.identity_url} as your identity."
|
|
156
|
+
|
|
157
|
+
# get the signed extension sreg arguments
|
|
158
|
+
sreg = response.extension_response('sreg')
|
|
159
|
+
if sreg.length > 0
|
|
160
|
+
message += "<hr/> With simple registration fields:<br/>"
|
|
161
|
+
sreg.keys.sort.each {|k| message += "<br/><b>#{k}</b>: #{sreg[k]}"}
|
|
162
|
+
elsif did_sreg
|
|
163
|
+
message += "<hr/> But the server does not support simple registration."
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
elsif response.status == OpenID::CANCEL
|
|
167
|
+
message = "Verification cancelled."
|
|
168
|
+
|
|
169
|
+
else
|
|
170
|
+
message = "Unknown response status: #{response.status}"
|
|
171
|
+
|
|
172
|
+
end
|
|
173
|
+
self.render(message, css_class, response.identity_url, sreg_checked)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def do_policy
|
|
177
|
+
@res.body = <<END
|
|
178
|
+
<html>
|
|
179
|
+
<head></head>
|
|
180
|
+
<body>
|
|
181
|
+
<h3>Ruby Consumer Simple Registration Policy</h3>
|
|
182
|
+
<p>This consumer makes a simple registration request for the following fields:<br/><br/>
|
|
183
|
+
<b>Required:</b> email, nickname<br/>
|
|
184
|
+
<b>Optional:</b> fullname, dob, gender, postcode, country<br/><br/>
|
|
185
|
+
Nothing is actually done with the data provided, it simply exists to illustrate the simple registration protocol.
|
|
186
|
+
</p>
|
|
187
|
+
</body>
|
|
188
|
+
</html>
|
|
189
|
+
|
|
190
|
+
END
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# build a URL relative to the server base URL, with the given query
|
|
194
|
+
# parameters added.
|
|
195
|
+
def build_url(action, query=nil)
|
|
196
|
+
url = URI.parse($base_url).merge(action).to_s
|
|
197
|
+
url = OpenID::Util.append_args(url, query) unless query.nil?
|
|
198
|
+
return url
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def redirect(url)
|
|
202
|
+
@res.set_redirect(HTTPStatus::TemporaryRedirect, url)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def render(message=nil, css_class="alert", form_contents="", checked="")
|
|
206
|
+
@res.body = self.page_header
|
|
207
|
+
unless message.nil?
|
|
208
|
+
@res.body << "<div class=\"#{css_class}\">#{message}</div>"
|
|
209
|
+
end
|
|
210
|
+
@res.body << self.page_footer(form_contents, checked)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def page_header(title="Ruby OpenID WEBrick example")
|
|
214
|
+
header = <<END_OF_STRING
|
|
215
|
+
<html>
|
|
216
|
+
<head><title>#{title}</title></head>
|
|
217
|
+
<style type="text/css">
|
|
218
|
+
* {
|
|
219
|
+
font-family: verdana,sans-serif;
|
|
220
|
+
}
|
|
221
|
+
body {
|
|
222
|
+
width: 50em;
|
|
223
|
+
margin: 1em;
|
|
224
|
+
}
|
|
225
|
+
div {
|
|
226
|
+
padding: .5em;
|
|
227
|
+
}
|
|
228
|
+
table {
|
|
229
|
+
margin: none;
|
|
230
|
+
padding: none;
|
|
231
|
+
}
|
|
232
|
+
.alert {
|
|
233
|
+
border: 1px solid #e7dc2b;
|
|
234
|
+
background: #fff888;
|
|
235
|
+
}
|
|
236
|
+
.error {
|
|
237
|
+
border: 1px solid #ff0000;
|
|
238
|
+
background: #ffaaaa;
|
|
239
|
+
}
|
|
240
|
+
#verify-form {
|
|
241
|
+
border: 1px solid #777777;
|
|
242
|
+
background: #dddddd;
|
|
243
|
+
margin-top: 1em;
|
|
244
|
+
padding-bottom: 0em;
|
|
245
|
+
}
|
|
246
|
+
</style>
|
|
247
|
+
<body>
|
|
248
|
+
<h1>#{title}</h1>
|
|
249
|
+
<p>
|
|
250
|
+
This example consumer uses the <a href="http://openidenabled.com/openid/libraries/ruby">Ruby OpenID</a> library
|
|
251
|
+
on a WEBrick platform. The example just verifies that the URL that
|
|
252
|
+
you enter is your identity URL.
|
|
253
|
+
</p>
|
|
254
|
+
END_OF_STRING
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def page_footer(form_contents="", checked="")
|
|
259
|
+
form_contents = "" if form_contents == "/"
|
|
260
|
+
footer = <<END_OF_STRING
|
|
261
|
+
<div id="verify-form">
|
|
262
|
+
<form method="get" action="#{self.build_url("/begin")}">
|
|
263
|
+
Identity URL:
|
|
264
|
+
<input type="text" name="openid_url" value="#{form_contents}" />
|
|
265
|
+
<input type="submit" value="Verify" />
|
|
266
|
+
<input type="checkbox" id="sregbox" name="sreg" #{checked} />
|
|
267
|
+
<label for="sregbox">with simple registration</label>
|
|
268
|
+
<a href="http://www.openidenabled.com/openid/simple-registration-extension" target="_blank">?</a>
|
|
269
|
+
</form>
|
|
270
|
+
</div>
|
|
271
|
+
</body>
|
|
272
|
+
</html>
|
|
273
|
+
END_OF_STRING
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
# Bootstrap the example
|
|
281
|
+
server.mount("/", SimpleServlet)
|
|
282
|
+
trap("INT") {server.shutdown}
|
|
283
|
+
print "\nVisit http://#{$host}:#{$port}/ in your browser.\n\n"
|
|
284
|
+
server.start
|
|
285
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
_eK��2�X,�|RG+
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
=Example SQL store using ActiveRecord
|
|
2
|
+
|
|
3
|
+
A store is required by an OpenID server and optionally by the consumer to
|
|
4
|
+
store associations, nonces, and auth key information across requests and
|
|
5
|
+
threads. This directory contains code useful in implementing an
|
|
6
|
+
ActiveRecord based store as an alternative to using the standard
|
|
7
|
+
OpenID::FilesystemOpenIDStore in Ruby on Rails applications.
|
|
8
|
+
|
|
9
|
+
==Setting up your database
|
|
10
|
+
|
|
11
|
+
You'll need to add three tables to your databases. There are two
|
|
12
|
+
different ways to do this outlined below.
|
|
13
|
+
|
|
14
|
+
===Starting from scratch
|
|
15
|
+
|
|
16
|
+
This directory contains three SQL schema files with the proper SQL for
|
|
17
|
+
adding the necessary OpenID tables in SQLite, MySQL, and Postgresql.
|
|
18
|
+
See the schema.type.sql files for more information.
|
|
19
|
+
|
|
20
|
+
===Upgrading with a rails migration script
|
|
21
|
+
|
|
22
|
+
Rails has built-in database migration functionality. If you are trying
|
|
23
|
+
to add OpenID support into your existing rails application, then
|
|
24
|
+
you'll probably want to use the enclosed migration script,
|
|
25
|
+
XX_add_openidstore.rb. Put this file in rails app's db/migrate
|
|
26
|
+
directory and replace the XX with the next migration number. If there
|
|
27
|
+
aren't migrations, the number will be 0.
|
|
28
|
+
|
|
29
|
+
==The OpenID Models
|
|
30
|
+
|
|
31
|
+
From the models dir, copy openid_association.rb, openid_nonce.rb, and
|
|
32
|
+
openid_setting.rb into the app/models dir of your rails app.
|
|
33
|
+
|
|
34
|
+
==The OpenIDStoreHelper
|
|
35
|
+
|
|
36
|
+
You'll probably have controller for handling openid operations in your
|
|
37
|
+
application (see the other examples). The control flow of the store
|
|
38
|
+
is handled in a helper. Look at OpenidHelper in openid_helper.rb,
|
|
39
|
+
which implements the OpenID::OpenIDStore interface.
|
|
40
|
+
|
|
41
|
+
Copy the openid_helper.rb into your app/helpers and then include the
|
|
42
|
+
OpenidHelper module in your openid controller. When instantiating
|
|
43
|
+
your OpenIDServer or OpenIDConsumer instance, you'll simply be able to
|
|
44
|
+
pass in self as the store.
|
|
45
|
+
|
|
46
|
+
==Unit testing your ActiveRecord OpenID store
|
|
47
|
+
|
|
48
|
+
The Ruby OpenID library comes with a generic StoreTestCase module that
|
|
49
|
+
can be mixed into any store test case. Copy openidstore_test.rb into
|
|
50
|
+
your rails' app test/unit dir. Change the line that contains "include
|
|
51
|
+
OpenidHelper" to include your openid helper if it has a different
|
|
52
|
+
name.
|
|
53
|
+
|
|
54
|
+
You may also need to change the require at the top to get at
|
|
55
|
+
storetestcase.rb. You won't need to change it if you are using
|
|
56
|
+
the openid library in the vendor directory of your rails' app.
|
|
57
|
+
|
|
58
|
+
==Questions?
|
|
59
|
+
Contact Brian Ellin a line at brian at janrain dot com
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
class AddOpenidstore < ActiveRecord::Migration
|
|
2
|
+
def self.up
|
|
3
|
+
create_table :openid_settings do |t|
|
|
4
|
+
t.column :setting, :string
|
|
5
|
+
t.column :value, :binary
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
create_table :openid_associations do |t|
|
|
9
|
+
# server_url is blob, because URLs could be longer
|
|
10
|
+
# than db can handle as a string
|
|
11
|
+
t.column :server_url, :binary
|
|
12
|
+
t.column :handle, :string
|
|
13
|
+
t.column :secret, :binary
|
|
14
|
+
t.column :issued, :integer
|
|
15
|
+
t.column :lifetime, :integer
|
|
16
|
+
t.column :assoc_type, :string
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
create_table :openid_nonces do |t|
|
|
20
|
+
t.column :nonce, :string
|
|
21
|
+
t.column :created, :integer
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.down
|
|
26
|
+
drop_table :openid_settings
|
|
27
|
+
drop_table :openid_associations
|
|
28
|
+
drop_table :openid_nonces
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
require 'openid/association'
|
|
2
|
+
|
|
3
|
+
module OpenidHelper
|
|
4
|
+
|
|
5
|
+
def get_auth_key
|
|
6
|
+
setting = OpenidSetting.find :first, :conditions => "setting = 'auth_key'"
|
|
7
|
+
if setting.nil?
|
|
8
|
+
auth_key = OpenID::Util.random_string(20)
|
|
9
|
+
setting = OpenidSetting.create :setting => 'auth_key', :value => auth_key
|
|
10
|
+
end
|
|
11
|
+
setting.value
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def store_association(server_url, assoc)
|
|
15
|
+
remove_association(server_url, assoc.handle)
|
|
16
|
+
OpenidAssociation.create(:server_url => server_url,
|
|
17
|
+
:handle => assoc.handle,
|
|
18
|
+
:secret => assoc.secret,
|
|
19
|
+
:issued => assoc.issued,
|
|
20
|
+
:lifetime => assoc.lifetime,
|
|
21
|
+
:assoc_type => assoc.assoc_type)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def get_association(server_url, handle=nil)
|
|
25
|
+
|
|
26
|
+
unless handle.nil?
|
|
27
|
+
assocs = OpenidAssociation.find(:all, :conditions => ["server_url = ? AND handle = ?", server_url, handle])
|
|
28
|
+
else
|
|
29
|
+
assocs = OpenidAssociation.find(:all, :conditions => ["server_url = ?", server_url])
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
return nil if assocs.nil?
|
|
33
|
+
|
|
34
|
+
assocs.reverse!
|
|
35
|
+
|
|
36
|
+
assocs.each do |assoc|
|
|
37
|
+
a = assoc.from_record
|
|
38
|
+
if a.expired?
|
|
39
|
+
assoc.destroy
|
|
40
|
+
else
|
|
41
|
+
return a
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
return nil
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def remove_association(server_url, handle)
|
|
49
|
+
assoc = OpenidAssociation.find(:first, :conditions => ["server_url = ? AND handle = ?", server_url, handle])
|
|
50
|
+
unless assoc.nil?
|
|
51
|
+
assoc.destroy
|
|
52
|
+
return true
|
|
53
|
+
end
|
|
54
|
+
return false
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def store_nonce(nonce)
|
|
58
|
+
use_nonce(nonce)
|
|
59
|
+
OpenidNonce.create :nonce => nonce, :created => Time.now.to_i
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def use_nonce(nonce)
|
|
63
|
+
nonce = OpenidNonce.find(:first, :conditions => ["nonce = ?", nonce])
|
|
64
|
+
return false if nonce.nil?
|
|
65
|
+
|
|
66
|
+
age = Time.now.to_i - nonce.created
|
|
67
|
+
nonce.destroy
|
|
68
|
+
|
|
69
|
+
return false if age > (6*60*60) # max nonce age of 6 hours
|
|
70
|
+
return true
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def dumb?
|
|
74
|
+
return false
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# not part of the api, but useful
|
|
78
|
+
def gc
|
|
79
|
+
now = Time.now.to_i
|
|
80
|
+
|
|
81
|
+
# remove old nonces
|
|
82
|
+
nonces = OpenidNonce.find(:all)
|
|
83
|
+
nonces.each {|n| n.destroy if now - n.created > (6*60*60)} unless nonces.nil?
|
|
84
|
+
|
|
85
|
+
# remove expired assocs
|
|
86
|
+
assocs = OpenidAssociation.find(:all)
|
|
87
|
+
assocs.each { |a| a.destroy if a.from_record.expired? } unless assocs.nil?
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
end
|