ruby-openid 1.1.4 → 2.0.1
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/INSTALL +0 -9
- data/README +21 -22
- data/UPGRADE +117 -0
- data/admin/runtests.rb +36 -0
- data/examples/README +13 -21
- data/examples/active_record_openid_store/README +8 -3
- data/examples/active_record_openid_store/XXX_add_open_id_store_to_db.rb +4 -8
- data/examples/active_record_openid_store/XXX_upgrade_open_id_store.rb +26 -0
- data/examples/active_record_openid_store/lib/association.rb +2 -0
- data/examples/active_record_openid_store/lib/openid_ar_store.rb +22 -47
- data/examples/active_record_openid_store/test/store_test.rb +78 -48
- data/examples/discover +46 -0
- data/examples/{rails_server → rails_openid}/README +0 -0
- data/examples/{rails_server → rails_openid}/Rakefile +0 -0
- data/examples/{rails_server → rails_openid}/app/controllers/application.rb +0 -0
- data/examples/rails_openid/app/controllers/consumer_controller.rb +115 -0
- data/examples/{rails_server → rails_openid}/app/controllers/login_controller.rb +10 -2
- data/examples/rails_openid/app/controllers/server_controller.rb +265 -0
- data/examples/{rails_server → rails_openid}/app/helpers/application_helper.rb +0 -0
- data/examples/{rails_server → rails_openid}/app/helpers/login_helper.rb +0 -0
- data/examples/{rails_server → rails_openid}/app/helpers/server_helper.rb +0 -0
- data/examples/rails_openid/app/views/consumer/index.rhtml +81 -0
- data/examples/rails_openid/app/views/consumer/start.rhtml +8 -0
- data/examples/{rails_server → rails_openid}/app/views/layouts/server.rhtml +0 -0
- data/examples/{rails_server → rails_openid}/app/views/login/index.rhtml +1 -1
- data/examples/rails_openid/app/views/server/decide.rhtml +26 -0
- data/examples/{rails_server → rails_openid}/config/boot.rb +0 -0
- data/examples/{rails_server → rails_openid}/config/database.yml +0 -0
- data/examples/{rails_server → rails_openid}/config/environment.rb +0 -0
- data/examples/{rails_server → rails_openid}/config/environments/development.rb +0 -0
- data/examples/{rails_server → rails_openid}/config/environments/production.rb +0 -0
- data/examples/{rails_server → rails_openid}/config/environments/test.rb +0 -0
- data/examples/{rails_server → rails_openid}/config/routes.rb +2 -1
- data/examples/{rails_server → rails_openid}/doc/README_FOR_APP +0 -0
- data/examples/{rails_server → rails_openid}/public/404.html +0 -0
- data/examples/{rails_server → rails_openid}/public/500.html +0 -0
- data/examples/{rails_server → rails_openid}/public/dispatch.cgi +0 -0
- data/examples/{rails_server → rails_openid}/public/dispatch.fcgi +0 -0
- data/examples/{rails_server → rails_openid}/public/dispatch.rb +0 -0
- data/examples/{rails_server → rails_openid}/public/favicon.ico +0 -0
- data/examples/rails_openid/public/images/openid_login_bg.gif +0 -0
- data/examples/{rails_server → rails_openid}/public/javascripts/controls.js +0 -0
- data/examples/{rails_server → rails_openid}/public/javascripts/dragdrop.js +0 -0
- data/examples/{rails_server → rails_openid}/public/javascripts/effects.js +0 -0
- data/examples/{rails_server → rails_openid}/public/javascripts/prototype.js +0 -0
- data/examples/{rails_server → rails_openid}/public/robots.txt +0 -0
- data/examples/{rails_server → rails_openid}/script/about +0 -0
- data/examples/{rails_server → rails_openid}/script/breakpointer +0 -0
- data/examples/{rails_server → rails_openid}/script/console +0 -0
- data/examples/{rails_server → rails_openid}/script/destroy +0 -0
- data/examples/{rails_server → rails_openid}/script/generate +0 -0
- data/examples/{rails_server → rails_openid}/script/performance/benchmarker +0 -0
- data/examples/{rails_server → rails_openid}/script/performance/profiler +0 -0
- data/examples/{rails_server → rails_openid}/script/plugin +0 -0
- data/examples/{rails_server → rails_openid}/script/process/reaper +0 -0
- data/examples/{rails_server → rails_openid}/script/process/spawner +0 -0
- data/examples/{rails_server → rails_openid}/script/process/spinner +0 -0
- data/examples/{rails_server → rails_openid}/script/runner +0 -0
- data/examples/{rails_server → rails_openid}/script/server +0 -0
- data/examples/{rails_server → rails_openid}/test/functional/login_controller_test.rb +0 -0
- data/examples/{rails_server → rails_openid}/test/functional/server_controller_test.rb +0 -0
- data/examples/{rails_server → rails_openid}/test/test_helper.rb +0 -0
- data/lib/{hmac.rb → hmac/hmac.rb} +0 -0
- data/lib/{hmac-sha1.rb → hmac/sha1.rb} +1 -1
- data/lib/{hmac-sha2.rb → hmac/sha2.rb} +1 -1
- data/lib/openid/association.rb +213 -73
- data/lib/openid/consumer/associationmanager.rb +338 -0
- data/lib/openid/consumer/checkid_request.rb +175 -0
- data/lib/openid/consumer/discovery.rb +480 -0
- data/lib/openid/consumer/discovery_manager.rb +123 -0
- data/lib/openid/consumer/html_parse.rb +136 -0
- data/lib/openid/consumer/idres.rb +525 -0
- data/lib/openid/consumer/responses.rb +133 -0
- data/lib/openid/consumer.rb +280 -807
- data/lib/openid/cryptutil.rb +85 -0
- data/lib/openid/dh.rb +60 -23
- data/lib/openid/extension.rb +31 -0
- data/lib/openid/extensions/ax.rb +506 -0
- data/lib/openid/extensions/pape.rb +182 -0
- data/lib/openid/extensions/sreg.rb +275 -0
- data/lib/openid/extras.rb +11 -0
- data/lib/openid/fetchers.rb +132 -93
- data/lib/openid/kvform.rb +133 -0
- data/lib/openid/kvpost.rb +56 -0
- data/lib/openid/message.rb +534 -0
- data/lib/openid/protocolerror.rb +6 -0
- data/lib/openid/server.rb +1215 -666
- data/lib/openid/store/filesystem.rb +271 -0
- data/lib/openid/store/interface.rb +75 -0
- data/lib/openid/store/memory.rb +84 -0
- data/lib/openid/store/nonce.rb +68 -0
- data/lib/openid/trustroot.rb +314 -87
- data/lib/openid/urinorm.rb +37 -34
- data/lib/openid/util.rb +42 -220
- data/lib/openid/yadis/accept.rb +148 -0
- data/lib/openid/yadis/constants.rb +21 -0
- data/lib/openid/yadis/discovery.rb +153 -0
- data/lib/openid/yadis/filters.rb +205 -0
- data/lib/openid/{htmltokenizer.rb → yadis/htmltokenizer.rb} +1 -54
- data/lib/openid/yadis/parsehtml.rb +36 -0
- data/lib/openid/yadis/services.rb +42 -0
- data/lib/openid/yadis/xrds.rb +171 -0
- data/lib/openid/yadis/xri.rb +90 -0
- data/lib/openid/yadis/xrires.rb +106 -0
- data/lib/openid.rb +1 -4
- data/test/data/accept.txt +124 -0
- data/test/data/dh.txt +29 -0
- data/test/data/example-xrds.xml +14 -0
- data/test/data/linkparse.txt +587 -0
- data/test/data/n2b64 +650 -0
- data/test/data/test1-discover.txt +137 -0
- data/test/data/test1-parsehtml.txt +128 -0
- data/test/data/test_discover/openid.html +11 -0
- data/test/data/test_discover/openid2.html +11 -0
- data/test/data/test_discover/openid2_xrds.xml +12 -0
- data/test/data/test_discover/openid2_xrds_no_local_id.xml +11 -0
- data/test/data/test_discover/openid_1_and_2.html +11 -0
- data/test/data/test_discover/openid_1_and_2_xrds.xml +16 -0
- data/test/data/test_discover/openid_1_and_2_xrds_bad_delegate.xml +17 -0
- data/test/data/test_discover/openid_and_yadis.html +12 -0
- data/test/data/test_discover/openid_no_delegate.html +10 -0
- data/test/data/test_discover/yadis_0entries.xml +12 -0
- data/test/data/test_discover/yadis_2_bad_local_id.xml +15 -0
- data/test/data/test_discover/yadis_2entries_delegate.xml +22 -0
- data/test/data/test_discover/yadis_2entries_idp.xml +21 -0
- data/test/data/test_discover/yadis_another_delegate.xml +14 -0
- data/test/data/test_discover/yadis_idp.xml +12 -0
- data/test/data/test_discover/yadis_idp_delegate.xml +13 -0
- data/test/data/test_discover/yadis_no_delegate.xml +11 -0
- data/test/data/test_xrds/=j3h.2007.11.14.xrds +25 -0
- data/test/data/test_xrds/README +12 -0
- data/test/data/test_xrds/delegated-20060809-r1.xrds +34 -0
- data/test/data/test_xrds/delegated-20060809-r2.xrds +34 -0
- data/test/data/test_xrds/delegated-20060809.xrds +34 -0
- data/test/data/test_xrds/no-xrd.xml +7 -0
- data/test/data/test_xrds/not-xrds.xml +2 -0
- data/test/data/test_xrds/prefixsometimes.xrds +34 -0
- data/test/data/test_xrds/ref.xrds +109 -0
- data/test/data/test_xrds/sometimesprefix.xrds +34 -0
- data/test/data/test_xrds/spoof1.xrds +25 -0
- data/test/data/test_xrds/spoof2.xrds +25 -0
- data/test/data/test_xrds/spoof3.xrds +37 -0
- data/test/data/test_xrds/status222.xrds +9 -0
- data/test/data/test_xrds/valid-populated-xrds.xml +39 -0
- data/test/data/trustroot.txt +147 -0
- data/test/discoverdata.rb +131 -0
- data/test/test_accept.rb +170 -0
- data/test/test_association.rb +266 -0
- data/test/test_associationmanager.rb +899 -0
- data/test/test_ax.rb +587 -0
- data/test/test_checkid_request.rb +297 -0
- data/test/test_consumer.rb +257 -0
- data/test/test_cryptutil.rb +117 -0
- data/test/test_dh.rb +86 -0
- data/test/test_discover.rb +772 -0
- data/test/test_discovery_manager.rb +262 -0
- data/test/test_extras.rb +35 -0
- data/test/test_fetchers.rb +472 -0
- data/test/test_filters.rb +270 -0
- data/test/test_idres.rb +816 -0
- data/test/test_kvform.rb +165 -0
- data/test/test_kvpost.rb +65 -0
- data/test/test_linkparse.rb +101 -0
- data/test/test_message.rb +1058 -0
- data/test/test_nonce.rb +89 -0
- data/test/test_openid_yadis.rb +178 -0
- data/test/test_pape.rb +233 -0
- data/test/test_parsehtml.rb +80 -0
- data/test/test_responses.rb +63 -0
- data/test/test_server.rb +2270 -0
- data/test/test_sreg.rb +479 -0
- data/test/test_stores.rb +269 -0
- data/test/test_trustroot.rb +112 -0
- data/test/{urinorm.rb → test_urinorm.rb} +6 -3
- data/test/test_util.rb +144 -0
- data/test/test_xrds.rb +160 -0
- data/test/test_xri.rb +48 -0
- data/test/test_xrires.rb +63 -0
- data/test/test_yadis_discovery.rb +207 -0
- data/test/testutil.rb +116 -0
- data/test/util.rb +47 -50
- metadata +233 -143
- data/examples/consumer.rb +0 -290
- data/examples/rails_openid_login_generator/openid_login_generator-0.1.gem +0 -0
- data/examples/rails_server/app/controllers/server_controller.rb +0 -190
- data/examples/rails_server/app/views/server/decide.rhtml +0 -11
- data/examples/rails_server/public/images/rails.png +0 -0
- data/lib/hmac-md5.rb +0 -11
- data/lib/hmac-rmd160.rb +0 -11
- data/lib/openid/discovery.rb +0 -122
- data/lib/openid/filestore.rb +0 -315
- data/lib/openid/parse.rb +0 -23
- data/lib/openid/service.rb +0 -147
- data/lib/openid/stores.rb +0 -178
- data/test/assoc.rb +0 -38
- data/test/consumer.rb +0 -376
- data/test/data/brian.xrds +0 -16
- data/test/data/brianellin.mylid.xrds +0 -42
- data/test/dh.rb +0 -20
- data/test/extensions.rb +0 -30
- data/test/linkparse.rb +0 -305
- data/test/runtests.rb +0 -22
- data/test/server2.rb +0 -1053
- data/test/service.rb +0 -47
- data/test/storetestcase.rb +0 -172
- data/test/teststore.rb +0 -47
- data/test/trustroot.rb +0 -117
data/lib/openid/filestore.rb
DELETED
|
@@ -1,315 +0,0 @@
|
|
|
1
|
-
require 'fileutils'
|
|
2
|
-
require 'pathname'
|
|
3
|
-
require 'tempfile'
|
|
4
|
-
|
|
5
|
-
require 'openid/util'
|
|
6
|
-
require 'openid/stores'
|
|
7
|
-
require 'openid/association'
|
|
8
|
-
|
|
9
|
-
module OpenID
|
|
10
|
-
|
|
11
|
-
# Filesystem-based store for OpenID associations and nonces.
|
|
12
|
-
#
|
|
13
|
-
# Methods of this object may raise SystemCallError if filestystem
|
|
14
|
-
# related errors are encountered.
|
|
15
|
-
class FilesystemStore < Store
|
|
16
|
-
|
|
17
|
-
@@FILENAME_ALLOWED = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-".split("")
|
|
18
|
-
|
|
19
|
-
# Create a FilesystemStore instance, putting all data in +directory+.
|
|
20
|
-
def initialize(directory)
|
|
21
|
-
p_dir = Pathname.new(directory)
|
|
22
|
-
@nonce_dir = p_dir.join('nonces')
|
|
23
|
-
@association_dir = p_dir.join('associations')
|
|
24
|
-
@temp_dir = p_dir.join('temp')
|
|
25
|
-
@auth_key_name = p_dir.join('auth_key')
|
|
26
|
-
@max_nonce_age = 6 * 60 * 60
|
|
27
|
-
|
|
28
|
-
self.ensure_dir(@nonce_dir)
|
|
29
|
-
self.ensure_dir(@association_dir)
|
|
30
|
-
self.ensure_dir(@temp_dir)
|
|
31
|
-
self.ensure_dir(File.dirname(@auth_key_name))
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# Read the auth key from the auth key file. Returns nil if there
|
|
35
|
-
# is currently no auth key.
|
|
36
|
-
def read_auth_key
|
|
37
|
-
f = nil
|
|
38
|
-
begin
|
|
39
|
-
f = File.open(@auth_key_name)
|
|
40
|
-
rescue Errno::ENOENT
|
|
41
|
-
return nil
|
|
42
|
-
else
|
|
43
|
-
return f.read
|
|
44
|
-
ensure
|
|
45
|
-
f.close unless f.nil?
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
# Generate a new random auth key and safely store it in the location
|
|
50
|
-
# specified by @auth_key_name
|
|
51
|
-
def create_auth_key
|
|
52
|
-
auth_key = OpenID::Util.random_string(@@AUTH_KEY_LEN)
|
|
53
|
-
f, tmp = mktemp
|
|
54
|
-
begin
|
|
55
|
-
begin
|
|
56
|
-
f.write(auth_key)
|
|
57
|
-
f.fsync
|
|
58
|
-
ensure
|
|
59
|
-
f.close
|
|
60
|
-
end
|
|
61
|
-
begin
|
|
62
|
-
begin
|
|
63
|
-
File.link(tmp, @auth_key_name)
|
|
64
|
-
rescue NotImplementedError # no link under windows
|
|
65
|
-
File.rename(tmp, @auth_key_name)
|
|
66
|
-
end
|
|
67
|
-
rescue Errno::EEXIST
|
|
68
|
-
raise if read_auth_key.nil?
|
|
69
|
-
end
|
|
70
|
-
ensure
|
|
71
|
-
self.remove_if_present(tmp)
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
auth_key
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
# Retrieve the auth key from the file specified by
|
|
78
|
-
# @auth_key_file, creating it if it does not exist
|
|
79
|
-
def get_auth_key
|
|
80
|
-
auth_key = read_auth_key
|
|
81
|
-
if auth_key.nil?
|
|
82
|
-
auth_key = create_auth_key
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
if auth_key.length != @@AUTH_KEY_LEN
|
|
86
|
-
raise StandardError.new("Bad auth key - wrong length")
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
auth_key
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
# Create a unique filename for a given server url and handle. The
|
|
93
|
-
# filename that is returned will contain the domain name from the
|
|
94
|
-
# server URL for ease of human inspection of the data dir.
|
|
95
|
-
def get_association_filename(server_url, handle)
|
|
96
|
-
filename = self.filename_from_url(server_url)
|
|
97
|
-
filename += '-' + safe64(handle)
|
|
98
|
-
@association_dir.join(filename)
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
# Store an association in the assoc directory
|
|
102
|
-
def store_association(server_url, association)
|
|
103
|
-
assoc_s = OpenID::Association.serialize(association)
|
|
104
|
-
filename = get_association_filename(server_url, association.handle)
|
|
105
|
-
f, tmp = mktemp
|
|
106
|
-
|
|
107
|
-
begin
|
|
108
|
-
begin
|
|
109
|
-
f.write(assoc_s)
|
|
110
|
-
f.fsync
|
|
111
|
-
ensure
|
|
112
|
-
f.close
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
begin
|
|
116
|
-
File.rename(tmp, filename)
|
|
117
|
-
rescue Errno::EEXIST
|
|
118
|
-
|
|
119
|
-
begin
|
|
120
|
-
File.unlink(filename)
|
|
121
|
-
rescue Errno::ENOENT
|
|
122
|
-
# do nothing
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
File.rename(tmp, filename)
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
rescue
|
|
129
|
-
self.remove_if_present(tmp)
|
|
130
|
-
raise
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
# Retrieve an association
|
|
135
|
-
def get_association(server_url, handle=nil)
|
|
136
|
-
unless handle.nil?
|
|
137
|
-
filename = get_association_filename(server_url, handle)
|
|
138
|
-
return _get_association(filename)
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
# search though existing files looking for a match
|
|
142
|
-
prefix = filename_from_url(server_url)
|
|
143
|
-
assoc_filenames = Dir.entries(@association_dir)
|
|
144
|
-
assoc_filenames = assoc_filenames.find_all { |f| f.index(prefix) == 0 }
|
|
145
|
-
|
|
146
|
-
assocs = assoc_filenames.collect do |f|
|
|
147
|
-
_get_association(@association_dir.join(f))
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
assocs = assocs.find_all { |a| not a.nil? }
|
|
151
|
-
assocs = assocs.sort_by { |a| a.issued }
|
|
152
|
-
|
|
153
|
-
return nil if assocs.empty?
|
|
154
|
-
return assocs[-1]
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
def _get_association(filename)
|
|
158
|
-
begin
|
|
159
|
-
assoc_file = File.open(filename, "r")
|
|
160
|
-
rescue Errno::ENOENT
|
|
161
|
-
return nil
|
|
162
|
-
else
|
|
163
|
-
begin
|
|
164
|
-
assoc_s = assoc_file.read
|
|
165
|
-
ensure
|
|
166
|
-
assoc_file.close
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
begin
|
|
170
|
-
association = OpenID::Association.deserialize(assoc_s)
|
|
171
|
-
rescue
|
|
172
|
-
self.remove_if_present(filename)
|
|
173
|
-
return nil
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
# clean up expired associations
|
|
177
|
-
if association.expires_in == 0
|
|
178
|
-
self.remove_if_present(filename)
|
|
179
|
-
return nil
|
|
180
|
-
else
|
|
181
|
-
return association
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
# Remove an association if it exists, otherwise do nothing.
|
|
187
|
-
def remove_association(server_url, handle)
|
|
188
|
-
assoc = get_association(server_url, handle)
|
|
189
|
-
|
|
190
|
-
if assoc.nil?
|
|
191
|
-
return false
|
|
192
|
-
else
|
|
193
|
-
filename = get_association_filename(server_url, handle)
|
|
194
|
-
return self.remove_if_present(filename)
|
|
195
|
-
end
|
|
196
|
-
end
|
|
197
|
-
|
|
198
|
-
# Mark this nonce as present
|
|
199
|
-
def store_nonce(nonce)
|
|
200
|
-
filename = @nonce_dir.join(nonce)
|
|
201
|
-
File.open(filename, "w").close
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
# Return whether this nonce is present. As a side-effect, mark it
|
|
205
|
-
# as no longer present.
|
|
206
|
-
def use_nonce(nonce)
|
|
207
|
-
filename = @nonce_dir.join(nonce)
|
|
208
|
-
begin
|
|
209
|
-
st = File.stat(filename)
|
|
210
|
-
rescue Errno::ENOENT
|
|
211
|
-
return false
|
|
212
|
-
else
|
|
213
|
-
begin
|
|
214
|
-
File.unlink(filename)
|
|
215
|
-
rescue Errno::ENOENT
|
|
216
|
-
return false
|
|
217
|
-
end
|
|
218
|
-
nonce_age = Time.now.to_f - st.mtime.to_f
|
|
219
|
-
nonce_age <= @max_nonce_age
|
|
220
|
-
end
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
# Garbage collection routine. Clean up old associations and nonces.
|
|
224
|
-
def clean
|
|
225
|
-
nonces = Dir[@nonce_dir.join("*")]
|
|
226
|
-
now = Time.now
|
|
227
|
-
|
|
228
|
-
nonces.each do |nonce|
|
|
229
|
-
filename = nonce_dir.join(nonce)
|
|
230
|
-
begin
|
|
231
|
-
st = File.stat(filename)
|
|
232
|
-
rescue Errno::ENOENT
|
|
233
|
-
next
|
|
234
|
-
else
|
|
235
|
-
nonce_age = now - st.mtime
|
|
236
|
-
self.remove_if_present(filename) if nonce_age > @max_nonce_age
|
|
237
|
-
end
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
association_filenames = Dir[@association_dir.join("*")]
|
|
241
|
-
association_filenames.each do |af|
|
|
242
|
-
begin
|
|
243
|
-
f = File.open(af, 'r')
|
|
244
|
-
rescue Errno::ENOENT
|
|
245
|
-
next
|
|
246
|
-
else
|
|
247
|
-
begin
|
|
248
|
-
assoc_s = f.read
|
|
249
|
-
ensure
|
|
250
|
-
f.close
|
|
251
|
-
end
|
|
252
|
-
begin
|
|
253
|
-
association = OpenID::Association.deserialize(assoc_s)
|
|
254
|
-
rescue "VersionError"
|
|
255
|
-
self.remove_if_present(af)
|
|
256
|
-
next
|
|
257
|
-
else
|
|
258
|
-
self.remove_if_present(af) if association.expires_in == 0
|
|
259
|
-
end
|
|
260
|
-
end
|
|
261
|
-
end
|
|
262
|
-
end
|
|
263
|
-
|
|
264
|
-
protected
|
|
265
|
-
|
|
266
|
-
# Create a temporary file and return the File object and filename.
|
|
267
|
-
def mktemp
|
|
268
|
-
f = Tempfile.new('tmp', @temp_dir)
|
|
269
|
-
[f, f.path]
|
|
270
|
-
end
|
|
271
|
-
|
|
272
|
-
# create a safe filename from a url
|
|
273
|
-
def filename_from_url(url)
|
|
274
|
-
filename = []
|
|
275
|
-
url.sub('://','-').split("").each do |c|
|
|
276
|
-
if @@FILENAME_ALLOWED.index(c)
|
|
277
|
-
filename << c
|
|
278
|
-
else
|
|
279
|
-
filename << sprintf("_%02X", c[0])
|
|
280
|
-
end
|
|
281
|
-
end
|
|
282
|
-
filename.join("")
|
|
283
|
-
end
|
|
284
|
-
|
|
285
|
-
def safe64(s)
|
|
286
|
-
s = OpenID::Util.sha1(s)
|
|
287
|
-
s = OpenID::Util.to_base64(s)
|
|
288
|
-
s.gsub!('+', '_')
|
|
289
|
-
s.gsub!('/', '.')
|
|
290
|
-
s.gsub!('=', '')
|
|
291
|
-
return s
|
|
292
|
-
end
|
|
293
|
-
|
|
294
|
-
# remove file if present in filesystem
|
|
295
|
-
def remove_if_present(filename)
|
|
296
|
-
begin
|
|
297
|
-
File.unlink(filename)
|
|
298
|
-
rescue Errno::ENOENT
|
|
299
|
-
return false
|
|
300
|
-
end
|
|
301
|
-
return true
|
|
302
|
-
end
|
|
303
|
-
|
|
304
|
-
# ensure that a path exists
|
|
305
|
-
|
|
306
|
-
def ensure_dir(dir_name)
|
|
307
|
-
FileUtils::mkdir_p(dir_name)
|
|
308
|
-
end
|
|
309
|
-
|
|
310
|
-
end
|
|
311
|
-
|
|
312
|
-
end
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
data/lib/openid/parse.rb
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
require "openid/htmltokenizer"
|
|
2
|
-
|
|
3
|
-
def parse_link_attrs(data)
|
|
4
|
-
parser = HTMLTokenizer.new(data)
|
|
5
|
-
in_head = false
|
|
6
|
-
begin
|
|
7
|
-
while el = parser.getTag("head", "link", "body")
|
|
8
|
-
if el.tag_name == "head"
|
|
9
|
-
in_head = true
|
|
10
|
-
elsif el.tag_name == "link"
|
|
11
|
-
continue unless in_head
|
|
12
|
-
yield el.attr_hash
|
|
13
|
-
elsif el.tag_name == "body"
|
|
14
|
-
return
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
rescue
|
|
18
|
-
return
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
data/lib/openid/service.rb
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
require 'rexml/document'
|
|
2
|
-
|
|
3
|
-
begin
|
|
4
|
-
require 'yadis'
|
|
5
|
-
rescue LoadError
|
|
6
|
-
require 'rubygems'
|
|
7
|
-
require_gem 'ruby-yadis'
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
module OpenID
|
|
11
|
-
|
|
12
|
-
# OpenIDService is an object representation of an OpenID server,
|
|
13
|
-
# and the services it provides. It contains a useful information such
|
|
14
|
-
# as the server URL, and information about the OpenID identity bound
|
|
15
|
-
# to the server. OpenIDService object should be produced using the
|
|
16
|
-
# OpenIDService.from_service class method with a Yadis Service object.
|
|
17
|
-
# See the ruby Yadis library for more information:
|
|
18
|
-
#
|
|
19
|
-
# http://www.openidenabled.com/yadis/libraries/ruby
|
|
20
|
-
#
|
|
21
|
-
# Unless you choose to do your own discovery and interface with
|
|
22
|
-
# OpenIDConsumer through the OpenIDConsumer.begin_without_discovery
|
|
23
|
-
# method, you won't need to ever use this object directly. It is used
|
|
24
|
-
# internally by the OpenIDConsumer object.
|
|
25
|
-
class OpenIDServiceEndpoint < ServiceEndpoint
|
|
26
|
-
|
|
27
|
-
@@namespace = {
|
|
28
|
-
'xrdsns' => 'xri://$xrds',
|
|
29
|
-
'xrdns' => 'xri://$xrd*($v*2.0)',
|
|
30
|
-
'openidns' => 'http://openid.net/xmlns/1.0'
|
|
31
|
-
}
|
|
32
|
-
attr_accessor :service_types, :uri, :yadis_url, :delegate_url, :xrds_uri, :canonical_id
|
|
33
|
-
|
|
34
|
-
# Class method to produce OpenIDService objects. Call with a Yadis Service
|
|
35
|
-
# object. Will return nil if the Service object does not represent an
|
|
36
|
-
# an OpenID server.
|
|
37
|
-
def OpenIDServiceEndpoint.from_endpoint(service, versions=nil)
|
|
38
|
-
return nil unless OpenIDServiceEndpoint.is_type?(service, versions)
|
|
39
|
-
|
|
40
|
-
s = new
|
|
41
|
-
s.service_types = service.service_types
|
|
42
|
-
s.uri = service.uri
|
|
43
|
-
s.yadis_url = service.yadis.uri if service.yadis
|
|
44
|
-
s.xrds_uri = service.yadis.xrds_uri if service.yadis
|
|
45
|
-
s.canonical_id = service.canonical_id
|
|
46
|
-
|
|
47
|
-
s.delegate_url = nil
|
|
48
|
-
REXML::XPath.each(service.element, 'openidns:Delegate',
|
|
49
|
-
@@namespace) do |e|
|
|
50
|
-
s.delegate_url = e.text.strip
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
return s
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
# Class method to determine if a Yadis service object is an OpenID server.
|
|
57
|
-
# +versions+ is a list of Strings representing the versions of the OpenID
|
|
58
|
-
# protocol you support. Only service that match one of the versions will
|
|
59
|
-
# return a value that evaluates to true. If no +versions+ list is
|
|
60
|
-
# specified, all versions will be accepted.
|
|
61
|
-
def OpenIDServiceEndpoint.is_type?(service, versions=nil)
|
|
62
|
-
# escape the period in the version numbers
|
|
63
|
-
versions.collect! {|v| v.gsub('.', '\.')} if versions
|
|
64
|
-
|
|
65
|
-
base_url = 'http://openid\.net/signon/'
|
|
66
|
-
base_url += '(' + versions.join('|') + '){1}' if versions
|
|
67
|
-
|
|
68
|
-
service.service_types.each do |st|
|
|
69
|
-
return true if st.match(base_url)
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
return false
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
# Alias for +supports?+
|
|
76
|
-
def uses_extension?(extension_url)
|
|
77
|
-
return supports?(extension_url)
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
# Same as uses_extension? Checks to see if the provided URL is
|
|
81
|
-
# in the list of service types. Example that checks for support
|
|
82
|
-
# of the simple registratino protocol:
|
|
83
|
-
#
|
|
84
|
-
# service.supports?('http://openid.net/sreg/1.0')
|
|
85
|
-
#
|
|
86
|
-
def supports?(url)
|
|
87
|
-
return @service_types.member?(url)
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
# Returns the OpenID delegate URL. This is the URL on the OpenID server,
|
|
91
|
-
# For example if example.com delegates to example-server.com/user, then
|
|
92
|
-
# this will return example-server.com/user
|
|
93
|
-
def delegate
|
|
94
|
-
@delegate_url or self.consumer_id
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
# Returns the OpenID server endpoint URL.
|
|
98
|
-
def server_url
|
|
99
|
-
@uri
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
# Returns user's URL which resides on the OpenID server. For
|
|
103
|
-
# example if http://example.com/ delegates to http://example.myopenid.com/,
|
|
104
|
-
# then http://example.myopenid.com/ will be returned by this method.
|
|
105
|
-
def server_id
|
|
106
|
-
self.delegate
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
# The URL the user entered to authenticate. For example, if
|
|
110
|
-
# http://example.com/ delegates to http://example.myopenid.com/, this
|
|
111
|
-
# method will return http://example.com/
|
|
112
|
-
def consumer_id
|
|
113
|
-
@yadis_url
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
def canonical_id
|
|
117
|
-
@canonical_id or self.consumer_id
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
# Used for providing an OpenIDService like object
|
|
123
|
-
# to the OpenID library for 1.X link rel discovery.
|
|
124
|
-
# See the documentation for OpenID::OpenIDService for more information
|
|
125
|
-
# on what this object does.
|
|
126
|
-
class FakeOpenIDServiceEndpoint < OpenIDServiceEndpoint
|
|
127
|
-
|
|
128
|
-
def initialize(consumer_id, server_id, server_url)
|
|
129
|
-
@uri = server_url
|
|
130
|
-
@delegate = server_id
|
|
131
|
-
@yadis_url = consumer_id
|
|
132
|
-
@service_types = ['http://openid.net/signon/1.0']
|
|
133
|
-
@yadis = nil
|
|
134
|
-
@xrds_uri = nil
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
def delegate
|
|
138
|
-
@delegate
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def supports?(url)
|
|
142
|
-
false
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
end
|
data/lib/openid/stores.rb
DELETED
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
require "openid/util"
|
|
2
|
-
|
|
3
|
-
module OpenID
|
|
4
|
-
|
|
5
|
-
# Interface for the abstract Store
|
|
6
|
-
class Store
|
|
7
|
-
|
|
8
|
-
@@AUTH_KEY_LEN = 20
|
|
9
|
-
|
|
10
|
-
# Put a Association object into storage
|
|
11
|
-
def store_association(server_url, association)
|
|
12
|
-
raise NotImplementedError
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
# Returns a Association object from storage that matches
|
|
16
|
-
# the server_url. Returns nil if no such association is found or if
|
|
17
|
-
# the one matching association is expired. (Is allowed to GC expired
|
|
18
|
-
# associations when found.)
|
|
19
|
-
def get_association(server_url, handle=nil)
|
|
20
|
-
raise NotImplementedError
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
# If there is a matching association, remove it from the store and
|
|
24
|
-
# return true, otherwise return false.
|
|
25
|
-
def remove_association(server_url, handle)
|
|
26
|
-
raise NotImplementedError
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
# Stores a nonce (which is passed in as a string).
|
|
30
|
-
def store_nonce(nonce)
|
|
31
|
-
raise NotImplementedError
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# If the nonce is in the store, remove it and return true. Otherwise
|
|
35
|
-
# return false.
|
|
36
|
-
def use_nonce(nonce)
|
|
37
|
-
raise NotImplementedError
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
# Returns a 20-byte auth key used to sign the tokens, to ensure
|
|
41
|
-
# that they haven't been tampered with in transit. It must return
|
|
42
|
-
# the same key every time it is called.
|
|
43
|
-
def get_auth_key
|
|
44
|
-
raise NotImplementedError
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# Method return true if the store is dumb-mode-style store.
|
|
48
|
-
def dumb?
|
|
49
|
-
false
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
class DumbStore < Store
|
|
56
|
-
|
|
57
|
-
def initialize(secret_phrase)
|
|
58
|
-
require "digest/sha1"
|
|
59
|
-
@auth_key = Digest::SHA1.hexdigest(secret_phrase)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def store_association(server_url, assoc)
|
|
63
|
-
nil
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def get_association(server_url, handle=nil)
|
|
67
|
-
nil
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def remove_association(server_url, handle)
|
|
71
|
-
false
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def store_nonce(nonce)
|
|
75
|
-
nil
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def use_nonce(nonce)
|
|
79
|
-
true
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def get_auth_key
|
|
83
|
-
@auth_key
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def dumb?
|
|
87
|
-
true
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
class ServerAssocs
|
|
93
|
-
def initialize
|
|
94
|
-
@assocs = {}
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def set(assoc)
|
|
98
|
-
@assocs[assoc.handle] = assoc
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
def get(handle)
|
|
102
|
-
@assocs[handle]
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def remove(handle)
|
|
106
|
-
return @assocs.delete(handle)
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
def best
|
|
110
|
-
best = nil
|
|
111
|
-
@assocs.each do |k, assoc|
|
|
112
|
-
if best.nil? or best.issued < assoc.issued
|
|
113
|
-
best = assoc
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
return best
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
# An in-memory implementation of Store. This class is mainly used
|
|
121
|
-
# for testing, though it may be useful for long-running single process apps.
|
|
122
|
-
#
|
|
123
|
-
# You should probably be looking at OpenID::FilesystemStore
|
|
124
|
-
class MemoryStore < Store
|
|
125
|
-
|
|
126
|
-
def initialize
|
|
127
|
-
@server_assocs = {}
|
|
128
|
-
@nonces = {}
|
|
129
|
-
@auth_key = OpenID::Util.random_string(@@AUTH_KEY_LEN)
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
def dumb?
|
|
133
|
-
false
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
def store_association(server_url, assoc)
|
|
137
|
-
assocs = _get_server_assocs(server_url)
|
|
138
|
-
assocs.set(self.deepcopy(assoc))
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def get_association(server_url, handle=nil)
|
|
142
|
-
assocs = _get_server_assocs(server_url)
|
|
143
|
-
return assocs.best if handle.nil?
|
|
144
|
-
return assocs.get(handle)
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
def remove_association(server_url, handle)
|
|
148
|
-
assocs = _get_server_assocs(server_url)
|
|
149
|
-
return assocs.remove(handle)
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
def use_nonce(nonce)
|
|
153
|
-
return true if @nonces.delete(nonce)
|
|
154
|
-
return false
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
def store_nonce(nonce)
|
|
158
|
-
@nonces[nonce] = true
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
def get_auth_key
|
|
162
|
-
@auth_key
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
def _get_server_assocs(server_url)
|
|
166
|
-
unless @server_assocs.has_key?(server_url)
|
|
167
|
-
@server_assocs[server_url] = ServerAssocs.new
|
|
168
|
-
end
|
|
169
|
-
return @server_assocs[server_url]
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
def deepcopy(o)
|
|
173
|
-
Marshal.load(Marshal.dump(o))
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
end
|
data/test/assoc.rb
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
require 'test/unit'
|
|
2
|
-
require 'openid/association'
|
|
3
|
-
|
|
4
|
-
class AssociationTestCase < Test::Unit::TestCase
|
|
5
|
-
|
|
6
|
-
def _get_assoc
|
|
7
|
-
issued = Time.now.to_i
|
|
8
|
-
lifetime = 600
|
|
9
|
-
OpenID::Association.new('handle', 'secret', issued, lifetime, 'HMAC-SHA1')
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def test_assoc
|
|
13
|
-
assoc = _get_assoc
|
|
14
|
-
s = OpenID::Association.serialize(assoc)
|
|
15
|
-
assert_equal(assoc, OpenID::Association.deserialize(s))
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def test_sign
|
|
19
|
-
assoc = _get_assoc
|
|
20
|
-
|
|
21
|
-
h = {
|
|
22
|
-
'openid.a' => 'b',
|
|
23
|
-
'openid.c' => 'd',
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
assoc.add_signature(['a','c'], h)
|
|
27
|
-
assert_not_nil(h['openid.signed'])
|
|
28
|
-
assert_not_nil(h['openid.sig'])
|
|
29
|
-
assert_equal(h['openid.signed'], 'a,c')
|
|
30
|
-
|
|
31
|
-
sig = OpenID::Util.to_base64( \
|
|
32
|
-
OpenID::Util.hmac_sha1(assoc.secret, "a:b\nc:d\n"))
|
|
33
|
-
|
|
34
|
-
assert_equal(h['openid.sig'], sig)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
end
|
|
38
|
-
|