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.

Files changed (158) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +14 -12
  3. data/README.md +67 -19
  4. data/changelog.md +23 -0
  5. data/lib/onelogin/ruby-saml/attributes.rb +24 -1
  6. data/lib/onelogin/ruby-saml/authrequest.rb +9 -4
  7. data/lib/onelogin/ruby-saml/idp_metadata_parser.rb +62 -24
  8. data/lib/onelogin/ruby-saml/logoutrequest.rb +7 -1
  9. data/lib/onelogin/ruby-saml/logoutresponse.rb +4 -0
  10. data/lib/onelogin/ruby-saml/metadata.rb +9 -1
  11. data/lib/onelogin/ruby-saml/response.rb +37 -15
  12. data/lib/onelogin/ruby-saml/saml_message.rb +6 -0
  13. data/lib/onelogin/ruby-saml/setting_error.rb +6 -0
  14. data/lib/onelogin/ruby-saml/settings.rb +34 -2
  15. data/lib/onelogin/ruby-saml/slo_logoutrequest.rb +4 -0
  16. data/lib/onelogin/ruby-saml/slo_logoutresponse.rb +27 -14
  17. data/lib/onelogin/ruby-saml/utils.rb +56 -0
  18. data/lib/onelogin/ruby-saml/version.rb +1 -1
  19. data/lib/xml_security.rb +34 -6
  20. data/ruby-saml.gemspec +8 -4
  21. metadata +22 -282
  22. data/test/certificates/certificate.der +0 -0
  23. data/test/certificates/certificate1 +0 -12
  24. data/test/certificates/certificate_without_head_foot +0 -1
  25. data/test/certificates/formatted_certificate +0 -14
  26. data/test/certificates/formatted_chained_certificate +0 -42
  27. data/test/certificates/formatted_private_key +0 -12
  28. data/test/certificates/formatted_rsa_private_key +0 -12
  29. data/test/certificates/invalid_certificate1 +0 -1
  30. data/test/certificates/invalid_certificate2 +0 -1
  31. data/test/certificates/invalid_certificate3 +0 -12
  32. data/test/certificates/invalid_chained_certificate1 +0 -1
  33. data/test/certificates/invalid_private_key1 +0 -1
  34. data/test/certificates/invalid_private_key2 +0 -1
  35. data/test/certificates/invalid_private_key3 +0 -10
  36. data/test/certificates/invalid_rsa_private_key1 +0 -1
  37. data/test/certificates/invalid_rsa_private_key2 +0 -1
  38. data/test/certificates/invalid_rsa_private_key3 +0 -10
  39. data/test/certificates/ruby-saml-2.crt +0 -15
  40. data/test/certificates/ruby-saml.crt +0 -14
  41. data/test/certificates/ruby-saml.key +0 -15
  42. data/test/idp_metadata_parser_test.rb +0 -594
  43. data/test/logging_test.rb +0 -62
  44. data/test/logout_requests/invalid_slo_request.xml +0 -6
  45. data/test/logout_requests/slo_request.xml +0 -4
  46. data/test/logout_requests/slo_request.xml.base64 +0 -1
  47. data/test/logout_requests/slo_request_deflated.xml.base64 +0 -1
  48. data/test/logout_requests/slo_request_with_name_id_format.xml +0 -4
  49. data/test/logout_requests/slo_request_with_session_index.xml +0 -5
  50. data/test/logout_responses/logoutresponse_fixtures.rb +0 -86
  51. data/test/logoutrequest_test.rb +0 -260
  52. data/test/logoutresponse_test.rb +0 -427
  53. data/test/metadata/idp_descriptor.xml +0 -26
  54. data/test/metadata/idp_descriptor_2.xml +0 -56
  55. data/test/metadata/idp_descriptor_3.xml +0 -14
  56. data/test/metadata/idp_descriptor_4.xml +0 -72
  57. data/test/metadata/idp_metadata_different_sign_and_encrypt_cert.xml +0 -72
  58. data/test/metadata/idp_metadata_multi_certs.xml +0 -75
  59. data/test/metadata/idp_metadata_multi_signing_certs.xml +0 -52
  60. data/test/metadata/idp_metadata_same_sign_and_encrypt_cert.xml +0 -71
  61. data/test/metadata/idp_multiple_descriptors.xml +0 -59
  62. data/test/metadata/idp_multiple_descriptors_2.xml +0 -59
  63. data/test/metadata/no_idp_descriptor.xml +0 -21
  64. data/test/metadata_test.rb +0 -331
  65. data/test/request_test.rb +0 -340
  66. data/test/response_test.rb +0 -1629
  67. data/test/responses/adfs_response_sha1.xml +0 -46
  68. data/test/responses/adfs_response_sha256.xml +0 -46
  69. data/test/responses/adfs_response_sha384.xml +0 -46
  70. data/test/responses/adfs_response_sha512.xml +0 -46
  71. data/test/responses/adfs_response_xmlns.xml +0 -45
  72. data/test/responses/attackxee.xml +0 -13
  73. data/test/responses/invalids/duplicated_attributes.xml.base64 +0 -1
  74. data/test/responses/invalids/empty_destination.xml.base64 +0 -1
  75. data/test/responses/invalids/empty_nameid.xml.base64 +0 -1
  76. data/test/responses/invalids/encrypted_new_attack.xml.base64 +0 -1
  77. data/test/responses/invalids/invalid_audience.xml.base64 +0 -1
  78. data/test/responses/invalids/invalid_issuer_assertion.xml.base64 +0 -1
  79. data/test/responses/invalids/invalid_issuer_message.xml.base64 +0 -1
  80. data/test/responses/invalids/invalid_signature_position.xml.base64 +0 -1
  81. data/test/responses/invalids/invalid_subjectconfirmation_inresponse.xml.base64 +0 -1
  82. data/test/responses/invalids/invalid_subjectconfirmation_nb.xml.base64 +0 -1
  83. data/test/responses/invalids/invalid_subjectconfirmation_noa.xml.base64 +0 -1
  84. data/test/responses/invalids/invalid_subjectconfirmation_recipient.xml.base64 +0 -1
  85. data/test/responses/invalids/multiple_assertions.xml.base64 +0 -2
  86. data/test/responses/invalids/multiple_signed.xml.base64 +0 -1
  87. data/test/responses/invalids/no_authnstatement.xml.base64 +0 -1
  88. data/test/responses/invalids/no_conditions.xml.base64 +0 -1
  89. data/test/responses/invalids/no_id.xml.base64 +0 -1
  90. data/test/responses/invalids/no_issuer_assertion.xml.base64 +0 -1
  91. data/test/responses/invalids/no_issuer_response.xml.base64 +0 -1
  92. data/test/responses/invalids/no_nameid.xml.base64 +0 -1
  93. data/test/responses/invalids/no_saml2.xml.base64 +0 -1
  94. data/test/responses/invalids/no_signature.xml.base64 +0 -1
  95. data/test/responses/invalids/no_status.xml.base64 +0 -1
  96. data/test/responses/invalids/no_status_code.xml.base64 +0 -1
  97. data/test/responses/invalids/no_subjectconfirmation_data.xml.base64 +0 -1
  98. data/test/responses/invalids/no_subjectconfirmation_method.xml.base64 +0 -1
  99. data/test/responses/invalids/response_invalid_signed_element.xml.base64 +0 -1
  100. data/test/responses/invalids/response_with_concealed_signed_assertion.xml +0 -51
  101. data/test/responses/invalids/response_with_doubled_signed_assertion.xml +0 -49
  102. data/test/responses/invalids/signature_wrapping_attack.xml.base64 +0 -1
  103. data/test/responses/invalids/status_code_responder.xml.base64 +0 -1
  104. data/test/responses/invalids/status_code_responer_and_msg.xml.base64 +0 -1
  105. data/test/responses/invalids/wrong_spnamequalifier.xml.base64 +0 -1
  106. data/test/responses/no_signature_ns.xml +0 -48
  107. data/test/responses/open_saml_response.xml +0 -56
  108. data/test/responses/response_assertion_wrapped.xml.base64 +0 -93
  109. data/test/responses/response_audience_self_closed_tag.xml.base64 +0 -1
  110. data/test/responses/response_double_status_code.xml.base64 +0 -1
  111. data/test/responses/response_encrypted_attrs.xml.base64 +0 -1
  112. data/test/responses/response_encrypted_nameid.xml.base64 +0 -1
  113. data/test/responses/response_eval.xml +0 -7
  114. data/test/responses/response_no_cert_and_encrypted_attrs.xml +0 -29
  115. data/test/responses/response_node_text_attack.xml.base64 +0 -1
  116. data/test/responses/response_node_text_attack2.xml.base64 +0 -1
  117. data/test/responses/response_node_text_attack3.xml.base64 +0 -1
  118. data/test/responses/response_unsigned_xml_base64 +0 -1
  119. data/test/responses/response_with_ampersands.xml +0 -139
  120. data/test/responses/response_with_ampersands.xml.base64 +0 -93
  121. data/test/responses/response_with_ds_namespace_at_the_root.xml.base64 +0 -1
  122. data/test/responses/response_with_multiple_attribute_statements.xml +0 -72
  123. data/test/responses/response_with_multiple_attribute_values.xml +0 -67
  124. data/test/responses/response_with_retrieval_method.xml +0 -26
  125. data/test/responses/response_with_saml2_namespace.xml.base64 +0 -102
  126. data/test/responses/response_with_signed_assertion.xml.base64 +0 -66
  127. data/test/responses/response_with_signed_assertion_2.xml.base64 +0 -1
  128. data/test/responses/response_with_signed_assertion_3.xml +0 -30
  129. data/test/responses/response_with_signed_message_and_assertion.xml +0 -34
  130. data/test/responses/response_with_undefined_recipient.xml.base64 +0 -1
  131. data/test/responses/response_without_attributes.xml.base64 +0 -79
  132. data/test/responses/response_without_reference_uri.xml.base64 +0 -1
  133. data/test/responses/response_wrapped.xml.base64 +0 -150
  134. data/test/responses/signed_message_encrypted_signed_assertion.xml.base64 +0 -1
  135. data/test/responses/signed_message_encrypted_unsigned_assertion.xml.base64 +0 -1
  136. data/test/responses/signed_nameid_in_atts.xml +0 -47
  137. data/test/responses/signed_unqual_nameid_in_atts.xml +0 -47
  138. data/test/responses/simple_saml_php.xml +0 -71
  139. data/test/responses/starfield_response.xml.base64 +0 -1
  140. data/test/responses/test_sign.xml +0 -43
  141. data/test/responses/unsigned_encrypted_adfs.xml +0 -23
  142. data/test/responses/unsigned_message_aes128_encrypted_signed_assertion.xml.base64 +0 -1
  143. data/test/responses/unsigned_message_aes192_encrypted_signed_assertion.xml.base64 +0 -1
  144. data/test/responses/unsigned_message_aes256_encrypted_signed_assertion.xml.base64 +0 -1
  145. data/test/responses/unsigned_message_des192_encrypted_signed_assertion.xml.base64 +0 -1
  146. data/test/responses/unsigned_message_encrypted_assertion_without_saml_namespace.xml.base64 +0 -1
  147. data/test/responses/unsigned_message_encrypted_signed_assertion.xml.base64 +0 -1
  148. data/test/responses/unsigned_message_encrypted_unsigned_assertion.xml.base64 +0 -1
  149. data/test/responses/valid_response.xml.base64 +0 -1
  150. data/test/responses/valid_response_with_formatted_x509certificate.xml.base64 +0 -1
  151. data/test/responses/valid_response_without_x509certificate.xml.base64 +0 -1
  152. data/test/saml_message_test.rb +0 -56
  153. data/test/settings_test.rb +0 -338
  154. data/test/slo_logoutrequest_test.rb +0 -467
  155. data/test/slo_logoutresponse_test.rb +0 -233
  156. data/test/test_helper.rb +0 -333
  157. data/test/utils_test.rb +0 -259
  158. data/test/xml_security_test.rb +0 -421
@@ -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