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
data/test/test_ax.rb ADDED
@@ -0,0 +1,587 @@
1
+ require 'openid/extensions/ax'
2
+ require 'openid/message'
3
+
4
+ module OpenID
5
+ module AX
6
+ class BogusAXMessage < AXMessage
7
+ @mode = 'bogus'
8
+
9
+ def get_extension_args
10
+ new_args
11
+ end
12
+
13
+ def do_check_mode(args)
14
+ check_mode(args)
15
+ end
16
+
17
+ def do_check_mode_new_args
18
+ check_mode(new_args)
19
+ end
20
+ end
21
+
22
+ class AXMessageTest < Test::Unit::TestCase
23
+ def setup
24
+ @bax = BogusAXMessage.new
25
+ end
26
+
27
+ def test_check_mode
28
+ assert_raises(Error) { @bax.do_check_mode({'mode' => 'fetch_request'})}
29
+ @bax.do_check_mode({'mode' => @bax.mode})
30
+ end
31
+
32
+ def test_check_mode_new_args
33
+ @bax.do_check_mode_new_args
34
+ end
35
+ end
36
+
37
+ class AttrInfoTest < Test::Unit::TestCase
38
+ def test_construct
39
+ assert_raises(ArgumentError) { AttrInfo.new }
40
+ type_uri = 'uri geller'
41
+ ainfo = AttrInfo.new(type_uri)
42
+
43
+ assert_equal(type_uri, ainfo.type_uri)
44
+ assert_equal(1, ainfo.count)
45
+ assert_equal(false, ainfo.required)
46
+ assert_equal(nil, ainfo.ns_alias)
47
+ end
48
+ end
49
+
50
+ class ToTypeURIsTest < Test::Unit::TestCase
51
+ def setup
52
+ @aliases = NamespaceMap.new
53
+ end
54
+
55
+ def test_empty
56
+ [nil, ''].each{|empty|
57
+ uris = AX.to_type_uris(@aliases, empty)
58
+ assert_equal([], uris)
59
+ }
60
+ end
61
+
62
+ def test_undefined
63
+ assert_raises(IndexError) {
64
+ AX.to_type_uris(@aliases, 'http://janrain.com/')
65
+ }
66
+ end
67
+
68
+ def test_one
69
+ uri = 'http://janrain.com/'
70
+ name = 'openid_hackers'
71
+ @aliases.add_alias(uri, name)
72
+ uris = AX::to_type_uris(@aliases, name)
73
+ assert_equal([uri], uris)
74
+ end
75
+
76
+ def test_two
77
+ uri1 = 'http://janrain.com/'
78
+ name1 = 'openid_hackers'
79
+ @aliases.add_alias(uri1, name1)
80
+
81
+ uri2 = 'http://jyte.com/'
82
+ name2 = 'openid_hack'
83
+ @aliases.add_alias(uri2, name2)
84
+
85
+ uris = AX.to_type_uris(@aliases, [name1, name2].join(','))
86
+ assert_equal([uri1, uri2], uris)
87
+ end
88
+ end
89
+
90
+ class ParseAXValuesTest < Test::Unit::TestCase
91
+ def ax_values(ax_args, expected_args)
92
+ msg = KeyValueMessage.new
93
+ msg.parse_extension_args(ax_args)
94
+ assert_equal(expected_args, msg.data)
95
+ end
96
+
97
+ def ax_error(ax_args, error)
98
+ msg = KeyValueMessage.new
99
+ assert_raises(error) {
100
+ msg.parse_extension_args(ax_args)
101
+ }
102
+ end
103
+
104
+ def test_empty_is_valid
105
+ ax_values({}, {})
106
+ end
107
+
108
+ def test_missing_value_for_alias_explodes
109
+ ax_error({'type.foo'=>'urn:foo'}, IndexError)
110
+ end
111
+
112
+ def test_count_present_but_not_value
113
+ ax_error({'type.foo'=>'urn:foo', 'count.foo' => '1'}, IndexError)
114
+ end
115
+
116
+ def test_invalid_count_value
117
+ msg = FetchRequest.new
118
+ assert_raises(Error) {
119
+ msg.parse_extension_args({'type.foo'=>'urn:foo',
120
+ 'count.foo' => 'bogus'})
121
+ }
122
+ end
123
+
124
+ def test_request_unlimited_values
125
+ msg = FetchRequest.new
126
+ args = {'mode' => 'fetch_request',
127
+ 'required' => 'foo',
128
+ 'type.foo' => 'urn:foo',
129
+ 'count.foo' => UNLIMITED_VALUES
130
+ }
131
+ msg.parse_extension_args(args)
132
+ foo = msg.attributes[0]
133
+ assert_equal(UNLIMITED_VALUES, foo.count)
134
+ assert(foo.wants_unlimited_values?)
135
+ end
136
+
137
+ def test_long_alias
138
+ # spec says we must support at least 32 character-long aliases
139
+ name = 'x' * MINIMUM_SUPPORTED_ALIAS_LENGTH
140
+
141
+ msg = KeyValueMessage.new
142
+ args = {
143
+ "type.#{name}" => 'urn:foo',
144
+ "count.#{name}" => '1',
145
+ "value.#{name}.1" => 'first',
146
+ }
147
+ msg.parse_extension_args(args)
148
+ assert_equal(['first'],msg['urn:foo'])
149
+ end
150
+
151
+ def test_invalid_alias
152
+ types = [
153
+ KeyValueMessage,
154
+ FetchRequest
155
+ ]
156
+ inputs = [
157
+ {'type.a.b'=>'urn:foo',
158
+ 'count.a.b'=>'1'},
159
+ {'type.a,b'=>'urn:foo',
160
+ 'count.a,b'=>'1'},
161
+ ]
162
+ types.each{|t|
163
+ inputs.each{|input|
164
+ msg = t.new
165
+ assert_raises(Error) {msg.parse_extension_args(input)}
166
+ }
167
+ }
168
+ end
169
+
170
+ def test_count_present_and_is_zero
171
+ ax_values(
172
+ {'type.foo'=>'urn:foo',
173
+ 'count.foo'=>'0',
174
+ },
175
+ {'urn:foo'=>[]}
176
+ )
177
+ end
178
+
179
+ def test_singleton_empty
180
+ ax_values(
181
+ {'type.foo'=>'urn:foo',
182
+ 'value.foo'=>'',
183
+ },
184
+ {'urn:foo'=>[]}
185
+ )
186
+ end
187
+
188
+ def test_double_alias
189
+ ax_error(
190
+ {'type.foo'=>'urn:foo',
191
+ 'value.foo'=>'',
192
+ 'type.bar'=>'urn:foo',
193
+ 'value.bar'=>'',
194
+ },
195
+ IndexError
196
+ )
197
+ end
198
+
199
+ def test_double_singleton
200
+ ax_values(
201
+ {'type.foo'=>'urn:foo',
202
+ 'value.foo'=>'',
203
+ 'type.bar'=>'urn:bar',
204
+ 'value.bar'=>'',
205
+ },
206
+ {'urn:foo'=>[],'urn:bar'=>[]}
207
+ )
208
+ end
209
+
210
+ def singleton_value
211
+ ax_values(
212
+ {'type.foo'=>'urn:foo',
213
+ 'value.foo'=>'something',
214
+ },
215
+ {'urn:foo'=>['something']}
216
+ )
217
+ end
218
+ end
219
+
220
+ class FetchRequestTest < Test::Unit::TestCase
221
+ def setup
222
+ @msg = FetchRequest.new
223
+ @type_a = 'http://janrain.example.com/a'
224
+ @name_a = 'a'
225
+ end
226
+
227
+ def test_mode
228
+ assert_equal('fetch_request', @msg.mode)
229
+ end
230
+
231
+ def test_construct
232
+ assert_equal({}, @msg.requested_attributes)
233
+ assert_equal(nil, @msg.update_url)
234
+
235
+ msg = FetchRequest.new('hailstorm')
236
+ assert_equal({}, msg.requested_attributes)
237
+ assert_equal('hailstorm', msg.update_url)
238
+ end
239
+
240
+ def test_add
241
+ uri = 'mud://puddle'
242
+
243
+ assert(! @msg.member?(uri))
244
+ a = AttrInfo.new(uri)
245
+ @msg.add(a)
246
+ assert(@msg.member?(uri))
247
+ end
248
+
249
+ def test_add_twice
250
+ uri = 'its://raining'
251
+ a = AttrInfo.new(uri)
252
+ @msg.add(a)
253
+ assert_raises(IndexError) {@msg.add(a)}
254
+ end
255
+
256
+ def do_extension_args(expected_args)
257
+ expected_args['mode'] = @msg.mode
258
+ assert_equal(expected_args, @msg.get_extension_args)
259
+ end
260
+
261
+ def test_get_extension_args_empty
262
+ do_extension_args({})
263
+ end
264
+
265
+ def test_get_extension_args_no_alias
266
+ a = AttrInfo.new('foo://bar')
267
+ @msg.add(a)
268
+ ax_args = @msg.get_extension_args
269
+ ax_args.each{|k,v|
270
+ if v == a.type_uri and k.index('type.') == 0
271
+ @name = k[5..-1]
272
+ break
273
+ end
274
+ }
275
+ do_extension_args({'type.'+@name => a.type_uri,
276
+ 'if_available' => @name})
277
+ end
278
+
279
+ def test_get_extension_args_alias_if_available
280
+ a = AttrInfo.new('type://of.transportation',
281
+ 'transport')
282
+ @msg.add(a)
283
+ do_extension_args({'type.'+a.ns_alias => a.type_uri,
284
+ 'if_available' => a.ns_alias})
285
+ end
286
+
287
+ def test_get_extension_args_alias_req
288
+ a = AttrInfo.new('type://of.transportation',
289
+ 'transport',
290
+ true)
291
+ @msg.add(a)
292
+ do_extension_args({'type.'+a.ns_alias => a.type_uri,
293
+ 'required' => a.ns_alias})
294
+ end
295
+
296
+ def test_get_required_attrs_empty
297
+ assert_equal([], @msg.get_required_attrs)
298
+ end
299
+
300
+ def test_parse_extension_args_extra_type
301
+ args = {
302
+ 'mode' => 'fetch_request',
303
+ 'type.' + @name_a => @type_a
304
+ }
305
+ assert_raises(Error) {@msg.parse_extension_args(args)}
306
+ end
307
+
308
+ def test_parse_extension_args
309
+ args = {
310
+ 'mode' => 'fetch_request',
311
+ 'type.' + @name_a => @type_a,
312
+ 'if_available' => @name_a
313
+ }
314
+ @msg.parse_extension_args(args)
315
+ assert(@msg.member?(@type_a) )
316
+ assert_equal([@type_a], @msg.requested_types)
317
+ ai = @msg.requested_attributes[@type_a]
318
+ assert(ai.is_a?(AttrInfo))
319
+ assert(!ai.required)
320
+ assert_equal(@type_a, ai.type_uri)
321
+ assert_equal(@name_a, ai.ns_alias)
322
+ assert_equal([ai], @msg.attributes)
323
+ end
324
+
325
+ def test_extension_args_idempotent
326
+ args = {
327
+ 'mode' => 'fetch_request',
328
+ 'type.' + @name_a => @type_a,
329
+ 'if_available' => @name_a
330
+ }
331
+ @msg.parse_extension_args(args)
332
+ assert_equal(args, @msg.get_extension_args)
333
+ assert(!@msg.requested_attributes[@type_a].required)
334
+ end
335
+
336
+ def test_extension_args_idempotent_count_required
337
+ args = {
338
+ 'mode' => 'fetch_request',
339
+ 'type.' + @name_a => @type_a,
340
+ 'count.' + @name_a => '2',
341
+ 'required' => @name_a
342
+ }
343
+ @msg.parse_extension_args(args)
344
+ assert_equal(args, @msg.get_extension_args)
345
+ assert(@msg.requested_attributes[@type_a].required)
346
+ end
347
+
348
+ def test_extension_args_count1
349
+ args = {
350
+ 'mode' => 'fetch_request',
351
+ 'type.' + @name_a => @type_a,
352
+ 'count.' + @name_a => '1',
353
+ 'if_available' => @name_a
354
+ }
355
+ norm_args = {
356
+ 'mode' => 'fetch_request',
357
+ 'type.' + @name_a => @type_a,
358
+ 'if_available' => @name_a
359
+ }
360
+ @msg.parse_extension_args(args)
361
+ assert_equal(norm_args, @msg.get_extension_args)
362
+ end
363
+
364
+ def test_from_openid_request_no_ax
365
+ message = Message.new
366
+ openid_req = Server::OpenIDRequest.new
367
+ openid_req.message = message
368
+ ax_req = FetchRequest.from_openid_request(openid_req)
369
+ assert(ax_req.nil?)
370
+ end
371
+
372
+ def test_openid_update_url_verification_error
373
+ openid_req_msg = Message.from_openid_args({
374
+ 'mode' => 'checkid_setup',
375
+ 'ns' => OPENID2_NS,
376
+ 'realm' => 'http://example.com/realm',
377
+ 'ns.ax' => AXMessage::NS_URI,
378
+ 'ax.update_url' => 'http://different.site/path',
379
+ 'ax.mode' => 'fetch_request',
380
+ })
381
+ openid_req = Server::OpenIDRequest.new
382
+ openid_req.message = openid_req_msg
383
+ assert_raises(Error) {
384
+ FetchRequest.from_openid_request(openid_req)
385
+ }
386
+ end
387
+
388
+ def test_openid_no_realm
389
+ openid_req_msg = Message.from_openid_args({
390
+ 'mode' => 'checkid_setup',
391
+ 'ns' => OPENID2_NS,
392
+ 'ns.ax' => AXMessage::NS_URI,
393
+ 'ax.update_url' => 'http://different.site/path',
394
+ 'ax.mode' => 'fetch_request',
395
+ })
396
+ openid_req = Server::OpenIDRequest.new
397
+ openid_req.message = openid_req_msg
398
+ assert_raises(Error) {
399
+ FetchRequest.from_openid_request(openid_req)
400
+ }
401
+ end
402
+
403
+ def test_openid_update_url_verification_success
404
+ openid_req_msg = Message.from_openid_args({
405
+ 'mode' => 'checkid_setup',
406
+ 'ns' => OPENID2_NS,
407
+ 'realm' => 'http://example.com/realm',
408
+ 'ns.ax' => AXMessage::NS_URI,
409
+ 'ax.update_url' => 'http://example.com/realm/update_path',
410
+ 'ax.mode' => 'fetch_request',
411
+ })
412
+ openid_req = Server::OpenIDRequest.new
413
+ openid_req.message = openid_req_msg
414
+ fr = FetchRequest.from_openid_request(openid_req)
415
+ assert(fr.is_a?(FetchRequest))
416
+ end
417
+
418
+ def test_openid_update_url_verification_success_return_to
419
+ openid_req_msg = Message.from_openid_args({
420
+ 'mode' => 'checkid_setup',
421
+ 'ns' => OPENID2_NS,
422
+ 'return_to' => 'http://example.com/realm',
423
+ 'ns.ax' => AXMessage::NS_URI,
424
+ 'ax.update_url' => 'http://example.com/realm/update_path',
425
+ 'ax.mode' => 'fetch_request',
426
+ })
427
+ openid_req = Server::OpenIDRequest.new
428
+ openid_req.message = openid_req_msg
429
+ fr = FetchRequest.from_openid_request(openid_req)
430
+ assert(fr.is_a?(FetchRequest))
431
+ end
432
+
433
+ end
434
+
435
+ class FetchResponseTest < Test::Unit::TestCase
436
+ def setup
437
+ @msg = FetchResponse.new
438
+ @value_a = 'commodity'
439
+ @type_a = 'http://blood.transfusion/'
440
+ @name_a = 'george'
441
+ @request_update_url = 'http://some.url.that.is.awesome/'
442
+ end
443
+
444
+ def test_construct
445
+ assert_equal(nil, @msg.update_url)
446
+ assert_equal({}, @msg.data)
447
+ end
448
+
449
+ def test_get_extension_args_empty
450
+ eargs = {
451
+ 'mode' => 'fetch_response'
452
+ }
453
+ assert_equal(eargs, @msg.get_extension_args)
454
+ end
455
+
456
+ def test_get_extension_args_empty_request
457
+ eargs = {
458
+ 'mode' => 'fetch_response'
459
+ }
460
+ req = FetchRequest.new
461
+ assert_equal(eargs, @msg.get_extension_args(req))
462
+ end
463
+
464
+ def test_get_extension_args_empty_request_some
465
+ uri = 'http://not.found/'
466
+ name = 'ext0'
467
+ eargs = {
468
+ 'mode' => 'fetch_response',
469
+ 'type.' + name => uri,
470
+ 'count.' + name => '0'
471
+ }
472
+ req = FetchRequest.new
473
+ req.add(AttrInfo.new(uri))
474
+ assert_equal(eargs, @msg.get_extension_args(req))
475
+ end
476
+
477
+ def test_update_url_in_response
478
+ uri = 'http://not.found/'
479
+ name = 'ext0'
480
+ eargs = {
481
+ 'mode' => 'fetch_response',
482
+ 'update_url' => @request_update_url,
483
+ 'type.' + name => uri,
484
+ 'count.' + name => '0'
485
+ }
486
+ req = FetchRequest.new(@request_update_url)
487
+ req.add(AttrInfo.new(uri))
488
+ assert_equal(eargs, @msg.get_extension_args(req))
489
+ end
490
+
491
+ def test_get_extension_args_some_request
492
+ eargs = {
493
+ 'mode' => 'fetch_response',
494
+ 'type.' + @name_a => @type_a,
495
+ 'value.' + @name_a + '.1' => @value_a,
496
+ 'count.' + @name_a => '1'
497
+ }
498
+ req = FetchRequest.new
499
+ req.add(AttrInfo.new(@type_a, @name_a))
500
+ @msg.add_value(@type_a, @value_a)
501
+ assert_equal(eargs, @msg.get_extension_args(req))
502
+ end
503
+
504
+ def test_get_extension_args_some_not_request
505
+ req = FetchRequest.new
506
+ @msg.add_value(@type_a, @value_a)
507
+ assert_raises(IndexError) {@msg.get_extension_args(req)}
508
+ end
509
+
510
+ def test_get_single_success
511
+ req = FetchRequest.new
512
+ @msg.add_value(@type_a, @value_a)
513
+ assert_equal(@value_a, @msg.get_single(@type_a))
514
+ end
515
+
516
+ def test_get_single_none
517
+ assert_equal(nil, @msg.get_single(@type_a))
518
+ end
519
+
520
+ def test_get_single_extra
521
+ @msg.set_values(@type_a, ['x', 'y'])
522
+ assert_raises(Error) { @msg.get_single(@type_a) }
523
+ end
524
+
525
+ end
526
+
527
+ class StoreRequestTest < Test::Unit::TestCase
528
+ def setup
529
+ @msg = StoreRequest.new
530
+ @type_a = 'http://oranges.are.for/'
531
+ @name_a = 'juggling'
532
+ end
533
+
534
+ def test_construct
535
+ assert_equal({}, @msg.data)
536
+ end
537
+
538
+ def test_get_extension_args_empty
539
+ eargs = {
540
+ 'mode' => 'store_request'
541
+ }
542
+ assert_equal(eargs, @msg.get_extension_args)
543
+ end
544
+
545
+ def test_get_extension_args_nonempty
546
+ @msg.set_values(@type_a, ['foo','bar'])
547
+ aliases = NamespaceMap.new
548
+ aliases.add_alias(@type_a, @name_a)
549
+ eargs = {
550
+ 'mode' => 'store_request',
551
+ 'type.' + @name_a => @type_a,
552
+ 'value.' + @name_a + '.1' => 'foo',
553
+ 'value.' + @name_a + '.2' => 'bar',
554
+ 'count.' + @name_a => '2'
555
+ }
556
+ assert_equal(eargs, @msg.get_extension_args(aliases))
557
+ end
558
+ end
559
+
560
+ class StoreResponseTest < Test::Unit::TestCase
561
+ def test_success
562
+ msg = StoreResponse.new
563
+ assert(msg.succeeded?)
564
+ assert(!msg.error_message)
565
+ assert_equal({'mode' => 'store_response_success'},
566
+ msg.get_extension_args)
567
+ end
568
+
569
+ def test_fail_nomsg
570
+ msg = StoreResponse.new(false)
571
+ assert(! msg.succeeded? )
572
+ assert(! msg.error_message )
573
+ assert_equal({'mode' => 'store_response_failure'},
574
+ msg.get_extension_args)
575
+ end
576
+
577
+ def test_fail_msg
578
+ reason = "because I said so"
579
+ msg = StoreResponse.new(false, reason)
580
+ assert(! msg.succeeded? )
581
+ assert_equal(reason, msg.error_message)
582
+ assert_equal({'mode' => 'store_response_failure', 'error' => reason},
583
+ msg.get_extension_args)
584
+ end
585
+ end
586
+ end
587
+ end