ruby-openid 1.1.4 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ruby-openid might be problematic. Click here for more details.

Files changed (207) hide show
  1. data/INSTALL +0 -9
  2. data/README +21 -22
  3. data/UPGRADE +117 -0
  4. data/admin/runtests.rb +36 -0
  5. data/examples/README +13 -21
  6. data/examples/active_record_openid_store/README +8 -3
  7. data/examples/active_record_openid_store/XXX_add_open_id_store_to_db.rb +4 -8
  8. data/examples/active_record_openid_store/XXX_upgrade_open_id_store.rb +26 -0
  9. data/examples/active_record_openid_store/lib/association.rb +2 -0
  10. data/examples/active_record_openid_store/lib/openid_ar_store.rb +22 -47
  11. data/examples/active_record_openid_store/test/store_test.rb +78 -48
  12. data/examples/discover +46 -0
  13. data/examples/{rails_server → rails_openid}/README +0 -0
  14. data/examples/{rails_server → rails_openid}/Rakefile +0 -0
  15. data/examples/{rails_server → rails_openid}/app/controllers/application.rb +0 -0
  16. data/examples/rails_openid/app/controllers/consumer_controller.rb +115 -0
  17. data/examples/{rails_server → rails_openid}/app/controllers/login_controller.rb +10 -2
  18. data/examples/rails_openid/app/controllers/server_controller.rb +265 -0
  19. data/examples/{rails_server → rails_openid}/app/helpers/application_helper.rb +0 -0
  20. data/examples/{rails_server → rails_openid}/app/helpers/login_helper.rb +0 -0
  21. data/examples/{rails_server → rails_openid}/app/helpers/server_helper.rb +0 -0
  22. data/examples/rails_openid/app/views/consumer/index.rhtml +81 -0
  23. data/examples/rails_openid/app/views/consumer/start.rhtml +8 -0
  24. data/examples/{rails_server → rails_openid}/app/views/layouts/server.rhtml +0 -0
  25. data/examples/{rails_server → rails_openid}/app/views/login/index.rhtml +1 -1
  26. data/examples/rails_openid/app/views/server/decide.rhtml +26 -0
  27. data/examples/{rails_server → rails_openid}/config/boot.rb +0 -0
  28. data/examples/{rails_server → rails_openid}/config/database.yml +0 -0
  29. data/examples/{rails_server → rails_openid}/config/environment.rb +0 -0
  30. data/examples/{rails_server → rails_openid}/config/environments/development.rb +0 -0
  31. data/examples/{rails_server → rails_openid}/config/environments/production.rb +0 -0
  32. data/examples/{rails_server → rails_openid}/config/environments/test.rb +0 -0
  33. data/examples/{rails_server → rails_openid}/config/routes.rb +2 -1
  34. data/examples/{rails_server → rails_openid}/doc/README_FOR_APP +0 -0
  35. data/examples/{rails_server → rails_openid}/public/404.html +0 -0
  36. data/examples/{rails_server → rails_openid}/public/500.html +0 -0
  37. data/examples/{rails_server → rails_openid}/public/dispatch.cgi +0 -0
  38. data/examples/{rails_server → rails_openid}/public/dispatch.fcgi +0 -0
  39. data/examples/{rails_server → rails_openid}/public/dispatch.rb +0 -0
  40. data/examples/{rails_server → rails_openid}/public/favicon.ico +0 -0
  41. data/examples/rails_openid/public/images/openid_login_bg.gif +0 -0
  42. data/examples/{rails_server → rails_openid}/public/javascripts/controls.js +0 -0
  43. data/examples/{rails_server → rails_openid}/public/javascripts/dragdrop.js +0 -0
  44. data/examples/{rails_server → rails_openid}/public/javascripts/effects.js +0 -0
  45. data/examples/{rails_server → rails_openid}/public/javascripts/prototype.js +0 -0
  46. data/examples/{rails_server → rails_openid}/public/robots.txt +0 -0
  47. data/examples/{rails_server → rails_openid}/script/about +0 -0
  48. data/examples/{rails_server → rails_openid}/script/breakpointer +0 -0
  49. data/examples/{rails_server → rails_openid}/script/console +0 -0
  50. data/examples/{rails_server → rails_openid}/script/destroy +0 -0
  51. data/examples/{rails_server → rails_openid}/script/generate +0 -0
  52. data/examples/{rails_server → rails_openid}/script/performance/benchmarker +0 -0
  53. data/examples/{rails_server → rails_openid}/script/performance/profiler +0 -0
  54. data/examples/{rails_server → rails_openid}/script/plugin +0 -0
  55. data/examples/{rails_server → rails_openid}/script/process/reaper +0 -0
  56. data/examples/{rails_server → rails_openid}/script/process/spawner +0 -0
  57. data/examples/{rails_server → rails_openid}/script/process/spinner +0 -0
  58. data/examples/{rails_server → rails_openid}/script/runner +0 -0
  59. data/examples/{rails_server → rails_openid}/script/server +0 -0
  60. data/examples/{rails_server → rails_openid}/test/functional/login_controller_test.rb +0 -0
  61. data/examples/{rails_server → rails_openid}/test/functional/server_controller_test.rb +0 -0
  62. data/examples/{rails_server → rails_openid}/test/test_helper.rb +0 -0
  63. data/lib/{hmac.rb → hmac/hmac.rb} +0 -0
  64. data/lib/{hmac-sha1.rb → hmac/sha1.rb} +1 -1
  65. data/lib/{hmac-sha2.rb → hmac/sha2.rb} +1 -1
  66. data/lib/openid/association.rb +213 -73
  67. data/lib/openid/consumer/associationmanager.rb +338 -0
  68. data/lib/openid/consumer/checkid_request.rb +175 -0
  69. data/lib/openid/consumer/discovery.rb +480 -0
  70. data/lib/openid/consumer/discovery_manager.rb +123 -0
  71. data/lib/openid/consumer/html_parse.rb +136 -0
  72. data/lib/openid/consumer/idres.rb +525 -0
  73. data/lib/openid/consumer/responses.rb +133 -0
  74. data/lib/openid/consumer.rb +280 -807
  75. data/lib/openid/cryptutil.rb +85 -0
  76. data/lib/openid/dh.rb +60 -23
  77. data/lib/openid/extension.rb +31 -0
  78. data/lib/openid/extensions/ax.rb +506 -0
  79. data/lib/openid/extensions/pape.rb +182 -0
  80. data/lib/openid/extensions/sreg.rb +275 -0
  81. data/lib/openid/extras.rb +11 -0
  82. data/lib/openid/fetchers.rb +132 -93
  83. data/lib/openid/kvform.rb +133 -0
  84. data/lib/openid/kvpost.rb +56 -0
  85. data/lib/openid/message.rb +534 -0
  86. data/lib/openid/protocolerror.rb +6 -0
  87. data/lib/openid/server.rb +1215 -666
  88. data/lib/openid/store/filesystem.rb +271 -0
  89. data/lib/openid/store/interface.rb +75 -0
  90. data/lib/openid/store/memory.rb +84 -0
  91. data/lib/openid/store/nonce.rb +68 -0
  92. data/lib/openid/trustroot.rb +314 -87
  93. data/lib/openid/urinorm.rb +37 -34
  94. data/lib/openid/util.rb +42 -220
  95. data/lib/openid/yadis/accept.rb +148 -0
  96. data/lib/openid/yadis/constants.rb +21 -0
  97. data/lib/openid/yadis/discovery.rb +153 -0
  98. data/lib/openid/yadis/filters.rb +205 -0
  99. data/lib/openid/{htmltokenizer.rb → yadis/htmltokenizer.rb} +1 -54
  100. data/lib/openid/yadis/parsehtml.rb +36 -0
  101. data/lib/openid/yadis/services.rb +42 -0
  102. data/lib/openid/yadis/xrds.rb +171 -0
  103. data/lib/openid/yadis/xri.rb +90 -0
  104. data/lib/openid/yadis/xrires.rb +106 -0
  105. data/lib/openid.rb +1 -4
  106. data/test/data/accept.txt +124 -0
  107. data/test/data/dh.txt +29 -0
  108. data/test/data/example-xrds.xml +14 -0
  109. data/test/data/linkparse.txt +587 -0
  110. data/test/data/n2b64 +650 -0
  111. data/test/data/test1-discover.txt +137 -0
  112. data/test/data/test1-parsehtml.txt +128 -0
  113. data/test/data/test_discover/openid.html +11 -0
  114. data/test/data/test_discover/openid2.html +11 -0
  115. data/test/data/test_discover/openid2_xrds.xml +12 -0
  116. data/test/data/test_discover/openid2_xrds_no_local_id.xml +11 -0
  117. data/test/data/test_discover/openid_1_and_2.html +11 -0
  118. data/test/data/test_discover/openid_1_and_2_xrds.xml +16 -0
  119. data/test/data/test_discover/openid_1_and_2_xrds_bad_delegate.xml +17 -0
  120. data/test/data/test_discover/openid_and_yadis.html +12 -0
  121. data/test/data/test_discover/openid_no_delegate.html +10 -0
  122. data/test/data/test_discover/yadis_0entries.xml +12 -0
  123. data/test/data/test_discover/yadis_2_bad_local_id.xml +15 -0
  124. data/test/data/test_discover/yadis_2entries_delegate.xml +22 -0
  125. data/test/data/test_discover/yadis_2entries_idp.xml +21 -0
  126. data/test/data/test_discover/yadis_another_delegate.xml +14 -0
  127. data/test/data/test_discover/yadis_idp.xml +12 -0
  128. data/test/data/test_discover/yadis_idp_delegate.xml +13 -0
  129. data/test/data/test_discover/yadis_no_delegate.xml +11 -0
  130. data/test/data/test_xrds/=j3h.2007.11.14.xrds +25 -0
  131. data/test/data/test_xrds/README +12 -0
  132. data/test/data/test_xrds/delegated-20060809-r1.xrds +34 -0
  133. data/test/data/test_xrds/delegated-20060809-r2.xrds +34 -0
  134. data/test/data/test_xrds/delegated-20060809.xrds +34 -0
  135. data/test/data/test_xrds/no-xrd.xml +7 -0
  136. data/test/data/test_xrds/not-xrds.xml +2 -0
  137. data/test/data/test_xrds/prefixsometimes.xrds +34 -0
  138. data/test/data/test_xrds/ref.xrds +109 -0
  139. data/test/data/test_xrds/sometimesprefix.xrds +34 -0
  140. data/test/data/test_xrds/spoof1.xrds +25 -0
  141. data/test/data/test_xrds/spoof2.xrds +25 -0
  142. data/test/data/test_xrds/spoof3.xrds +37 -0
  143. data/test/data/test_xrds/status222.xrds +9 -0
  144. data/test/data/test_xrds/valid-populated-xrds.xml +39 -0
  145. data/test/data/trustroot.txt +147 -0
  146. data/test/discoverdata.rb +131 -0
  147. data/test/test_accept.rb +170 -0
  148. data/test/test_association.rb +266 -0
  149. data/test/test_associationmanager.rb +899 -0
  150. data/test/test_ax.rb +587 -0
  151. data/test/test_checkid_request.rb +297 -0
  152. data/test/test_consumer.rb +257 -0
  153. data/test/test_cryptutil.rb +117 -0
  154. data/test/test_dh.rb +86 -0
  155. data/test/test_discover.rb +772 -0
  156. data/test/test_discovery_manager.rb +262 -0
  157. data/test/test_extras.rb +35 -0
  158. data/test/test_fetchers.rb +472 -0
  159. data/test/test_filters.rb +270 -0
  160. data/test/test_idres.rb +816 -0
  161. data/test/test_kvform.rb +165 -0
  162. data/test/test_kvpost.rb +65 -0
  163. data/test/test_linkparse.rb +101 -0
  164. data/test/test_message.rb +1058 -0
  165. data/test/test_nonce.rb +89 -0
  166. data/test/test_openid_yadis.rb +178 -0
  167. data/test/test_pape.rb +233 -0
  168. data/test/test_parsehtml.rb +80 -0
  169. data/test/test_responses.rb +63 -0
  170. data/test/test_server.rb +2270 -0
  171. data/test/test_sreg.rb +479 -0
  172. data/test/test_stores.rb +269 -0
  173. data/test/test_trustroot.rb +112 -0
  174. data/test/{urinorm.rb → test_urinorm.rb} +6 -3
  175. data/test/test_util.rb +144 -0
  176. data/test/test_xrds.rb +160 -0
  177. data/test/test_xri.rb +48 -0
  178. data/test/test_xrires.rb +63 -0
  179. data/test/test_yadis_discovery.rb +207 -0
  180. data/test/testutil.rb +116 -0
  181. data/test/util.rb +47 -50
  182. metadata +233 -143
  183. data/examples/consumer.rb +0 -290
  184. data/examples/rails_openid_login_generator/openid_login_generator-0.1.gem +0 -0
  185. data/examples/rails_server/app/controllers/server_controller.rb +0 -190
  186. data/examples/rails_server/app/views/server/decide.rhtml +0 -11
  187. data/examples/rails_server/public/images/rails.png +0 -0
  188. data/lib/hmac-md5.rb +0 -11
  189. data/lib/hmac-rmd160.rb +0 -11
  190. data/lib/openid/discovery.rb +0 -122
  191. data/lib/openid/filestore.rb +0 -315
  192. data/lib/openid/parse.rb +0 -23
  193. data/lib/openid/service.rb +0 -147
  194. data/lib/openid/stores.rb +0 -178
  195. data/test/assoc.rb +0 -38
  196. data/test/consumer.rb +0 -376
  197. data/test/data/brian.xrds +0 -16
  198. data/test/data/brianellin.mylid.xrds +0 -42
  199. data/test/dh.rb +0 -20
  200. data/test/extensions.rb +0 -30
  201. data/test/linkparse.rb +0 -305
  202. data/test/runtests.rb +0 -22
  203. data/test/server2.rb +0 -1053
  204. data/test/service.rb +0 -47
  205. data/test/storetestcase.rb +0 -172
  206. data/test/teststore.rb +0 -47
  207. data/test/trustroot.rb +0 -117
@@ -0,0 +1,297 @@
1
+ require "openid/consumer/checkid_request"
2
+ require "openid/message"
3
+ require "test/unit"
4
+ require "testutil"
5
+ require "util"
6
+
7
+ module OpenID
8
+ class Consumer
9
+ class CheckIDRequest
10
+ # For testing
11
+ attr_reader :message
12
+
13
+ class DummyEndpoint
14
+ attr_accessor :preferred_namespace, :local_id, :server_url,
15
+ :is_op_identifier, :claimed_id
16
+
17
+ def initialize
18
+ @preferred_namespace = nil
19
+ @local_id = nil
20
+ @server_url = nil
21
+ @is_op_identifier = false
22
+ end
23
+
24
+ def get_local_id
25
+ @local_id
26
+ end
27
+
28
+ def compatibility_mode
29
+ @preferred_namespace == OPENID1_NS
30
+ end
31
+ end
32
+
33
+ module CheckIDTestMixin
34
+ include TestUtil
35
+
36
+ def setup
37
+ @endpoint = DummyEndpoint.new
38
+ @endpoint.local_id = 'http://server.unittest/joe'
39
+ @endpoint.claimed_id = 'http://joe.vanity.example/'
40
+ @endpoint.server_url = 'http://server.unittest/'
41
+ @endpoint.preferred_namespace = preferred_namespace
42
+ @realm = 'http://example/'
43
+ @return_to = 'http://example/return/'
44
+ @assoc = GoodAssoc.new
45
+ @checkid_req = CheckIDRequest.new(@assoc, @endpoint)
46
+ end
47
+
48
+ def assert_has_identifiers(msg, local_id, claimed_id)
49
+ assert_openid_value_equal(msg, 'identity', local_id)
50
+ assert_openid_value_equal(msg, 'claimed_id', claimed_id)
51
+ end
52
+
53
+ def assert_openid_key_exists(msg, key)
54
+ assert(msg.get_arg(OPENID_NS, key),
55
+ "#{key} not present in #{msg.get_args(OPENID_NS).inspect}")
56
+ end
57
+
58
+ def assert_openid_key_absent(msg, key)
59
+ assert(msg.get_arg(OPENID_NS, key).nil?)
60
+ end
61
+
62
+ def assert_openid_value_equal(msg, key, expected)
63
+ actual = msg.get_arg(OPENID_NS, key, NO_DEFAULT)
64
+ error_text = ("Expected #{expected.inspect} for openid.#{key} "\
65
+ "but got #{actual.inspect}: #{msg.inspect}")
66
+ assert_equal(expected, actual, error_text)
67
+ end
68
+
69
+ def assert_anonymous(msg)
70
+ ['claimed_id', 'identity'].each do |key|
71
+ assert_openid_key_absent(msg, key)
72
+ end
73
+ end
74
+
75
+ def assert_has_required_fields(msg)
76
+ internal_message = @checkid_req.instance_variable_get(:@message)
77
+ assert_equal(preferred_namespace,
78
+ internal_message.get_openid_namespace)
79
+
80
+ assert_equal(preferred_namespace, msg.get_openid_namespace)
81
+ assert_openid_value_equal(msg, 'mode', expected_mode)
82
+
83
+ # Implement these in subclasses because they depend on
84
+ # protocol differences!
85
+ assert_has_realm(msg)
86
+ assert_identifiers_present(msg)
87
+ end
88
+
89
+ # TESTS
90
+
91
+ def test_check_no_assoc_handle
92
+ @checkid_req.instance_variable_set('@assoc', nil)
93
+ msg = assert_log_matches("Generated checkid") {
94
+ @checkid_req.get_message(@realm, @return_to, immediate)
95
+ }
96
+ assert_openid_key_absent(msg, 'assoc_handle')
97
+ end
98
+
99
+ def test_check_with_assoc_handle
100
+ msg = assert_log_matches("Generated checkid") {
101
+ @checkid_req.get_message(@realm, @return_to, immediate)
102
+ }
103
+
104
+ assert_openid_value_equal(msg, 'assoc_handle', @assoc.handle)
105
+ end
106
+
107
+ def test_add_extension_arg
108
+ @checkid_req.add_extension_arg('bag:', 'color', 'brown')
109
+ @checkid_req.add_extension_arg('bag:', 'material', 'paper')
110
+ assert(@checkid_req.message.namespaces.member?('bag:'))
111
+ assert_equal(@checkid_req.message.get_args('bag:'),
112
+ {'color' => 'brown', 'material' => 'paper'})
113
+
114
+ msg = assert_log_matches("Generated checkid") {
115
+ @checkid_req.get_message(@realm, @return_to, immediate)
116
+ }
117
+
118
+ # XXX: this depends on the way that Message assigns
119
+ # namespaces. Really it doesn't care that it has alias "0",
120
+ # but that is tested anyway
121
+ post_args = msg.to_post_args()
122
+ assert_equal('brown', post_args['openid.ext0.color'])
123
+ assert_equal('paper', post_args['openid.ext0.material'])
124
+ end
125
+
126
+ def test_standard
127
+ msg = assert_log_matches('Generated checkid') {
128
+ @checkid_req.get_message(@realm, @return_to, immediate)
129
+ }
130
+ assert_has_identifiers(msg, @endpoint.local_id, @endpoint.claimed_id)
131
+ end
132
+
133
+ def test_send_redirect?
134
+ silence_logging {
135
+ url = @checkid_req.redirect_url(@realm, @return_to, immediate)
136
+ assert(url.length < OPENID1_URL_LIMIT)
137
+ assert(@checkid_req.send_redirect?(@realm, @return_to, immediate))
138
+
139
+ @return_to << '/foo' * 1000
140
+ url = @checkid_req.redirect_url(@realm, @return_to, immediate)
141
+ assert(url.length > OPENID1_URL_LIMIT)
142
+ actual = @checkid_req.send_redirect?(@realm, @return_to, immediate)
143
+ expected = preferred_namespace != OPENID2_NS
144
+ assert_equal(expected, actual)
145
+ }
146
+ end
147
+ end
148
+
149
+ class TestCheckIDRequestOpenID2 < Test::Unit::TestCase
150
+ include CheckIDTestMixin
151
+
152
+ def immediate
153
+ false
154
+ end
155
+
156
+ def expected_mode
157
+ 'checkid_setup'
158
+ end
159
+
160
+ def preferred_namespace
161
+ OPENID2_NS
162
+ end
163
+
164
+ # check presence of proper realm key and absence of the wrong
165
+ # one.
166
+ def assert_has_realm(msg)
167
+ assert_openid_value_equal(msg, 'realm', @realm)
168
+ assert_openid_key_absent(msg, 'trust_root')
169
+ end
170
+
171
+ def assert_identifiers_present(msg)
172
+ identity_present = msg.has_key?(OPENID_NS, 'identity')
173
+ claimed_present = msg.has_key?(OPENID_NS, 'claimed_id')
174
+
175
+ assert_equal(claimed_present, identity_present)
176
+ end
177
+
178
+ # OpenID Checkid_Requests should be able to set 'anonymous' to true.
179
+ def test_set_anonymous_works_for_openid2
180
+ assert(@checkid_req.message.is_openid2)
181
+ assert_nothing_raised {@checkid_req.anonymous = true}
182
+ assert_nothing_raised {@checkid_req.anonymous = false}
183
+ end
184
+
185
+ def test_user_anonymous_ignores_identfier
186
+ @checkid_req.anonymous = true
187
+ msg = assert_log_matches('Generated checkid') {
188
+ @checkid_req.get_message(@realm, @return_to, immediate)
189
+ }
190
+ assert_has_required_fields(msg)
191
+ assert_anonymous(msg)
192
+ end
193
+
194
+ def test_op_anonymous_ignores_identifier
195
+ @endpoint.is_op_identifier = true
196
+ @checkid_req.anonymous = true
197
+ msg = assert_log_matches('Generated checkid') {
198
+ @checkid_req.get_message(@realm, @return_to, immediate)
199
+ }
200
+ assert_has_required_fields(msg)
201
+ assert_anonymous(msg)
202
+ end
203
+
204
+ def test_op_identifier_sends_identifier_select
205
+ @endpoint.is_op_identifier = true
206
+ msg = assert_log_matches('Generated checkid') {
207
+ @checkid_req.get_message(@realm, @return_to, immediate)
208
+ }
209
+ assert_has_required_fields(msg)
210
+ assert_has_identifiers(msg, IDENTIFIER_SELECT, IDENTIFIER_SELECT)
211
+ end
212
+ end
213
+
214
+ class TestCheckIDRequestOpenID1 < Test::Unit::TestCase
215
+ include CheckIDTestMixin
216
+
217
+ def immediate
218
+ false
219
+ end
220
+
221
+ def preferred_namespace
222
+ OPENID1_NS
223
+ end
224
+
225
+ def expected_mode
226
+ 'checkid_setup'
227
+ end
228
+
229
+ # Make sure claimed_is is *absent* in request.
230
+ def assert_has_identifiers(msg, op_specific_id, claimed_id)
231
+ assert_openid_value_equal(msg, 'identity', op_specific_id)
232
+ assert_openid_key_absent(msg, 'claimed_id')
233
+ end
234
+
235
+ def assert_identifiers_present(msg)
236
+ assert_openid_key_absent(msg, 'claimed_id')
237
+ assert(msg.has_key?(OPENID_NS, 'identity'))
238
+ end
239
+
240
+ # check presence of proper realm key and absence of the wrong
241
+ # one.
242
+ def assert_has_realm(msg)
243
+ assert_openid_value_equal(msg, 'trust_root', @realm)
244
+ assert_openid_key_absent(msg, 'realm')
245
+ end
246
+
247
+ # TESTS
248
+
249
+ # OpenID 1 requests MUST NOT be able to set anonymous to true
250
+ def test_set_anonymous_fails_for_openid1
251
+ assert(@checkid_req.message.is_openid1)
252
+ assert_raises(ArgumentError) {
253
+ @checkid_req.anonymous = true
254
+ }
255
+ assert_nothing_raised{
256
+ @checkid_req.anonymous = false
257
+ }
258
+ end
259
+
260
+ # Identfier select SHOULD NOT be sent, but this pathway is in
261
+ # here in case some special discovery stuff is done to trigger
262
+ # it with OpenID 1. If it is triggered, it will send
263
+ # identifier_select just like OpenID 2.
264
+ def test_identifier_select
265
+ @endpoint.is_op_identifier = true
266
+ msg = assert_log_matches('Generated checkid') {
267
+ @checkid_req.get_message(@realm, @return_to, immediate)
268
+ }
269
+ assert_has_required_fields(msg)
270
+ assert_equal(IDENTIFIER_SELECT,
271
+ msg.get_arg(OPENID1_NS, 'identity'))
272
+ end
273
+
274
+ end
275
+
276
+ class TestCheckIDRequestOpenID1Immediate < TestCheckIDRequestOpenID1
277
+ def immediate
278
+ true
279
+ end
280
+
281
+ def expected_mode
282
+ 'checkid_immediate'
283
+ end
284
+ end
285
+
286
+ class TestCheckid_RequestOpenID2Immediate < TestCheckIDRequestOpenID2
287
+ def immediate
288
+ true
289
+ end
290
+
291
+ def expected_mode
292
+ 'checkid_immediate'
293
+ end
294
+ end
295
+ end
296
+ end
297
+ end
@@ -0,0 +1,257 @@
1
+ require "openid/consumer"
2
+ require "test/unit"
3
+ require "testutil"
4
+
5
+ module OpenID
6
+ class Consumer
7
+ module TestConsumer
8
+ class TestLastEndpoint < Test::Unit::TestCase
9
+ def test_set_get
10
+ session = {}
11
+ consumer = Consumer.new(session, nil)
12
+ consumer.send(:last_requested_endpoint=, :endpoint)
13
+ ep = consumer.send(:last_requested_endpoint)
14
+ assert_equal(:endpoint, ep)
15
+ ep = consumer.send(:last_requested_endpoint)
16
+ assert_equal(:endpoint, ep)
17
+ consumer.send(:cleanup_last_requested_endpoint)
18
+ ep = consumer.send(:last_requested_endpoint)
19
+ assert_equal(nil, ep)
20
+ end
21
+ end
22
+
23
+ class TestBegin < Test::Unit::TestCase
24
+ attr_accessor :user_input, :anonymous, :services,
25
+ :discovered_identifier, :checkid_request, :service
26
+
27
+ def setup
28
+ @discovered_identifier = 'http://discovered/'
29
+ @user_input = 'user.input'
30
+ @service = :service
31
+ @services = [@service]
32
+ @session = {}
33
+ @anonymous = false
34
+ @checkid_request = :checkid_request
35
+ end
36
+
37
+ def consumer
38
+ test = self
39
+ consumer = Consumer.new(@session, nil)
40
+ consumer.extend(InstanceDefExtension)
41
+ consumer.instance_def(:discover) do |identifier|
42
+ test.assert_equal(test.user_input, identifier)
43
+ [test.discovered_identifier, test.services]
44
+ end
45
+ consumer.instance_def(:begin_without_discovery) do
46
+ |service, sent_anonymous|
47
+ test.assert_equal(test.service, service)
48
+ test.assert_equal(test.anonymous, sent_anonymous)
49
+ test.checkid_request
50
+ end
51
+ consumer
52
+ end
53
+
54
+ def test_begin
55
+ checkid_request = consumer.begin(@user_input, @anonymous)
56
+ assert_equal(:checkid_request, checkid_request)
57
+ assert_equal(['OpenID::Consumer::DiscoveredServices::'\
58
+ 'OpenID::Consumer::'], @session.keys.sort!)
59
+ end
60
+
61
+ def test_begin_failure
62
+ @services = []
63
+ assert_raises(DiscoveryFailure) {
64
+ consumer.begin(@user_input, @anonymous)
65
+ }
66
+ end
67
+
68
+ def test_begin_fallback
69
+ @services = [:service1, :service2]
70
+ consumer = self.consumer
71
+ @service = :service1
72
+ consumer.begin(@user_input, @anonymous)
73
+ @service = :service2
74
+ consumer.begin(@user_input, @anonymous)
75
+ @service = :service1
76
+ consumer.begin(@user_input, @anonymous)
77
+ @service = :service2
78
+ consumer.begin(@user_input, @anonymous)
79
+ end
80
+ end
81
+
82
+ class TestBeginWithoutDiscovery < Test::Unit::TestCase
83
+ attr_reader :assoc
84
+ def setup
85
+ @session = {}
86
+ @assoc = :assoc
87
+ @service = OpenIDServiceEndpoint.new
88
+ @claimed_id = 'http://claimed.id/'
89
+ @service.claimed_id = @claimed_id
90
+ @anonymous = false
91
+ end
92
+
93
+ def consumer
94
+ test = self
95
+ assoc_manager = Object.new
96
+ assoc_manager.extend(InstanceDefExtension)
97
+ assoc_manager.instance_def(:get_association) do
98
+ test.assoc
99
+ end
100
+
101
+ consumer = Consumer.new(@session, nil)
102
+ consumer.extend(InstanceDefExtension)
103
+ consumer.instance_def(:association_manager) do
104
+ assoc_manager
105
+ end
106
+ consumer
107
+ end
108
+
109
+ def call_begin_without_discovery
110
+ result = consumer.begin_without_discovery(@service, @anonymous)
111
+ assert(result.instance_of?(CheckIDRequest))
112
+ assert_equal(@anonymous, result.anonymous)
113
+ assert_equal(@service, consumer.send(:last_requested_endpoint))
114
+ assert_equal(result.instance_variable_get(:@assoc), @assoc)
115
+ return result
116
+ end
117
+
118
+ def cid_name
119
+ Consumer.openid1_return_to_claimed_id_name
120
+ end
121
+
122
+ def nonce_name
123
+ Consumer.openid1_return_to_nonce_name
124
+ end
125
+
126
+ def test_begin_without_openid1
127
+ result = call_begin_without_discovery
128
+
129
+ assert_equal(@claimed_id, result.return_to_args[cid_name])
130
+ assert_equal([cid_name, nonce_name].sort!,
131
+ result.return_to_args.keys.sort!)
132
+ end
133
+
134
+ def test_begin_without_openid1_anonymous
135
+ @anonymous = true
136
+ assert_raises(ArgumentError) {
137
+ call_begin_without_discovery
138
+ }
139
+ end
140
+
141
+ def test_begin_without_openid2
142
+ @service.type_uris = [OPENID_2_0_TYPE]
143
+ result = call_begin_without_discovery
144
+
145
+ assert(result.return_to_args.empty?)
146
+ end
147
+
148
+ def test_begin_without_openid2_anonymous
149
+ @anonymous = true
150
+ @service.type_uris = [OPENID_2_0_TYPE]
151
+ result = call_begin_without_discovery
152
+
153
+ assert(result.return_to_args.empty?)
154
+ end
155
+ end
156
+
157
+ class TestComplete < Test::Unit::TestCase
158
+ def setup
159
+ @session = {}
160
+ @consumer = Consumer.new(@session, nil)
161
+ end
162
+
163
+ def test_bad_mode
164
+ response = @consumer.complete({'openid.ns' => OPENID2_NS,
165
+ 'openid.mode' => 'bad'}, nil)
166
+ assert_equal(FAILURE, response.status)
167
+ end
168
+
169
+ def test_missing_mode
170
+ response = @consumer.complete({'openid.ns' => OPENID2_NS}, nil)
171
+ assert_equal(FAILURE, response.status)
172
+ end
173
+
174
+ def test_cancel
175
+ response = @consumer.complete({'openid.mode' => 'cancel'}, nil)
176
+ assert_equal(CANCEL, response.status)
177
+ end
178
+
179
+ def test_setup_needed_openid1
180
+ response = @consumer.complete({'openid.mode' => 'setup_needed'}, nil)
181
+ assert_equal(FAILURE, response.status)
182
+ end
183
+
184
+ def test_setup_needed_openid2
185
+ args = {'openid.ns' => OPENID2_NS, 'openid.mode' => 'setup_needed'}
186
+ response = @consumer.complete(args, nil)
187
+ assert_equal(SETUP_NEEDED, response.status)
188
+ end
189
+
190
+ def test_idres_setup_needed_openid1
191
+ setup_url = 'http://setup.url/'
192
+ args = {
193
+ 'openid.user_setup_url' => setup_url,
194
+ 'openid.mode' => 'id_res',
195
+ }
196
+ response = @consumer.complete(args, nil)
197
+ assert_equal(SETUP_NEEDED, response.status)
198
+ end
199
+
200
+ def test_error
201
+ contact = 'me'
202
+ reference = 'thing thing'
203
+ args = {
204
+ 'openid.mode' => 'error',
205
+ 'openid.contact' => contact,
206
+ 'openid.reference' => reference,
207
+ }
208
+ response = @consumer.complete(args, nil)
209
+ assert_equal(FAILURE, response.status)
210
+ assert_equal(contact, response.contact)
211
+ assert_equal(reference, response.reference)
212
+
213
+ args['openid.ns'] = OPENID2_NS
214
+ response = @consumer.complete(args, nil)
215
+ assert_equal(FAILURE, response.status)
216
+ assert_equal(contact, response.contact)
217
+ assert_equal(reference, response.reference)
218
+ end
219
+
220
+ def test_idres_openid1
221
+ args = {
222
+ 'openid.mode' => 'id_res',
223
+ }
224
+
225
+ endpoint = OpenIDServiceEndpoint.new
226
+ endpoint.claimed_id = :test_claimed_id
227
+
228
+ idres = Object.new
229
+ idres.extend(InstanceDefExtension)
230
+ idres.instance_def(:endpoint){endpoint}
231
+ idres.instance_def(:signed_fields){:test_signed_fields}
232
+
233
+ test = self
234
+ @consumer.extend(InstanceDefExtension)
235
+ @consumer.instance_def(:handle_idres) {|message, return_to|
236
+ test.assert_equal(args, message.to_post_args)
237
+ test.assert_equal(:test_return_to, return_to)
238
+ idres
239
+ }
240
+
241
+ response = @consumer.complete(args, :test_return_to)
242
+ assert_equal(SUCCESS, response.status, response.message)
243
+ assert_equal(:test_claimed_id, response.identity_url)
244
+ assert_equal(endpoint, response.endpoint)
245
+
246
+ error_message = "In Soviet Russia, id_res handles you!"
247
+ @consumer.instance_def(:handle_idres) {|message, return_to|
248
+ raise ProtocolError, error_message
249
+ }
250
+ response = @consumer.complete(args, :test_return_to)
251
+ assert_equal(FAILURE, response.status)
252
+ assert_equal(error_message, response.message)
253
+ end
254
+ end
255
+ end
256
+ end
257
+ end
@@ -0,0 +1,117 @@
1
+ require 'test/unit'
2
+ require "openid/cryptutil"
3
+
4
+ class CryptUtilTestCase < Test::Unit::TestCase
5
+ BIG = 2 ** 256
6
+
7
+ def test_rand
8
+ # If this is not true, the rest of our test won't work
9
+ assert(BIG.is_a?(Bignum))
10
+
11
+ # It's possible that these will be small enough for fixnums, but
12
+ # extraorindarily unlikely.
13
+ a = OpenID::CryptUtil.rand(BIG)
14
+ b = OpenID::CryptUtil.rand(BIG)
15
+ assert(a.is_a?(Bignum))
16
+ assert(b.is_a?(Bignum))
17
+ assert_not_equal(a, b)
18
+ end
19
+
20
+ def test_rand_doesnt_depend_on_srand
21
+ Kernel.srand(1)
22
+ a = OpenID::CryptUtil.rand(BIG)
23
+ Kernel.srand(1)
24
+ b = OpenID::CryptUtil.rand(BIG)
25
+ assert_not_equal(a, b)
26
+ end
27
+
28
+ def test_random_binary_convert
29
+ (0..500).each do
30
+ n = (0..10).inject(0) {|sum, element| sum + OpenID::CryptUtil.rand(BIG) }
31
+ s = OpenID::CryptUtil.num_to_binary n
32
+ assert(s.is_a?(String))
33
+ n_converted_back = OpenID::CryptUtil.binary_to_num(s)
34
+ assert_equal(n, n_converted_back)
35
+ end
36
+ end
37
+
38
+ def test_enumerated_binary_convert
39
+ {
40
+ "\x00" => 0,
41
+ "\x01" => 1,
42
+ "\x7F" => 127,
43
+ "\x00\xFF" => 255,
44
+ "\x00\x80" => 128,
45
+ "\x00\x81" => 129,
46
+ "\x00\x80\x00" => 32768,
47
+ "OpenID is cool" => 1611215304203901150134421257416556,
48
+ }.each do |str, num|
49
+ num_prime = OpenID::CryptUtil.binary_to_num(str)
50
+ str_prime = OpenID::CryptUtil.num_to_binary(num)
51
+ assert_equal(num, num_prime)
52
+ assert_equal(str, str_prime)
53
+ end
54
+ end
55
+
56
+ def with_n2b64
57
+ test_dir = Pathname.new(__FILE__).dirname
58
+ filename = test_dir.join('data', 'n2b64')
59
+ File.open(filename) do |file|
60
+ file.each_line do |line|
61
+ base64, base10 = line.chomp.split
62
+ yield base64, base10.to_i
63
+ end
64
+ end
65
+ end
66
+
67
+ def test_base64_to_num
68
+ with_n2b64 do |base64, num|
69
+ assert_equal(num, OpenID::CryptUtil.base64_to_num(base64))
70
+ end
71
+ end
72
+
73
+ def test_base64_to_num_invalid
74
+ assert_raises(ArgumentError) {
75
+ OpenID::CryptUtil.base64_to_num('!@#$')
76
+ }
77
+ end
78
+
79
+ def test_num_to_base64
80
+ with_n2b64 do |base64, num|
81
+ assert_equal(base64, OpenID::CryptUtil.num_to_base64(num))
82
+ end
83
+ end
84
+
85
+ def test_randomstring
86
+ s1 = OpenID::CryptUtil.random_string(42)
87
+ assert_equal(42, s1.length)
88
+ s2 = OpenID::CryptUtil.random_string(42)
89
+ assert_equal(42, s2.length)
90
+ assert_not_equal(s1, s2)
91
+ end
92
+
93
+ def test_randomstring_population
94
+ s1 = OpenID::CryptUtil.random_string(42, "XO")
95
+ assert_match(/[XO]{42}/, s1)
96
+ end
97
+
98
+ def test_sha1
99
+ assert_equal("\x11\xf6\xad\x8e\xc5*)\x84\xab\xaa\xfd|;Qe\x03x\\ r",
100
+ OpenID::CryptUtil.sha1('x'))
101
+ end
102
+
103
+ def test_hmac_sha1
104
+ assert_equal("\x8bo\xf7O\xa7\x18*\x90\xac ah\x16\xf7\xb8\x81JB\x9f|",
105
+ OpenID::CryptUtil.hmac_sha1('x', 'x'))
106
+ end
107
+
108
+ def test_sha256
109
+ assert_equal("-q\x16B\xb7&\xb0D\x01b|\xa9\xfb\xac2\xf5\xc8S\x0f\xb1\x90<\xc4\xdb\x02%\x87\x17\x92\x1aH\x81",
110
+ OpenID::CryptUtil.sha256('x'))
111
+ end
112
+
113
+ def test_hmac_sha256
114
+ assert_equal("\x94{\xd2w\xb2\xd3\\\xfc\x07\xfb\xc7\xe3b\xf2iuXz1\xf8:}\xffx\x8f\xda\xc1\xfaC\xc4\xb2\x87",
115
+ OpenID::CryptUtil.hmac_sha256('x', 'x'))
116
+ end
117
+ end