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.
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