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.
- data/CHANGELOG +215 -0
- data/INSTALL +47 -0
- data/LICENSE +210 -0
- data/NOTICE +2 -0
- data/README +85 -0
- data/UPGRADE +127 -0
- data/admin/runtests.rb +45 -0
- data/examples/README +32 -0
- data/examples/active_record_openid_store/README +58 -0
- data/examples/active_record_openid_store/XXX_add_open_id_store_to_db.rb +24 -0
- data/examples/active_record_openid_store/XXX_upgrade_open_id_store.rb +26 -0
- data/examples/active_record_openid_store/init.rb +8 -0
- data/examples/active_record_openid_store/lib/association.rb +10 -0
- data/examples/active_record_openid_store/lib/nonce.rb +3 -0
- data/examples/active_record_openid_store/lib/open_id_setting.rb +4 -0
- data/examples/active_record_openid_store/lib/openid_ar_store.rb +57 -0
- data/examples/active_record_openid_store/test/store_test.rb +212 -0
- data/examples/discover +49 -0
- data/examples/rails_openid/README +153 -0
- data/examples/rails_openid/Rakefile +10 -0
- data/examples/rails_openid/app/controllers/application.rb +4 -0
- data/examples/rails_openid/app/controllers/consumer_controller.rb +125 -0
- data/examples/rails_openid/app/controllers/login_controller.rb +45 -0
- data/examples/rails_openid/app/controllers/server_controller.rb +265 -0
- data/examples/rails_openid/app/helpers/application_helper.rb +3 -0
- data/examples/rails_openid/app/helpers/login_helper.rb +2 -0
- data/examples/rails_openid/app/helpers/server_helper.rb +9 -0
- data/examples/rails_openid/app/views/consumer/index.rhtml +81 -0
- data/examples/rails_openid/app/views/layouts/server.rhtml +68 -0
- data/examples/rails_openid/app/views/login/index.rhtml +56 -0
- data/examples/rails_openid/app/views/server/decide.rhtml +26 -0
- data/examples/rails_openid/config/boot.rb +19 -0
- data/examples/rails_openid/config/database.yml +74 -0
- data/examples/rails_openid/config/environment.rb +54 -0
- data/examples/rails_openid/config/environments/development.rb +19 -0
- data/examples/rails_openid/config/environments/production.rb +19 -0
- data/examples/rails_openid/config/environments/test.rb +19 -0
- data/examples/rails_openid/config/routes.rb +24 -0
- data/examples/rails_openid/doc/README_FOR_APP +2 -0
- data/examples/rails_openid/public/404.html +8 -0
- data/examples/rails_openid/public/500.html +8 -0
- data/examples/rails_openid/public/dispatch.cgi +12 -0
- data/examples/rails_openid/public/dispatch.fcgi +26 -0
- data/examples/rails_openid/public/dispatch.rb +12 -0
- data/examples/rails_openid/public/favicon.ico +0 -0
- data/examples/rails_openid/public/images/openid_login_bg.gif +0 -0
- data/examples/rails_openid/public/javascripts/controls.js +750 -0
- data/examples/rails_openid/public/javascripts/dragdrop.js +584 -0
- data/examples/rails_openid/public/javascripts/effects.js +854 -0
- data/examples/rails_openid/public/javascripts/prototype.js +1785 -0
- data/examples/rails_openid/public/robots.txt +1 -0
- data/examples/rails_openid/script/about +3 -0
- data/examples/rails_openid/script/breakpointer +3 -0
- data/examples/rails_openid/script/console +3 -0
- data/examples/rails_openid/script/destroy +3 -0
- data/examples/rails_openid/script/generate +3 -0
- data/examples/rails_openid/script/performance/benchmarker +3 -0
- data/examples/rails_openid/script/performance/profiler +3 -0
- data/examples/rails_openid/script/plugin +3 -0
- data/examples/rails_openid/script/process/reaper +3 -0
- data/examples/rails_openid/script/process/spawner +3 -0
- data/examples/rails_openid/script/process/spinner +3 -0
- data/examples/rails_openid/script/runner +3 -0
- data/examples/rails_openid/script/server +3 -0
- data/examples/rails_openid/test/functional/login_controller_test.rb +18 -0
- data/examples/rails_openid/test/functional/server_controller_test.rb +18 -0
- data/examples/rails_openid/test/test_helper.rb +28 -0
- data/lib/hmac/hmac.rb +112 -0
- data/lib/hmac/sha1.rb +11 -0
- data/lib/hmac/sha2.rb +25 -0
- data/lib/openid.rb +22 -0
- data/lib/openid/association.rb +249 -0
- data/lib/openid/consumer.rb +395 -0
- data/lib/openid/consumer/associationmanager.rb +344 -0
- data/lib/openid/consumer/checkid_request.rb +186 -0
- data/lib/openid/consumer/discovery.rb +497 -0
- data/lib/openid/consumer/discovery_manager.rb +123 -0
- data/lib/openid/consumer/html_parse.rb +134 -0
- data/lib/openid/consumer/idres.rb +523 -0
- data/lib/openid/consumer/responses.rb +150 -0
- data/lib/openid/cryptutil.rb +115 -0
- data/lib/openid/dh.rb +89 -0
- data/lib/openid/extension.rb +39 -0
- data/lib/openid/extensions/ax.rb +539 -0
- data/lib/openid/extensions/oauth.rb +91 -0
- data/lib/openid/extensions/pape.rb +179 -0
- data/lib/openid/extensions/sreg.rb +277 -0
- data/lib/openid/extras.rb +11 -0
- data/lib/openid/fetchers.rb +258 -0
- data/lib/openid/kvform.rb +136 -0
- data/lib/openid/kvpost.rb +58 -0
- data/lib/openid/message.rb +553 -0
- data/lib/openid/protocolerror.rb +12 -0
- data/lib/openid/server.rb +1544 -0
- data/lib/openid/store.rb +10 -0
- data/lib/openid/store/filesystem.rb +272 -0
- data/lib/openid/store/interface.rb +75 -0
- data/lib/openid/store/memcache.rb +109 -0
- data/lib/openid/store/memory.rb +84 -0
- data/lib/openid/store/nonce.rb +68 -0
- data/lib/openid/trustroot.rb +349 -0
- data/lib/openid/urinorm.rb +75 -0
- data/lib/openid/util.rb +119 -0
- data/lib/openid/version.rb +3 -0
- data/lib/openid/yadis.rb +15 -0
- data/lib/openid/yadis/accept.rb +148 -0
- data/lib/openid/yadis/constants.rb +21 -0
- data/lib/openid/yadis/discovery.rb +153 -0
- data/lib/openid/yadis/filters.rb +205 -0
- data/lib/openid/yadis/htmltokenizer.rb +305 -0
- data/lib/openid/yadis/parsehtml.rb +45 -0
- data/lib/openid/yadis/services.rb +42 -0
- data/lib/openid/yadis/xrds.rb +155 -0
- data/lib/openid/yadis/xri.rb +90 -0
- data/lib/openid/yadis/xrires.rb +91 -0
- data/test/data/test_discover/openid_utf8.html +11 -0
- data/test/support/test_data_mixin.rb +127 -0
- data/test/support/test_util.rb +53 -0
- data/test/support/yadis_data.rb +131 -0
- data/test/support/yadis_data/accept.txt +124 -0
- data/test/support/yadis_data/dh.txt +29 -0
- data/test/support/yadis_data/example-xrds.xml +14 -0
- data/test/support/yadis_data/linkparse.txt +587 -0
- data/test/support/yadis_data/n2b64 +650 -0
- data/test/support/yadis_data/test1-discover.txt +137 -0
- data/test/support/yadis_data/test1-parsehtml.txt +152 -0
- data/test/support/yadis_data/test_discover/malformed_meta_tag.html +19 -0
- data/test/support/yadis_data/test_discover/openid.html +11 -0
- data/test/support/yadis_data/test_discover/openid2.html +11 -0
- data/test/support/yadis_data/test_discover/openid2_xrds.xml +12 -0
- data/test/support/yadis_data/test_discover/openid2_xrds_no_local_id.xml +11 -0
- data/test/support/yadis_data/test_discover/openid_1_and_2.html +11 -0
- data/test/support/yadis_data/test_discover/openid_1_and_2_xrds.xml +16 -0
- data/test/support/yadis_data/test_discover/openid_1_and_2_xrds_bad_delegate.xml +17 -0
- data/test/support/yadis_data/test_discover/openid_and_yadis.html +12 -0
- data/test/support/yadis_data/test_discover/openid_no_delegate.html +10 -0
- data/test/support/yadis_data/test_discover/openid_utf8.html +11 -0
- data/test/support/yadis_data/test_discover/yadis_0entries.xml +12 -0
- data/test/support/yadis_data/test_discover/yadis_2_bad_local_id.xml +15 -0
- data/test/support/yadis_data/test_discover/yadis_2entries_delegate.xml +22 -0
- data/test/support/yadis_data/test_discover/yadis_2entries_idp.xml +21 -0
- data/test/support/yadis_data/test_discover/yadis_another_delegate.xml +14 -0
- data/test/support/yadis_data/test_discover/yadis_idp.xml +12 -0
- data/test/support/yadis_data/test_discover/yadis_idp_delegate.xml +13 -0
- data/test/support/yadis_data/test_discover/yadis_no_delegate.xml +11 -0
- data/test/support/yadis_data/test_xrds/=j3h.2007.11.14.xrds +25 -0
- data/test/support/yadis_data/test_xrds/README +12 -0
- data/test/support/yadis_data/test_xrds/delegated-20060809-r1.xrds +34 -0
- data/test/support/yadis_data/test_xrds/delegated-20060809-r2.xrds +34 -0
- data/test/support/yadis_data/test_xrds/delegated-20060809.xrds +34 -0
- data/test/support/yadis_data/test_xrds/no-xrd.xml +7 -0
- data/test/support/yadis_data/test_xrds/not-xrds.xml +2 -0
- data/test/support/yadis_data/test_xrds/prefixsometimes.xrds +34 -0
- data/test/support/yadis_data/test_xrds/ref.xrds +109 -0
- data/test/support/yadis_data/test_xrds/sometimesprefix.xrds +34 -0
- data/test/support/yadis_data/test_xrds/spoof1.xrds +25 -0
- data/test/support/yadis_data/test_xrds/spoof2.xrds +25 -0
- data/test/support/yadis_data/test_xrds/spoof3.xrds +37 -0
- data/test/support/yadis_data/test_xrds/status222.xrds +9 -0
- data/test/support/yadis_data/test_xrds/subsegments.xrds +58 -0
- data/test/support/yadis_data/test_xrds/valid-populated-xrds.xml +39 -0
- data/test/support/yadis_data/trustroot.txt +153 -0
- data/test/support/yadis_data/urinorm.txt +79 -0
- data/test/test_accept.rb +170 -0
- data/test/test_association.rb +268 -0
- data/test/test_associationmanager.rb +918 -0
- data/test/test_ax.rb +690 -0
- data/test/test_checkid_request.rb +293 -0
- data/test/test_consumer.rb +260 -0
- data/test/test_cryptutil.rb +119 -0
- data/test/test_dh.rb +85 -0
- data/test/test_discover.rb +848 -0
- data/test/test_discovery_manager.rb +259 -0
- data/test/test_extension.rb +46 -0
- data/test/test_extras.rb +35 -0
- data/test/test_fetchers.rb +554 -0
- data/test/test_filters.rb +269 -0
- data/test/test_helper.rb +4 -0
- data/test/test_idres.rb +961 -0
- data/test/test_kvform.rb +164 -0
- data/test/test_kvpost.rb +64 -0
- data/test/test_linkparse.rb +100 -0
- data/test/test_message.rb +1115 -0
- data/test/test_nonce.rb +89 -0
- data/test/test_oauth.rb +176 -0
- data/test/test_openid_yadis.rb +177 -0
- data/test/test_pape.rb +248 -0
- data/test/test_parsehtml.rb +79 -0
- data/test/test_responses.rb +63 -0
- data/test/test_server.rb +2455 -0
- data/test/test_sreg.rb +479 -0
- data/test/test_stores.rb +292 -0
- data/test/test_trustroot.rb +111 -0
- data/test/test_urinorm.rb +34 -0
- data/test/test_util.rb +145 -0
- data/test/test_xrds.rb +167 -0
- data/test/test_xri.rb +48 -0
- data/test/test_xrires.rb +67 -0
- data/test/test_yadis_discovery.rb +218 -0
- metadata +268 -0
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
require 'openid/yadis/filters'
|
|
3
|
+
|
|
4
|
+
module OpenID
|
|
5
|
+
class BasicServiceEndpointTest < Test::Unit::TestCase
|
|
6
|
+
def test_match_types
|
|
7
|
+
# Make sure the match_types operation returns the expected
|
|
8
|
+
# results with various inputs.
|
|
9
|
+
types = ["urn:bogus", "urn:testing"]
|
|
10
|
+
yadis_url = "http://yadis/"
|
|
11
|
+
|
|
12
|
+
no_types_endpoint = Yadis::BasicServiceEndpoint.new(yadis_url, [], nil, nil)
|
|
13
|
+
|
|
14
|
+
some_types_endpoint = Yadis::BasicServiceEndpoint.new(yadis_url, types,
|
|
15
|
+
nil, nil)
|
|
16
|
+
|
|
17
|
+
assert(no_types_endpoint.match_types([]) == [])
|
|
18
|
+
assert(no_types_endpoint.match_types(["urn:absent"]) == [])
|
|
19
|
+
|
|
20
|
+
assert(some_types_endpoint.match_types([]) == [])
|
|
21
|
+
assert(some_types_endpoint.match_types(["urn:absent"]) == [])
|
|
22
|
+
assert(some_types_endpoint.match_types(types) == types)
|
|
23
|
+
assert(some_types_endpoint.match_types([types[1], types[0]]) == types)
|
|
24
|
+
assert(some_types_endpoint.match_types([types[0]]) == [types[0]])
|
|
25
|
+
assert(some_types_endpoint.match_types(types + ["urn:absent"]) == types)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def test_from_basic_service_endpoint
|
|
29
|
+
# Check BasicServiceEndpoint.from_basic_service_endpoint
|
|
30
|
+
endpoint = "unused"
|
|
31
|
+
e = Yadis::BasicServiceEndpoint.new(nil, [], nil, nil)
|
|
32
|
+
|
|
33
|
+
assert(Yadis::BasicServiceEndpoint.from_basic_service_endpoint(endpoint) ==
|
|
34
|
+
endpoint)
|
|
35
|
+
assert(e.from_basic_service_endpoint(endpoint) ==
|
|
36
|
+
endpoint)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
class TransformFilterMakerTest < Test::Unit::TestCase
|
|
41
|
+
def make_service_element(types, uris)
|
|
42
|
+
service = REXML::Element.new('Service')
|
|
43
|
+
types.each { |type_text|
|
|
44
|
+
service.add_element('Type').text = type_text
|
|
45
|
+
}
|
|
46
|
+
uris.each { |uri_text|
|
|
47
|
+
service.add_element('URI').text = uri_text
|
|
48
|
+
}
|
|
49
|
+
return service
|
|
50
|
+
end
|
|
51
|
+
def test_get_service_endpoints
|
|
52
|
+
yadis_url = "http://yad.is/"
|
|
53
|
+
uri = "http://uri/"
|
|
54
|
+
type_uris = ["urn:type1", "urn:type2"]
|
|
55
|
+
element = make_service_element(type_uris, [uri])
|
|
56
|
+
|
|
57
|
+
data = [
|
|
58
|
+
[type_uris, uri, element],
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
filters = [Proc.new { |endpoint|
|
|
62
|
+
if endpoint.service_element == element
|
|
63
|
+
endpoint
|
|
64
|
+
else
|
|
65
|
+
nil
|
|
66
|
+
end
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
tf = Yadis::TransformFilterMaker.new(filters)
|
|
71
|
+
result = tf.get_service_endpoints(yadis_url, element)
|
|
72
|
+
|
|
73
|
+
assert_equal(result[0].yadis_url, yadis_url, result)
|
|
74
|
+
assert_equal(result[0].uri, uri, result)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def test_empty_transform_filter
|
|
78
|
+
# A transform filter with no filter procs should return nil.
|
|
79
|
+
endpoint = "unused"
|
|
80
|
+
t = Yadis::TransformFilterMaker.new([])
|
|
81
|
+
assert(t.apply_filters(endpoint).nil?)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def test_nil_filter
|
|
85
|
+
# A transform filter with a single nil filter should return nil.
|
|
86
|
+
nil_filter = Proc.new { |endpoint| nil }
|
|
87
|
+
t = Yadis::TransformFilterMaker.new([nil_filter])
|
|
88
|
+
endpoint = "unused"
|
|
89
|
+
assert(t.apply_filters(endpoint).nil?)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def test_identity_filter
|
|
93
|
+
# A transform filter with an identity filter should return the
|
|
94
|
+
# input.
|
|
95
|
+
identity_filter = Proc.new { |endpoint| endpoint }
|
|
96
|
+
t = Yadis::TransformFilterMaker.new([identity_filter])
|
|
97
|
+
endpoint = "unused"
|
|
98
|
+
assert(t.apply_filters(endpoint) == endpoint)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def test_return_different_endpoint
|
|
102
|
+
# Make sure the result of the filter is returned, rather than
|
|
103
|
+
# the input.
|
|
104
|
+
returned_endpoint = "returned endpoint"
|
|
105
|
+
filter = Proc.new { |endpoint| returned_endpoint }
|
|
106
|
+
t = Yadis::TransformFilterMaker.new([filter])
|
|
107
|
+
endpoint = "unused"
|
|
108
|
+
assert(t.apply_filters(endpoint) == returned_endpoint)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def test_multiple_filters
|
|
112
|
+
# Check filter fallback behavior on different inputs.
|
|
113
|
+
odd, odd_result = 45, "odd"
|
|
114
|
+
even, even_result = 46, "even"
|
|
115
|
+
|
|
116
|
+
filter_odd = Proc.new { |endpoint|
|
|
117
|
+
if endpoint % 2 == 1
|
|
118
|
+
odd_result
|
|
119
|
+
else
|
|
120
|
+
nil
|
|
121
|
+
end
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
filter_even = Proc.new { |endpoint|
|
|
125
|
+
if endpoint % 2 == 0
|
|
126
|
+
even_result
|
|
127
|
+
else
|
|
128
|
+
nil
|
|
129
|
+
end
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
t = Yadis::TransformFilterMaker.new([filter_odd, filter_even])
|
|
133
|
+
assert(t.apply_filters(odd) == odd_result)
|
|
134
|
+
assert(t.apply_filters(even) == even_result)
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
class BogusServiceEndpointExtractor
|
|
139
|
+
def initialize(data)
|
|
140
|
+
@data = data
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def get_service_endpoints(yadis_url, service_element)
|
|
144
|
+
return @data
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
class CompoundFilterTest < Test::Unit::TestCase
|
|
149
|
+
def test_get_service_endpoints
|
|
150
|
+
first = ["bogus", "test"]
|
|
151
|
+
second = ["third"]
|
|
152
|
+
all = first + second
|
|
153
|
+
|
|
154
|
+
subfilters = [
|
|
155
|
+
BogusServiceEndpointExtractor.new(first),
|
|
156
|
+
BogusServiceEndpointExtractor.new(second),
|
|
157
|
+
]
|
|
158
|
+
|
|
159
|
+
cf = Yadis::CompoundFilter.new(subfilters)
|
|
160
|
+
assert(cf.get_service_endpoints("unused", "unused") == all)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
class MakeFilterTest < Test::Unit::TestCase
|
|
165
|
+
def test_parts_nil
|
|
166
|
+
result = Yadis.make_filter(nil)
|
|
167
|
+
assert(result.is_a?(Yadis::TransformFilterMaker),
|
|
168
|
+
result.to_s)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def test_parts_array
|
|
172
|
+
e1 = Yadis::BasicServiceEndpoint.new(nil, [], nil, nil)
|
|
173
|
+
e2 = Yadis::BasicServiceEndpoint.new(nil, [], nil, nil)
|
|
174
|
+
|
|
175
|
+
result = Yadis.make_filter([e1, e2])
|
|
176
|
+
assert(result.is_a?(Yadis::TransformFilterMaker),
|
|
177
|
+
result.to_s)
|
|
178
|
+
assert(result.filter_procs[0] == e1.method('from_basic_service_endpoint'))
|
|
179
|
+
assert(result.filter_procs[1] == e2.method('from_basic_service_endpoint'))
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def test_parts_single
|
|
183
|
+
e = Yadis::BasicServiceEndpoint.new(nil, [], nil, nil)
|
|
184
|
+
result = Yadis.make_filter(e)
|
|
185
|
+
assert(result.is_a?(Yadis::TransformFilterMaker),
|
|
186
|
+
result.to_s)
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
class MakeCompoundFilterTest < Test::Unit::TestCase
|
|
191
|
+
def test_no_filters
|
|
192
|
+
result = Yadis.mk_compound_filter([])
|
|
193
|
+
assert(result.subfilters == [])
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def test_single_transform_filter
|
|
197
|
+
f = Yadis::TransformFilterMaker.new([])
|
|
198
|
+
assert(Yadis.mk_compound_filter([f]) == f)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def test_single_endpoint
|
|
202
|
+
e = Yadis::BasicServiceEndpoint.new(nil, [], nil, nil)
|
|
203
|
+
result = Yadis.mk_compound_filter([e])
|
|
204
|
+
assert(result.is_a?(Yadis::TransformFilterMaker))
|
|
205
|
+
|
|
206
|
+
# Expect the transform filter to call
|
|
207
|
+
# from_basic_service_endpoint on the endpoint
|
|
208
|
+
filter = result.filter_procs[0]
|
|
209
|
+
assert(filter == e.method('from_basic_service_endpoint'),
|
|
210
|
+
filter.to_s)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def test_single_proc
|
|
214
|
+
# Create a proc that just returns nil for any endpoint
|
|
215
|
+
p = Proc.new { |endpoint| nil }
|
|
216
|
+
result = Yadis.mk_compound_filter([p])
|
|
217
|
+
assert(result.is_a?(Yadis::TransformFilterMaker))
|
|
218
|
+
|
|
219
|
+
# Expect the transform filter to call
|
|
220
|
+
# from_basic_service_endpoint on the endpoint
|
|
221
|
+
filter = result.filter_procs[0]
|
|
222
|
+
assert(filter == p)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def test_multiple_filters_same_type
|
|
226
|
+
f1 = Yadis::TransformFilterMaker.new([])
|
|
227
|
+
f2 = Yadis::TransformFilterMaker.new([])
|
|
228
|
+
|
|
229
|
+
# Expect mk_compound_filter to actually make a CompoundFilter
|
|
230
|
+
# from f1 and f2.
|
|
231
|
+
result = Yadis.mk_compound_filter([f1, f2])
|
|
232
|
+
|
|
233
|
+
assert(result.is_a?(Yadis::CompoundFilter))
|
|
234
|
+
assert(result.subfilters == [f1, f2])
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def test_multiple_filters_different_type
|
|
238
|
+
f1 = Yadis::TransformFilterMaker.new([])
|
|
239
|
+
f2 = Yadis::BasicServiceEndpoint.new(nil, [], nil, nil)
|
|
240
|
+
f3 = Proc.new { |endpoint| nil }
|
|
241
|
+
|
|
242
|
+
e = Yadis::BasicServiceEndpoint.new(nil, [], nil, nil)
|
|
243
|
+
f4 = [e]
|
|
244
|
+
|
|
245
|
+
# Expect mk_compound_filter to actually make a CompoundFilter
|
|
246
|
+
# from f1 and f2.
|
|
247
|
+
result = Yadis.mk_compound_filter([f1, f2, f3, f4])
|
|
248
|
+
|
|
249
|
+
assert(result.is_a?(Yadis::CompoundFilter))
|
|
250
|
+
|
|
251
|
+
assert(result.subfilters[0] == f1)
|
|
252
|
+
assert(result.subfilters[1].filter_procs[0] ==
|
|
253
|
+
e.method('from_basic_service_endpoint'))
|
|
254
|
+
assert(result.subfilters[2].filter_procs[0] ==
|
|
255
|
+
f2.method('from_basic_service_endpoint'))
|
|
256
|
+
assert(result.subfilters[2].filter_procs[1] == f3)
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def test_filter_type_error
|
|
260
|
+
# Pass various non-filter objects and make sure the filter
|
|
261
|
+
# machinery explodes.
|
|
262
|
+
[nil, ["bogus"], [1], [nil, "bogus"]].each { |thing|
|
|
263
|
+
assert_raise(TypeError) {
|
|
264
|
+
Yadis.mk_compound_filter(thing)
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
end
|
data/test/test_helper.rb
ADDED
data/test/test_idres.rb
ADDED
|
@@ -0,0 +1,961 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
require "openid/consumer/idres"
|
|
3
|
+
require "openid/protocolerror"
|
|
4
|
+
require "openid/store/memory"
|
|
5
|
+
require "openid/store/nonce"
|
|
6
|
+
|
|
7
|
+
module OpenID
|
|
8
|
+
class Consumer
|
|
9
|
+
class IdResHandler
|
|
10
|
+
|
|
11
|
+
# Subclass of IdResHandler that doesn't do verification upon
|
|
12
|
+
# construction. All of the tests call this, except for the ones
|
|
13
|
+
# explicitly for id_res.
|
|
14
|
+
class IdResHandler < OpenID::Consumer::IdResHandler
|
|
15
|
+
def id_res
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class CheckForFieldsTest < Test::Unit::TestCase
|
|
20
|
+
include ProtocolErrorMixin
|
|
21
|
+
|
|
22
|
+
BASE_FIELDS = ['return_to', 'assoc_handle', 'sig', 'signed']
|
|
23
|
+
OPENID2_FIELDS = BASE_FIELDS + ['op_endpoint']
|
|
24
|
+
OPENID1_FIELDS = BASE_FIELDS + ['identity']
|
|
25
|
+
|
|
26
|
+
OPENID1_SIGNED = ['return_to', 'identity']
|
|
27
|
+
OPENID2_SIGNED =
|
|
28
|
+
OPENID1_SIGNED + ['response_nonce', 'claimed_id', 'assoc_handle',
|
|
29
|
+
'op_endpoint']
|
|
30
|
+
|
|
31
|
+
def mkMsg(ns, fields, signed_fields)
|
|
32
|
+
msg = Message.new(ns)
|
|
33
|
+
fields.each do |field|
|
|
34
|
+
msg.set_arg(OPENID_NS, field, "don't care")
|
|
35
|
+
end
|
|
36
|
+
if fields.member?('signed')
|
|
37
|
+
msg.set_arg(OPENID_NS, 'signed', signed_fields.join(','))
|
|
38
|
+
end
|
|
39
|
+
msg
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
1.times do # so as not to bleed into the outer namespace
|
|
43
|
+
n = 0
|
|
44
|
+
[[],
|
|
45
|
+
['foo'],
|
|
46
|
+
['bar', 'baz'],
|
|
47
|
+
].each do |signed_fields|
|
|
48
|
+
test = lambda do
|
|
49
|
+
msg = mkMsg(OPENID2_NS, OPENID2_FIELDS, signed_fields)
|
|
50
|
+
idres = IdResHandler.new(msg, nil)
|
|
51
|
+
assert_equal(signed_fields, idres.send(:signed_list))
|
|
52
|
+
# Do it again to make sure logic for caching is correct
|
|
53
|
+
assert_equal(signed_fields, idres.send(:signed_list))
|
|
54
|
+
end
|
|
55
|
+
define_method("test_signed_list_#{n += 1}", test)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# test all missing fields for OpenID 1 and 2
|
|
60
|
+
1.times do
|
|
61
|
+
[["openid1", OPENID1_NS, OPENID1_FIELDS],
|
|
62
|
+
["openid1", OPENID11_NS, OPENID1_FIELDS],
|
|
63
|
+
["openid2", OPENID2_NS, OPENID2_FIELDS],
|
|
64
|
+
].each do |ver, ns, all_fields|
|
|
65
|
+
all_fields.each do |field|
|
|
66
|
+
test = lambda do
|
|
67
|
+
fields = all_fields.dup
|
|
68
|
+
fields.delete(field)
|
|
69
|
+
msg = mkMsg(ns, fields, [])
|
|
70
|
+
idres = IdResHandler.new(msg, nil)
|
|
71
|
+
assert_protocol_error("Missing required field #{field}") {
|
|
72
|
+
idres.send(:check_for_fields)
|
|
73
|
+
}
|
|
74
|
+
end
|
|
75
|
+
define_method("test_#{ver}_check_missing_#{field}", test)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Test all missing signed for OpenID 1 and 2
|
|
81
|
+
1.times do
|
|
82
|
+
[["openid1", OPENID1_NS, OPENID1_FIELDS, OPENID1_SIGNED],
|
|
83
|
+
["openid1", OPENID11_NS, OPENID1_FIELDS, OPENID1_SIGNED],
|
|
84
|
+
["openid2", OPENID2_NS, OPENID2_FIELDS, OPENID2_SIGNED],
|
|
85
|
+
].each do |ver, ns, all_fields, signed_fields|
|
|
86
|
+
signed_fields.each do |signed_field|
|
|
87
|
+
test = lambda do
|
|
88
|
+
fields = signed_fields.dup
|
|
89
|
+
fields.delete(signed_field)
|
|
90
|
+
msg = mkMsg(ns, all_fields, fields)
|
|
91
|
+
# Make sure the signed field is actually in the request
|
|
92
|
+
msg.set_arg(OPENID_NS, signed_field, "don't care")
|
|
93
|
+
idres = IdResHandler.new(msg, nil)
|
|
94
|
+
assert_protocol_error("#{signed_field.inspect} not signed") {
|
|
95
|
+
idres.send(:check_for_fields)
|
|
96
|
+
}
|
|
97
|
+
end
|
|
98
|
+
define_method("test_#{ver}_check_missing_signed_#{signed_field}", test)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def test_112
|
|
104
|
+
args = {'openid.assoc_handle' => 'fa1f5ff0-cde4-11dc-a183-3714bfd55ca8',
|
|
105
|
+
'openid.claimed_id' => 'http://binkley.lan/user/test01',
|
|
106
|
+
'openid.identity' => 'http://test01.binkley.lan/',
|
|
107
|
+
'openid.mode' => 'id_res',
|
|
108
|
+
'openid.ns' => 'http://specs.openid.net/auth/2.0',
|
|
109
|
+
'openid.ns.pape' => 'http://specs.openid.net/extensions/pape/1.0',
|
|
110
|
+
'openid.op_endpoint' => 'http://binkley.lan/server',
|
|
111
|
+
'openid.pape.auth_policies' => 'none',
|
|
112
|
+
'openid.pape.auth_time' => '2008-01-28T20:42:36Z',
|
|
113
|
+
'openid.pape.nist_auth_level' => '0',
|
|
114
|
+
'openid.response_nonce' => '2008-01-28T21:07:04Z99Q=',
|
|
115
|
+
'openid.return_to' => 'http://binkley.lan:8001/process?janrain_nonce=2008-01-28T21%3A07%3A02Z0tMIKx',
|
|
116
|
+
'openid.sig' => 'YJlWH4U6SroB1HoPkmEKx9AyGGg=',
|
|
117
|
+
'openid.signed' => 'assoc_handle,identity,response_nonce,return_to,claimed_id,op_endpoint,pape.auth_time,ns.pape,pape.nist_auth_level,pape.auth_policies'
|
|
118
|
+
}
|
|
119
|
+
assert_equal(args['openid.ns'], OPENID2_NS)
|
|
120
|
+
incoming = Message.from_post_args(args)
|
|
121
|
+
assert(incoming.is_openid2)
|
|
122
|
+
idres = IdResHandler.new(incoming, nil)
|
|
123
|
+
car = idres.send(:create_check_auth_request)
|
|
124
|
+
expected_args = args.dup
|
|
125
|
+
expected_args['openid.mode'] = 'check_authentication'
|
|
126
|
+
expected = Message.from_post_args(expected_args)
|
|
127
|
+
assert(expected.is_openid2)
|
|
128
|
+
assert_equal(expected, car)
|
|
129
|
+
assert_equal(expected_args, car.to_post_args)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def test_no_signed_list
|
|
133
|
+
msg = Message.new(OPENID2_NS)
|
|
134
|
+
idres = IdResHandler.new(msg, nil)
|
|
135
|
+
assert_protocol_error("Response missing signed") {
|
|
136
|
+
idres.send(:signed_list)
|
|
137
|
+
}
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def test_success_openid1
|
|
141
|
+
msg = mkMsg(OPENID1_NS, OPENID1_FIELDS, OPENID1_SIGNED)
|
|
142
|
+
idres = IdResHandler.new(msg, nil)
|
|
143
|
+
assert_nothing_raised {
|
|
144
|
+
idres.send(:check_for_fields)
|
|
145
|
+
}
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def test_success_openid1_1
|
|
149
|
+
msg = mkMsg(OPENID11_NS, OPENID1_FIELDS, OPENID1_SIGNED)
|
|
150
|
+
idres = IdResHandler.new(msg, nil)
|
|
151
|
+
assert_nothing_raised {
|
|
152
|
+
idres.send(:check_for_fields)
|
|
153
|
+
}
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
class ReturnToArgsTest < Test::Unit::TestCase
|
|
158
|
+
include OpenID::ProtocolErrorMixin
|
|
159
|
+
|
|
160
|
+
def check_return_to_args(query)
|
|
161
|
+
idres = IdResHandler.new(Message.from_post_args(query), nil)
|
|
162
|
+
class << idres
|
|
163
|
+
def verify_return_to_base(unused)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
idres.send(:verify_return_to)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def assert_bad_args(msg, query)
|
|
170
|
+
assert_protocol_error(msg) {
|
|
171
|
+
check_return_to_args(query)
|
|
172
|
+
}
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def test_return_to_args_okay
|
|
176
|
+
assert_nothing_raised {
|
|
177
|
+
check_return_to_args({
|
|
178
|
+
'openid.mode' => 'id_res',
|
|
179
|
+
'openid.return_to' => 'http://example.com/?foo=bar',
|
|
180
|
+
'foo' => 'bar',
|
|
181
|
+
})
|
|
182
|
+
}
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def test_unexpected_arg_okay
|
|
186
|
+
assert_bad_args("Unexpected parameter", {
|
|
187
|
+
'openid.mode' => 'id_res',
|
|
188
|
+
'openid.return_to' => 'http://example.com/',
|
|
189
|
+
'foo' => 'bar',
|
|
190
|
+
})
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def test_return_to_mismatch
|
|
194
|
+
assert_bad_args('Message missing ret', {
|
|
195
|
+
'openid.mode' => 'id_res',
|
|
196
|
+
'openid.return_to' => 'http://example.com/?foo=bar',
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
assert_bad_args("Parameter 'foo' val", {
|
|
200
|
+
'openid.mode' => 'id_res',
|
|
201
|
+
'openid.return_to' => 'http://example.com/?foo=bar',
|
|
202
|
+
'foo' => 'foos',
|
|
203
|
+
})
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
class ReturnToVerifyTest < Test::Unit::TestCase
|
|
208
|
+
def test_bad_return_to
|
|
209
|
+
return_to = "http://some.url/path?foo=bar"
|
|
210
|
+
|
|
211
|
+
m = Message.new(OPENID1_NS)
|
|
212
|
+
m.set_arg(OPENID_NS, 'mode', 'cancel')
|
|
213
|
+
m.set_arg(BARE_NS, 'foo', 'bar')
|
|
214
|
+
|
|
215
|
+
# Scheme, authority, and path differences are checked by
|
|
216
|
+
# IdResHandler.verify_return_to_base. Query args checked by
|
|
217
|
+
# IdResHandler.verify_return_to_args.
|
|
218
|
+
[
|
|
219
|
+
# Scheme only
|
|
220
|
+
"https://some.url/path?foo=bar",
|
|
221
|
+
# Authority only
|
|
222
|
+
"http://some.url.invalid/path?foo=bar",
|
|
223
|
+
# Path only
|
|
224
|
+
"http://some.url/path_extra?foo=bar",
|
|
225
|
+
# Query args differ
|
|
226
|
+
"http://some.url/path?foo=bar2",
|
|
227
|
+
"http://some.url/path?foo2=bar",
|
|
228
|
+
].each do |bad|
|
|
229
|
+
m.set_arg(OPENID_NS, 'return_to', bad)
|
|
230
|
+
idres = IdResHandler.new(m, return_to)
|
|
231
|
+
assert_raises(ProtocolError) {
|
|
232
|
+
idres.send(:verify_return_to)
|
|
233
|
+
}
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def test_good_return_to
|
|
238
|
+
base = 'http://example.janrain.com/path'
|
|
239
|
+
[ [base, {}],
|
|
240
|
+
[base + "?another=arg", {'another' => 'arg'}],
|
|
241
|
+
[base + "?another=arg#frag", {'another' => 'arg'}],
|
|
242
|
+
['HTTP'+base[4..-1], {}],
|
|
243
|
+
[base.sub('com', 'COM'), {}],
|
|
244
|
+
['http://example.janrain.com:80/path', {}],
|
|
245
|
+
['http://example.janrain.com/p%61th', {}],
|
|
246
|
+
['http://example.janrain.com/./path',{}],
|
|
247
|
+
].each do |return_to, args|
|
|
248
|
+
args['openid.return_to'] = return_to
|
|
249
|
+
msg = Message.from_post_args(args)
|
|
250
|
+
idres = IdResHandler.new(msg, base)
|
|
251
|
+
assert_nothing_raised {
|
|
252
|
+
idres.send(:verify_return_to)
|
|
253
|
+
}
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
class DummyEndpoint
|
|
259
|
+
attr_accessor :server_url
|
|
260
|
+
def initialize(server_url)
|
|
261
|
+
@server_url = server_url
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
class CheckSigTest < Test::Unit::TestCase
|
|
266
|
+
include ProtocolErrorMixin
|
|
267
|
+
include TestUtil
|
|
268
|
+
|
|
269
|
+
def setup
|
|
270
|
+
@assoc = GoodAssoc.new('{not_dumb}')
|
|
271
|
+
@store = Store::Memory.new
|
|
272
|
+
@server_url = 'http://server.url/'
|
|
273
|
+
@endpoint = DummyEndpoint.new(@server_url)
|
|
274
|
+
@store.store_association(@server_url, @assoc)
|
|
275
|
+
|
|
276
|
+
@message = Message.from_post_args({
|
|
277
|
+
'openid.mode' => 'id_res',
|
|
278
|
+
'openid.identity' => '=example',
|
|
279
|
+
'openid.sig' => GOODSIG,
|
|
280
|
+
'openid.assoc_handle' => @assoc.handle,
|
|
281
|
+
'openid.signed' => 'mode,identity,assoc_handle,signed',
|
|
282
|
+
'frobboz' => 'banzit',
|
|
283
|
+
})
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def call_idres_method(method_name)
|
|
287
|
+
idres = IdResHandler.new(@message, nil, @store, @endpoint)
|
|
288
|
+
idres.extend(InstanceDefExtension)
|
|
289
|
+
yield idres
|
|
290
|
+
idres.send(method_name)
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
def call_check_sig(&proc)
|
|
294
|
+
call_idres_method(:check_signature, &proc)
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
def no_check_auth(idres)
|
|
298
|
+
idres.instance_def(:check_auth) { fail "Called check_auth" }
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
def test_sign_good
|
|
302
|
+
assert_nothing_raised {
|
|
303
|
+
call_check_sig(&method(:no_check_auth))
|
|
304
|
+
}
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
def test_bad_sig
|
|
308
|
+
@message.set_arg(OPENID_NS, 'sig', 'bad sig!')
|
|
309
|
+
assert_protocol_error('Bad signature') {
|
|
310
|
+
call_check_sig(&method(:no_check_auth))
|
|
311
|
+
}
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
def test_check_auth_ok
|
|
315
|
+
@message.set_arg(OPENID_NS, 'assoc_handle', 'dumb-handle')
|
|
316
|
+
check_auth_called = false
|
|
317
|
+
call_check_sig do |idres|
|
|
318
|
+
idres.instance_def(:check_auth) do
|
|
319
|
+
check_auth_called = true
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
assert(check_auth_called)
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
def test_check_auth_ok_no_store
|
|
326
|
+
@store = nil
|
|
327
|
+
check_auth_called = false
|
|
328
|
+
call_check_sig do |idres|
|
|
329
|
+
idres.instance_def(:check_auth) do
|
|
330
|
+
check_auth_called = true
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
assert(check_auth_called)
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
def test_expired_assoc
|
|
337
|
+
@assoc.expires_in = -1
|
|
338
|
+
@store.store_association(@server_url, @assoc)
|
|
339
|
+
assert_protocol_error('Association with') {
|
|
340
|
+
call_check_sig(&method(:no_check_auth))
|
|
341
|
+
}
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
def call_check_auth(&proc)
|
|
345
|
+
assert_log_matches("Using 'check_authentication'") {
|
|
346
|
+
call_idres_method(:check_auth, &proc)
|
|
347
|
+
}
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
def test_check_auth_create_fail
|
|
351
|
+
assert_protocol_error("Could not generate") {
|
|
352
|
+
call_check_auth do |idres|
|
|
353
|
+
idres.instance_def(:create_check_auth_request) do
|
|
354
|
+
raise Message::KeyNotFound, "Testing"
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
}
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
def test_check_auth_okay
|
|
361
|
+
OpenID.extend(OverrideMethodMixin)
|
|
362
|
+
me = self
|
|
363
|
+
send_resp = Proc.new do |req, server_url|
|
|
364
|
+
me.assert_equal(:req, req)
|
|
365
|
+
:expected_response
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
OpenID.with_method_overridden(:make_kv_post, send_resp) do
|
|
369
|
+
final_resp = call_check_auth do |idres|
|
|
370
|
+
idres.instance_def(:create_check_auth_request) {
|
|
371
|
+
:req
|
|
372
|
+
}
|
|
373
|
+
idres.instance_def(:process_check_auth_response) do |resp|
|
|
374
|
+
me.assert_equal(:expected_response, resp)
|
|
375
|
+
end
|
|
376
|
+
end
|
|
377
|
+
end
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
def test_check_auth_process_fail
|
|
381
|
+
OpenID.extend(OverrideMethodMixin)
|
|
382
|
+
me = self
|
|
383
|
+
send_resp = Proc.new do |req, server_url|
|
|
384
|
+
me.assert_equal(:req, req)
|
|
385
|
+
:expected_response
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
OpenID.with_method_overridden(:make_kv_post, send_resp) do
|
|
389
|
+
assert_protocol_error("Testing") do
|
|
390
|
+
final_resp = call_check_auth do |idres|
|
|
391
|
+
idres.instance_def(:create_check_auth_request) { :req }
|
|
392
|
+
idres.instance_def(:process_check_auth_response) do |resp|
|
|
393
|
+
me.assert_equal(:expected_response, resp)
|
|
394
|
+
raise ProtocolError, "Testing"
|
|
395
|
+
end
|
|
396
|
+
end
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
1.times do
|
|
402
|
+
# Fields from the signed list
|
|
403
|
+
['mode', 'identity', 'assoc_handle'
|
|
404
|
+
].each do |field|
|
|
405
|
+
test = lambda do
|
|
406
|
+
@message.del_arg(OPENID_NS, field)
|
|
407
|
+
assert_raises(Message::KeyNotFound) {
|
|
408
|
+
call_idres_method(:create_check_auth_request) {}
|
|
409
|
+
}
|
|
410
|
+
end
|
|
411
|
+
define_method("test_create_check_auth_missing_#{field}", test)
|
|
412
|
+
end
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
def test_create_check_auth_request_success
|
|
416
|
+
ca_msg = call_idres_method(:create_check_auth_request) {}
|
|
417
|
+
expected = @message.copy
|
|
418
|
+
expected.set_arg(OPENID_NS, 'mode', 'check_authentication')
|
|
419
|
+
assert_equal(expected, ca_msg)
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
class CheckAuthResponseTest < Test::Unit::TestCase
|
|
425
|
+
include TestUtil
|
|
426
|
+
include ProtocolErrorMixin
|
|
427
|
+
|
|
428
|
+
def setup
|
|
429
|
+
@message = Message.from_openid_args({
|
|
430
|
+
'is_valid' => 'true',
|
|
431
|
+
})
|
|
432
|
+
@assoc = GoodAssoc.new
|
|
433
|
+
@store = Store::Memory.new
|
|
434
|
+
@server_url = 'http://invalid/'
|
|
435
|
+
@endpoint = DummyEndpoint.new(@server_url)
|
|
436
|
+
@idres = IdResHandler.new(nil, nil, @store, @endpoint)
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
def call_process
|
|
440
|
+
@idres.send(:process_check_auth_response, @message)
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
def test_valid
|
|
444
|
+
assert_log_matches() { call_process }
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
def test_invalid
|
|
448
|
+
for is_valid in ['false', 'monkeys']
|
|
449
|
+
@message.set_arg(OPENID_NS, 'is_valid', 'false')
|
|
450
|
+
assert_protocol_error("Server #{@server_url} responds") {
|
|
451
|
+
assert_log_matches() { call_process }
|
|
452
|
+
}
|
|
453
|
+
end
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
def test_valid_invalidate
|
|
457
|
+
@message.set_arg(OPENID_NS, 'invalidate_handle', 'cheese')
|
|
458
|
+
assert_log_matches("Received 'invalidate_handle'") { call_process }
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
def test_invalid_invalidate
|
|
462
|
+
@message.set_arg(OPENID_NS, 'invalidate_handle', 'cheese')
|
|
463
|
+
for is_valid in ['false', 'monkeys']
|
|
464
|
+
@message.set_arg(OPENID_NS, 'is_valid', 'false')
|
|
465
|
+
assert_protocol_error("Server #{@server_url} responds") {
|
|
466
|
+
assert_log_matches("Received 'invalidate_handle'") {
|
|
467
|
+
call_process
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
end
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
def test_invalidate_no_store
|
|
474
|
+
@idres.instance_variable_set(:@store, nil)
|
|
475
|
+
@message.set_arg(OPENID_NS, 'invalidate_handle', 'cheese')
|
|
476
|
+
assert_log_matches("Received 'invalidate_handle'",
|
|
477
|
+
'Unexpectedly got "invalidate_handle"') {
|
|
478
|
+
call_process
|
|
479
|
+
}
|
|
480
|
+
end
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
class NonceTest < Test::Unit::TestCase
|
|
484
|
+
include TestUtil
|
|
485
|
+
include ProtocolErrorMixin
|
|
486
|
+
|
|
487
|
+
def setup
|
|
488
|
+
@store = Object.new
|
|
489
|
+
class << @store
|
|
490
|
+
attr_accessor :nonces, :succeed
|
|
491
|
+
def use_nonce(server_url, time, extra)
|
|
492
|
+
@nonces << [server_url, time, extra]
|
|
493
|
+
@succeed
|
|
494
|
+
end
|
|
495
|
+
end
|
|
496
|
+
@store.nonces = []
|
|
497
|
+
@nonce = Nonce.mk_nonce
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
def call_check_nonce(post_args, succeed=false)
|
|
501
|
+
response = Message.from_post_args(post_args)
|
|
502
|
+
if !@store.nil?
|
|
503
|
+
@store.succeed = succeed
|
|
504
|
+
end
|
|
505
|
+
idres = IdResHandler.new(response, nil, @store, nil)
|
|
506
|
+
idres.send(:check_nonce)
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
def test_openid1_success
|
|
510
|
+
[{},
|
|
511
|
+
{'openid.ns' => OPENID1_NS},
|
|
512
|
+
{'openid.ns' => OPENID11_NS}
|
|
513
|
+
].each do |args|
|
|
514
|
+
assert_nothing_raised {
|
|
515
|
+
call_check_nonce({'rp_nonce' => @nonce}.merge(args), true)
|
|
516
|
+
}
|
|
517
|
+
end
|
|
518
|
+
end
|
|
519
|
+
|
|
520
|
+
def test_openid1_missing
|
|
521
|
+
[{},
|
|
522
|
+
{'openid.ns' => OPENID1_NS},
|
|
523
|
+
{'openid.ns' => OPENID11_NS}
|
|
524
|
+
].each do |args|
|
|
525
|
+
assert_protocol_error('Nonce missing') { call_check_nonce(args) }
|
|
526
|
+
end
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
def test_openid2_ignore_rp_nonce
|
|
530
|
+
assert_protocol_error('Nonce missing') {
|
|
531
|
+
call_check_nonce({'rp_nonce' => @nonce,
|
|
532
|
+
'openid.ns' => OPENID2_NS})
|
|
533
|
+
}
|
|
534
|
+
end
|
|
535
|
+
|
|
536
|
+
def test_openid2_success
|
|
537
|
+
assert_nothing_raised {
|
|
538
|
+
call_check_nonce({'openid.response_nonce' => @nonce,
|
|
539
|
+
'openid.ns' => OPENID2_NS}, true)
|
|
540
|
+
}
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
def test_openid1_ignore_response_nonce
|
|
544
|
+
[{},
|
|
545
|
+
{'openid.ns' => OPENID1_NS},
|
|
546
|
+
{'openid.ns' => OPENID11_NS}
|
|
547
|
+
].each do |args|
|
|
548
|
+
assert_protocol_error('Nonce missing') {
|
|
549
|
+
call_check_nonce({'openid.response_nonce' => @nonce}.merge(args))
|
|
550
|
+
}
|
|
551
|
+
end
|
|
552
|
+
end
|
|
553
|
+
|
|
554
|
+
def test_no_store
|
|
555
|
+
@store = nil
|
|
556
|
+
assert_nothing_raised {
|
|
557
|
+
call_check_nonce({'rp_nonce' => @nonce})
|
|
558
|
+
}
|
|
559
|
+
end
|
|
560
|
+
|
|
561
|
+
def test_already_used
|
|
562
|
+
assert_protocol_error('Nonce already used') {
|
|
563
|
+
call_check_nonce({'rp_nonce' => @nonce}, false)
|
|
564
|
+
}
|
|
565
|
+
end
|
|
566
|
+
|
|
567
|
+
def test_malformed_nonce
|
|
568
|
+
assert_protocol_error('Malformed nonce') {
|
|
569
|
+
call_check_nonce({'rp_nonce' => 'whee!'})
|
|
570
|
+
}
|
|
571
|
+
end
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
class DiscoveryVerificationTest < Test::Unit::TestCase
|
|
575
|
+
include ProtocolErrorMixin
|
|
576
|
+
include TestUtil
|
|
577
|
+
|
|
578
|
+
def setup
|
|
579
|
+
@endpoint = OpenIDServiceEndpoint.new
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
def call_verify(msg_args)
|
|
583
|
+
call_verify_modify(msg_args){}
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
def call_verify_modify(msg_args)
|
|
587
|
+
msg = Message.from_openid_args(msg_args)
|
|
588
|
+
idres = IdResHandler.new(msg, nil, nil, @endpoint)
|
|
589
|
+
idres.extend(InstanceDefExtension)
|
|
590
|
+
yield idres
|
|
591
|
+
idres.send(:verify_discovery_results)
|
|
592
|
+
idres.instance_variable_get(:@endpoint)
|
|
593
|
+
end
|
|
594
|
+
|
|
595
|
+
def assert_verify_protocol_error(error_prefix, openid_args)
|
|
596
|
+
assert_protocol_error(error_prefix) {call_verify(openid_args)}
|
|
597
|
+
end
|
|
598
|
+
|
|
599
|
+
def test_openid1_no_local_id
|
|
600
|
+
@endpoint.claimed_id = 'http://invalid/'
|
|
601
|
+
assert_verify_protocol_error("Missing required field: "\
|
|
602
|
+
"<#{OPENID1_NS}>identity", {})
|
|
603
|
+
end
|
|
604
|
+
|
|
605
|
+
def test_openid1_no_endpoint
|
|
606
|
+
@endpoint = nil
|
|
607
|
+
assert_raises(ProtocolError) {
|
|
608
|
+
call_verify({'identity' => 'snakes on a plane'})
|
|
609
|
+
}
|
|
610
|
+
end
|
|
611
|
+
|
|
612
|
+
def test_openid1_fallback_1_0
|
|
613
|
+
[OPENID1_NS, OPENID11_NS].each do |openid1_ns|
|
|
614
|
+
claimed_id = 'http://claimed.id/'
|
|
615
|
+
@endpoint = nil
|
|
616
|
+
resp_mesg = Message.from_openid_args({
|
|
617
|
+
'ns' => openid1_ns,
|
|
618
|
+
'identity' => claimed_id,
|
|
619
|
+
})
|
|
620
|
+
|
|
621
|
+
# Pass the OpenID 1 claimed_id this way since we're
|
|
622
|
+
# passing None for the endpoint.
|
|
623
|
+
resp_mesg.set_arg(BARE_NS, 'openid1_claimed_id', claimed_id)
|
|
624
|
+
|
|
625
|
+
# We expect the OpenID 1 discovery verification to try
|
|
626
|
+
# matching the discovered endpoint against the 1.1 type
|
|
627
|
+
# and fall back to 1.0.
|
|
628
|
+
expected_endpoint = OpenIDServiceEndpoint.new
|
|
629
|
+
expected_endpoint.type_uris = [OPENID_1_0_TYPE]
|
|
630
|
+
expected_endpoint.local_id = nil
|
|
631
|
+
expected_endpoint.claimed_id = claimed_id
|
|
632
|
+
|
|
633
|
+
hacked_discover = Proc.new {
|
|
634
|
+
|_claimed_id| ['unused', [expected_endpoint]]
|
|
635
|
+
}
|
|
636
|
+
idres = IdResHandler.new(resp_mesg, nil, nil, @endpoint)
|
|
637
|
+
assert_log_matches('Performing discovery') {
|
|
638
|
+
OpenID.with_method_overridden(:discover, hacked_discover) {
|
|
639
|
+
idres.send(:verify_discovery_results)
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
actual_endpoint = idres.instance_variable_get(:@endpoint)
|
|
643
|
+
assert_equal(actual_endpoint, expected_endpoint)
|
|
644
|
+
end
|
|
645
|
+
end
|
|
646
|
+
|
|
647
|
+
def test_openid2_no_op_endpoint
|
|
648
|
+
assert_protocol_error("Missing required field: "\
|
|
649
|
+
"<#{OPENID2_NS}>op_endpoint") {
|
|
650
|
+
call_verify({'ns'=>OPENID2_NS})
|
|
651
|
+
}
|
|
652
|
+
end
|
|
653
|
+
|
|
654
|
+
def test_openid2_local_id_no_claimed
|
|
655
|
+
assert_verify_protocol_error('openid.identity is present without',
|
|
656
|
+
{'ns' => OPENID2_NS,
|
|
657
|
+
'op_endpoint' => 'Phone Home',
|
|
658
|
+
'identity' => 'Jorge Lius Borges'})
|
|
659
|
+
end
|
|
660
|
+
|
|
661
|
+
def test_openid2_no_local_id_claimed
|
|
662
|
+
assert_log_matches() {
|
|
663
|
+
assert_protocol_error('openid.claimed_id is present without') {
|
|
664
|
+
call_verify({'ns' => OPENID2_NS,
|
|
665
|
+
'op_endpoint' => 'Phone Home',
|
|
666
|
+
'claimed_id' => 'Manuel Noriega'})
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
end
|
|
670
|
+
|
|
671
|
+
def test_openid2_no_identifiers
|
|
672
|
+
op_endpoint = 'Phone Home'
|
|
673
|
+
result_endpoint = assert_log_matches() {
|
|
674
|
+
call_verify({'ns' => OPENID2_NS,
|
|
675
|
+
'op_endpoint' => op_endpoint})
|
|
676
|
+
}
|
|
677
|
+
assert(result_endpoint.is_op_identifier)
|
|
678
|
+
assert_equal(op_endpoint, result_endpoint.server_url)
|
|
679
|
+
assert(result_endpoint.claimed_id.nil?)
|
|
680
|
+
end
|
|
681
|
+
|
|
682
|
+
def test_openid2_no_endpoint_does_disco
|
|
683
|
+
endpoint = OpenIDServiceEndpoint.new
|
|
684
|
+
endpoint.claimed_id = 'monkeysoft'
|
|
685
|
+
@endpoint = nil
|
|
686
|
+
result = assert_log_matches('No pre-discovered') {
|
|
687
|
+
call_verify_modify({'ns' => OPENID2_NS,
|
|
688
|
+
'identity' => 'sour grapes',
|
|
689
|
+
'claimed_id' => 'monkeysoft',
|
|
690
|
+
'op_endpoint' => 'Phone Home'}) do |idres|
|
|
691
|
+
idres.instance_def(:discover_and_verify) do |claimed_id, endpoints|
|
|
692
|
+
@endpoint = endpoint
|
|
693
|
+
end
|
|
694
|
+
end
|
|
695
|
+
}
|
|
696
|
+
assert_equal(endpoint, result)
|
|
697
|
+
end
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
def test_openid2_mismatched_does_disco
|
|
701
|
+
@endpoint.claimed_id = 'nothing special, but different'
|
|
702
|
+
@endpoint.local_id = 'green cheese'
|
|
703
|
+
|
|
704
|
+
endpoint = OpenIDServiceEndpoint.new
|
|
705
|
+
endpoint.claimed_id = 'monkeysoft'
|
|
706
|
+
|
|
707
|
+
result = assert_log_matches('Error attempting to use stored',
|
|
708
|
+
'Attempting discovery') {
|
|
709
|
+
call_verify_modify({'ns' => OPENID2_NS,
|
|
710
|
+
'identity' => 'sour grapes',
|
|
711
|
+
'claimed_id' => 'monkeysoft',
|
|
712
|
+
'op_endpoint' => 'Green Cheese'}) do |idres|
|
|
713
|
+
idres.instance_def(:discover_and_verify) do |claimed_id, endpoints|
|
|
714
|
+
@endpoint = endpoint
|
|
715
|
+
end
|
|
716
|
+
end
|
|
717
|
+
}
|
|
718
|
+
assert(endpoint.equal?(result))
|
|
719
|
+
end
|
|
720
|
+
|
|
721
|
+
def test_verify_discovery_single_claimed_id_mismatch
|
|
722
|
+
idres = IdResHandler.new(nil, nil)
|
|
723
|
+
@endpoint.local_id = 'my identity'
|
|
724
|
+
@endpoint.claimed_id = 'http://i-am-sam/'
|
|
725
|
+
@endpoint.server_url = 'Phone Home'
|
|
726
|
+
@endpoint.type_uris = [OPENID_2_0_TYPE]
|
|
727
|
+
|
|
728
|
+
to_match = @endpoint.dup
|
|
729
|
+
to_match.claimed_id = 'http://something.else/'
|
|
730
|
+
|
|
731
|
+
e = assert_raises(ProtocolError) {
|
|
732
|
+
idres.send(:verify_discovery_single, @endpoint, to_match)
|
|
733
|
+
}
|
|
734
|
+
assert(e.to_s =~ /different subjects/)
|
|
735
|
+
end
|
|
736
|
+
|
|
737
|
+
def test_openid1_1_verify_discovery_single_no_server_url
|
|
738
|
+
idres = IdResHandler.new(nil, nil)
|
|
739
|
+
@endpoint.local_id = 'my identity'
|
|
740
|
+
@endpoint.claimed_id = 'http://i-am-sam/'
|
|
741
|
+
@endpoint.server_url = 'Phone Home'
|
|
742
|
+
@endpoint.type_uris = [OPENID_1_1_TYPE]
|
|
743
|
+
|
|
744
|
+
to_match = @endpoint.dup
|
|
745
|
+
to_match.claimed_id = 'http://i-am-sam/'
|
|
746
|
+
to_match.type_uris = [OPENID_1_1_TYPE]
|
|
747
|
+
to_match.server_url = nil
|
|
748
|
+
|
|
749
|
+
idres.send(:verify_discovery_single, @endpoint, to_match)
|
|
750
|
+
end
|
|
751
|
+
|
|
752
|
+
def test_openid2_use_pre_discovered
|
|
753
|
+
@endpoint.local_id = 'my identity'
|
|
754
|
+
@endpoint.claimed_id = 'http://i-am-sam/'
|
|
755
|
+
@endpoint.server_url = 'Phone Home'
|
|
756
|
+
@endpoint.type_uris = [OPENID_2_0_TYPE]
|
|
757
|
+
|
|
758
|
+
result = assert_log_matches() {
|
|
759
|
+
call_verify({'ns' => OPENID2_NS,
|
|
760
|
+
'identity' => @endpoint.local_id,
|
|
761
|
+
'claimed_id' => @endpoint.claimed_id,
|
|
762
|
+
'op_endpoint' => @endpoint.server_url
|
|
763
|
+
})
|
|
764
|
+
}
|
|
765
|
+
assert(result.equal?(@endpoint))
|
|
766
|
+
end
|
|
767
|
+
|
|
768
|
+
def test_openid2_use_pre_discovered_wrong_type
|
|
769
|
+
text = "verify failed"
|
|
770
|
+
me = self
|
|
771
|
+
|
|
772
|
+
@endpoint.local_id = 'my identity'
|
|
773
|
+
@endpoint.claimed_id = 'i am sam'
|
|
774
|
+
@endpoint.server_url = 'Phone Home'
|
|
775
|
+
@endpoint.type_uris = [OPENID_1_1_TYPE]
|
|
776
|
+
endpoint = @endpoint
|
|
777
|
+
|
|
778
|
+
msg = Message.from_openid_args({'ns' => OPENID2_NS,
|
|
779
|
+
'identity' => @endpoint.local_id,
|
|
780
|
+
'claimed_id' =>
|
|
781
|
+
@endpoint.claimed_id,
|
|
782
|
+
'op_endpoint' =>
|
|
783
|
+
@endpoint.server_url})
|
|
784
|
+
|
|
785
|
+
idres = IdResHandler.new(msg, nil, nil, @endpoint)
|
|
786
|
+
idres.extend(InstanceDefExtension)
|
|
787
|
+
idres.instance_def(:discover_and_verify) { |claimed_id, to_match|
|
|
788
|
+
me.assert_equal(endpoint.claimed_id, to_match[0].claimed_id)
|
|
789
|
+
me.assert_equal(claimed_id, endpoint.claimed_id)
|
|
790
|
+
raise ProtocolError, text
|
|
791
|
+
}
|
|
792
|
+
assert_log_matches('Error attempting to use stored',
|
|
793
|
+
'Attempting discovery') {
|
|
794
|
+
assert_protocol_error(text) {
|
|
795
|
+
idres.send(:verify_discovery_results)
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
end
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
def test_openid1_use_pre_discovered
|
|
802
|
+
@endpoint.local_id = 'my identity'
|
|
803
|
+
@endpoint.claimed_id = 'http://i-am-sam/'
|
|
804
|
+
@endpoint.server_url = 'Phone Home'
|
|
805
|
+
@endpoint.type_uris = [OPENID_1_1_TYPE]
|
|
806
|
+
|
|
807
|
+
result = assert_log_matches() {
|
|
808
|
+
call_verify({'ns' => OPENID1_NS,
|
|
809
|
+
'identity' => @endpoint.local_id})
|
|
810
|
+
}
|
|
811
|
+
assert(result.equal?(@endpoint))
|
|
812
|
+
end
|
|
813
|
+
|
|
814
|
+
|
|
815
|
+
def test_openid1_use_pre_discovered_wrong_type
|
|
816
|
+
verified_error = Class.new(Exception)
|
|
817
|
+
|
|
818
|
+
@endpoint.local_id = 'my identity'
|
|
819
|
+
@endpoint.claimed_id = 'i am sam'
|
|
820
|
+
@endpoint.server_url = 'Phone Home'
|
|
821
|
+
@endpoint.type_uris = [OPENID_2_0_TYPE]
|
|
822
|
+
|
|
823
|
+
assert_log_matches('Error attempting to use stored',
|
|
824
|
+
'Attempting discovery') {
|
|
825
|
+
assert_raises(verified_error) {
|
|
826
|
+
call_verify_modify({'ns' => OPENID1_NS,
|
|
827
|
+
'identity' => @endpoint.local_id}) { |idres|
|
|
828
|
+
idres.instance_def(:discover_and_verify) do |claimed_id, endpoints|
|
|
829
|
+
raise verified_error
|
|
830
|
+
end
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
end
|
|
835
|
+
|
|
836
|
+
def test_openid2_fragment
|
|
837
|
+
claimed_id = "http://unittest.invalid/"
|
|
838
|
+
claimed_id_frag = claimed_id + "#fragment"
|
|
839
|
+
|
|
840
|
+
@endpoint.local_id = 'my identity'
|
|
841
|
+
@endpoint.claimed_id = claimed_id
|
|
842
|
+
@endpoint.server_url = 'Phone Home'
|
|
843
|
+
@endpoint.type_uris = [OPENID_2_0_TYPE]
|
|
844
|
+
|
|
845
|
+
result = assert_log_matches() {
|
|
846
|
+
call_verify({'ns' => OPENID2_NS,
|
|
847
|
+
'identity' => @endpoint.local_id,
|
|
848
|
+
'claimed_id' => claimed_id_frag,
|
|
849
|
+
'op_endpoint' => @endpoint.server_url})
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
[:local_id, :server_url, :type_uris].each do |sym|
|
|
853
|
+
assert_equal(@endpoint.send(sym), result.send(sym))
|
|
854
|
+
end
|
|
855
|
+
assert_equal(claimed_id_frag, result.claimed_id)
|
|
856
|
+
end
|
|
857
|
+
|
|
858
|
+
def test_endpoint_without_local_id
|
|
859
|
+
# An endpoint like this with no local_id is generated as a result of
|
|
860
|
+
# e.g. Yadis discovery with no LocalID tag.
|
|
861
|
+
@endpoint.server_url = "http://localhost:8000/openidserver"
|
|
862
|
+
@endpoint.claimed_id = "http://localhost:8000/id/id-jo"
|
|
863
|
+
|
|
864
|
+
to_match = OpenIDServiceEndpoint.new
|
|
865
|
+
to_match.server_url = "http://localhost:8000/openidserver"
|
|
866
|
+
to_match.claimed_id = "http://localhost:8000/id/id-jo"
|
|
867
|
+
to_match.local_id = "http://localhost:8000/id/id-jo"
|
|
868
|
+
|
|
869
|
+
idres = IdResHandler.new(nil, nil)
|
|
870
|
+
assert_log_matches() {
|
|
871
|
+
result = idres.send(:verify_discovery_single, @endpoint, to_match)
|
|
872
|
+
}
|
|
873
|
+
end
|
|
874
|
+
end
|
|
875
|
+
|
|
876
|
+
class IdResTopLevelTest < Test::Unit::TestCase
|
|
877
|
+
def test_id_res
|
|
878
|
+
endpoint = OpenIDServiceEndpoint.new
|
|
879
|
+
endpoint.server_url = 'http://invalid/server'
|
|
880
|
+
endpoint.claimed_id = 'http://my.url/'
|
|
881
|
+
endpoint.local_id = 'http://invalid/username'
|
|
882
|
+
endpoint.type_uris = [OPENID_2_0_TYPE]
|
|
883
|
+
|
|
884
|
+
assoc = GoodAssoc.new
|
|
885
|
+
store = Store::Memory.new
|
|
886
|
+
store.store_association(endpoint.server_url, assoc)
|
|
887
|
+
|
|
888
|
+
signed_fields =
|
|
889
|
+
[
|
|
890
|
+
'response_nonce',
|
|
891
|
+
'op_endpoint',
|
|
892
|
+
'assoc_handle',
|
|
893
|
+
'identity',
|
|
894
|
+
'claimed_id',
|
|
895
|
+
'ns',
|
|
896
|
+
'return_to',
|
|
897
|
+
]
|
|
898
|
+
|
|
899
|
+
return_to = 'http://return.to/'
|
|
900
|
+
args = {
|
|
901
|
+
'ns' => OPENID2_NS,
|
|
902
|
+
'return_to' => return_to,
|
|
903
|
+
'claimed_id' => endpoint.claimed_id,
|
|
904
|
+
'identity' => endpoint.local_id,
|
|
905
|
+
'assoc_handle' => assoc.handle,
|
|
906
|
+
'op_endpoint' => endpoint.server_url,
|
|
907
|
+
'response_nonce' => Nonce.mk_nonce,
|
|
908
|
+
'signed' => signed_fields.join(','),
|
|
909
|
+
'sig' => GOODSIG,
|
|
910
|
+
}
|
|
911
|
+
msg = Message.from_openid_args(args)
|
|
912
|
+
idres = OpenID::Consumer::IdResHandler.new(msg, return_to,
|
|
913
|
+
store, endpoint)
|
|
914
|
+
assert_equal(idres.signed_fields,
|
|
915
|
+
signed_fields.map {|f|'openid.' + f})
|
|
916
|
+
end
|
|
917
|
+
end
|
|
918
|
+
|
|
919
|
+
|
|
920
|
+
class DiscoverAndVerifyTest < Test::Unit::TestCase
|
|
921
|
+
include ProtocolErrorMixin
|
|
922
|
+
include TestUtil
|
|
923
|
+
|
|
924
|
+
def test_no_services
|
|
925
|
+
me = self
|
|
926
|
+
disco = Proc.new do |e|
|
|
927
|
+
me.assert_equal(e, :sentinel)
|
|
928
|
+
[:undefined, []]
|
|
929
|
+
end
|
|
930
|
+
endpoint = OpenIDServiceEndpoint.new
|
|
931
|
+
endpoint.claimed_id = :sentinel
|
|
932
|
+
idres = IdResHandler.new(nil, nil)
|
|
933
|
+
assert_log_matches('Performing discovery on') do
|
|
934
|
+
assert_protocol_error('No OpenID information found') do
|
|
935
|
+
OpenID.with_method_overridden(:discover, disco) do
|
|
936
|
+
idres.send(:discover_and_verify, :sentinel, [endpoint])
|
|
937
|
+
end
|
|
938
|
+
end
|
|
939
|
+
end
|
|
940
|
+
end
|
|
941
|
+
end
|
|
942
|
+
|
|
943
|
+
class VerifyDiscoveredServicesTest < Test::Unit::TestCase
|
|
944
|
+
include ProtocolErrorMixin
|
|
945
|
+
include TestUtil
|
|
946
|
+
|
|
947
|
+
def test_no_services
|
|
948
|
+
endpoint = OpenIDServiceEndpoint.new
|
|
949
|
+
endpoint.claimed_id = :sentinel
|
|
950
|
+
idres = IdResHandler.new(nil, nil)
|
|
951
|
+
assert_log_matches('Discovery verification failure') do
|
|
952
|
+
assert_protocol_error('No matching endpoint') do
|
|
953
|
+
idres.send(:verify_discovered_services,
|
|
954
|
+
'http://bogus.id/', [], [endpoint])
|
|
955
|
+
end
|
|
956
|
+
end
|
|
957
|
+
end
|
|
958
|
+
end
|
|
959
|
+
end
|
|
960
|
+
end
|
|
961
|
+
end
|