ruby-saml 0.8.18 → 0.9
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +1 -6
- data/Gemfile +2 -12
- data/README.md +363 -35
- data/Rakefile +14 -0
- data/changelog.md +22 -9
- data/lib/onelogin/ruby-saml/attribute_service.rb +34 -0
- data/lib/onelogin/ruby-saml/attributes.rb +26 -64
- data/lib/onelogin/ruby-saml/authrequest.rb +47 -93
- data/lib/onelogin/ruby-saml/idp_metadata_parser.rb +87 -0
- data/lib/onelogin/ruby-saml/logoutrequest.rb +36 -100
- data/lib/onelogin/ruby-saml/logoutresponse.rb +25 -35
- data/lib/onelogin/ruby-saml/metadata.rb +46 -16
- data/lib/onelogin/ruby-saml/response.rb +63 -373
- data/lib/onelogin/ruby-saml/saml_message.rb +78 -0
- data/lib/onelogin/ruby-saml/settings.rb +54 -122
- data/lib/onelogin/ruby-saml/slo_logoutrequest.rb +25 -71
- data/lib/onelogin/ruby-saml/slo_logoutresponse.rb +37 -102
- data/lib/onelogin/ruby-saml/utils.rb +32 -199
- data/lib/onelogin/ruby-saml/version.rb +1 -1
- data/lib/ruby-saml.rb +5 -2
- data/lib/schemas/{saml20assertion_schema.xsd → saml-schema-assertion-2.0.xsd} +283 -283
- data/lib/schemas/saml-schema-authn-context-2.0.xsd +23 -0
- data/lib/schemas/saml-schema-authn-context-types-2.0.xsd +821 -0
- data/lib/schemas/saml-schema-metadata-2.0.xsd +339 -0
- data/lib/schemas/{saml20protocol_schema.xsd → saml-schema-protocol-2.0.xsd} +302 -302
- data/lib/schemas/sstc-metadata-attr.xsd +35 -0
- data/lib/schemas/sstc-saml-attribute-ext.xsd +25 -0
- data/lib/schemas/sstc-saml-metadata-algsupport-v1.0.xsd +41 -0
- data/lib/schemas/sstc-saml-metadata-ui-v1.0.xsd +89 -0
- data/lib/schemas/{xenc_schema.xsd → xenc-schema.xsd} +1 -11
- data/lib/schemas/xml.xsd +287 -0
- data/lib/schemas/{xmldsig_schema.xsd → xmldsig-core-schema.xsd} +0 -9
- data/lib/xml_security.rb +83 -235
- data/ruby-saml.gemspec +1 -0
- data/test/idp_metadata_parser_test.rb +54 -0
- data/test/logoutrequest_test.rb +68 -155
- data/test/logoutresponse_test.rb +43 -32
- data/test/metadata_test.rb +87 -0
- data/test/request_test.rb +102 -99
- data/test/response_test.rb +181 -495
- data/test/responses/idp_descriptor.xml +3 -0
- data/test/responses/logoutresponse_fixtures.rb +7 -8
- data/test/responses/response_no_cert_and_encrypted_attrs.xml +29 -0
- data/test/responses/response_with_multiple_attribute_values.xml +1 -1
- data/test/responses/slo_request.xml +4 -0
- data/test/settings_test.rb +25 -112
- data/test/slo_logoutrequest_test.rb +40 -50
- data/test/slo_logoutresponse_test.rb +86 -185
- data/test/test_helper.rb +27 -102
- data/test/xml_security_test.rb +114 -337
- metadata +30 -81
- data/lib/onelogin/ruby-saml/setting_error.rb +0 -6
- data/test/certificates/certificate.der +0 -0
- data/test/certificates/formatted_certificate +0 -14
- data/test/certificates/formatted_chained_certificate +0 -42
- data/test/certificates/formatted_private_key +0 -12
- data/test/certificates/formatted_rsa_private_key +0 -12
- data/test/certificates/invalid_certificate1 +0 -1
- data/test/certificates/invalid_certificate2 +0 -1
- data/test/certificates/invalid_certificate3 +0 -12
- data/test/certificates/invalid_chained_certificate1 +0 -1
- data/test/certificates/invalid_private_key1 +0 -1
- data/test/certificates/invalid_private_key2 +0 -1
- data/test/certificates/invalid_private_key3 +0 -10
- data/test/certificates/invalid_rsa_private_key1 +0 -1
- data/test/certificates/invalid_rsa_private_key2 +0 -1
- data/test/certificates/invalid_rsa_private_key3 +0 -10
- data/test/certificates/ruby-saml-2.crt +0 -15
- data/test/requests/logoutrequest_fixtures.rb +0 -47
- data/test/responses/encrypted_new_attack.xml.base64 +0 -1
- data/test/responses/invalids/invalid_issuer_assertion.xml.base64 +0 -1
- data/test/responses/invalids/invalid_issuer_message.xml.base64 +0 -1
- data/test/responses/invalids/multiple_signed.xml.base64 +0 -1
- data/test/responses/invalids/no_signature.xml.base64 +0 -1
- data/test/responses/invalids/response_with_concealed_signed_assertion.xml +0 -51
- data/test/responses/invalids/response_with_doubled_signed_assertion.xml +0 -49
- data/test/responses/invalids/signature_wrapping_attack.xml.base64 +0 -1
- data/test/responses/response_node_text_attack.xml.base64 +0 -1
- data/test/responses/response_with_concealed_signed_assertion.xml +0 -51
- data/test/responses/response_with_doubled_signed_assertion.xml +0 -49
- data/test/responses/response_with_multiple_attribute_statements.xml +0 -72
- data/test/responses/response_with_signed_assertion_3.xml +0 -30
- data/test/responses/response_with_signed_message_and_assertion.xml +0 -34
- data/test/responses/response_with_undefined_recipient.xml.base64 +0 -1
- data/test/responses/response_wrapped.xml.base64 +0 -150
- data/test/responses/valid_response.xml.base64 +0 -1
- data/test/responses/valid_response_without_x509certificate.xml.base64 +0 -1
- data/test/utils_test.rb +0 -231
data/test/response_test.rb
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
|
|
2
2
|
|
|
3
|
-
class
|
|
3
|
+
class RubySamlTest < Test::Unit::TestCase
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
OneLogin::RubySaml::Response.new(nil)
|
|
9
|
-
end
|
|
10
|
-
assert_equal "Response cannot be nil", err.message
|
|
5
|
+
context "Response" do
|
|
6
|
+
should "raise an exception when response is initialized with nil" do
|
|
7
|
+
assert_raises(ArgumentError) { OneLogin::RubySaml::Response.new(nil) }
|
|
11
8
|
end
|
|
12
9
|
|
|
13
|
-
|
|
10
|
+
should "be able to parse a document which contains ampersands" do
|
|
14
11
|
XMLSecurity::SignedDocument.any_instance.stubs(:digests_match?).returns(true)
|
|
15
12
|
OneLogin::RubySaml::Response.any_instance.stubs(:validate_conditions).returns(true)
|
|
16
13
|
|
|
@@ -21,135 +18,74 @@ class ResponseTest < Minitest::Test
|
|
|
21
18
|
response.validate!
|
|
22
19
|
end
|
|
23
20
|
|
|
24
|
-
|
|
21
|
+
should "adapt namespace" do
|
|
25
22
|
response = OneLogin::RubySaml::Response.new(response_document)
|
|
26
|
-
|
|
23
|
+
assert_not_nil response.name_id
|
|
27
24
|
response = OneLogin::RubySaml::Response.new(response_document_2)
|
|
28
|
-
|
|
25
|
+
assert_not_nil response.name_id
|
|
29
26
|
response = OneLogin::RubySaml::Response.new(response_document_3)
|
|
30
|
-
|
|
27
|
+
assert_not_nil response.name_id
|
|
31
28
|
end
|
|
32
29
|
|
|
33
|
-
|
|
30
|
+
should "default to raw input when a response is not Base64 encoded" do
|
|
34
31
|
decoded = Base64.decode64(response_document_2)
|
|
35
32
|
response = OneLogin::RubySaml::Response.new(decoded)
|
|
36
33
|
assert response.document
|
|
37
34
|
end
|
|
38
35
|
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
context "Assertion" do
|
|
37
|
+
should "only retreive an assertion with an ID that matches the signature's reference URI" do
|
|
41
38
|
response = OneLogin::RubySaml::Response.new(wrapped_response_2)
|
|
42
39
|
response.stubs(:conditions).returns(nil)
|
|
43
40
|
settings = OneLogin::RubySaml::Settings.new
|
|
44
41
|
settings.idp_cert_fingerprint = signature_fingerprint_1
|
|
45
42
|
response.settings = settings
|
|
46
|
-
|
|
43
|
+
assert_nil response.name_id
|
|
47
44
|
end
|
|
48
45
|
end
|
|
49
46
|
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
context "#validate!" do
|
|
48
|
+
should "raise when encountering a condition that prevents the document from being valid" do
|
|
52
49
|
response = OneLogin::RubySaml::Response.new(response_document)
|
|
53
|
-
|
|
54
|
-
response.validate!
|
|
55
|
-
end
|
|
56
|
-
assert_equal "No settings on response", err.message
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
it "raise when encountering a condition that prevents the document from being valid" do
|
|
60
|
-
response = OneLogin::RubySaml::Response.new(response_document)
|
|
61
|
-
response.settings = settings
|
|
62
|
-
err = assert_raises(OneLogin::RubySaml::ValidationError) do
|
|
63
|
-
response.validate!
|
|
64
|
-
end
|
|
65
|
-
assert_equal "Current time is on or after NotOnOrAfter condition", err.message
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
it "raises an exception when no cert or fingerprint provided" do
|
|
69
|
-
response = OneLogin::RubySaml::Response.new(response_document_valid_signed)
|
|
70
|
-
response.stubs(:conditions).returns(nil)
|
|
71
|
-
settings = OneLogin::RubySaml::Settings.new
|
|
72
|
-
response.settings = settings
|
|
73
|
-
settings.idp_cert = nil
|
|
74
|
-
settings.idp_cert_fingerprint = nil
|
|
75
|
-
err = assert_raises(OneLogin::RubySaml::ValidationError) do
|
|
50
|
+
assert_raise(OneLogin::RubySaml::ValidationError) do
|
|
76
51
|
response.validate!
|
|
77
52
|
end
|
|
78
|
-
assert_equal "No fingerprint or certificate on settings", err.message
|
|
79
53
|
end
|
|
54
|
+
end
|
|
80
55
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
response_no_signed_elements.validate!
|
|
87
|
-
end
|
|
88
|
-
assert_equal "Found an unexpected number of Signature Element. SAML Response rejected", err.message
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
it "raise when multiple signatures" do
|
|
92
|
-
response_multiple_signed = OneLogin::RubySaml::Response.new(read_invalid_response("multiple_signed.xml.base64"))
|
|
93
|
-
settings.idp_cert_fingerprint = signature_fingerprint_1
|
|
94
|
-
response_multiple_signed.settings = settings
|
|
95
|
-
response_multiple_signed.stubs(:validate_structure).returns(true)
|
|
96
|
-
err = assert_raises(OneLogin::RubySaml::ValidationError) do
|
|
97
|
-
response_multiple_signed.validate!
|
|
98
|
-
end
|
|
99
|
-
assert_equal "Duplicated ID. SAML Response rejected", err.message
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
it "raise when fingerprint missmatch" do
|
|
103
|
-
resp_xml = Base64.decode64(response_document_valid_signed)
|
|
104
|
-
response = OneLogin::RubySaml::Response.new(Base64.encode64(resp_xml))
|
|
105
|
-
response.stubs(:conditions).returns(nil)
|
|
106
|
-
settings = OneLogin::RubySaml::Settings.new
|
|
107
|
-
settings.idp_cert_fingerprint = signature_fingerprint_1
|
|
108
|
-
response.settings = settings
|
|
109
|
-
|
|
110
|
-
err = assert_raises(OneLogin::RubySaml::ValidationError) do
|
|
111
|
-
response.validate!
|
|
112
|
-
end
|
|
113
|
-
assert_equal 'Fingerprint mismatch', err.message
|
|
56
|
+
context "#validate_structure" do
|
|
57
|
+
should "raise when encountering a condition that prevents the document from being valid" do
|
|
58
|
+
response = OneLogin::RubySaml::Response.new(response_document_2)
|
|
59
|
+
response.send(:validate_structure)
|
|
60
|
+
assert response.errors.include? "Schema validation failed"
|
|
114
61
|
end
|
|
115
|
-
|
|
116
62
|
end
|
|
117
63
|
|
|
118
|
-
|
|
119
|
-
|
|
64
|
+
context "#is_valid?" do
|
|
65
|
+
should "return false when response is initialized with blank data" do
|
|
120
66
|
response = OneLogin::RubySaml::Response.new('')
|
|
121
67
|
assert !response.is_valid?
|
|
122
68
|
end
|
|
123
69
|
|
|
124
|
-
|
|
70
|
+
should "return false if settings have not been set" do
|
|
125
71
|
response = OneLogin::RubySaml::Response.new(response_document)
|
|
126
72
|
assert !response.is_valid?
|
|
127
73
|
end
|
|
128
74
|
|
|
129
|
-
|
|
130
|
-
response = OneLogin::RubySaml::Response.new(
|
|
131
|
-
response.stubs(:conditions).returns(nil)
|
|
132
|
-
settings = OneLogin::RubySaml::Settings.new
|
|
133
|
-
response.settings = settings
|
|
134
|
-
settings.idp_cert = nil
|
|
135
|
-
settings.idp_cert_fingerprint = nil
|
|
136
|
-
assert !response.is_valid?
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
it "return true when the response is initialized with valid data" do
|
|
140
|
-
response = OneLogin::RubySaml::Response.new(response_document_valid_signed)
|
|
75
|
+
should "return true when the response is initialized with valid data" do
|
|
76
|
+
response = OneLogin::RubySaml::Response.new(response_document_4)
|
|
141
77
|
response.stubs(:conditions).returns(nil)
|
|
142
78
|
assert !response.is_valid?
|
|
143
79
|
settings = OneLogin::RubySaml::Settings.new
|
|
144
80
|
assert !response.is_valid?
|
|
145
81
|
response.settings = settings
|
|
146
82
|
assert !response.is_valid?
|
|
147
|
-
|
|
148
|
-
response.
|
|
83
|
+
settings.idp_cert_fingerprint = signature_fingerprint_1
|
|
84
|
+
assert response.is_valid?
|
|
149
85
|
end
|
|
150
86
|
|
|
151
|
-
|
|
152
|
-
response = OneLogin::RubySaml::Response.new(
|
|
87
|
+
should "should be idempotent when the response is initialized with invalid data" do
|
|
88
|
+
response = OneLogin::RubySaml::Response.new(response_document_4)
|
|
153
89
|
response.stubs(:conditions).returns(nil)
|
|
154
90
|
settings = OneLogin::RubySaml::Settings.new
|
|
155
91
|
response.settings = settings
|
|
@@ -157,58 +93,36 @@ class ResponseTest < Minitest::Test
|
|
|
157
93
|
assert !response.is_valid?
|
|
158
94
|
end
|
|
159
95
|
|
|
160
|
-
|
|
161
|
-
response = OneLogin::RubySaml::Response.new(
|
|
96
|
+
should "should be idempotent when the response is initialized with valid data" do
|
|
97
|
+
response = OneLogin::RubySaml::Response.new(response_document_4)
|
|
162
98
|
response.stubs(:conditions).returns(nil)
|
|
163
99
|
settings = OneLogin::RubySaml::Settings.new
|
|
164
100
|
response.settings = settings
|
|
165
|
-
|
|
101
|
+
settings.idp_cert_fingerprint = signature_fingerprint_1
|
|
166
102
|
assert response.is_valid?
|
|
167
103
|
assert response.is_valid?
|
|
168
104
|
end
|
|
169
105
|
|
|
170
|
-
|
|
171
|
-
response = OneLogin::RubySaml::Response.new(
|
|
172
|
-
response.stubs(:conditions).returns(nil)
|
|
173
|
-
settings = OneLogin::RubySaml::Settings.new
|
|
174
|
-
response.settings = settings
|
|
175
|
-
settings.idp_cert = nil
|
|
176
|
-
settings.idp_cert_fingerprint = "4B:68:C4:53:C7:D9:94:AA:D9:02:5C:99:D5:EF:CF:56:62:87:FE:8D"
|
|
177
|
-
assert response.is_valid?
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
it "return true when valid response using certificate" do
|
|
181
|
-
response = OneLogin::RubySaml::Response.new(response_document_valid_signed)
|
|
106
|
+
should "return true when using certificate instead of fingerprint" do
|
|
107
|
+
response = OneLogin::RubySaml::Response.new(response_document_4)
|
|
182
108
|
response.stubs(:conditions).returns(nil)
|
|
183
109
|
settings = OneLogin::RubySaml::Settings.new
|
|
184
110
|
response.settings = settings
|
|
185
|
-
settings.idp_cert =
|
|
111
|
+
settings.idp_cert = signature_1
|
|
186
112
|
assert response.is_valid?
|
|
187
113
|
end
|
|
188
114
|
|
|
189
|
-
|
|
115
|
+
should "not allow signature wrapping attack" do
|
|
190
116
|
response = OneLogin::RubySaml::Response.new(response_document_4)
|
|
191
117
|
response.stubs(:conditions).returns(nil)
|
|
192
118
|
settings = OneLogin::RubySaml::Settings.new
|
|
193
119
|
settings.idp_cert_fingerprint = signature_fingerprint_1
|
|
194
120
|
response.settings = settings
|
|
195
|
-
assert
|
|
121
|
+
assert response.is_valid?
|
|
196
122
|
assert response.name_id == "test@onelogin.com"
|
|
197
123
|
end
|
|
198
124
|
|
|
199
|
-
|
|
200
|
-
response_wrapped = OneLogin::RubySaml::Response.new(response_document_wrapped)
|
|
201
|
-
response_wrapped.stubs(:conditions).returns(nil)
|
|
202
|
-
response_wrapped.stubs(:validate_subject_confirmation).returns(true)
|
|
203
|
-
settings = OneLogin::RubySaml::Settings.new
|
|
204
|
-
response_wrapped.settings = settings
|
|
205
|
-
response_wrapped.settings.idp_cert_fingerprint = signature_fingerprint_1
|
|
206
|
-
|
|
207
|
-
assert !response_wrapped.is_valid?
|
|
208
|
-
assert_nil response_wrapped.name_id
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
it "support dynamic namespace resolution on signature elements" do
|
|
125
|
+
should "support dynamic namespace resolution on signature elements" do
|
|
212
126
|
response = OneLogin::RubySaml::Response.new(fixture("no_signature_ns.xml"))
|
|
213
127
|
response.stubs(:conditions).returns(nil)
|
|
214
128
|
settings = OneLogin::RubySaml::Settings.new
|
|
@@ -218,52 +132,7 @@ class ResponseTest < Minitest::Test
|
|
|
218
132
|
assert response.validate!
|
|
219
133
|
end
|
|
220
134
|
|
|
221
|
-
|
|
222
|
-
response = OneLogin::RubySaml::Response.new(response_document_valid_signed_without_x509certificate)
|
|
223
|
-
response.stubs(:conditions).returns(nil)
|
|
224
|
-
settings = OneLogin::RubySaml::Settings.new
|
|
225
|
-
response.settings = settings
|
|
226
|
-
settings.idp_cert = ruby_saml_cert
|
|
227
|
-
settings.idp_cert_fingerprint = nil
|
|
228
|
-
XMLSecurity::SignedDocument.any_instance.expects(:validate_signature).returns(true)
|
|
229
|
-
assert response.validate!
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
it "support signature elements with no KeyInfo if cert provided as text" do
|
|
233
|
-
response = OneLogin::RubySaml::Response.new(response_document_valid_signed_without_x509certificate)
|
|
234
|
-
response.stubs(:conditions).returns(nil)
|
|
235
|
-
settings = OneLogin::RubySaml::Settings.new
|
|
236
|
-
response.settings = settings
|
|
237
|
-
settings.idp_cert = ruby_saml_cert_text
|
|
238
|
-
settings.idp_cert_fingerprint = nil
|
|
239
|
-
XMLSecurity::SignedDocument.any_instance.expects(:validate_signature).returns(true)
|
|
240
|
-
assert response.validate!
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
it "returns an error if the signature contains no KeyInfo, cert is not provided and soft" do
|
|
244
|
-
response = OneLogin::RubySaml::Response.new(response_document_valid_signed_without_x509certificate)
|
|
245
|
-
response.stubs(:conditions).returns(nil)
|
|
246
|
-
settings = OneLogin::RubySaml::Settings.new
|
|
247
|
-
response.settings = settings
|
|
248
|
-
settings.idp_cert = nil
|
|
249
|
-
settings.idp_cert_fingerprint = "28:74:9B:E8:1F:E8:10:9C:A8:7C:A9:C3:E3:C5:01:6C:92:1C:B4:BA"
|
|
250
|
-
assert !response.is_valid?
|
|
251
|
-
end
|
|
252
|
-
|
|
253
|
-
it "raises an exception if the signature contains no KeyInfo, cert is not provided and no soft" do
|
|
254
|
-
response = OneLogin::RubySaml::Response.new(response_document_valid_signed_without_x509certificate)
|
|
255
|
-
response.stubs(:conditions).returns(nil)
|
|
256
|
-
settings = OneLogin::RubySaml::Settings.new
|
|
257
|
-
response.settings = settings
|
|
258
|
-
settings.idp_cert = nil
|
|
259
|
-
settings.idp_cert_fingerprint = "28:74:9B:E8:1F:E8:10:9C:A8:7C:A9:C3:E3:C5:01:6C:92:1C:B4:BA"
|
|
260
|
-
err = assert_raises(OneLogin::RubySaml::ValidationError) do
|
|
261
|
-
response.validate!
|
|
262
|
-
end
|
|
263
|
-
assert_equal "Certificate element missing in response (ds:X509Certificate) and not cert provided at settings", err.message
|
|
264
|
-
end
|
|
265
|
-
|
|
266
|
-
it "validate ADFS assertions" do
|
|
135
|
+
should "validate ADFS assertions" do
|
|
267
136
|
response = OneLogin::RubySaml::Response.new(fixture(:adfs_response_sha256))
|
|
268
137
|
response.stubs(:conditions).returns(nil)
|
|
269
138
|
settings = OneLogin::RubySaml::Settings.new
|
|
@@ -272,7 +141,7 @@ class ResponseTest < Minitest::Test
|
|
|
272
141
|
assert response.validate!
|
|
273
142
|
end
|
|
274
143
|
|
|
275
|
-
|
|
144
|
+
should "validate the digest" do
|
|
276
145
|
response = OneLogin::RubySaml::Response.new(r1_response_document_6)
|
|
277
146
|
response.stubs(:conditions).returns(nil)
|
|
278
147
|
settings = OneLogin::RubySaml::Settings.new
|
|
@@ -281,75 +150,19 @@ class ResponseTest < Minitest::Test
|
|
|
281
150
|
assert response.validate!
|
|
282
151
|
end
|
|
283
152
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
response = OneLogin::RubySaml::Response.new(
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
end
|
|
291
|
-
|
|
292
|
-
describe '#validate_audience' do
|
|
293
|
-
it "return true when sp_entity_id not set or empty" do
|
|
294
|
-
response = OneLogin::RubySaml::Response.new(response_document_valid_signed)
|
|
295
|
-
response.stubs(:conditions).returns(nil)
|
|
296
|
-
settings = OneLogin::RubySaml::Settings.new
|
|
297
|
-
response.settings = settings
|
|
298
|
-
settings.idp_cert_fingerprint = signature_fingerprint_valid_res
|
|
299
|
-
assert response.is_valid?
|
|
300
|
-
settings.sp_entity_id = ''
|
|
301
|
-
assert response.is_valid?
|
|
302
|
-
end
|
|
303
|
-
|
|
304
|
-
it "return false when sp_entity_id set to incorrectly" do
|
|
305
|
-
response = OneLogin::RubySaml::Response.new(response_document_valid_signed)
|
|
306
|
-
response.stubs(:conditions).returns(nil)
|
|
307
|
-
settings = OneLogin::RubySaml::Settings.new
|
|
308
|
-
response.settings = settings
|
|
309
|
-
settings.idp_cert_fingerprint = signature_fingerprint_valid_res
|
|
310
|
-
settings.sp_entity_id = 'wrong_audience'
|
|
311
|
-
assert !response.is_valid?
|
|
312
|
-
end
|
|
313
|
-
|
|
314
|
-
it "return true when sp_entity_id set to correctly" do
|
|
315
|
-
response = OneLogin::RubySaml::Response.new(response_document_valid_signed)
|
|
316
|
-
response.stubs(:conditions).returns(nil)
|
|
317
|
-
settings = OneLogin::RubySaml::Settings.new
|
|
318
|
-
response.settings = settings
|
|
319
|
-
settings.idp_cert_fingerprint = signature_fingerprint_valid_res
|
|
320
|
-
settings.sp_entity_id = 'https://someone.example.com/audience'
|
|
321
|
-
assert response.is_valid?
|
|
322
|
-
end
|
|
323
|
-
end
|
|
324
|
-
end
|
|
325
|
-
|
|
326
|
-
describe "#validate_issuer" do
|
|
327
|
-
it "return true when the issuer of the Message/Assertion matches the IdP entityId" do
|
|
328
|
-
response = OneLogin::RubySaml::Response.new(response_document_valid_signed)
|
|
329
|
-
response.settings = settings
|
|
330
|
-
assert response.send(:validate_issuer)
|
|
331
|
-
|
|
332
|
-
response.settings.idp_entity_id = 'https://app.onelogin.com/saml2'
|
|
333
|
-
assert response.send(:validate_issuer)
|
|
334
|
-
end
|
|
335
|
-
|
|
336
|
-
it "return false when the issuer of the Message does not match the IdP entityId" do
|
|
337
|
-
response = OneLogin::RubySaml::Response.new(read_invalid_response("invalid_issuer_message.xml.base64"))
|
|
338
|
-
response.settings = settings
|
|
339
|
-
response.settings.idp_entity_id = 'http://idp.example.com/'
|
|
340
|
-
assert !response.send(:validate_issuer)
|
|
341
|
-
end
|
|
342
|
-
|
|
343
|
-
it "return false when the issuer of the Assertion does not match the IdP entityId" do
|
|
344
|
-
response = OneLogin::RubySaml::Response.new(read_invalid_response("invalid_issuer_assertion.xml.base64"))
|
|
153
|
+
should "validate SAML 2.0 XML structure" do
|
|
154
|
+
resp_xml = Base64.decode64(response_document_4).gsub(/emailAddress/,'test')
|
|
155
|
+
response = OneLogin::RubySaml::Response.new(Base64.encode64(resp_xml))
|
|
156
|
+
response.stubs(:conditions).returns(nil)
|
|
157
|
+
settings = OneLogin::RubySaml::Settings.new
|
|
158
|
+
settings.idp_cert_fingerprint = signature_fingerprint_1
|
|
345
159
|
response.settings = settings
|
|
346
|
-
|
|
347
|
-
assert !response.send(:validate_issuer)
|
|
160
|
+
assert_raises(OneLogin::RubySaml::ValidationError, 'Digest mismatch'){ response.validate! }
|
|
348
161
|
end
|
|
349
162
|
end
|
|
350
163
|
|
|
351
|
-
|
|
352
|
-
|
|
164
|
+
context "#name_id" do
|
|
165
|
+
should "extract the value of the name id element" do
|
|
353
166
|
response = OneLogin::RubySaml::Response.new(response_document)
|
|
354
167
|
assert_equal "support@onelogin.com", response.name_id
|
|
355
168
|
|
|
@@ -357,43 +170,19 @@ class ResponseTest < Minitest::Test
|
|
|
357
170
|
assert_equal "someone@example.com", response.name_id
|
|
358
171
|
end
|
|
359
172
|
|
|
360
|
-
|
|
173
|
+
should "be extractable from an OpenSAML response" do
|
|
361
174
|
response = OneLogin::RubySaml::Response.new(fixture(:open_saml))
|
|
362
175
|
assert_equal "someone@example.org", response.name_id
|
|
363
176
|
end
|
|
364
177
|
|
|
365
|
-
|
|
178
|
+
should "be extractable from a Simple SAML PHP response" do
|
|
366
179
|
response = OneLogin::RubySaml::Response.new(fixture(:simple_saml_php))
|
|
367
180
|
assert_equal "someone@example.com", response.name_id
|
|
368
181
|
end
|
|
369
182
|
end
|
|
370
183
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
response = OneLogin::RubySaml::Response.new(response_document)
|
|
374
|
-
response_signed = OneLogin::RubySaml::Response.new(response_document_valid_signed)
|
|
375
|
-
assert_equal "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", response.name_id_format
|
|
376
|
-
assert_equal "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", response_signed.name_id_format
|
|
377
|
-
end
|
|
378
|
-
end
|
|
379
|
-
|
|
380
|
-
describe "#sessionindex" do
|
|
381
|
-
it "extract the value of the sessionindex element" do
|
|
382
|
-
response = OneLogin::RubySaml::Response.new(fixture(:simple_saml_php))
|
|
383
|
-
assert_equal "_51be37965feb5579d803141076936dc2e9d1d98ebf", response.sessionindex
|
|
384
|
-
end
|
|
385
|
-
end
|
|
386
|
-
|
|
387
|
-
describe "#response_id and assertion_id" do
|
|
388
|
-
it "extract the value of the Response and Assertion IDs" do
|
|
389
|
-
response = OneLogin::RubySaml::Response.new(response_document)
|
|
390
|
-
assert_equal "GOSAMLR12901174571794", response.response_id
|
|
391
|
-
assert_equal "pfxa46574df-b3b0-a06a-23c8-636413198772", response.assertion_id
|
|
392
|
-
end
|
|
393
|
-
end
|
|
394
|
-
|
|
395
|
-
describe "#check_conditions" do
|
|
396
|
-
it "check time conditions" do
|
|
184
|
+
context "#check_conditions" do
|
|
185
|
+
should "check time conditions" do
|
|
397
186
|
response = OneLogin::RubySaml::Response.new(response_document)
|
|
398
187
|
assert !response.send(:validate_conditions, true)
|
|
399
188
|
response = OneLogin::RubySaml::Response.new(response_document_6)
|
|
@@ -404,290 +193,187 @@ class ResponseTest < Minitest::Test
|
|
|
404
193
|
assert response.send(:validate_conditions, true)
|
|
405
194
|
end
|
|
406
195
|
|
|
407
|
-
|
|
196
|
+
should "optionally allow for clock drift" do
|
|
408
197
|
# The NotBefore condition in the document is 2011-06-14T18:21:01.516Z
|
|
409
|
-
|
|
410
|
-
Time.stubs(:now).returns(expected_time)
|
|
198
|
+
Time.stubs(:now).returns(Time.parse("2011-06-14T18:21:01Z"))
|
|
411
199
|
response = OneLogin::RubySaml::Response.new(response_document_5, :allowed_clock_drift => 0.515)
|
|
412
200
|
assert !response.send(:validate_conditions, true)
|
|
413
201
|
|
|
414
|
-
|
|
415
|
-
Time.stubs(:now).returns(expected_time)
|
|
202
|
+
Time.stubs(:now).returns(Time.parse("2011-06-14T18:21:01Z"))
|
|
416
203
|
response = OneLogin::RubySaml::Response.new(response_document_5, :allowed_clock_drift => 0.516)
|
|
417
204
|
assert response.send(:validate_conditions, true)
|
|
418
205
|
end
|
|
419
206
|
end
|
|
420
207
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
response = OneLogin::RubySaml::Response.new(
|
|
424
|
-
|
|
425
|
-
response.settings = settings
|
|
426
|
-
settings.idp_cert = nil
|
|
427
|
-
settings.idp_cert_fingerprint = nil
|
|
428
|
-
err = assert_raises(OneLogin::RubySaml::ValidationError) do
|
|
429
|
-
response.send(:validate_signature, false)
|
|
430
|
-
end
|
|
431
|
-
assert_equal "No fingerprint or certificate on settings", err.message
|
|
208
|
+
context "#attributes" do
|
|
209
|
+
should "extract the first attribute in a hash accessed via its symbol" do
|
|
210
|
+
response = OneLogin::RubySaml::Response.new(response_document)
|
|
211
|
+
assert_equal "demo", response.attributes[:uid]
|
|
432
212
|
end
|
|
433
213
|
|
|
434
|
-
|
|
435
|
-
response = OneLogin::RubySaml::Response.new(
|
|
436
|
-
|
|
437
|
-
response.settings = settings
|
|
438
|
-
settings.idp_cert = ruby_saml_cert2
|
|
439
|
-
settings.idp_cert_fingerprint = nil
|
|
440
|
-
err = assert_raises(OneLogin::RubySaml::ValidationError) do
|
|
441
|
-
response.send(:validate_signature, false)
|
|
442
|
-
end
|
|
443
|
-
assert_equal "Fingerprint mismatch", err.message
|
|
214
|
+
should "extract the first attribute in a hash accessed via its name" do
|
|
215
|
+
response = OneLogin::RubySaml::Response.new(response_document)
|
|
216
|
+
assert_equal "demo", response.attributes["uid"]
|
|
444
217
|
end
|
|
445
218
|
|
|
446
|
-
|
|
447
|
-
response = OneLogin::RubySaml::Response.new(
|
|
448
|
-
|
|
449
|
-
response.
|
|
450
|
-
settings.idp_cert = nil
|
|
451
|
-
settings.idp_cert_fingerprint = "28:74:9B:E8:1F:E8:10:9C:A8:7C:A9:C3:E3:C5:01:6C:92:1C:B4:BA"
|
|
452
|
-
err = assert_raises(OneLogin::RubySaml::ValidationError) do
|
|
453
|
-
response.send(:validate_signature, false)
|
|
454
|
-
end
|
|
455
|
-
assert_equal "Fingerprint mismatch", err.message
|
|
219
|
+
should "extract all attributes" do
|
|
220
|
+
response = OneLogin::RubySaml::Response.new(response_document)
|
|
221
|
+
assert_equal "demo", response.attributes[:uid]
|
|
222
|
+
assert_equal "value", response.attributes[:another_value]
|
|
456
223
|
end
|
|
457
224
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
response_no_signed_elements.settings = settings
|
|
462
|
-
err = assert_raises(OneLogin::RubySaml::ValidationError) do
|
|
463
|
-
response_no_signed_elements.validate!
|
|
464
|
-
end
|
|
465
|
-
assert_equal "Found an unexpected number of Signature Element. SAML Response rejected", err.message
|
|
225
|
+
should "work for implicit namespaces" do
|
|
226
|
+
response = OneLogin::RubySaml::Response.new(response_document_3)
|
|
227
|
+
assert_equal "someone@example.com", response.attributes["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"]
|
|
466
228
|
end
|
|
467
|
-
end
|
|
468
229
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
230
|
+
should "not raise errors about nil/empty attributes for EncryptedAttributes" do
|
|
231
|
+
response = OneLogin::RubySaml::Response.new(response_document_7)
|
|
232
|
+
assert_equal 'Demo', response.attributes["first_name"]
|
|
472
233
|
end
|
|
473
234
|
|
|
474
|
-
|
|
475
|
-
|
|
235
|
+
should "not raise on responses without attributes" do
|
|
236
|
+
response = OneLogin::RubySaml::Response.new(response_document_4)
|
|
237
|
+
assert_equal OneLogin::RubySaml::Attributes.new, response.attributes
|
|
476
238
|
end
|
|
477
239
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
240
|
+
context "#multiple values" do
|
|
241
|
+
should "extract single value as string" do
|
|
242
|
+
response = OneLogin::RubySaml::Response.new(fixture(:response_with_multiple_attribute_values))
|
|
243
|
+
assert_equal "demo", response.attributes[:uid]
|
|
244
|
+
end
|
|
481
245
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
246
|
+
should "extract single value as string in compatibility mode off" do
|
|
247
|
+
response = OneLogin::RubySaml::Response.new(fixture(:response_with_multiple_attribute_values))
|
|
248
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
|
249
|
+
assert_equal ["demo"], response.attributes[:uid]
|
|
250
|
+
# classes are not reloaded between tests so restore default
|
|
251
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
|
252
|
+
end
|
|
486
253
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
254
|
+
should "extract first of multiple values as string for b/w compatibility" do
|
|
255
|
+
response = OneLogin::RubySaml::Response.new(fixture(:response_with_multiple_attribute_values))
|
|
256
|
+
assert_equal 'value1', response.attributes[:another_value]
|
|
257
|
+
end
|
|
491
258
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
259
|
+
should "extract first of multiple values as string for b/w compatibility in compatibility mode off" do
|
|
260
|
+
response = OneLogin::RubySaml::Response.new(fixture(:response_with_multiple_attribute_values))
|
|
261
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
|
262
|
+
assert_equal ['value1', 'value2'], response.attributes[:another_value]
|
|
263
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
|
264
|
+
end
|
|
496
265
|
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
266
|
+
should "return array with all attributes when asked in XML order" do
|
|
267
|
+
response = OneLogin::RubySaml::Response.new(fixture(:response_with_multiple_attribute_values))
|
|
268
|
+
assert_equal ['value1', 'value2'], response.attributes.multi(:another_value)
|
|
269
|
+
end
|
|
501
270
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
271
|
+
should "return array with all attributes when asked in XML order in compatibility mode off" do
|
|
272
|
+
response = OneLogin::RubySaml::Response.new(fixture(:response_with_multiple_attribute_values))
|
|
273
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
|
274
|
+
assert_equal ['value1', 'value2'], response.attributes.multi(:another_value)
|
|
275
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
|
276
|
+
end
|
|
505
277
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
278
|
+
should "return first of multiple values when multiple Attribute tags in XML" do
|
|
279
|
+
response = OneLogin::RubySaml::Response.new(fixture(:response_with_multiple_attribute_values))
|
|
280
|
+
assert_equal 'role1', response.attributes[:role]
|
|
281
|
+
end
|
|
509
282
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
283
|
+
should "return first of multiple values when multiple Attribute tags in XML in compatibility mode off" do
|
|
284
|
+
response = OneLogin::RubySaml::Response.new(fixture(:response_with_multiple_attribute_values))
|
|
285
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
|
286
|
+
assert_equal ['role1', 'role2', 'role3'], response.attributes[:role]
|
|
287
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
should "return all of multiple values in reverse order when multiple Attribute tags in XML" do
|
|
291
|
+
response = OneLogin::RubySaml::Response.new(fixture(:response_with_multiple_attribute_values))
|
|
292
|
+
assert_equal ['role1', 'role2', 'role3'], response.attributes.multi(:role)
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
should "return all of multiple values in reverse order when multiple Attribute tags in XML in compatibility mode off" do
|
|
296
|
+
response = OneLogin::RubySaml::Response.new(fixture(:response_with_multiple_attribute_values))
|
|
297
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
|
298
|
+
assert_equal ['role1', 'role2', 'role3'], response.attributes.multi(:role)
|
|
299
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
should "return nil value correctly" do
|
|
303
|
+
response = OneLogin::RubySaml::Response.new(fixture(:response_with_multiple_attribute_values))
|
|
304
|
+
assert_nil response.attributes[:attribute_with_nil_value]
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
should "return nil value correctly when not in compatibility mode off" do
|
|
308
|
+
response = OneLogin::RubySaml::Response.new(fixture(:response_with_multiple_attribute_values))
|
|
309
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
|
310
|
+
assert_equal [nil], response.attributes[:attribute_with_nil_value]
|
|
311
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
should "return multiple values including nil and empty string" do
|
|
315
|
+
response = OneLogin::RubySaml::Response.new(fixture(:response_with_multiple_attribute_values))
|
|
316
|
+
assert_equal ["", "valuePresent", nil, nil], response.attributes.multi(:attribute_with_nils_and_empty_strings)
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
should "return multiple values from [] when not in compatibility mode off" do
|
|
320
|
+
response = OneLogin::RubySaml::Response.new(fixture(:response_with_multiple_attribute_values))
|
|
321
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
|
322
|
+
assert_equal ["", "valuePresent", nil, nil], response.attributes[:attribute_with_nils_and_empty_strings]
|
|
323
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
should "check what happens when trying retrieve attribute that does not exists" do
|
|
327
|
+
response = OneLogin::RubySaml::Response.new(fixture(:response_with_multiple_attribute_values))
|
|
328
|
+
assert_equal nil, response.attributes[:attribute_not_exists]
|
|
329
|
+
assert_equal nil, response.attributes.single(:attribute_not_exists)
|
|
330
|
+
assert_equal nil, response.attributes.multi(:attribute_not_exists)
|
|
331
|
+
|
|
332
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
|
333
|
+
assert_equal nil, response.attributes[:attribute_not_exists]
|
|
334
|
+
assert_equal nil, response.attributes.single(:attribute_not_exists)
|
|
335
|
+
assert_equal nil, response.attributes.multi(:attribute_not_exists)
|
|
336
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
|
337
|
+
end
|
|
514
338
|
|
|
515
|
-
it "be manipulable by hash methods such as #shift and actually remove the value" do
|
|
516
|
-
removed_value = @response.attributes.shift
|
|
517
|
-
assert_nil @response.attributes[removed_value[0]]
|
|
518
339
|
end
|
|
519
340
|
end
|
|
520
341
|
|
|
521
|
-
|
|
522
|
-
|
|
342
|
+
context "#session_expires_at" do
|
|
343
|
+
should "extract the value of the SessionNotOnOrAfter attribute" do
|
|
523
344
|
response = OneLogin::RubySaml::Response.new(response_document)
|
|
524
345
|
assert response.session_expires_at.is_a?(Time)
|
|
525
346
|
|
|
526
347
|
response = OneLogin::RubySaml::Response.new(response_document_2)
|
|
527
|
-
|
|
348
|
+
assert_nil response.session_expires_at
|
|
528
349
|
end
|
|
529
350
|
end
|
|
530
351
|
|
|
531
|
-
|
|
532
|
-
|
|
352
|
+
context "#issuer" do
|
|
353
|
+
should "return the issuer inside the response assertion" do
|
|
533
354
|
response = OneLogin::RubySaml::Response.new(response_document)
|
|
534
355
|
assert_equal "https://app.onelogin.com/saml/metadata/13590", response.issuer
|
|
535
356
|
end
|
|
536
357
|
|
|
537
|
-
|
|
358
|
+
should "return the issuer inside the response" do
|
|
538
359
|
response = OneLogin::RubySaml::Response.new(response_document_2)
|
|
539
360
|
assert_equal "wibble", response.issuer
|
|
540
361
|
end
|
|
541
362
|
end
|
|
542
363
|
|
|
543
|
-
|
|
544
|
-
|
|
364
|
+
context "#success" do
|
|
365
|
+
should "find a status code that says success" do
|
|
545
366
|
response = OneLogin::RubySaml::Response.new(response_document)
|
|
546
|
-
|
|
367
|
+
response.success?
|
|
547
368
|
end
|
|
548
369
|
end
|
|
549
370
|
|
|
550
|
-
|
|
551
|
-
|
|
371
|
+
context '#xpath_first_from_signed_assertion' do
|
|
372
|
+
should 'not allow arbitrary code execution' do
|
|
552
373
|
malicious_response_document = fixture('response_eval', false)
|
|
553
374
|
response = OneLogin::RubySaml::Response.new(malicious_response_document)
|
|
554
375
|
response.send(:xpath_first_from_signed_assertion)
|
|
555
|
-
|
|
556
|
-
end
|
|
557
|
-
end
|
|
558
|
-
|
|
559
|
-
describe "#multiple values" do
|
|
560
|
-
it "extract single value as string" do
|
|
561
|
-
assert_equal "demo", response_multiple_attr_values.attributes[:uid]
|
|
562
|
-
end
|
|
563
|
-
|
|
564
|
-
it "extract single value as string in compatibility mode off" do
|
|
565
|
-
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
|
566
|
-
assert_equal ["demo"], response_multiple_attr_values.attributes[:uid]
|
|
567
|
-
# classes are not reloaded between tests so restore default
|
|
568
|
-
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
|
569
|
-
end
|
|
570
|
-
|
|
571
|
-
it "extract first of multiple values as string for b/w compatibility" do
|
|
572
|
-
assert_equal 'value1', response_multiple_attr_values.attributes[:another_value]
|
|
573
|
-
end
|
|
574
|
-
|
|
575
|
-
it "extract first of multiple values as string for b/w compatibility in compatibility mode off" do
|
|
576
|
-
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
|
577
|
-
assert_equal ['value1', 'value2'], response_multiple_attr_values.attributes[:another_value]
|
|
578
|
-
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
|
579
|
-
end
|
|
580
|
-
|
|
581
|
-
it "return array with all attributes when asked in XML order" do
|
|
582
|
-
assert_equal ['value1', 'value2'], response_multiple_attr_values.attributes.multi(:another_value)
|
|
583
|
-
end
|
|
584
|
-
|
|
585
|
-
it "return array with all attributes when asked in XML order in compatibility mode off" do
|
|
586
|
-
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
|
587
|
-
assert_equal ['value1', 'value2'], response_multiple_attr_values.attributes.multi(:another_value)
|
|
588
|
-
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
|
589
|
-
end
|
|
590
|
-
|
|
591
|
-
it "return first of multiple values when multiple Attribute tags in XML" do
|
|
592
|
-
assert_equal 'role1', response_multiple_attr_values.attributes[:role]
|
|
593
|
-
end
|
|
594
|
-
|
|
595
|
-
it "return first of multiple values when multiple Attribute tags in XML in compatibility mode off" do
|
|
596
|
-
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
|
597
|
-
assert_equal ['role1', 'role2', 'role3'], response_multiple_attr_values.attributes[:role]
|
|
598
|
-
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
|
599
|
-
end
|
|
600
|
-
|
|
601
|
-
it "return all of multiple values in reverse order when multiple Attribute tags in XML" do
|
|
602
|
-
assert_equal ['role1', 'role2', 'role3'], response_multiple_attr_values.attributes.multi(:role)
|
|
603
|
-
end
|
|
604
|
-
|
|
605
|
-
it "return all of multiple values in reverse order when multiple Attribute tags in XML in compatibility mode off" do
|
|
606
|
-
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
|
607
|
-
assert_equal ['role1', 'role2', 'role3'], response_multiple_attr_values.attributes.multi(:role)
|
|
608
|
-
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
|
609
|
-
end
|
|
610
|
-
|
|
611
|
-
it "return all of multiple values when multiple Attribute tags in multiple AttributeStatement tags" do
|
|
612
|
-
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
|
613
|
-
assert_equal ['role1', 'role2', 'role3'], response_with_multiple_attribute_statements.attributes.multi(:role)
|
|
614
|
-
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
|
615
|
-
end
|
|
616
|
-
|
|
617
|
-
it "return nil value correctly" do
|
|
618
|
-
assert_nil response_multiple_attr_values.attributes[:attribute_with_nil_value]
|
|
619
|
-
end
|
|
620
|
-
|
|
621
|
-
it "return nil value correctly when not in compatibility mode off" do
|
|
622
|
-
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
|
623
|
-
assert [nil] == response_multiple_attr_values.attributes[:attribute_with_nil_value]
|
|
624
|
-
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
|
625
|
-
end
|
|
626
|
-
|
|
627
|
-
it "return multiple values including nil and empty string" do
|
|
628
|
-
response = OneLogin::RubySaml::Response.new(fixture(:response_with_multiple_attribute_values))
|
|
629
|
-
assert_equal ["", "valuePresent", nil, nil], response.attributes.multi(:attribute_with_nils_and_empty_strings)
|
|
630
|
-
end
|
|
631
|
-
|
|
632
|
-
it "return multiple values from [] when not in compatibility mode off" do
|
|
633
|
-
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
|
634
|
-
assert_equal ["", "valuePresent", nil, nil], response_multiple_attr_values.attributes[:attribute_with_nils_and_empty_strings]
|
|
635
|
-
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
|
636
|
-
end
|
|
637
|
-
|
|
638
|
-
it "check what happens when trying retrieve attribute that does not exists" do
|
|
639
|
-
assert_nil response_multiple_attr_values.attributes[:attribute_not_exists]
|
|
640
|
-
assert_nil response_multiple_attr_values.attributes.single(:attribute_not_exists)
|
|
641
|
-
assert_nil response_multiple_attr_values.attributes.multi(:attribute_not_exists)
|
|
642
|
-
|
|
643
|
-
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
|
644
|
-
assert_nil response_multiple_attr_values.attributes[:attribute_not_exists]
|
|
645
|
-
assert_nil response_multiple_attr_values.attributes.single(:attribute_not_exists)
|
|
646
|
-
assert_nil response_multiple_attr_values.attributes.multi(:attribute_not_exists)
|
|
647
|
-
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
|
648
|
-
end
|
|
649
|
-
end
|
|
650
|
-
|
|
651
|
-
describe "signature wrapping attack with encrypted assertion" do
|
|
652
|
-
it "should not be valid" do
|
|
653
|
-
settings = OneLogin::RubySaml::Settings.new
|
|
654
|
-
settings.private_key = valid_key
|
|
655
|
-
signature_wrapping_attack = read_response("encrypted_new_attack.xml.base64")
|
|
656
|
-
response_wrapped = OneLogin::RubySaml::Response.new(signature_wrapping_attack, :settings => settings)
|
|
657
|
-
response_wrapped.stubs(:conditions).returns(nil)
|
|
658
|
-
response_wrapped.stubs(:validate_subject_confirmation).returns(true)
|
|
659
|
-
settings.idp_cert_fingerprint = "385b1eec71143f00db6af936e2ea12a28771d72c"
|
|
660
|
-
assert !response_wrapped.is_valid?
|
|
661
|
-
err = assert_raises(OneLogin::RubySaml::ValidationError) do
|
|
662
|
-
response_wrapped.validate!
|
|
663
|
-
end
|
|
664
|
-
assert_equal "Found an invalid Signed Element. SAML Response rejected", err.message
|
|
665
|
-
end
|
|
666
|
-
end
|
|
667
|
-
|
|
668
|
-
describe "signature wrapping attack - concealed SAML response body" do
|
|
669
|
-
it "should not be valid" do
|
|
670
|
-
settings = OneLogin::RubySaml::Settings.new
|
|
671
|
-
signature_wrapping_attack = read_response("response_with_concealed_signed_assertion.xml")
|
|
672
|
-
response_wrapped = OneLogin::RubySaml::Response.new(signature_wrapping_attack, :settings => settings)
|
|
673
|
-
settings.idp_cert_fingerprint = '4b68c453c7d994aad9025c99d5efcf566287fe8d'
|
|
674
|
-
response_wrapped.stubs(:conditions).returns(nil)
|
|
675
|
-
response_wrapped.stubs(:validate_subject_confirmation).returns(true)
|
|
676
|
-
response_wrapped.stubs(:validate_structure).returns(true)
|
|
677
|
-
assert !response_wrapped.is_valid?
|
|
678
|
-
assert !response_wrapped.validate!
|
|
679
|
-
end
|
|
680
|
-
end
|
|
681
|
-
|
|
682
|
-
describe "signature wrapping attack - doubled signed assertion SAML response" do
|
|
683
|
-
it "should not be valid" do
|
|
684
|
-
settings = OneLogin::RubySaml::Settings.new
|
|
685
|
-
signature_wrapping_attack = read_response("response_with_doubled_signed_assertion.xml")
|
|
686
|
-
response_wrapped = OneLogin::RubySaml::Response.new(signature_wrapping_attack, :settings => settings)
|
|
687
|
-
settings.idp_cert_fingerprint = '4b68c453c7d994aad9025c99d5efcf566287fe8d'
|
|
688
|
-
response_wrapped.stubs(:conditions).returns(nil)
|
|
689
|
-
response_wrapped.stubs(:validate_subject_confirmation).returns(true)
|
|
690
|
-
assert !response_wrapped.is_valid?
|
|
376
|
+
assert_equal($evalled, nil)
|
|
691
377
|
end
|
|
692
378
|
end
|
|
693
379
|
end
|