ruby-saml 1.11.0 → 1.12.0
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.
Potentially problematic release.
This version of ruby-saml might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/.travis.yml +14 -12
- data/README.md +67 -19
- data/changelog.md +23 -0
- data/lib/onelogin/ruby-saml/attributes.rb +24 -1
- data/lib/onelogin/ruby-saml/authrequest.rb +9 -4
- data/lib/onelogin/ruby-saml/idp_metadata_parser.rb +62 -24
- data/lib/onelogin/ruby-saml/logoutrequest.rb +7 -1
- data/lib/onelogin/ruby-saml/logoutresponse.rb +4 -0
- data/lib/onelogin/ruby-saml/metadata.rb +9 -1
- data/lib/onelogin/ruby-saml/response.rb +37 -15
- data/lib/onelogin/ruby-saml/saml_message.rb +6 -0
- data/lib/onelogin/ruby-saml/setting_error.rb +6 -0
- data/lib/onelogin/ruby-saml/settings.rb +34 -2
- data/lib/onelogin/ruby-saml/slo_logoutrequest.rb +4 -0
- data/lib/onelogin/ruby-saml/slo_logoutresponse.rb +27 -14
- data/lib/onelogin/ruby-saml/utils.rb +56 -0
- data/lib/onelogin/ruby-saml/version.rb +1 -1
- data/lib/xml_security.rb +34 -6
- data/ruby-saml.gemspec +8 -4
- metadata +22 -282
- data/test/certificates/certificate.der +0 -0
- data/test/certificates/certificate1 +0 -12
- data/test/certificates/certificate_without_head_foot +0 -1
- 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/certificates/ruby-saml.crt +0 -14
- data/test/certificates/ruby-saml.key +0 -15
- data/test/idp_metadata_parser_test.rb +0 -594
- data/test/logging_test.rb +0 -62
- data/test/logout_requests/invalid_slo_request.xml +0 -6
- data/test/logout_requests/slo_request.xml +0 -4
- data/test/logout_requests/slo_request.xml.base64 +0 -1
- data/test/logout_requests/slo_request_deflated.xml.base64 +0 -1
- data/test/logout_requests/slo_request_with_name_id_format.xml +0 -4
- data/test/logout_requests/slo_request_with_session_index.xml +0 -5
- data/test/logout_responses/logoutresponse_fixtures.rb +0 -86
- data/test/logoutrequest_test.rb +0 -260
- data/test/logoutresponse_test.rb +0 -427
- data/test/metadata/idp_descriptor.xml +0 -26
- data/test/metadata/idp_descriptor_2.xml +0 -56
- data/test/metadata/idp_descriptor_3.xml +0 -14
- data/test/metadata/idp_descriptor_4.xml +0 -72
- data/test/metadata/idp_metadata_different_sign_and_encrypt_cert.xml +0 -72
- data/test/metadata/idp_metadata_multi_certs.xml +0 -75
- data/test/metadata/idp_metadata_multi_signing_certs.xml +0 -52
- data/test/metadata/idp_metadata_same_sign_and_encrypt_cert.xml +0 -71
- data/test/metadata/idp_multiple_descriptors.xml +0 -59
- data/test/metadata/idp_multiple_descriptors_2.xml +0 -59
- data/test/metadata/no_idp_descriptor.xml +0 -21
- data/test/metadata_test.rb +0 -331
- data/test/request_test.rb +0 -340
- data/test/response_test.rb +0 -1629
- data/test/responses/adfs_response_sha1.xml +0 -46
- data/test/responses/adfs_response_sha256.xml +0 -46
- data/test/responses/adfs_response_sha384.xml +0 -46
- data/test/responses/adfs_response_sha512.xml +0 -46
- data/test/responses/adfs_response_xmlns.xml +0 -45
- data/test/responses/attackxee.xml +0 -13
- data/test/responses/invalids/duplicated_attributes.xml.base64 +0 -1
- data/test/responses/invalids/empty_destination.xml.base64 +0 -1
- data/test/responses/invalids/empty_nameid.xml.base64 +0 -1
- data/test/responses/invalids/encrypted_new_attack.xml.base64 +0 -1
- data/test/responses/invalids/invalid_audience.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/invalid_signature_position.xml.base64 +0 -1
- data/test/responses/invalids/invalid_subjectconfirmation_inresponse.xml.base64 +0 -1
- data/test/responses/invalids/invalid_subjectconfirmation_nb.xml.base64 +0 -1
- data/test/responses/invalids/invalid_subjectconfirmation_noa.xml.base64 +0 -1
- data/test/responses/invalids/invalid_subjectconfirmation_recipient.xml.base64 +0 -1
- data/test/responses/invalids/multiple_assertions.xml.base64 +0 -2
- data/test/responses/invalids/multiple_signed.xml.base64 +0 -1
- data/test/responses/invalids/no_authnstatement.xml.base64 +0 -1
- data/test/responses/invalids/no_conditions.xml.base64 +0 -1
- data/test/responses/invalids/no_id.xml.base64 +0 -1
- data/test/responses/invalids/no_issuer_assertion.xml.base64 +0 -1
- data/test/responses/invalids/no_issuer_response.xml.base64 +0 -1
- data/test/responses/invalids/no_nameid.xml.base64 +0 -1
- data/test/responses/invalids/no_saml2.xml.base64 +0 -1
- data/test/responses/invalids/no_signature.xml.base64 +0 -1
- data/test/responses/invalids/no_status.xml.base64 +0 -1
- data/test/responses/invalids/no_status_code.xml.base64 +0 -1
- data/test/responses/invalids/no_subjectconfirmation_data.xml.base64 +0 -1
- data/test/responses/invalids/no_subjectconfirmation_method.xml.base64 +0 -1
- data/test/responses/invalids/response_invalid_signed_element.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/invalids/status_code_responder.xml.base64 +0 -1
- data/test/responses/invalids/status_code_responer_and_msg.xml.base64 +0 -1
- data/test/responses/invalids/wrong_spnamequalifier.xml.base64 +0 -1
- data/test/responses/no_signature_ns.xml +0 -48
- data/test/responses/open_saml_response.xml +0 -56
- data/test/responses/response_assertion_wrapped.xml.base64 +0 -93
- data/test/responses/response_audience_self_closed_tag.xml.base64 +0 -1
- data/test/responses/response_double_status_code.xml.base64 +0 -1
- data/test/responses/response_encrypted_attrs.xml.base64 +0 -1
- data/test/responses/response_encrypted_nameid.xml.base64 +0 -1
- data/test/responses/response_eval.xml +0 -7
- data/test/responses/response_no_cert_and_encrypted_attrs.xml +0 -29
- data/test/responses/response_node_text_attack.xml.base64 +0 -1
- data/test/responses/response_node_text_attack2.xml.base64 +0 -1
- data/test/responses/response_node_text_attack3.xml.base64 +0 -1
- data/test/responses/response_unsigned_xml_base64 +0 -1
- data/test/responses/response_with_ampersands.xml +0 -139
- data/test/responses/response_with_ampersands.xml.base64 +0 -93
- data/test/responses/response_with_ds_namespace_at_the_root.xml.base64 +0 -1
- data/test/responses/response_with_multiple_attribute_statements.xml +0 -72
- data/test/responses/response_with_multiple_attribute_values.xml +0 -67
- data/test/responses/response_with_retrieval_method.xml +0 -26
- data/test/responses/response_with_saml2_namespace.xml.base64 +0 -102
- data/test/responses/response_with_signed_assertion.xml.base64 +0 -66
- data/test/responses/response_with_signed_assertion_2.xml.base64 +0 -1
- 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_without_attributes.xml.base64 +0 -79
- data/test/responses/response_without_reference_uri.xml.base64 +0 -1
- data/test/responses/response_wrapped.xml.base64 +0 -150
- data/test/responses/signed_message_encrypted_signed_assertion.xml.base64 +0 -1
- data/test/responses/signed_message_encrypted_unsigned_assertion.xml.base64 +0 -1
- data/test/responses/signed_nameid_in_atts.xml +0 -47
- data/test/responses/signed_unqual_nameid_in_atts.xml +0 -47
- data/test/responses/simple_saml_php.xml +0 -71
- data/test/responses/starfield_response.xml.base64 +0 -1
- data/test/responses/test_sign.xml +0 -43
- data/test/responses/unsigned_encrypted_adfs.xml +0 -23
- data/test/responses/unsigned_message_aes128_encrypted_signed_assertion.xml.base64 +0 -1
- data/test/responses/unsigned_message_aes192_encrypted_signed_assertion.xml.base64 +0 -1
- data/test/responses/unsigned_message_aes256_encrypted_signed_assertion.xml.base64 +0 -1
- data/test/responses/unsigned_message_des192_encrypted_signed_assertion.xml.base64 +0 -1
- data/test/responses/unsigned_message_encrypted_assertion_without_saml_namespace.xml.base64 +0 -1
- data/test/responses/unsigned_message_encrypted_signed_assertion.xml.base64 +0 -1
- data/test/responses/unsigned_message_encrypted_unsigned_assertion.xml.base64 +0 -1
- data/test/responses/valid_response.xml.base64 +0 -1
- data/test/responses/valid_response_with_formatted_x509certificate.xml.base64 +0 -1
- data/test/responses/valid_response_without_x509certificate.xml.base64 +0 -1
- data/test/saml_message_test.rb +0 -56
- data/test/settings_test.rb +0 -338
- data/test/slo_logoutrequest_test.rb +0 -467
- data/test/slo_logoutresponse_test.rb +0 -233
- data/test/test_helper.rb +0 -333
- data/test/utils_test.rb +0 -259
- data/test/xml_security_test.rb +0 -421
data/test/settings_test.rb
DELETED
@@ -1,338 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
|
2
|
-
|
3
|
-
require 'onelogin/ruby-saml/settings'
|
4
|
-
require 'onelogin/ruby-saml/validation_error'
|
5
|
-
|
6
|
-
class SettingsTest < Minitest::Test
|
7
|
-
|
8
|
-
describe "Settings" do
|
9
|
-
before do
|
10
|
-
@settings = OneLogin::RubySaml::Settings.new
|
11
|
-
end
|
12
|
-
|
13
|
-
it "should provide getters and settings" do
|
14
|
-
accessors = [
|
15
|
-
:idp_entity_id, :idp_sso_target_url, :idp_slo_target_url, :valid_until,
|
16
|
-
:idp_cert, :idp_cert_fingerprint, :idp_cert_fingerprint_algorithm, :idp_cert_multi,
|
17
|
-
:idp_attribute_names, :issuer, :assertion_consumer_service_url, :assertion_consumer_service_binding,
|
18
|
-
:single_logout_service_url, :single_logout_service_binding,
|
19
|
-
:sp_name_qualifier, :name_identifier_format, :name_identifier_value, :name_identifier_value_requested,
|
20
|
-
:sessionindex, :attributes_index, :passive, :force_authn,
|
21
|
-
:compress_request, :double_quote_xml_attribute_values, :protocol_binding,
|
22
|
-
:security, :certificate, :private_key,
|
23
|
-
:authn_context, :authn_context_comparison, :authn_context_decl_ref,
|
24
|
-
:assertion_consumer_logout_service_url,
|
25
|
-
:assertion_consumer_logout_service_binding
|
26
|
-
]
|
27
|
-
|
28
|
-
accessors.each do |accessor|
|
29
|
-
value = Kernel.rand
|
30
|
-
@settings.send("#{accessor}=".to_sym, value)
|
31
|
-
assert_equal value, @settings.send(accessor)
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
it "create settings from hash" do
|
37
|
-
config = {
|
38
|
-
:assertion_consumer_service_url => "http://app.muda.no/sso",
|
39
|
-
:issuer => "http://muda.no",
|
40
|
-
:sp_name_qualifier => "http://sso.muda.no",
|
41
|
-
:idp_sso_target_url => "http://sso.muda.no/sso",
|
42
|
-
:idp_slo_target_url => "http://sso.muda.no/slo",
|
43
|
-
:idp_cert_fingerprint => "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00",
|
44
|
-
:valid_until => '2029-04-16T03:35:08.277Z',
|
45
|
-
:name_identifier_format => "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
|
46
|
-
:attributes_index => 30,
|
47
|
-
:passive => true,
|
48
|
-
:protocol_binding => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'
|
49
|
-
}
|
50
|
-
@settings = OneLogin::RubySaml::Settings.new(config)
|
51
|
-
|
52
|
-
config.each do |k,v|
|
53
|
-
assert_equal v, @settings.send(k)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
it "configure attribute service attributes correctly" do
|
58
|
-
@settings.attribute_consuming_service.configure do
|
59
|
-
service_name "Test Service"
|
60
|
-
add_attribute :name => "Name", :name_format => "Name Format", :friendly_name => "Friendly Name"
|
61
|
-
end
|
62
|
-
|
63
|
-
assert_equal @settings.attribute_consuming_service.configured?, true
|
64
|
-
assert_equal @settings.attribute_consuming_service.name, "Test Service"
|
65
|
-
assert_equal @settings.attribute_consuming_service.attributes, [{:name => "Name", :name_format => "Name Format", :friendly_name => "Friendly Name" }]
|
66
|
-
end
|
67
|
-
|
68
|
-
it "does not modify default security settings" do
|
69
|
-
settings = OneLogin::RubySaml::Settings.new
|
70
|
-
settings.security[:authn_requests_signed] = true
|
71
|
-
settings.security[:embed_sign] = true
|
72
|
-
settings.security[:digest_method] = XMLSecurity::Document::SHA256
|
73
|
-
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
|
74
|
-
|
75
|
-
new_settings = OneLogin::RubySaml::Settings.new
|
76
|
-
assert_equal new_settings.security[:authn_requests_signed], false
|
77
|
-
assert_equal new_settings.security[:embed_sign], false
|
78
|
-
assert_equal new_settings.security[:digest_method], XMLSecurity::Document::SHA1
|
79
|
-
assert_equal new_settings.security[:signature_method], XMLSecurity::Document::RSA_SHA1
|
80
|
-
end
|
81
|
-
|
82
|
-
it "overrides only provided security attributes passing a second parameter" do
|
83
|
-
config = {
|
84
|
-
:security => {
|
85
|
-
:metadata_signed => true
|
86
|
-
}
|
87
|
-
}
|
88
|
-
|
89
|
-
@default_attributes = OneLogin::RubySaml::Settings::DEFAULTS
|
90
|
-
|
91
|
-
@settings = OneLogin::RubySaml::Settings.new(config, true)
|
92
|
-
assert_equal @settings.security[:metadata_signed], true
|
93
|
-
assert_equal @settings.security[:digest_method], @default_attributes[:security][:digest_method]
|
94
|
-
end
|
95
|
-
|
96
|
-
it "doesn't override only provided security attributes without passing a second parameter" do
|
97
|
-
config = {
|
98
|
-
:security => {
|
99
|
-
:metadata_signed => true
|
100
|
-
}
|
101
|
-
}
|
102
|
-
|
103
|
-
@default_attributes = OneLogin::RubySaml::Settings::DEFAULTS
|
104
|
-
|
105
|
-
@settings = OneLogin::RubySaml::Settings.new(config)
|
106
|
-
assert_equal @settings.security[:metadata_signed], true
|
107
|
-
assert_nil @settings.security[:digest_method]
|
108
|
-
end
|
109
|
-
|
110
|
-
describe "#single_logout_service_url" do
|
111
|
-
it "when single_logout_service_url is nil but assertion_consumer_logout_service_url returns its value" do
|
112
|
-
@settings.single_logout_service_url = nil
|
113
|
-
@settings.assertion_consumer_logout_service_url = "http://app.muda.no/sls"
|
114
|
-
|
115
|
-
assert_equal "http://app.muda.no/sls", @settings.single_logout_service_url
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
describe "#single_logout_service_binding" do
|
120
|
-
it "when single_logout_service_binding is nil but assertion_consumer_logout_service_binding returns its value" do
|
121
|
-
@settings.single_logout_service_binding = nil
|
122
|
-
@settings.assertion_consumer_logout_service_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
123
|
-
|
124
|
-
assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", @settings.single_logout_service_binding
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
describe "#get_idp_cert" do
|
129
|
-
it "returns nil when the cert is an empty string" do
|
130
|
-
@settings.idp_cert = ""
|
131
|
-
assert_nil @settings.get_idp_cert
|
132
|
-
end
|
133
|
-
|
134
|
-
it "returns nil when the cert is nil" do
|
135
|
-
@settings.idp_cert = nil
|
136
|
-
assert_nil @settings.get_idp_cert
|
137
|
-
end
|
138
|
-
|
139
|
-
it "returns the certificate when it is valid" do
|
140
|
-
@settings.idp_cert = ruby_saml_cert_text
|
141
|
-
assert @settings.get_idp_cert.kind_of? OpenSSL::X509::Certificate
|
142
|
-
end
|
143
|
-
|
144
|
-
it "raises when the certificate is not valid" do
|
145
|
-
# formatted but invalid cert
|
146
|
-
@settings.idp_cert = read_certificate("formatted_certificate")
|
147
|
-
assert_raises(OpenSSL::X509::CertificateError) {
|
148
|
-
@settings.get_idp_cert
|
149
|
-
}
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
describe "#get_idp_cert_multi" do
|
154
|
-
it "returns nil when the value is empty" do
|
155
|
-
@settings.idp_cert = {}
|
156
|
-
assert_nil @settings.get_idp_cert_multi
|
157
|
-
end
|
158
|
-
|
159
|
-
it "returns nil when the idp_cert_multi is nil or empty" do
|
160
|
-
@settings.idp_cert_multi = nil
|
161
|
-
assert_nil @settings.get_idp_cert_multi
|
162
|
-
end
|
163
|
-
|
164
|
-
it "returns partial hash when contains some values" do
|
165
|
-
empty_multi = {
|
166
|
-
:signing => [],
|
167
|
-
:encryption => []
|
168
|
-
}
|
169
|
-
|
170
|
-
@settings.idp_cert_multi = {
|
171
|
-
:signing => []
|
172
|
-
}
|
173
|
-
assert_equal empty_multi, @settings.get_idp_cert_multi
|
174
|
-
|
175
|
-
@settings.idp_cert_multi = {
|
176
|
-
:encryption => []
|
177
|
-
}
|
178
|
-
assert_equal empty_multi, @settings.get_idp_cert_multi
|
179
|
-
|
180
|
-
@settings.idp_cert_multi = {
|
181
|
-
:signing => [],
|
182
|
-
:encryption => []
|
183
|
-
}
|
184
|
-
assert_equal empty_multi, @settings.get_idp_cert_multi
|
185
|
-
|
186
|
-
@settings.idp_cert_multi = {
|
187
|
-
:yyy => [],
|
188
|
-
:zzz => []
|
189
|
-
}
|
190
|
-
assert_equal empty_multi, @settings.get_idp_cert_multi
|
191
|
-
end
|
192
|
-
|
193
|
-
it "returns the hash with certificates when values were valid" do
|
194
|
-
certificates = ruby_saml_cert_text
|
195
|
-
@settings.idp_cert_multi = {
|
196
|
-
:signing => [ruby_saml_cert_text],
|
197
|
-
:encryption => [ruby_saml_cert_text],
|
198
|
-
}
|
199
|
-
|
200
|
-
assert @settings.get_idp_cert_multi.kind_of? Hash
|
201
|
-
assert @settings.get_idp_cert_multi[:signing].kind_of? Array
|
202
|
-
assert @settings.get_idp_cert_multi[:encryption].kind_of? Array
|
203
|
-
assert @settings.get_idp_cert_multi[:signing][0].kind_of? OpenSSL::X509::Certificate
|
204
|
-
assert @settings.get_idp_cert_multi[:encryption][0].kind_of? OpenSSL::X509::Certificate
|
205
|
-
end
|
206
|
-
|
207
|
-
it "raises when there is a cert in idp_cert_multi not valid" do
|
208
|
-
certificate = read_certificate("formatted_certificate")
|
209
|
-
|
210
|
-
@settings.idp_cert_multi = {
|
211
|
-
:signing => [],
|
212
|
-
:encryption => []
|
213
|
-
}
|
214
|
-
@settings.idp_cert_multi[:signing].push(certificate)
|
215
|
-
@settings.idp_cert_multi[:encryption].push(certificate)
|
216
|
-
|
217
|
-
assert_raises(OpenSSL::X509::CertificateError) {
|
218
|
-
@settings.get_idp_cert_multi
|
219
|
-
}
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
describe "#get_sp_cert" do
|
224
|
-
it "returns nil when the cert is an empty string" do
|
225
|
-
@settings.certificate = ""
|
226
|
-
assert_nil @settings.get_sp_cert
|
227
|
-
end
|
228
|
-
|
229
|
-
it "returns nil when the cert is nil" do
|
230
|
-
@settings.certificate = nil
|
231
|
-
assert_nil @settings.get_sp_cert
|
232
|
-
end
|
233
|
-
|
234
|
-
it "returns the certificate when it is valid" do
|
235
|
-
@settings.certificate = ruby_saml_cert_text
|
236
|
-
assert @settings.get_sp_cert.kind_of? OpenSSL::X509::Certificate
|
237
|
-
end
|
238
|
-
|
239
|
-
it "raises when the certificate is not valid" do
|
240
|
-
# formatted but invalid cert
|
241
|
-
@settings.certificate = read_certificate("formatted_certificate")
|
242
|
-
assert_raises(OpenSSL::X509::CertificateError) {
|
243
|
-
@settings.get_sp_cert
|
244
|
-
}
|
245
|
-
end
|
246
|
-
|
247
|
-
it "raises an error if SP certificate expired and check_sp_cert_expiration enabled" do
|
248
|
-
@settings.certificate = ruby_saml_cert_text
|
249
|
-
@settings.security[:check_sp_cert_expiration] = true
|
250
|
-
assert_raises(OneLogin::RubySaml::ValidationError) {
|
251
|
-
settings.get_sp_cert
|
252
|
-
}
|
253
|
-
end
|
254
|
-
end
|
255
|
-
|
256
|
-
describe "#get_sp_cert_new" do
|
257
|
-
it "returns nil when the cert is an empty string" do
|
258
|
-
@settings.certificate_new = ""
|
259
|
-
assert_nil @settings.get_sp_cert_new
|
260
|
-
end
|
261
|
-
|
262
|
-
it "returns nil when the cert is nil" do
|
263
|
-
@settings.certificate_new = nil
|
264
|
-
assert_nil @settings.get_sp_cert_new
|
265
|
-
end
|
266
|
-
|
267
|
-
it "returns the certificate when it is valid" do
|
268
|
-
@settings.certificate_new = ruby_saml_cert_text
|
269
|
-
assert @settings.get_sp_cert_new.kind_of? OpenSSL::X509::Certificate
|
270
|
-
end
|
271
|
-
|
272
|
-
it "raises when the certificate is not valid" do
|
273
|
-
# formatted but invalid cert
|
274
|
-
@settings.certificate_new = read_certificate("formatted_certificate")
|
275
|
-
assert_raises(OpenSSL::X509::CertificateError) {
|
276
|
-
@settings.get_sp_cert_new
|
277
|
-
}
|
278
|
-
end
|
279
|
-
|
280
|
-
end
|
281
|
-
|
282
|
-
describe "#get_sp_key" do
|
283
|
-
it "returns nil when the private key is an empty string" do
|
284
|
-
@settings.private_key = ""
|
285
|
-
assert_nil @settings.get_sp_key
|
286
|
-
end
|
287
|
-
|
288
|
-
it "returns nil when the private key is nil" do
|
289
|
-
@settings.private_key = nil
|
290
|
-
assert_nil @settings.get_sp_key
|
291
|
-
end
|
292
|
-
|
293
|
-
it "returns the private key when it is valid" do
|
294
|
-
@settings.private_key = ruby_saml_key_text
|
295
|
-
assert @settings.get_sp_key.kind_of? OpenSSL::PKey::RSA
|
296
|
-
end
|
297
|
-
|
298
|
-
it "raises when the private key is not valid" do
|
299
|
-
# formatted but invalid rsa private key
|
300
|
-
@settings.private_key = read_certificate("formatted_rsa_private_key")
|
301
|
-
assert_raises(OpenSSL::PKey::RSAError) {
|
302
|
-
@settings.get_sp_key
|
303
|
-
}
|
304
|
-
end
|
305
|
-
|
306
|
-
end
|
307
|
-
|
308
|
-
describe "#get_fingerprint" do
|
309
|
-
it "get the fingerprint value when cert and fingerprint in settings are nil" do
|
310
|
-
@settings.idp_cert_fingerprint = nil
|
311
|
-
@settings.idp_cert = nil
|
312
|
-
fingerprint = @settings.get_fingerprint
|
313
|
-
assert_nil fingerprint
|
314
|
-
end
|
315
|
-
|
316
|
-
it "get the fingerprint value when there is a cert at the settings" do
|
317
|
-
@settings.idp_cert_fingerprint = nil
|
318
|
-
@settings.idp_cert = ruby_saml_cert_text
|
319
|
-
fingerprint = @settings.get_fingerprint
|
320
|
-
assert fingerprint.downcase == ruby_saml_cert_fingerprint.downcase
|
321
|
-
end
|
322
|
-
|
323
|
-
it "get the fingerprint value when there is a fingerprint at the settings" do
|
324
|
-
@settings.idp_cert_fingerprint = ruby_saml_cert_fingerprint
|
325
|
-
@settings.idp_cert = nil
|
326
|
-
fingerprint = @settings.get_fingerprint
|
327
|
-
assert fingerprint.downcase == ruby_saml_cert_fingerprint.downcase
|
328
|
-
end
|
329
|
-
|
330
|
-
it "get the fingerprint value when there are cert and fingerprint at the settings" do
|
331
|
-
@settings.idp_cert_fingerprint = ruby_saml_cert_fingerprint
|
332
|
-
@settings.idp_cert = ruby_saml_cert_text
|
333
|
-
fingerprint = @settings.get_fingerprint
|
334
|
-
assert fingerprint.downcase == ruby_saml_cert_fingerprint.downcase
|
335
|
-
end
|
336
|
-
end
|
337
|
-
end
|
338
|
-
end
|
@@ -1,467 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
|
2
|
-
require 'logout_responses/logoutresponse_fixtures'
|
3
|
-
|
4
|
-
require 'onelogin/ruby-saml/slo_logoutrequest'
|
5
|
-
require 'timecop'
|
6
|
-
|
7
|
-
class RubySamlTest < Minitest::Test
|
8
|
-
|
9
|
-
describe "SloLogoutrequest" do
|
10
|
-
|
11
|
-
let(:settings) { OneLogin::RubySaml::Settings.new }
|
12
|
-
let(:logout_request) { OneLogin::RubySaml::SloLogoutrequest.new(logout_request_document) }
|
13
|
-
let(:invalid_logout_request) { OneLogin::RubySaml::SloLogoutrequest.new(invalid_logout_request_document) }
|
14
|
-
|
15
|
-
before do
|
16
|
-
settings.idp_entity_id = 'https://app.onelogin.com/saml/metadata/SOMEACCOUNT'
|
17
|
-
settings.soft = true
|
18
|
-
logout_request.settings = settings
|
19
|
-
invalid_logout_request.settings = settings
|
20
|
-
end
|
21
|
-
|
22
|
-
describe "initiator" do
|
23
|
-
it "raise an exception when logout request is initialized with nil" do
|
24
|
-
assert_raises(ArgumentError) { OneLogin::RubySaml::SloLogoutrequest.new(nil) }
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
describe "#is_valid?" do
|
29
|
-
it "return false when logout request is initialized with blank data" do
|
30
|
-
logout_request_blank = OneLogin::RubySaml::SloLogoutrequest.new('')
|
31
|
-
assert !logout_request_blank.is_valid?
|
32
|
-
assert_includes logout_request_blank.errors, 'Blank logout request'
|
33
|
-
end
|
34
|
-
|
35
|
-
it "return true when the logout request is initialized with valid data" do
|
36
|
-
assert logout_request.is_valid?
|
37
|
-
assert_empty logout_request.errors
|
38
|
-
assert_equal 'someone@example.org', logout_request.nameid
|
39
|
-
end
|
40
|
-
|
41
|
-
it "should be idempotent when the logout request is initialized with invalid data" do
|
42
|
-
assert !invalid_logout_request.is_valid?
|
43
|
-
assert_equal ['Invalid SAML Logout Request. Not match the saml-schema-protocol-2.0.xsd'], invalid_logout_request.errors
|
44
|
-
assert !invalid_logout_request.is_valid?
|
45
|
-
assert_equal ['Invalid SAML Logout Request. Not match the saml-schema-protocol-2.0.xsd'], invalid_logout_request.errors
|
46
|
-
end
|
47
|
-
|
48
|
-
it "should be idempotent when the logout request is initialized with valid data" do
|
49
|
-
assert logout_request.is_valid?
|
50
|
-
assert_empty logout_request.errors
|
51
|
-
assert logout_request.is_valid?
|
52
|
-
assert_empty logout_request.errors
|
53
|
-
end
|
54
|
-
|
55
|
-
it "collect errors when collect_errors=true" do
|
56
|
-
settings.idp_entity_id = 'http://idp.example.com/invalid'
|
57
|
-
settings.idp_slo_target_url = "http://example.com?field=value"
|
58
|
-
settings.security[:logout_requests_signed] = true
|
59
|
-
settings.security[:embed_sign] = false
|
60
|
-
settings.certificate = ruby_saml_cert_text
|
61
|
-
settings.private_key = ruby_saml_key_text
|
62
|
-
settings.idp_cert = ruby_saml_cert_text
|
63
|
-
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
|
64
|
-
params = {}
|
65
|
-
params['SAMLRequest'] = logout_request_deflated_base64
|
66
|
-
params['RelayState'] = 'http://invalid.example.com'
|
67
|
-
params['Signature'] = 'invalid_signature'
|
68
|
-
params['SigAlg'] = XMLSecurity::Document::RSA_SHA1
|
69
|
-
options = {}
|
70
|
-
options[:get_params] = params
|
71
|
-
|
72
|
-
logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
|
73
|
-
logout_request_sign_test.settings = settings
|
74
|
-
|
75
|
-
collect_errors = true
|
76
|
-
assert !logout_request_sign_test.is_valid?(collect_errors)
|
77
|
-
assert_includes logout_request_sign_test.errors, "Invalid Signature on Logout Request"
|
78
|
-
assert_includes logout_request_sign_test.errors, "Doesn't match the issuer, expected: <http://idp.example.com/invalid>, but was: <https://app.onelogin.com/saml/metadata/SOMEACCOUNT>"
|
79
|
-
end
|
80
|
-
|
81
|
-
it "raise error for invalid xml" do
|
82
|
-
invalid_logout_request.soft = false
|
83
|
-
assert_raises(OneLogin::RubySaml::ValidationError) { invalid_logout_request.is_valid? }
|
84
|
-
end
|
85
|
-
|
86
|
-
end
|
87
|
-
|
88
|
-
describe "#nameid" do
|
89
|
-
it "extract the value of the name id element" do
|
90
|
-
assert_equal "someone@example.org", logout_request.nameid
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
describe "#nameid_format" do
|
95
|
-
let(:logout_request) { OneLogin::RubySaml::SloLogoutrequest.new(logout_request_document_with_name_id_format) }
|
96
|
-
|
97
|
-
it "extract the format attribute of the name id element" do
|
98
|
-
assert_equal "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", logout_request.nameid_format
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
describe "#issuer" do
|
103
|
-
it "return the issuer inside the logout request" do
|
104
|
-
assert_equal "https://app.onelogin.com/saml/metadata/SOMEACCOUNT", logout_request.issuer
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
describe "#id" do
|
109
|
-
it "extract the value of the ID attribute" do
|
110
|
-
assert_equal "_c0348950-935b-0131-1060-782bcb56fcaa", logout_request.id
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
describe "#not_on_or_after" do
|
115
|
-
it "extract the value of the NotOnOrAfter attribute" do
|
116
|
-
time_value = '2014-07-17T01:01:48Z'
|
117
|
-
assert_nil logout_request.not_on_or_after
|
118
|
-
logout_request.document.root.attributes['NotOnOrAfter'] = time_value
|
119
|
-
assert_equal Time.parse(time_value), logout_request.not_on_or_after
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
describe '#session_indexes' do
|
124
|
-
it "return empty array when no SessionIndex" do
|
125
|
-
assert_equal [], logout_request.session_indexes
|
126
|
-
end
|
127
|
-
|
128
|
-
it "return an Array with one SessionIndex" do
|
129
|
-
logout_request_with_session_index = OneLogin::RubySaml::SloLogoutrequest.new(logout_request_xml_with_session_index)
|
130
|
-
assert_equal ['_ea853497-c58a-408a-bc23-c849752d9741'], logout_request_with_session_index.session_indexes
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
describe "#validate_id" do
|
135
|
-
it "return true when there is a valid ID in the logout request" do
|
136
|
-
assert logout_request.send(:validate_id)
|
137
|
-
assert_empty logout_request.errors
|
138
|
-
end
|
139
|
-
|
140
|
-
it "return false when there is an invalid ID in the logout request" do
|
141
|
-
logout_request_blank = OneLogin::RubySaml::SloLogoutrequest.new('')
|
142
|
-
assert !logout_request_blank.send(:validate_id)
|
143
|
-
assert_includes logout_request_blank.errors, "Missing ID attribute on Logout Request"
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
describe "#validate_version" do
|
148
|
-
it "return true when the logout request is SAML 2.0 Version" do
|
149
|
-
assert logout_request.send(:validate_version)
|
150
|
-
end
|
151
|
-
|
152
|
-
it "return false when the logout request is not SAML 2.0 Version" do
|
153
|
-
logout_request_blank = OneLogin::RubySaml::SloLogoutrequest.new('')
|
154
|
-
assert !logout_request_blank.send(:validate_version)
|
155
|
-
assert_includes logout_request_blank.errors, "Unsupported SAML version"
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
describe "#validate_not_on_or_after" do
|
160
|
-
it "return true when the logout request has a valid NotOnOrAfter or does not contain any" do
|
161
|
-
assert logout_request.send(:validate_not_on_or_after)
|
162
|
-
assert_empty logout_request.errors
|
163
|
-
Timecop.freeze Time.parse('2011-06-14T18:25:01.516Z') do
|
164
|
-
time_value = '2014-07-17T01:01:48Z'
|
165
|
-
logout_request.document.root.attributes['NotOnOrAfter'] = time_value
|
166
|
-
assert logout_request.send(:validate_not_on_or_after)
|
167
|
-
assert_empty logout_request.errors
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
it "return false when the logout request has an invalid NotOnOrAfter" do
|
172
|
-
logout_request.document.root.attributes['NotOnOrAfter'] = '2014-07-17T01:01:48Z'
|
173
|
-
assert !logout_request.send(:validate_not_on_or_after)
|
174
|
-
assert /Current time is on or after NotOnOrAfter/.match(logout_request.errors[0])
|
175
|
-
end
|
176
|
-
|
177
|
-
it "raise when the logout request has an invalid NotOnOrAfter" do
|
178
|
-
logout_request.document.root.attributes['NotOnOrAfter'] = '2014-07-17T01:01:48Z'
|
179
|
-
logout_request.soft = false
|
180
|
-
assert_raises(OneLogin::RubySaml::ValidationError, "Current time is on or after NotOnOrAfter") do
|
181
|
-
logout_request.send(:validate_not_on_or_after)
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
describe "#validate_request_state" do
|
187
|
-
it "return true when valid logout request xml" do
|
188
|
-
assert logout_request.send(:validate_request_state)
|
189
|
-
assert_empty logout_request.errors
|
190
|
-
assert logout_request.send(:validate_request_state)
|
191
|
-
assert_empty logout_request.errors
|
192
|
-
end
|
193
|
-
|
194
|
-
it "return false when invalid logout request xml" do
|
195
|
-
logout_request_blank = OneLogin::RubySaml::SloLogoutrequest.new('')
|
196
|
-
logout_request_blank.soft = true
|
197
|
-
assert !logout_request_blank.send(:validate_request_state)
|
198
|
-
assert_includes logout_request_blank.errors, "Blank logout request"
|
199
|
-
end
|
200
|
-
|
201
|
-
it "raise error for invalid xml" do
|
202
|
-
logout_request_blank = OneLogin::RubySaml::SloLogoutrequest.new('')
|
203
|
-
logout_request_blank.soft = false
|
204
|
-
assert_raises(OneLogin::RubySaml::ValidationError, "Blank logout request") do
|
205
|
-
logout_request_blank.send(:validate_request_state)
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
describe "#validate_structure" do
|
211
|
-
it "return true when encountering a valid Logout Request xml" do
|
212
|
-
assert logout_request.send(:validate_structure)
|
213
|
-
assert_empty logout_request.errors
|
214
|
-
end
|
215
|
-
|
216
|
-
it "return false when encountering a Logout Request bad formatted" do
|
217
|
-
assert !invalid_logout_request.send(:validate_structure)
|
218
|
-
assert_includes invalid_logout_request.errors, "Invalid SAML Logout Request. Not match the saml-schema-protocol-2.0.xsd"
|
219
|
-
end
|
220
|
-
|
221
|
-
it "raise when encountering a Logout Request bad formatted" do
|
222
|
-
invalid_logout_request.soft = false
|
223
|
-
assert_raises(OneLogin::RubySaml::ValidationError, "Element '{urn:oasis:names:tc:SAML:2.0:assertion}Issuer': This element is not expected") do
|
224
|
-
invalid_logout_request.send(:validate_structure)
|
225
|
-
end
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
describe "#validate_issuer" do
|
230
|
-
it "return true when the issuer of the Logout Request matchs the IdP entityId" do
|
231
|
-
logout_request.settings.idp_entity_id = 'https://app.onelogin.com/saml/metadata/SOMEACCOUNT'
|
232
|
-
assert logout_request.send(:validate_issuer)
|
233
|
-
end
|
234
|
-
it "return false when the issuer of the Logout Request does not match the IdP entityId" do
|
235
|
-
logout_request.settings.idp_entity_id = 'http://idp.example.com/invalid'
|
236
|
-
assert !logout_request.send(:validate_issuer)
|
237
|
-
assert_includes logout_request.errors, "Doesn't match the issuer, expected: <#{logout_request.settings.idp_entity_id}>, but was: <https://app.onelogin.com/saml/metadata/SOMEACCOUNT>"
|
238
|
-
end
|
239
|
-
it "raise when the issuer of the Logout Request does not match the IdP entityId" do
|
240
|
-
logout_request.settings.idp_entity_id = 'http://idp.example.com/invalid'
|
241
|
-
logout_request.soft = false
|
242
|
-
assert_raises(OneLogin::RubySaml::ValidationError, "Doesn't match the issuer, expected: <#{logout_request.settings.idp_entity_id}>, but was: <https://app.onelogin.com/saml/metadata/SOMEACCOUNT>") do
|
243
|
-
logout_request.send(:validate_issuer)
|
244
|
-
end
|
245
|
-
end
|
246
|
-
end
|
247
|
-
|
248
|
-
describe "#validate_signature" do
|
249
|
-
before do
|
250
|
-
settings.idp_slo_target_url = "http://example.com?field=value"
|
251
|
-
settings.security[:logout_requests_signed] = true
|
252
|
-
settings.security[:embed_sign] = false
|
253
|
-
settings.certificate = ruby_saml_cert_text
|
254
|
-
settings.private_key = ruby_saml_key_text
|
255
|
-
settings.idp_cert = ruby_saml_cert_text
|
256
|
-
end
|
257
|
-
|
258
|
-
it "return true when no idp_cert is provided and option :relax_signature_validation is present" do
|
259
|
-
settings.idp_cert = nil
|
260
|
-
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
|
261
|
-
params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
|
262
|
-
params['RelayState'] = params[:RelayState]
|
263
|
-
options = {}
|
264
|
-
options[:get_params] = params
|
265
|
-
options[:relax_signature_validation] = true
|
266
|
-
logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
|
267
|
-
logout_request_sign_test.settings = settings
|
268
|
-
assert logout_request_sign_test.send(:validate_signature)
|
269
|
-
end
|
270
|
-
|
271
|
-
it "return false when no idp_cert is provided and no option :relax_signature_validation is present" do
|
272
|
-
settings.idp_cert = nil
|
273
|
-
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
|
274
|
-
params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
|
275
|
-
params['RelayState'] = params[:RelayState]
|
276
|
-
options = {}
|
277
|
-
options[:get_params] = params
|
278
|
-
logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
|
279
|
-
logout_request_sign_test.settings = settings
|
280
|
-
assert !logout_request_sign_test.send(:validate_signature)
|
281
|
-
end
|
282
|
-
|
283
|
-
it "return true when valid RSA_SHA1 Signature" do
|
284
|
-
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
|
285
|
-
params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
|
286
|
-
params['RelayState'] = params[:RelayState]
|
287
|
-
options = {}
|
288
|
-
options[:get_params] = params
|
289
|
-
logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
|
290
|
-
logout_request_sign_test.settings = settings
|
291
|
-
assert logout_request_sign_test.send(:validate_signature)
|
292
|
-
end
|
293
|
-
|
294
|
-
it "return true when valid RSA_SHA256 Signature" do
|
295
|
-
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
|
296
|
-
params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
|
297
|
-
options = {}
|
298
|
-
options[:get_params] = params
|
299
|
-
logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
|
300
|
-
params['RelayState'] = params[:RelayState]
|
301
|
-
logout_request_sign_test.settings = settings
|
302
|
-
assert logout_request_sign_test.send(:validate_signature)
|
303
|
-
end
|
304
|
-
|
305
|
-
it "return false when invalid RSA_SHA1 Signature" do
|
306
|
-
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
|
307
|
-
params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
|
308
|
-
params['RelayState'] = 'http://invalid.example.com'
|
309
|
-
params[:RelayState] = params['RelayState']
|
310
|
-
options = {}
|
311
|
-
options[:get_params] = params
|
312
|
-
|
313
|
-
logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
|
314
|
-
logout_request_sign_test.settings = settings
|
315
|
-
assert !logout_request_sign_test.send(:validate_signature)
|
316
|
-
end
|
317
|
-
|
318
|
-
it "raise when invalid RSA_SHA1 Signature" do
|
319
|
-
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
|
320
|
-
settings.soft = false
|
321
|
-
params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
|
322
|
-
params['RelayState'] = 'http://invalid.example.com'
|
323
|
-
params[:RelayState] = params['RelayState']
|
324
|
-
options = {}
|
325
|
-
options[:get_params] = params
|
326
|
-
options[:settings] = settings
|
327
|
-
|
328
|
-
logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
|
329
|
-
assert_raises(OneLogin::RubySaml::ValidationError, "Invalid Signature on Logout Request") do
|
330
|
-
logout_request_sign_test.send(:validate_signature)
|
331
|
-
end
|
332
|
-
end
|
333
|
-
|
334
|
-
it "raise when get_params encoding differs from what this library generates" do
|
335
|
-
# Use Logoutrequest only to build the SAMLRequest parameter.
|
336
|
-
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
|
337
|
-
settings.soft = false
|
338
|
-
params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, "RelayState" => "http://example.com")
|
339
|
-
# Assemble query string.
|
340
|
-
query = OneLogin::RubySaml::Utils.build_query(
|
341
|
-
:type => 'SAMLRequest',
|
342
|
-
:data => params['SAMLRequest'],
|
343
|
-
:relay_state => params['RelayState'],
|
344
|
-
:sig_alg => params['SigAlg']
|
345
|
-
)
|
346
|
-
# Modify the query string so that it encodes the same values,
|
347
|
-
# but with different percent-encoding. Sanity-check that they
|
348
|
-
# really are equialent before moving on.
|
349
|
-
original_query = query.dup
|
350
|
-
query.gsub!("example", "ex%61mple")
|
351
|
-
refute_equal(query, original_query)
|
352
|
-
assert_equal(CGI.unescape(query), CGI.unescape(original_query))
|
353
|
-
# Make normalised signature based on our modified params.
|
354
|
-
sign_algorithm = XMLSecurity::BaseDocument.new.algorithm(settings.security[:signature_method])
|
355
|
-
signature = settings.get_sp_key.sign(sign_algorithm.new, query)
|
356
|
-
params['Signature'] = Base64.encode64(signature).gsub(/\n/, "")
|
357
|
-
# Construct SloLogoutrequest and ask it to validate the signature.
|
358
|
-
# It will do it incorrectly, because it will compute it based on re-encoded
|
359
|
-
# query parameters, rather than their original encodings.
|
360
|
-
options = {}
|
361
|
-
options[:get_params] = params
|
362
|
-
options[:settings] = settings
|
363
|
-
logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
|
364
|
-
assert_raises(OneLogin::RubySaml::ValidationError, "Invalid Signature on Logout Request") do
|
365
|
-
logout_request_sign_test.send(:validate_signature)
|
366
|
-
end
|
367
|
-
end
|
368
|
-
|
369
|
-
it "return true even if raw_get_params encoding differs from what this library generates" do
|
370
|
-
# Use Logoutrequest only to build the SAMLRequest parameter.
|
371
|
-
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
|
372
|
-
settings.soft = false
|
373
|
-
params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, "RelayState" => "http://example.com")
|
374
|
-
# Assemble query string.
|
375
|
-
query = OneLogin::RubySaml::Utils.build_query(
|
376
|
-
:type => 'SAMLRequest',
|
377
|
-
:data => params['SAMLRequest'],
|
378
|
-
:relay_state => params['RelayState'],
|
379
|
-
:sig_alg => params['SigAlg']
|
380
|
-
)
|
381
|
-
# Modify the query string so that it encodes the same values,
|
382
|
-
# but with different percent-encoding. Sanity-check that they
|
383
|
-
# really are equialent before moving on.
|
384
|
-
original_query = query.dup
|
385
|
-
query.gsub!("example", "ex%61mple")
|
386
|
-
refute_equal(query, original_query)
|
387
|
-
assert_equal(CGI.unescape(query), CGI.unescape(original_query))
|
388
|
-
# Make normalised signature based on our modified params.
|
389
|
-
sign_algorithm = XMLSecurity::BaseDocument.new.algorithm(settings.security[:signature_method])
|
390
|
-
signature = settings.get_sp_key.sign(sign_algorithm.new, query)
|
391
|
-
params['Signature'] = Base64.encode64(signature).gsub(/\n/, "")
|
392
|
-
# Construct SloLogoutrequest and ask it to validate the signature.
|
393
|
-
# Provide the altered parameter in its raw URI-encoded form,
|
394
|
-
# so that we don't have to guess the value that contributed to the signature.
|
395
|
-
options = {}
|
396
|
-
options[:get_params] = params
|
397
|
-
options[:get_params].delete("RelayState")
|
398
|
-
options[:raw_get_params] = {
|
399
|
-
"RelayState" => "http%3A%2F%2Fex%61mple.com",
|
400
|
-
}
|
401
|
-
options[:settings] = settings
|
402
|
-
logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
|
403
|
-
assert logout_request_sign_test.send(:validate_signature)
|
404
|
-
end
|
405
|
-
end
|
406
|
-
|
407
|
-
describe "#validate_signature with multiple idp certs" do
|
408
|
-
before do
|
409
|
-
settings.idp_slo_target_url = "http://example.com?field=value"
|
410
|
-
settings.certificate = ruby_saml_cert_text
|
411
|
-
settings.private_key = ruby_saml_key_text
|
412
|
-
settings.idp_cert = nil
|
413
|
-
settings.security[:logout_requests_signed] = true
|
414
|
-
settings.security[:embed_sign] = false
|
415
|
-
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
|
416
|
-
end
|
417
|
-
|
418
|
-
it "return true when at least a idp_cert is valid" do
|
419
|
-
params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
|
420
|
-
params['RelayState'] = params[:RelayState]
|
421
|
-
options = {}
|
422
|
-
options[:get_params] = params
|
423
|
-
logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
|
424
|
-
settings.idp_cert_multi = {
|
425
|
-
:signing => [ruby_saml_cert_text2, ruby_saml_cert_text],
|
426
|
-
:encryption => []
|
427
|
-
}
|
428
|
-
logout_request_sign_test.settings = settings
|
429
|
-
assert logout_request_sign_test.send(:validate_signature)
|
430
|
-
end
|
431
|
-
|
432
|
-
it "return false when cert expired and check_idp_cert_expiration expired" do
|
433
|
-
params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
|
434
|
-
params['RelayState'] = params[:RelayState]
|
435
|
-
options = {}
|
436
|
-
options[:get_params] = params
|
437
|
-
settings.security[:check_idp_cert_expiration] = true
|
438
|
-
logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
|
439
|
-
settings.idp_cert = nil
|
440
|
-
settings.idp_cert_multi = {
|
441
|
-
:signing => [ruby_saml_cert_text],
|
442
|
-
:encryption => []
|
443
|
-
}
|
444
|
-
logout_request_sign_test.settings = settings
|
445
|
-
assert !logout_request_sign_test.send(:validate_signature)
|
446
|
-
assert_includes logout_request_sign_test.errors, "IdP x509 certificate expired"
|
447
|
-
end
|
448
|
-
|
449
|
-
it "return false when none cert on idp_cert_multi is valid" do
|
450
|
-
params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
|
451
|
-
params['RelayState'] = params[:RelayState]
|
452
|
-
options = {}
|
453
|
-
options[:get_params] = params
|
454
|
-
logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
|
455
|
-
settings.idp_cert_fingerprint = ruby_saml_cert_fingerprint
|
456
|
-
settings.idp_cert_multi = {
|
457
|
-
:signing => [ruby_saml_cert_text2, ruby_saml_cert_text2],
|
458
|
-
:encryption => []
|
459
|
-
}
|
460
|
-
logout_request_sign_test.settings = settings
|
461
|
-
assert !logout_request_sign_test.send(:validate_signature)
|
462
|
-
assert_includes logout_request_sign_test.errors, "Invalid Signature on Logout Request"
|
463
|
-
|
464
|
-
end
|
465
|
-
end
|
466
|
-
end
|
467
|
-
end
|