entp-ruby-openid 2.2

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 (200) hide show
  1. data/CHANGELOG +215 -0
  2. data/INSTALL +47 -0
  3. data/LICENSE +210 -0
  4. data/NOTICE +2 -0
  5. data/README +85 -0
  6. data/UPGRADE +127 -0
  7. data/admin/runtests.rb +45 -0
  8. data/examples/README +32 -0
  9. data/examples/active_record_openid_store/README +58 -0
  10. data/examples/active_record_openid_store/XXX_add_open_id_store_to_db.rb +24 -0
  11. data/examples/active_record_openid_store/XXX_upgrade_open_id_store.rb +26 -0
  12. data/examples/active_record_openid_store/init.rb +8 -0
  13. data/examples/active_record_openid_store/lib/association.rb +10 -0
  14. data/examples/active_record_openid_store/lib/nonce.rb +3 -0
  15. data/examples/active_record_openid_store/lib/open_id_setting.rb +4 -0
  16. data/examples/active_record_openid_store/lib/openid_ar_store.rb +57 -0
  17. data/examples/active_record_openid_store/test/store_test.rb +212 -0
  18. data/examples/discover +49 -0
  19. data/examples/rails_openid/README +153 -0
  20. data/examples/rails_openid/Rakefile +10 -0
  21. data/examples/rails_openid/app/controllers/application.rb +4 -0
  22. data/examples/rails_openid/app/controllers/consumer_controller.rb +125 -0
  23. data/examples/rails_openid/app/controllers/login_controller.rb +45 -0
  24. data/examples/rails_openid/app/controllers/server_controller.rb +265 -0
  25. data/examples/rails_openid/app/helpers/application_helper.rb +3 -0
  26. data/examples/rails_openid/app/helpers/login_helper.rb +2 -0
  27. data/examples/rails_openid/app/helpers/server_helper.rb +9 -0
  28. data/examples/rails_openid/app/views/consumer/index.rhtml +81 -0
  29. data/examples/rails_openid/app/views/layouts/server.rhtml +68 -0
  30. data/examples/rails_openid/app/views/login/index.rhtml +56 -0
  31. data/examples/rails_openid/app/views/server/decide.rhtml +26 -0
  32. data/examples/rails_openid/config/boot.rb +19 -0
  33. data/examples/rails_openid/config/database.yml +74 -0
  34. data/examples/rails_openid/config/environment.rb +54 -0
  35. data/examples/rails_openid/config/environments/development.rb +19 -0
  36. data/examples/rails_openid/config/environments/production.rb +19 -0
  37. data/examples/rails_openid/config/environments/test.rb +19 -0
  38. data/examples/rails_openid/config/routes.rb +24 -0
  39. data/examples/rails_openid/doc/README_FOR_APP +2 -0
  40. data/examples/rails_openid/public/404.html +8 -0
  41. data/examples/rails_openid/public/500.html +8 -0
  42. data/examples/rails_openid/public/dispatch.cgi +12 -0
  43. data/examples/rails_openid/public/dispatch.fcgi +26 -0
  44. data/examples/rails_openid/public/dispatch.rb +12 -0
  45. data/examples/rails_openid/public/favicon.ico +0 -0
  46. data/examples/rails_openid/public/images/openid_login_bg.gif +0 -0
  47. data/examples/rails_openid/public/javascripts/controls.js +750 -0
  48. data/examples/rails_openid/public/javascripts/dragdrop.js +584 -0
  49. data/examples/rails_openid/public/javascripts/effects.js +854 -0
  50. data/examples/rails_openid/public/javascripts/prototype.js +1785 -0
  51. data/examples/rails_openid/public/robots.txt +1 -0
  52. data/examples/rails_openid/script/about +3 -0
  53. data/examples/rails_openid/script/breakpointer +3 -0
  54. data/examples/rails_openid/script/console +3 -0
  55. data/examples/rails_openid/script/destroy +3 -0
  56. data/examples/rails_openid/script/generate +3 -0
  57. data/examples/rails_openid/script/performance/benchmarker +3 -0
  58. data/examples/rails_openid/script/performance/profiler +3 -0
  59. data/examples/rails_openid/script/plugin +3 -0
  60. data/examples/rails_openid/script/process/reaper +3 -0
  61. data/examples/rails_openid/script/process/spawner +3 -0
  62. data/examples/rails_openid/script/process/spinner +3 -0
  63. data/examples/rails_openid/script/runner +3 -0
  64. data/examples/rails_openid/script/server +3 -0
  65. data/examples/rails_openid/test/functional/login_controller_test.rb +18 -0
  66. data/examples/rails_openid/test/functional/server_controller_test.rb +18 -0
  67. data/examples/rails_openid/test/test_helper.rb +28 -0
  68. data/lib/hmac/hmac.rb +112 -0
  69. data/lib/hmac/sha1.rb +11 -0
  70. data/lib/hmac/sha2.rb +25 -0
  71. data/lib/openid.rb +22 -0
  72. data/lib/openid/association.rb +249 -0
  73. data/lib/openid/consumer.rb +395 -0
  74. data/lib/openid/consumer/associationmanager.rb +344 -0
  75. data/lib/openid/consumer/checkid_request.rb +186 -0
  76. data/lib/openid/consumer/discovery.rb +497 -0
  77. data/lib/openid/consumer/discovery_manager.rb +123 -0
  78. data/lib/openid/consumer/html_parse.rb +134 -0
  79. data/lib/openid/consumer/idres.rb +523 -0
  80. data/lib/openid/consumer/responses.rb +150 -0
  81. data/lib/openid/cryptutil.rb +115 -0
  82. data/lib/openid/dh.rb +89 -0
  83. data/lib/openid/extension.rb +39 -0
  84. data/lib/openid/extensions/ax.rb +539 -0
  85. data/lib/openid/extensions/oauth.rb +91 -0
  86. data/lib/openid/extensions/pape.rb +179 -0
  87. data/lib/openid/extensions/sreg.rb +277 -0
  88. data/lib/openid/extras.rb +11 -0
  89. data/lib/openid/fetchers.rb +258 -0
  90. data/lib/openid/kvform.rb +136 -0
  91. data/lib/openid/kvpost.rb +58 -0
  92. data/lib/openid/message.rb +553 -0
  93. data/lib/openid/protocolerror.rb +12 -0
  94. data/lib/openid/server.rb +1544 -0
  95. data/lib/openid/store.rb +10 -0
  96. data/lib/openid/store/filesystem.rb +272 -0
  97. data/lib/openid/store/interface.rb +75 -0
  98. data/lib/openid/store/memcache.rb +109 -0
  99. data/lib/openid/store/memory.rb +84 -0
  100. data/lib/openid/store/nonce.rb +68 -0
  101. data/lib/openid/trustroot.rb +349 -0
  102. data/lib/openid/urinorm.rb +75 -0
  103. data/lib/openid/util.rb +119 -0
  104. data/lib/openid/version.rb +3 -0
  105. data/lib/openid/yadis.rb +15 -0
  106. data/lib/openid/yadis/accept.rb +148 -0
  107. data/lib/openid/yadis/constants.rb +21 -0
  108. data/lib/openid/yadis/discovery.rb +153 -0
  109. data/lib/openid/yadis/filters.rb +205 -0
  110. data/lib/openid/yadis/htmltokenizer.rb +305 -0
  111. data/lib/openid/yadis/parsehtml.rb +45 -0
  112. data/lib/openid/yadis/services.rb +42 -0
  113. data/lib/openid/yadis/xrds.rb +155 -0
  114. data/lib/openid/yadis/xri.rb +90 -0
  115. data/lib/openid/yadis/xrires.rb +91 -0
  116. data/test/data/test_discover/openid_utf8.html +11 -0
  117. data/test/support/test_data_mixin.rb +127 -0
  118. data/test/support/test_util.rb +53 -0
  119. data/test/support/yadis_data.rb +131 -0
  120. data/test/support/yadis_data/accept.txt +124 -0
  121. data/test/support/yadis_data/dh.txt +29 -0
  122. data/test/support/yadis_data/example-xrds.xml +14 -0
  123. data/test/support/yadis_data/linkparse.txt +587 -0
  124. data/test/support/yadis_data/n2b64 +650 -0
  125. data/test/support/yadis_data/test1-discover.txt +137 -0
  126. data/test/support/yadis_data/test1-parsehtml.txt +152 -0
  127. data/test/support/yadis_data/test_discover/malformed_meta_tag.html +19 -0
  128. data/test/support/yadis_data/test_discover/openid.html +11 -0
  129. data/test/support/yadis_data/test_discover/openid2.html +11 -0
  130. data/test/support/yadis_data/test_discover/openid2_xrds.xml +12 -0
  131. data/test/support/yadis_data/test_discover/openid2_xrds_no_local_id.xml +11 -0
  132. data/test/support/yadis_data/test_discover/openid_1_and_2.html +11 -0
  133. data/test/support/yadis_data/test_discover/openid_1_and_2_xrds.xml +16 -0
  134. data/test/support/yadis_data/test_discover/openid_1_and_2_xrds_bad_delegate.xml +17 -0
  135. data/test/support/yadis_data/test_discover/openid_and_yadis.html +12 -0
  136. data/test/support/yadis_data/test_discover/openid_no_delegate.html +10 -0
  137. data/test/support/yadis_data/test_discover/openid_utf8.html +11 -0
  138. data/test/support/yadis_data/test_discover/yadis_0entries.xml +12 -0
  139. data/test/support/yadis_data/test_discover/yadis_2_bad_local_id.xml +15 -0
  140. data/test/support/yadis_data/test_discover/yadis_2entries_delegate.xml +22 -0
  141. data/test/support/yadis_data/test_discover/yadis_2entries_idp.xml +21 -0
  142. data/test/support/yadis_data/test_discover/yadis_another_delegate.xml +14 -0
  143. data/test/support/yadis_data/test_discover/yadis_idp.xml +12 -0
  144. data/test/support/yadis_data/test_discover/yadis_idp_delegate.xml +13 -0
  145. data/test/support/yadis_data/test_discover/yadis_no_delegate.xml +11 -0
  146. data/test/support/yadis_data/test_xrds/=j3h.2007.11.14.xrds +25 -0
  147. data/test/support/yadis_data/test_xrds/README +12 -0
  148. data/test/support/yadis_data/test_xrds/delegated-20060809-r1.xrds +34 -0
  149. data/test/support/yadis_data/test_xrds/delegated-20060809-r2.xrds +34 -0
  150. data/test/support/yadis_data/test_xrds/delegated-20060809.xrds +34 -0
  151. data/test/support/yadis_data/test_xrds/no-xrd.xml +7 -0
  152. data/test/support/yadis_data/test_xrds/not-xrds.xml +2 -0
  153. data/test/support/yadis_data/test_xrds/prefixsometimes.xrds +34 -0
  154. data/test/support/yadis_data/test_xrds/ref.xrds +109 -0
  155. data/test/support/yadis_data/test_xrds/sometimesprefix.xrds +34 -0
  156. data/test/support/yadis_data/test_xrds/spoof1.xrds +25 -0
  157. data/test/support/yadis_data/test_xrds/spoof2.xrds +25 -0
  158. data/test/support/yadis_data/test_xrds/spoof3.xrds +37 -0
  159. data/test/support/yadis_data/test_xrds/status222.xrds +9 -0
  160. data/test/support/yadis_data/test_xrds/subsegments.xrds +58 -0
  161. data/test/support/yadis_data/test_xrds/valid-populated-xrds.xml +39 -0
  162. data/test/support/yadis_data/trustroot.txt +153 -0
  163. data/test/support/yadis_data/urinorm.txt +79 -0
  164. data/test/test_accept.rb +170 -0
  165. data/test/test_association.rb +268 -0
  166. data/test/test_associationmanager.rb +918 -0
  167. data/test/test_ax.rb +690 -0
  168. data/test/test_checkid_request.rb +293 -0
  169. data/test/test_consumer.rb +260 -0
  170. data/test/test_cryptutil.rb +119 -0
  171. data/test/test_dh.rb +85 -0
  172. data/test/test_discover.rb +848 -0
  173. data/test/test_discovery_manager.rb +259 -0
  174. data/test/test_extension.rb +46 -0
  175. data/test/test_extras.rb +35 -0
  176. data/test/test_fetchers.rb +554 -0
  177. data/test/test_filters.rb +269 -0
  178. data/test/test_helper.rb +4 -0
  179. data/test/test_idres.rb +961 -0
  180. data/test/test_kvform.rb +164 -0
  181. data/test/test_kvpost.rb +64 -0
  182. data/test/test_linkparse.rb +100 -0
  183. data/test/test_message.rb +1115 -0
  184. data/test/test_nonce.rb +89 -0
  185. data/test/test_oauth.rb +176 -0
  186. data/test/test_openid_yadis.rb +177 -0
  187. data/test/test_pape.rb +248 -0
  188. data/test/test_parsehtml.rb +79 -0
  189. data/test/test_responses.rb +63 -0
  190. data/test/test_server.rb +2455 -0
  191. data/test/test_sreg.rb +479 -0
  192. data/test/test_stores.rb +292 -0
  193. data/test/test_trustroot.rb +111 -0
  194. data/test/test_urinorm.rb +34 -0
  195. data/test/test_util.rb +145 -0
  196. data/test/test_xrds.rb +167 -0
  197. data/test/test_xri.rb +48 -0
  198. data/test/test_xrires.rb +67 -0
  199. data/test/test_yadis_discovery.rb +218 -0
  200. metadata +268 -0
@@ -0,0 +1,690 @@
1
+ require 'openid/extensions/ax'
2
+ require 'openid/message'
3
+ require 'openid/consumer/responses'
4
+ require 'openid/consumer/discovery'
5
+ require 'openid/consumer/checkid_request'
6
+
7
+ module OpenID
8
+ module AX
9
+ class BogusAXMessage < AXMessage
10
+ @mode = 'bogus'
11
+
12
+ def get_extension_args
13
+ new_args
14
+ end
15
+
16
+ def do_check_mode(args)
17
+ check_mode(args)
18
+ end
19
+
20
+ def do_check_mode_new_args
21
+ check_mode(new_args)
22
+ end
23
+ end
24
+
25
+ class AXMessageTest < Test::Unit::TestCase
26
+ def setup
27
+ @bax = BogusAXMessage.new
28
+ end
29
+
30
+ def test_check_mode
31
+ assert_raises(Error) { @bax.do_check_mode({'mode' => 'fetch_request'})}
32
+ @bax.do_check_mode({'mode' => @bax.mode})
33
+ end
34
+
35
+ def test_check_mode_new_args
36
+ @bax.do_check_mode_new_args
37
+ end
38
+ end
39
+
40
+ class AttrInfoTest < Test::Unit::TestCase
41
+ def test_construct
42
+ assert_raises(ArgumentError) { AttrInfo.new }
43
+ type_uri = 'uri geller'
44
+ ainfo = AttrInfo.new(type_uri)
45
+
46
+ assert_equal(type_uri, ainfo.type_uri)
47
+ assert_equal(1, ainfo.count)
48
+ assert_equal(false, ainfo.required)
49
+ assert_equal(nil, ainfo.ns_alias)
50
+ end
51
+ end
52
+
53
+ class ToTypeURIsTest < Test::Unit::TestCase
54
+ def setup
55
+ @aliases = NamespaceMap.new
56
+ end
57
+
58
+ def test_empty
59
+ [nil, ''].each{|empty|
60
+ uris = AX.to_type_uris(@aliases, empty)
61
+ assert_equal([], uris)
62
+ }
63
+ end
64
+
65
+ def test_undefined
66
+ assert_raises(IndexError) {
67
+ AX.to_type_uris(@aliases, 'http://janrain.com/')
68
+ }
69
+ end
70
+
71
+ def test_one
72
+ uri = 'http://janrain.com/'
73
+ name = 'openid_hackers'
74
+ @aliases.add_alias(uri, name)
75
+ uris = AX::to_type_uris(@aliases, name)
76
+ assert_equal([uri], uris)
77
+ end
78
+
79
+ def test_two
80
+ uri1 = 'http://janrain.com/'
81
+ name1 = 'openid_hackers'
82
+ @aliases.add_alias(uri1, name1)
83
+
84
+ uri2 = 'http://jyte.com/'
85
+ name2 = 'openid_hack'
86
+ @aliases.add_alias(uri2, name2)
87
+
88
+ uris = AX.to_type_uris(@aliases, [name1, name2].join(','))
89
+ assert_equal([uri1, uri2], uris)
90
+ end
91
+ end
92
+
93
+ class ParseAXValuesTest < Test::Unit::TestCase
94
+ def ax_values(ax_args, expected_args)
95
+ msg = KeyValueMessage.new
96
+ msg.parse_extension_args(ax_args)
97
+ assert_equal(expected_args, msg.data)
98
+ end
99
+
100
+ def ax_error(ax_args, error)
101
+ msg = KeyValueMessage.new
102
+ assert_raises(error) {
103
+ msg.parse_extension_args(ax_args)
104
+ }
105
+ end
106
+
107
+ def test_empty_is_valid
108
+ ax_values({}, {})
109
+ end
110
+
111
+ def test_missing_value_for_alias_explodes
112
+ ax_error({'type.foo'=>'urn:foo'}, IndexError)
113
+ end
114
+
115
+ def test_count_present_but_not_value
116
+ ax_error({'type.foo'=>'urn:foo', 'count.foo' => '1'}, IndexError)
117
+ end
118
+
119
+ def test_invalid_count_value
120
+ msg = FetchRequest.new
121
+ assert_raises(Error) {
122
+ msg.parse_extension_args({'type.foo'=>'urn:foo',
123
+ 'count.foo' => 'bogus'})
124
+ }
125
+ end
126
+
127
+ def test_request_unlimited_values
128
+ msg = FetchRequest.new
129
+ args = {'mode' => 'fetch_request',
130
+ 'required' => 'foo',
131
+ 'type.foo' => 'urn:foo',
132
+ 'count.foo' => UNLIMITED_VALUES
133
+ }
134
+ msg.parse_extension_args(args)
135
+ foo = msg.attributes[0]
136
+ assert_equal(UNLIMITED_VALUES, foo.count)
137
+ assert(foo.wants_unlimited_values?)
138
+ end
139
+
140
+ def test_long_alias
141
+ # spec says we must support at least 32 character-long aliases
142
+ name = 'x' * MINIMUM_SUPPORTED_ALIAS_LENGTH
143
+
144
+ msg = KeyValueMessage.new
145
+ args = {
146
+ "type.#{name}" => 'urn:foo',
147
+ "count.#{name}" => '1',
148
+ "value.#{name}.1" => 'first',
149
+ }
150
+ msg.parse_extension_args(args)
151
+ assert_equal(['first'],msg['urn:foo'])
152
+ end
153
+
154
+ def test_invalid_alias
155
+ types = [
156
+ KeyValueMessage,
157
+ FetchRequest
158
+ ]
159
+ inputs = [
160
+ {'type.a.b'=>'urn:foo',
161
+ 'count.a.b'=>'1'},
162
+ {'type.a,b'=>'urn:foo',
163
+ 'count.a,b'=>'1'},
164
+ ]
165
+ types.each{|t|
166
+ inputs.each{|input|
167
+ msg = t.new
168
+ assert_raises(Error) {msg.parse_extension_args(input)}
169
+ }
170
+ }
171
+ end
172
+
173
+ def test_count_present_and_is_zero
174
+ ax_values(
175
+ {'type.foo'=>'urn:foo',
176
+ 'count.foo'=>'0',
177
+ },
178
+ {'urn:foo'=>[]}
179
+ )
180
+ end
181
+
182
+ def test_singleton_empty
183
+ ax_values(
184
+ {'type.foo'=>'urn:foo',
185
+ 'value.foo'=>'',
186
+ },
187
+ {'urn:foo'=>[]}
188
+ )
189
+ end
190
+
191
+ def test_double_alias
192
+ ax_error(
193
+ {'type.foo'=>'urn:foo',
194
+ 'value.foo'=>'',
195
+ 'type.bar'=>'urn:foo',
196
+ 'value.bar'=>'',
197
+ },
198
+ IndexError
199
+ )
200
+ end
201
+
202
+ def test_double_singleton
203
+ ax_values(
204
+ {'type.foo'=>'urn:foo',
205
+ 'value.foo'=>'',
206
+ 'type.bar'=>'urn:bar',
207
+ 'value.bar'=>'',
208
+ },
209
+ {'urn:foo'=>[],'urn:bar'=>[]}
210
+ )
211
+ end
212
+
213
+ def singleton_value
214
+ ax_values(
215
+ {'type.foo'=>'urn:foo',
216
+ 'value.foo'=>'something',
217
+ },
218
+ {'urn:foo'=>['something']}
219
+ )
220
+ end
221
+ end
222
+
223
+ class FetchRequestTest < Test::Unit::TestCase
224
+ def setup
225
+ @msg = FetchRequest.new
226
+ @type_a = 'http://janrain.example.com/a'
227
+ @name_a = 'a'
228
+ end
229
+
230
+ def test_mode
231
+ assert_equal('fetch_request', @msg.mode)
232
+ end
233
+
234
+ def test_construct
235
+ assert_equal({}, @msg.requested_attributes)
236
+ assert_equal(nil, @msg.update_url)
237
+
238
+ msg = FetchRequest.new('hailstorm')
239
+ assert_equal({}, msg.requested_attributes)
240
+ assert_equal('hailstorm', msg.update_url)
241
+ end
242
+
243
+ def test_add
244
+ uri = 'mud://puddle'
245
+
246
+ assert(! @msg.member?(uri))
247
+ a = AttrInfo.new(uri)
248
+ @msg.add(a)
249
+ assert(@msg.member?(uri))
250
+ end
251
+
252
+ def test_add_twice
253
+ uri = 'its://raining'
254
+ a = AttrInfo.new(uri)
255
+ @msg.add(a)
256
+ assert_raises(IndexError) {@msg.add(a)}
257
+ end
258
+
259
+ def do_extension_args(expected_args)
260
+ expected_args['mode'] = @msg.mode
261
+ assert_equal(expected_args, @msg.get_extension_args)
262
+ end
263
+
264
+ def test_get_extension_args_empty
265
+ do_extension_args({})
266
+ end
267
+
268
+ def test_get_extension_args_no_alias
269
+ a = AttrInfo.new('foo://bar')
270
+ @msg.add(a)
271
+ ax_args = @msg.get_extension_args
272
+ ax_args.each{|k,v|
273
+ if v == a.type_uri and k.index('type.') == 0
274
+ @name = k[5..-1]
275
+ break
276
+ end
277
+ }
278
+ do_extension_args({'type.'+@name => a.type_uri,
279
+ 'if_available' => @name})
280
+ end
281
+
282
+ def test_get_extension_args_alias_if_available
283
+ a = AttrInfo.new('type://of.transportation',
284
+ 'transport')
285
+ @msg.add(a)
286
+ do_extension_args({'type.'+a.ns_alias => a.type_uri,
287
+ 'if_available' => a.ns_alias})
288
+ end
289
+
290
+ def test_get_extension_args_alias_req
291
+ a = AttrInfo.new('type://of.transportation',
292
+ 'transport',
293
+ true)
294
+ @msg.add(a)
295
+ do_extension_args({'type.'+a.ns_alias => a.type_uri,
296
+ 'required' => a.ns_alias})
297
+ end
298
+
299
+ def test_get_required_attrs_empty
300
+ assert_equal([], @msg.get_required_attrs)
301
+ end
302
+
303
+ def test_parse_extension_args_extra_type
304
+ args = {
305
+ 'mode' => 'fetch_request',
306
+ 'type.' + @name_a => @type_a
307
+ }
308
+ assert_raises(Error) {@msg.parse_extension_args(args)}
309
+ end
310
+
311
+ def test_parse_extension_args
312
+ args = {
313
+ 'mode' => 'fetch_request',
314
+ 'type.' + @name_a => @type_a,
315
+ 'if_available' => @name_a
316
+ }
317
+ @msg.parse_extension_args(args)
318
+ assert(@msg.member?(@type_a) )
319
+ assert_equal([@type_a], @msg.requested_types)
320
+ ai = @msg.requested_attributes[@type_a]
321
+ assert(ai.is_a?(AttrInfo))
322
+ assert(!ai.required)
323
+ assert_equal(@type_a, ai.type_uri)
324
+ assert_equal(@name_a, ai.ns_alias)
325
+ assert_equal([ai], @msg.attributes)
326
+ end
327
+
328
+ def test_extension_args_idempotent
329
+ args = {
330
+ 'mode' => 'fetch_request',
331
+ 'type.' + @name_a => @type_a,
332
+ 'if_available' => @name_a
333
+ }
334
+ @msg.parse_extension_args(args)
335
+ assert_equal(args, @msg.get_extension_args)
336
+ assert(!@msg.requested_attributes[@type_a].required)
337
+ end
338
+
339
+ def test_extension_args_idempotent_count_required
340
+ args = {
341
+ 'mode' => 'fetch_request',
342
+ 'type.' + @name_a => @type_a,
343
+ 'count.' + @name_a => '2',
344
+ 'required' => @name_a
345
+ }
346
+ @msg.parse_extension_args(args)
347
+ assert_equal(args, @msg.get_extension_args)
348
+ assert(@msg.requested_attributes[@type_a].required)
349
+ end
350
+
351
+ def test_extension_args_count1
352
+ args = {
353
+ 'mode' => 'fetch_request',
354
+ 'type.' + @name_a => @type_a,
355
+ 'count.' + @name_a => '1',
356
+ 'if_available' => @name_a
357
+ }
358
+ norm_args = {
359
+ 'mode' => 'fetch_request',
360
+ 'type.' + @name_a => @type_a,
361
+ 'if_available' => @name_a
362
+ }
363
+ @msg.parse_extension_args(args)
364
+ assert_equal(norm_args, @msg.get_extension_args)
365
+ end
366
+
367
+ def test_from_openid_request_no_ax
368
+ message = Message.new
369
+ openid_req = Server::OpenIDRequest.new
370
+ openid_req.message = message
371
+ ax_req = FetchRequest.from_openid_request(openid_req)
372
+ assert(ax_req.nil?)
373
+ end
374
+
375
+ def test_from_openid_request_wrong_ax_mode
376
+ uri = 'http://under.the.sea/'
377
+ name = 'ext0'
378
+ value = 'snarfblat'
379
+
380
+ message = OpenID::Message.from_openid_args({
381
+ 'mode' => 'id_res',
382
+ 'ns' => OPENID2_NS,
383
+ 'ns.ax' => AXMessage::NS_URI,
384
+ 'ax.update_url' => 'http://example.com/realm/update_path',
385
+ 'ax.mode' => 'store_request',
386
+ 'ax.type.' + name => uri,
387
+ 'ax.count.' + name => '1',
388
+ 'ax.value.' + name + '.1' => value
389
+ })
390
+ openid_req = Server::OpenIDRequest.new
391
+ openid_req.message = message
392
+ ax_req = FetchRequest.from_openid_request(openid_req)
393
+ assert(ax_req.nil?)
394
+ end
395
+
396
+ def test_openid_update_url_verification_error
397
+ openid_req_msg = Message.from_openid_args({
398
+ 'mode' => 'checkid_setup',
399
+ 'ns' => OPENID2_NS,
400
+ 'realm' => 'http://example.com/realm',
401
+ 'ns.ax' => AXMessage::NS_URI,
402
+ 'ax.update_url' => 'http://different.site/path',
403
+ 'ax.mode' => 'fetch_request',
404
+ })
405
+ openid_req = Server::OpenIDRequest.new
406
+ openid_req.message = openid_req_msg
407
+ assert_raises(Error) {
408
+ FetchRequest.from_openid_request(openid_req)
409
+ }
410
+ end
411
+
412
+ def test_openid_no_realm
413
+ openid_req_msg = Message.from_openid_args({
414
+ 'mode' => 'checkid_setup',
415
+ 'ns' => OPENID2_NS,
416
+ 'ns.ax' => AXMessage::NS_URI,
417
+ 'ax.update_url' => 'http://different.site/path',
418
+ 'ax.mode' => 'fetch_request',
419
+ })
420
+ openid_req = Server::OpenIDRequest.new
421
+ openid_req.message = openid_req_msg
422
+ assert_raises(Error) {
423
+ FetchRequest.from_openid_request(openid_req)
424
+ }
425
+ end
426
+
427
+ def test_openid_update_url_verification_success
428
+ openid_req_msg = Message.from_openid_args({
429
+ 'mode' => 'checkid_setup',
430
+ 'ns' => OPENID2_NS,
431
+ 'realm' => 'http://example.com/realm',
432
+ 'ns.ax' => AXMessage::NS_URI,
433
+ 'ax.update_url' => 'http://example.com/realm/update_path',
434
+ 'ax.mode' => 'fetch_request',
435
+ })
436
+ openid_req = Server::OpenIDRequest.new
437
+ openid_req.message = openid_req_msg
438
+ fr = FetchRequest.from_openid_request(openid_req)
439
+ assert(fr.is_a?(FetchRequest))
440
+ end
441
+
442
+ def test_openid_update_url_verification_success_return_to
443
+ openid_req_msg = Message.from_openid_args({
444
+ 'mode' => 'checkid_setup',
445
+ 'ns' => OPENID2_NS,
446
+ 'return_to' => 'http://example.com/realm',
447
+ 'ns.ax' => AXMessage::NS_URI,
448
+ 'ax.update_url' => 'http://example.com/realm/update_path',
449
+ 'ax.mode' => 'fetch_request',
450
+ })
451
+ openid_req = Server::OpenIDRequest.new
452
+ openid_req.message = openid_req_msg
453
+ fr = FetchRequest.from_openid_request(openid_req)
454
+ assert(fr.is_a?(FetchRequest))
455
+ end
456
+
457
+ def test_add_extension
458
+ openid_req_msg = Message.from_openid_args({
459
+ 'mode' => 'checkid_setup',
460
+ 'ns' => OPENID2_NS,
461
+ 'return_to' => 'http://example.com/realm',
462
+ })
463
+
464
+ e = OpenID::OpenIDServiceEndpoint.new
465
+ openid_req = Consumer::CheckIDRequest.new(nil, e)
466
+ openid_req.message = openid_req_msg
467
+
468
+ fr = FetchRequest.new
469
+ fr.add(AttrInfo.new("urn:bogus"))
470
+
471
+ openid_req.add_extension(fr)
472
+
473
+ expected = {
474
+ 'mode' => 'fetch_request',
475
+ 'if_available' => 'ext0',
476
+ 'type.ext0' => 'urn:bogus',
477
+ }
478
+
479
+ expected.each { |k,v|
480
+ assert(openid_req.message.get_arg(AXMessage::NS_URI, k) == v)
481
+ }
482
+ end
483
+ end
484
+
485
+ class FetchResponseTest < Test::Unit::TestCase
486
+ def setup
487
+ @msg = FetchResponse.new
488
+ @value_a = 'commodity'
489
+ @type_a = 'http://blood.transfusion/'
490
+ @name_a = 'george'
491
+ @request_update_url = 'http://some.url.that.is.awesome/'
492
+ end
493
+
494
+ def test_construct
495
+ assert_equal(nil, @msg.update_url)
496
+ assert_equal({}, @msg.data)
497
+ end
498
+
499
+ def test_get_extension_args_empty
500
+ eargs = {
501
+ 'mode' => 'fetch_response'
502
+ }
503
+ assert_equal(eargs, @msg.get_extension_args)
504
+ end
505
+
506
+ def test_get_extension_args_empty_request
507
+ eargs = {
508
+ 'mode' => 'fetch_response'
509
+ }
510
+ req = FetchRequest.new
511
+ assert_equal(eargs, @msg.get_extension_args(req))
512
+ end
513
+
514
+ def test_get_extension_args_empty_request_some
515
+ uri = 'http://not.found/'
516
+ name = 'ext0'
517
+ eargs = {
518
+ 'mode' => 'fetch_response',
519
+ 'type.' + name => uri,
520
+ 'count.' + name => '0'
521
+ }
522
+ req = FetchRequest.new
523
+ req.add(AttrInfo.new(uri))
524
+ assert_equal(eargs, @msg.get_extension_args(req))
525
+ end
526
+
527
+ def test_update_url_in_response
528
+ uri = 'http://not.found/'
529
+ name = 'ext0'
530
+ eargs = {
531
+ 'mode' => 'fetch_response',
532
+ 'update_url' => @request_update_url,
533
+ 'type.' + name => uri,
534
+ 'count.' + name => '0'
535
+ }
536
+ req = FetchRequest.new(@request_update_url)
537
+ req.add(AttrInfo.new(uri))
538
+ assert_equal(eargs, @msg.get_extension_args(req))
539
+ end
540
+
541
+ def test_get_extension_args_some_request
542
+ eargs = {
543
+ 'mode' => 'fetch_response',
544
+ 'type.' + @name_a => @type_a,
545
+ 'value.' + @name_a + '.1' => @value_a,
546
+ 'count.' + @name_a => '1'
547
+ }
548
+ req = FetchRequest.new
549
+ req.add(AttrInfo.new(@type_a, @name_a))
550
+ @msg.add_value(@type_a, @value_a)
551
+ assert_equal(eargs, @msg.get_extension_args(req))
552
+ end
553
+
554
+ def test_get_extension_args_some_not_request
555
+ req = FetchRequest.new
556
+ @msg.add_value(@type_a, @value_a)
557
+ assert_raises(IndexError) {@msg.get_extension_args(req)}
558
+ end
559
+
560
+ def test_get_single_success
561
+ req = FetchRequest.new
562
+ @msg.add_value(@type_a, @value_a)
563
+ assert_equal(@value_a, @msg.get_single(@type_a))
564
+ end
565
+
566
+ def test_get_single_none
567
+ assert_equal(nil, @msg.get_single(@type_a))
568
+ end
569
+
570
+ def test_get_single_extra
571
+ @msg.set_values(@type_a, ['x', 'y'])
572
+ assert_raises(Error) { @msg.get_single(@type_a) }
573
+ end
574
+
575
+ def test_from_success_response
576
+ uri = 'http://under.the.sea/'
577
+ name = 'ext0'
578
+ value = 'snarfblat'
579
+
580
+ m = OpenID::Message.from_openid_args({
581
+ 'mode' => 'id_res',
582
+ 'ns' => OPENID2_NS,
583
+ 'ns.ax' => AXMessage::NS_URI,
584
+ 'ax.update_url' => 'http://example.com/realm/update_path',
585
+ 'ax.mode' => 'fetch_response',
586
+ 'ax.type.' + name => uri,
587
+ 'ax.count.' + name => '1',
588
+ 'ax.value.' + name + '.1' => value,
589
+ })
590
+
591
+ e = OpenID::OpenIDServiceEndpoint.new()
592
+ resp = OpenID::Consumer::SuccessResponse.new(e, m, [])
593
+
594
+ ax_resp = FetchResponse.from_success_response(resp, false)
595
+
596
+ values = ax_resp[uri]
597
+ assert_equal(values, [value])
598
+ end
599
+
600
+ def test_from_success_response_empty
601
+ e = OpenID::OpenIDServiceEndpoint.new()
602
+ m = OpenID::Message.from_openid_args({'mode' => 'id_res'})
603
+ resp = OpenID::Consumer::SuccessResponse.new(e, m, [])
604
+ ax_resp = FetchResponse.from_success_response(resp)
605
+ assert(ax_resp.nil?)
606
+ end
607
+ end
608
+
609
+ class StoreRequestTest < Test::Unit::TestCase
610
+ def setup
611
+ @msg = StoreRequest.new
612
+ @type_a = 'http://oranges.are.for/'
613
+ @name_a = 'juggling'
614
+ end
615
+
616
+ def test_construct
617
+ assert_equal({}, @msg.data)
618
+ end
619
+
620
+ def test_get_extension_args_empty
621
+ eargs = {
622
+ 'mode' => 'store_request'
623
+ }
624
+ assert_equal(eargs, @msg.get_extension_args)
625
+ end
626
+
627
+ def test_from_openid_request_wrong_ax_mode
628
+ uri = 'http://under.the.sea/'
629
+ name = 'ext0'
630
+ value = 'snarfblat'
631
+
632
+ message = OpenID::Message.from_openid_args({
633
+ 'mode' => 'id_res',
634
+ 'ns' => OPENID2_NS,
635
+ 'ns.ax' => AXMessage::NS_URI,
636
+ 'ax.update_url' => 'http://example.com/realm/update_path',
637
+ 'ax.mode' => 'fetch_request',
638
+ 'ax.type.' + name => uri,
639
+ 'ax.count.' + name => '1',
640
+ 'ax.value.' + name + '.1' => value
641
+ })
642
+ openid_req = Server::OpenIDRequest.new
643
+ openid_req.message = message
644
+ ax_req = StoreRequest.from_openid_request(openid_req)
645
+ assert(ax_req.nil?)
646
+ end
647
+
648
+ def test_get_extension_args_nonempty
649
+ @msg.set_values(@type_a, ['foo','bar'])
650
+ aliases = NamespaceMap.new
651
+ aliases.add_alias(@type_a, @name_a)
652
+ eargs = {
653
+ 'mode' => 'store_request',
654
+ 'type.' + @name_a => @type_a,
655
+ 'value.' + @name_a + '.1' => 'foo',
656
+ 'value.' + @name_a + '.2' => 'bar',
657
+ 'count.' + @name_a => '2'
658
+ }
659
+ assert_equal(eargs, @msg.get_extension_args(aliases))
660
+ end
661
+ end
662
+
663
+ class StoreResponseTest < Test::Unit::TestCase
664
+ def test_success
665
+ msg = StoreResponse.new
666
+ assert(msg.succeeded?)
667
+ assert(!msg.error_message)
668
+ assert_equal({'mode' => 'store_response_success'},
669
+ msg.get_extension_args)
670
+ end
671
+
672
+ def test_fail_nomsg
673
+ msg = StoreResponse.new(false)
674
+ assert(! msg.succeeded? )
675
+ assert(! msg.error_message )
676
+ assert_equal({'mode' => 'store_response_failure'},
677
+ msg.get_extension_args)
678
+ end
679
+
680
+ def test_fail_msg
681
+ reason = "because I said so"
682
+ msg = StoreResponse.new(false, reason)
683
+ assert(! msg.succeeded? )
684
+ assert_equal(reason, msg.error_message)
685
+ assert_equal({'mode' => 'store_response_failure', 'error' => reason},
686
+ msg.get_extension_args)
687
+ end
688
+ end
689
+ end
690
+ end