ruby-saml 1.11.0 → 1.12.1

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 +76 -22
  4. data/changelog.md +27 -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 +38 -16
  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,331 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
2
-
3
- require 'onelogin/ruby-saml/metadata'
4
-
5
- class MetadataTest < Minitest::Test
6
-
7
- describe 'Metadata' do
8
- let(:settings) { OneLogin::RubySaml::Settings.new }
9
- let(:xml_text) { OneLogin::RubySaml::Metadata.new.generate(settings, false) }
10
- let(:xml_doc) { REXML::Document.new(xml_text) }
11
- let(:spsso_descriptor) { REXML::XPath.first(xml_doc, "//md:SPSSODescriptor") }
12
- let(:acs) { REXML::XPath.first(xml_doc, "//md:AssertionConsumerService") }
13
-
14
- before do
15
- settings.sp_entity_id = "https://example.com"
16
- settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
17
- settings.assertion_consumer_service_url = "https://foo.example/saml/consume"
18
- end
19
-
20
- it "generates Pretty Print Service Provider Metadata" do
21
- xml_text = OneLogin::RubySaml::Metadata.new.generate(settings, true)
22
- # assert correct xml declaration
23
- start = "<?xml version='1.0' encoding='UTF-8'?>\n<md:EntityDescriptor"
24
- assert_equal xml_text[0..start.length-1],start
25
-
26
- assert_equal "https://example.com", REXML::XPath.first(xml_doc, "//md:EntityDescriptor").attribute("entityID").value
27
-
28
- assert_equal "urn:oasis:names:tc:SAML:2.0:protocol", spsso_descriptor.attribute("protocolSupportEnumeration").value
29
- assert_equal "false", spsso_descriptor.attribute("AuthnRequestsSigned").value
30
- assert_equal "false", spsso_descriptor.attribute("WantAssertionsSigned").value
31
-
32
- assert_equal "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", REXML::XPath.first(xml_doc, "//md:NameIDFormat").text.strip
33
-
34
- assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST", acs.attribute("Binding").value
35
- assert_equal "https://foo.example/saml/consume", acs.attribute("Location").value
36
-
37
- assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
38
- end
39
-
40
- it "generates Service Provider Metadata" do
41
- settings.single_logout_service_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
42
- settings.single_logout_service_url = "https://foo.example/saml/sls"
43
- xml_metadata = OneLogin::RubySaml::Metadata.new.generate(settings, false)
44
-
45
- start = "<?xml version='1.0' encoding='UTF-8'?><md:EntityDescriptor"
46
- assert_equal xml_metadata[0..start.length-1],start
47
-
48
- doc_metadata = REXML::Document.new(xml_metadata)
49
- sls = REXML::XPath.first(doc_metadata, "//md:SingleLogoutService")
50
-
51
- assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", sls.attribute("Binding").value
52
- assert_equal "https://foo.example/saml/sls", sls.attribute("Location").value
53
- assert_equal "https://foo.example/saml/sls", sls.attribute("ResponseLocation").value
54
- assert_nil sls.attribute("isDefault")
55
- assert_nil sls.attribute("index")
56
-
57
- assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
58
- end
59
-
60
- it "generates Service Provider Metadata with single logout service" do
61
- start = "<?xml version='1.0' encoding='UTF-8'?><md:EntityDescriptor"
62
- assert_equal xml_text[0..start.length-1], start
63
-
64
- assert_equal "https://example.com", REXML::XPath.first(xml_doc, "//md:EntityDescriptor").attribute("entityID").value
65
-
66
- assert_equal "urn:oasis:names:tc:SAML:2.0:protocol", spsso_descriptor.attribute("protocolSupportEnumeration").value
67
- assert_equal "false", spsso_descriptor.attribute("AuthnRequestsSigned").value
68
- assert_equal "false", spsso_descriptor.attribute("WantAssertionsSigned").value
69
-
70
- assert_equal "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", REXML::XPath.first(xml_doc, "//md:NameIDFormat").text.strip
71
-
72
- assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST", acs.attribute("Binding").value
73
- assert_equal "https://foo.example/saml/consume", acs.attribute("Location").value
74
-
75
- assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
76
- end
77
-
78
- describe "WantAssertionsSigned" do
79
- it "generates Service Provider Metadata with WantAssertionsSigned = false" do
80
- settings.security[:want_assertions_signed] = false
81
- assert_equal "false", spsso_descriptor.attribute("WantAssertionsSigned").value
82
- assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
83
- end
84
-
85
- it "generates Service Provider Metadata with WantAssertionsSigned = true" do
86
- settings.security[:want_assertions_signed] = true
87
- assert_equal "true", spsso_descriptor.attribute("WantAssertionsSigned").value
88
- assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
89
- end
90
- end
91
-
92
- describe "with a sign/encrypt certificate" do
93
- let(:key_descriptors) do
94
- REXML::XPath.match(
95
- xml_doc,
96
- "//md:KeyDescriptor",
97
- "md" => "urn:oasis:names:tc:SAML:2.0:metadata"
98
- )
99
- end
100
- let(:cert_nodes) do
101
- REXML::XPath.match(
102
- xml_doc,
103
- "//md:KeyDescriptor/ds:KeyInfo/ds:X509Data/ds:X509Certificate",
104
- "md" => "urn:oasis:names:tc:SAML:2.0:metadata",
105
- "ds" => "http://www.w3.org/2000/09/xmldsig#"
106
- )
107
- end
108
- let(:cert) { OpenSSL::X509::Certificate.new(Base64.decode64(cert_nodes[0].text)) }
109
-
110
- before do
111
- settings.certificate = ruby_saml_cert_text
112
- end
113
-
114
- it "generates Service Provider Metadata with X509Certificate for sign" do
115
- assert_equal 1, key_descriptors.length
116
- assert_equal "signing", key_descriptors[0].attribute("use").value
117
-
118
- assert_equal 1, cert_nodes.length
119
- assert_equal ruby_saml_cert.to_der, cert.to_der
120
-
121
- assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
122
- end
123
-
124
- describe "and signed authentication requests" do
125
- before do
126
- settings.security[:authn_requests_signed] = true
127
- end
128
-
129
- it "generates Service Provider Metadata with AuthnRequestsSigned" do
130
- assert_equal "true", spsso_descriptor.attribute("AuthnRequestsSigned").value
131
- assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
132
- end
133
- end
134
-
135
- describe "and encrypted assertions" do
136
- before do
137
- settings.security[:want_assertions_encrypted] = true
138
- end
139
-
140
- it "generates Service Provider Metadata with X509Certificate for encrypt" do
141
- assert_equal 2, key_descriptors.length
142
-
143
- assert_equal "encryption", key_descriptors[1].attribute("use").value
144
-
145
- assert_equal 2, cert_nodes.length
146
- assert_equal cert_nodes[0].text, cert_nodes[1].text
147
- assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
148
- end
149
- end
150
- end
151
-
152
- describe "with a future SP certificate" do
153
- let(:key_descriptors) do
154
- REXML::XPath.match(
155
- xml_doc,
156
- "//md:KeyDescriptor",
157
- "md" => "urn:oasis:names:tc:SAML:2.0:metadata"
158
- )
159
- end
160
- let(:cert_nodes) do
161
- REXML::XPath.match(
162
- xml_doc,
163
- "//md:KeyDescriptor/ds:KeyInfo/ds:X509Data/ds:X509Certificate",
164
- "md" => "urn:oasis:names:tc:SAML:2.0:metadata",
165
- "ds" => "http://www.w3.org/2000/09/xmldsig#"
166
- )
167
- end
168
-
169
- before do
170
- settings.certificate = ruby_saml_cert_text
171
- settings.certificate_new = ruby_saml_cert_text2
172
- end
173
-
174
- it "generates Service Provider Metadata with 2 X509Certificate for sign" do
175
- assert_equal 2, key_descriptors.length
176
- assert_equal "signing", key_descriptors[0].attribute("use").value
177
- assert_equal "signing", key_descriptors[1].attribute("use").value
178
-
179
- cert = OpenSSL::X509::Certificate.new(Base64.decode64(cert_nodes[0].text))
180
- cert_new = OpenSSL::X509::Certificate.new(Base64.decode64(cert_nodes[1].text))
181
-
182
- assert_equal 2, cert_nodes.length
183
- assert_equal ruby_saml_cert.to_der, cert.to_der
184
- assert_equal ruby_saml_cert2.to_der, cert_new.to_der
185
-
186
- assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
187
- end
188
-
189
- describe "and signed authentication requests" do
190
- before do
191
- settings.security[:authn_requests_signed] = true
192
- end
193
-
194
- it "generates Service Provider Metadata with AuthnRequestsSigned" do
195
- assert_equal "true", spsso_descriptor.attribute("AuthnRequestsSigned").value
196
- assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
197
- end
198
- end
199
-
200
- describe "and encrypted assertions" do
201
- before do
202
- settings.security[:want_assertions_encrypted] = true
203
- end
204
-
205
- it "generates Service Provider Metadata with X509Certificate for encrypt" do
206
- assert_equal 4, key_descriptors.length
207
- assert_equal "signing", key_descriptors[0].attribute("use").value
208
- assert_equal "encryption", key_descriptors[1].attribute("use").value
209
- assert_equal "signing", key_descriptors[2].attribute("use").value
210
- assert_equal "encryption", key_descriptors[3].attribute("use").value
211
-
212
- assert_equal 4, cert_nodes.length
213
- assert_equal cert_nodes[0].text, cert_nodes[1].text
214
- assert_equal cert_nodes[2].text, cert_nodes[3].text
215
- assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
216
- end
217
- end
218
-
219
- end
220
-
221
- describe "when attribute service is configured with multiple attribute values" do
222
- let(:attr_svc) { REXML::XPath.first(xml_doc, "//md:AttributeConsumingService") }
223
- let(:req_attr) { REXML::XPath.first(xml_doc, "//md:RequestedAttribute") }
224
-
225
- before do
226
- settings.attribute_consuming_service.configure do
227
- service_name "Test Service"
228
- add_attribute(:name => 'Name', :name_format => 'Name Format', :friendly_name => 'Friendly Name', :attribute_value => ['Attribute Value One', false])
229
- end
230
- end
231
-
232
- it "generates attribute service" do
233
- assert_equal "true", attr_svc.attribute("isDefault").value
234
- assert_equal "1", attr_svc.attribute("index").value
235
- assert_equal REXML::XPath.first(xml_doc, "//md:ServiceName").text.strip, "Test Service"
236
-
237
- assert_equal "Name", req_attr.attribute("Name").value
238
- assert_equal "Name Format", req_attr.attribute("NameFormat").value
239
- assert_equal "Friendly Name", req_attr.attribute("FriendlyName").value
240
-
241
- attribute_values = REXML::XPath.match(xml_doc, "//saml:AttributeValue").map(&:text)
242
- assert_equal "Attribute Value One", attribute_values[0]
243
- assert_equal 'false', attribute_values[1]
244
-
245
- assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
246
- end
247
- end
248
-
249
- describe "when attribute service is configured" do
250
- let(:attr_svc) { REXML::XPath.first(xml_doc, '//md:AttributeConsumingService') }
251
- let(:req_attr) { REXML::XPath.first(xml_doc, '//md:RequestedAttribute') }
252
-
253
- before do
254
- settings.attribute_consuming_service.configure do
255
- service_name "Test Service"
256
- add_attribute(:name => 'active', :name_format => 'format', :friendly_name => 'Active', :attribute_value => true)
257
- end
258
- end
259
-
260
- it "generates attribute service" do
261
- assert_equal "true", attr_svc.attribute("isDefault").value
262
- assert_equal "1", attr_svc.attribute("index").value
263
- assert_equal REXML::XPath.first(xml_doc, "//md:ServiceName").text.strip, "Test Service"
264
-
265
- assert_equal 'active', req_attr.attribute('Name').value
266
- assert_equal 'format', req_attr.attribute('NameFormat').value
267
- assert_equal 'Active', req_attr.attribute('FriendlyName').value
268
- assert_equal 'true', REXML::XPath.first(xml_doc, '//saml:AttributeValue').text.strip
269
-
270
- assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
271
- end
272
-
273
- describe "#service_name" do
274
- before do
275
- settings.attribute_consuming_service.service_name("Test2 Service")
276
- end
277
-
278
- it "change service name" do
279
- assert_equal REXML::XPath.first(xml_doc, "//md:ServiceName").text.strip, "Test2 Service"
280
- end
281
- end
282
-
283
- describe "#service_index" do
284
- before do
285
- settings.attribute_consuming_service.service_index(2)
286
- end
287
-
288
- it "change service index" do
289
- assert_equal "2", attr_svc.attribute("index").value
290
- end
291
- end
292
- end
293
-
294
- describe "when the settings indicate to sign (embedded) metadata" do
295
- before do
296
- settings.security[:metadata_signed] = true
297
- settings.certificate = ruby_saml_cert_text
298
- settings.private_key = ruby_saml_key_text
299
- end
300
-
301
- it "creates a signed metadata" do
302
- assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>]m, xml_text
303
- assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1'/>], xml_text
304
- assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/>], xml_text
305
- signed_metadata = XMLSecurity::SignedDocument.new(xml_text)
306
- assert signed_metadata.validate_document(ruby_saml_cert_fingerprint, false)
307
-
308
- assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
309
- end
310
-
311
- describe "when digest and signature methods are specified" do
312
- before do
313
- settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
314
- settings.security[:digest_method] = XMLSecurity::Document::SHA512
315
- end
316
-
317
- it "creates a signed metadata with specified digest and signature methods" do
318
- assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>]m, xml_text
319
- assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'/>], xml_text
320
- assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2001/04/xmlenc#sha512'/>], xml_text
321
-
322
- signed_metadata_2 = XMLSecurity::SignedDocument.new(xml_text)
323
-
324
- assert signed_metadata_2.validate_document(ruby_saml_cert_fingerprint, false)
325
-
326
- assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
327
- end
328
- end
329
- end
330
- end
331
- end
data/test/request_test.rb DELETED
@@ -1,340 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
2
-
3
- require 'onelogin/ruby-saml/authrequest'
4
-
5
- class RequestTest < Minitest::Test
6
-
7
- describe "Authrequest" do
8
- let(:settings) { OneLogin::RubySaml::Settings.new }
9
-
10
- before do
11
- settings.idp_sso_target_url = "http://example.com"
12
- end
13
-
14
- it "create the deflated SAMLRequest URL parameter" do
15
- auth_url = OneLogin::RubySaml::Authrequest.new.create(settings)
16
- assert_match /^http:\/\/example\.com\?SAMLRequest=/, auth_url
17
- payload = CGI.unescape(auth_url.split("=").last)
18
- decoded = Base64.decode64(payload)
19
-
20
- zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
21
- inflated = zstream.inflate(decoded)
22
- zstream.finish
23
- zstream.close
24
-
25
- assert_match /^<samlp:AuthnRequest/, inflated
26
- end
27
-
28
- it "create the deflated SAMLRequest URL parameter including the Destination" do
29
- auth_url = OneLogin::RubySaml::Authrequest.new.create(settings)
30
- payload = CGI.unescape(auth_url.split("=").last)
31
- decoded = Base64.decode64(payload)
32
-
33
- zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
34
- inflated = zstream.inflate(decoded)
35
- zstream.finish
36
- zstream.close
37
-
38
- assert_match /<samlp:AuthnRequest[^<]* Destination='http:\/\/example.com'/, inflated
39
- end
40
-
41
- it "create the SAMLRequest URL parameter without deflating" do
42
- settings.compress_request = false
43
- auth_url = OneLogin::RubySaml::Authrequest.new.create(settings)
44
- assert_match /^http:\/\/example\.com\?SAMLRequest=/, auth_url
45
- payload = CGI.unescape(auth_url.split("=").last)
46
- decoded = Base64.decode64(payload)
47
-
48
- assert_match /^<samlp:AuthnRequest/, decoded
49
- end
50
-
51
- it "create the SAMLRequest URL parameter with IsPassive" do
52
- settings.passive = true
53
- auth_url = OneLogin::RubySaml::Authrequest.new.create(settings)
54
- assert_match /^http:\/\/example\.com\?SAMLRequest=/, auth_url
55
- payload = CGI.unescape(auth_url.split("=").last)
56
- decoded = Base64.decode64(payload)
57
-
58
- zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
59
- inflated = zstream.inflate(decoded)
60
- zstream.finish
61
- zstream.close
62
-
63
- assert_match /<samlp:AuthnRequest[^<]* IsPassive='true'/, inflated
64
- end
65
-
66
- it "create the SAMLRequest URL parameter with ProtocolBinding" do
67
- settings.protocol_binding = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'
68
- auth_url = OneLogin::RubySaml::Authrequest.new.create(settings)
69
- assert_match /^http:\/\/example\.com\?SAMLRequest=/, auth_url
70
- payload = CGI.unescape(auth_url.split("=").last)
71
- decoded = Base64.decode64(payload)
72
-
73
- zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
74
- inflated = zstream.inflate(decoded)
75
- zstream.finish
76
- zstream.close
77
-
78
- assert_match /<samlp:AuthnRequest[^<]* ProtocolBinding='urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'/, inflated
79
- end
80
-
81
- it "create the SAMLRequest URL parameter with AttributeConsumingServiceIndex" do
82
- settings.attributes_index = 30
83
- auth_url = OneLogin::RubySaml::Authrequest.new.create(settings)
84
- assert_match /^http:\/\/example\.com\?SAMLRequest=/, auth_url
85
- payload = CGI.unescape(auth_url.split("=").last)
86
- decoded = Base64.decode64(payload)
87
-
88
- zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
89
- inflated = zstream.inflate(decoded)
90
- zstream.finish
91
- zstream.close
92
- assert_match /<samlp:AuthnRequest[^<]* AttributeConsumingServiceIndex='30'/, inflated
93
- end
94
-
95
- it "create the SAMLRequest URL parameter with ForceAuthn" do
96
- settings.force_authn = true
97
- auth_url = OneLogin::RubySaml::Authrequest.new.create(settings)
98
- assert_match /^http:\/\/example\.com\?SAMLRequest=/, auth_url
99
- payload = CGI.unescape(auth_url.split("=").last)
100
- decoded = Base64.decode64(payload)
101
-
102
- zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
103
- inflated = zstream.inflate(decoded)
104
- zstream.finish
105
- zstream.close
106
- assert_match /<samlp:AuthnRequest[^<]* ForceAuthn='true'/, inflated
107
- end
108
-
109
- it "create the SAMLRequest URL parameter with NameID Format" do
110
- settings.name_identifier_format = "urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
111
- auth_url = OneLogin::RubySaml::Authrequest.new.create(settings)
112
- assert_match /^http:\/\/example\.com\?SAMLRequest=/, auth_url
113
- payload = CGI.unescape(auth_url.split("=").last)
114
- decoded = Base64.decode64(payload)
115
- zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
116
- inflated = zstream.inflate(decoded)
117
- zstream.finish
118
- zstream.close
119
-
120
- assert_match /<samlp:NameIDPolicy[^<]* AllowCreate='true'/, inflated
121
- assert_match /<samlp:NameIDPolicy[^<]* Format='urn:oasis:names:tc:SAML:2.0:nameid-format:transient'/, inflated
122
- end
123
-
124
- it "create the SAMLRequest URL parameter with Subject" do
125
- settings.name_identifier_value_requested = "testuser@example.com"
126
- settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
127
- auth_url = OneLogin::RubySaml::Authrequest.new.create(settings)
128
- assert_match /^http:\/\/example\.com\?SAMLRequest=/, auth_url
129
- payload = CGI.unescape(auth_url.split("=").last)
130
- decoded = Base64.decode64(payload)
131
- zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
132
- inflated = zstream.inflate(decoded)
133
- zstream.finish
134
- zstream.close
135
-
136
- assert inflated.include?('<saml:Subject>')
137
- assert inflated.include?("<saml:NameID Format='urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress'>testuser@example.com</saml:NameID>")
138
- assert inflated.include?("<saml:SubjectConfirmation Method='urn:oasis:names:tc:SAML:2.0:cm:bearer'/>")
139
- end
140
-
141
- it "accept extra parameters" do
142
- auth_url = OneLogin::RubySaml::Authrequest.new.create(settings, { :hello => "there" })
143
- assert_match /&hello=there$/, auth_url
144
-
145
- auth_url = OneLogin::RubySaml::Authrequest.new.create(settings, { :hello => nil })
146
- assert_match /&hello=$/, auth_url
147
- end
148
-
149
- it "RelayState cases" do
150
- auth_url = OneLogin::RubySaml::Authrequest.new.create(settings, { :RelayState => nil })
151
- assert !auth_url.include?('RelayState')
152
-
153
- auth_url = OneLogin::RubySaml::Authrequest.new.create(settings, { :RelayState => "http://example.com" })
154
- assert auth_url.include?('&RelayState=http%3A%2F%2Fexample.com')
155
-
156
- auth_url = OneLogin::RubySaml::Authrequest.new.create(settings, { 'RelayState' => nil })
157
- assert !auth_url.include?('RelayState')
158
-
159
- auth_url = OneLogin::RubySaml::Authrequest.new.create(settings, { 'RelayState' => "http://example.com" })
160
- assert auth_url.include?('&RelayState=http%3A%2F%2Fexample.com')
161
- end
162
-
163
- describe "when the target url is not set" do
164
- before do
165
- settings.idp_sso_target_url = nil
166
- end
167
-
168
- it "raises an error with a descriptive message" do
169
- err = assert_raises RuntimeError do
170
- OneLogin::RubySaml::Authrequest.new.create(settings)
171
- end
172
- assert_match /idp_sso_target_url is not set/, err.message
173
- end
174
- end
175
-
176
- describe "when the target url doesn't contain a query string" do
177
- it "create the SAMLRequest parameter correctly" do
178
-
179
- auth_url = OneLogin::RubySaml::Authrequest.new.create(settings)
180
- assert_match /^http:\/\/example.com\?SAMLRequest/, auth_url
181
- end
182
- end
183
-
184
- describe "when the target url contains a query string" do
185
- it "create the SAMLRequest parameter correctly" do
186
- settings.idp_sso_target_url = "http://example.com?field=value"
187
-
188
- auth_url = OneLogin::RubySaml::Authrequest.new.create(settings)
189
- assert_match /^http:\/\/example.com\?field=value&SAMLRequest/, auth_url
190
- end
191
- end
192
-
193
- it "create the saml:AuthnContextClassRef element correctly" do
194
- settings.authn_context = 'secure/name/password/uri'
195
- auth_doc = OneLogin::RubySaml::Authrequest.new.create_authentication_xml_doc(settings)
196
- assert_match /<saml:AuthnContextClassRef>secure\/name\/password\/uri<\/saml:AuthnContextClassRef>/, auth_doc.to_s
197
- end
198
-
199
- it "create multiple saml:AuthnContextClassRef elements correctly" do
200
- settings.authn_context = ['secure/name/password/uri', 'secure/email/password/uri']
201
- auth_doc = OneLogin::RubySaml::Authrequest.new.create_authentication_xml_doc(settings)
202
- assert_match /<saml:AuthnContextClassRef>secure\/name\/password\/uri<\/saml:AuthnContextClassRef>/, auth_doc.to_s
203
- assert_match /<saml:AuthnContextClassRef>secure\/email\/password\/uri<\/saml:AuthnContextClassRef>/, auth_doc.to_s
204
- end
205
-
206
- it "create the saml:AuthnContextClassRef with comparison exact" do
207
- settings.authn_context = 'secure/name/password/uri'
208
- auth_doc = OneLogin::RubySaml::Authrequest.new.create_authentication_xml_doc(settings)
209
- assert_match /<samlp:RequestedAuthnContext[\S ]+Comparison='exact'/, auth_doc.to_s
210
- assert_match /<saml:AuthnContextClassRef>secure\/name\/password\/uri<\/saml:AuthnContextClassRef>/, auth_doc.to_s
211
- end
212
-
213
- it "create the saml:AuthnContextClassRef with comparison minimun" do
214
- settings.authn_context = 'secure/name/password/uri'
215
- settings.authn_context_comparison = 'minimun'
216
- auth_doc = OneLogin::RubySaml::Authrequest.new.create_authentication_xml_doc(settings)
217
- assert_match /<samlp:RequestedAuthnContext[\S ]+Comparison='minimun'/, auth_doc.to_s
218
- assert_match /<saml:AuthnContextClassRef>secure\/name\/password\/uri<\/saml:AuthnContextClassRef>/, auth_doc.to_s
219
- end
220
-
221
- it "create the saml:AuthnContextDeclRef element correctly" do
222
- settings.authn_context_decl_ref = 'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport'
223
- auth_doc = OneLogin::RubySaml::Authrequest.new.create_authentication_xml_doc(settings)
224
- assert_match /<saml:AuthnContextDeclRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport<\/saml:AuthnContextDeclRef>/, auth_doc.to_s
225
- end
226
-
227
- describe "#create_params when the settings indicate to sign (embebed) the request" do
228
- before do
229
- settings.compress_request = false
230
- settings.idp_sso_target_url = "http://example.com?field=value"
231
- settings.security[:authn_requests_signed] = true
232
- settings.security[:embed_sign] = true
233
- settings.certificate = ruby_saml_cert_text
234
- settings.private_key = ruby_saml_key_text
235
- end
236
-
237
- it "create a signed request" do
238
- params = OneLogin::RubySaml::Authrequest.new.create_params(settings)
239
- request_xml = Base64.decode64(params["SAMLRequest"])
240
- assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>], request_xml
241
- assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1'/>], request_xml
242
- end
243
-
244
- it "create a signed request with 256 digest and signature methods" do
245
- settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
246
- settings.security[:digest_method] = XMLSecurity::Document::SHA512
247
-
248
- params = OneLogin::RubySaml::Authrequest.new.create_params(settings)
249
-
250
- request_xml = Base64.decode64(params["SAMLRequest"])
251
- assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>], request_xml
252
- assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'/>], request_xml
253
- assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2001/04/xmlenc#sha512'/>], request_xml
254
- end
255
- end
256
-
257
- describe "#create_params when the settings indicate to sign the request" do
258
- let(:cert) { OpenSSL::X509::Certificate.new(ruby_saml_cert_text) }
259
-
260
- before do
261
- settings.compress_request = false
262
- settings.idp_sso_target_url = "http://example.com?field=value"
263
- settings.assertion_consumer_service_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign"
264
- settings.security[:authn_requests_signed] = true
265
- settings.security[:embed_sign] = false
266
- settings.certificate = ruby_saml_cert_text
267
- settings.private_key = ruby_saml_key_text
268
- end
269
-
270
- it "create a signature parameter with RSA_SHA1 and validate it" do
271
- settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
272
-
273
- params = OneLogin::RubySaml::Authrequest.new.create_params(settings, :RelayState => 'http://example.com')
274
- assert params['SAMLRequest']
275
- assert params[:RelayState]
276
- assert params['Signature']
277
- assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA1
278
-
279
- query_string = "SAMLRequest=#{CGI.escape(params['SAMLRequest'])}"
280
- query_string << "&RelayState=#{CGI.escape(params[:RelayState])}"
281
- query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}"
282
-
283
- signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg'])
284
- assert_equal signature_algorithm, OpenSSL::Digest::SHA1
285
-
286
- assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string)
287
- end
288
-
289
- it "create a signature parameter with RSA_SHA256 and validate it" do
290
- settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
291
-
292
- params = OneLogin::RubySaml::Authrequest.new.create_params(settings, :RelayState => 'http://example.com')
293
- assert params['Signature']
294
- assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA256
295
-
296
- query_string = "SAMLRequest=#{CGI.escape(params['SAMLRequest'])}"
297
- query_string << "&RelayState=#{CGI.escape(params[:RelayState])}"
298
- query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}"
299
-
300
- signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg'])
301
- assert_equal signature_algorithm, OpenSSL::Digest::SHA256
302
- assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string)
303
- end
304
- end
305
-
306
- it "create the saml:AuthnContextClassRef element correctly" do
307
- settings.authn_context = 'secure/name/password/uri'
308
- auth_doc = OneLogin::RubySaml::Authrequest.new.create_authentication_xml_doc(settings)
309
- assert auth_doc.to_s =~ /<saml:AuthnContextClassRef>secure\/name\/password\/uri<\/saml:AuthnContextClassRef>/
310
- end
311
-
312
- it "create the saml:AuthnContextClassRef with comparison exact" do
313
- settings.authn_context = 'secure/name/password/uri'
314
- auth_doc = OneLogin::RubySaml::Authrequest.new.create_authentication_xml_doc(settings)
315
- assert auth_doc.to_s =~ /<samlp:RequestedAuthnContext[\S ]+Comparison='exact'/
316
- assert auth_doc.to_s =~ /<saml:AuthnContextClassRef>secure\/name\/password\/uri<\/saml:AuthnContextClassRef>/
317
- end
318
-
319
- it "create the saml:AuthnContextClassRef with comparison minimun" do
320
- settings.authn_context = 'secure/name/password/uri'
321
- settings.authn_context_comparison = 'minimun'
322
- auth_doc = OneLogin::RubySaml::Authrequest.new.create_authentication_xml_doc(settings)
323
- assert auth_doc.to_s =~ /<samlp:RequestedAuthnContext[\S ]+Comparison='minimun'/
324
- assert auth_doc.to_s =~ /<saml:AuthnContextClassRef>secure\/name\/password\/uri<\/saml:AuthnContextClassRef>/
325
- end
326
-
327
- it "create the saml:AuthnContextDeclRef element correctly" do
328
- settings.authn_context_decl_ref = 'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport'
329
- auth_doc = OneLogin::RubySaml::Authrequest.new.create_authentication_xml_doc(settings)
330
- assert auth_doc.to_s =~ /<saml:AuthnContextDeclRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport<\/saml:AuthnContextDeclRef>/
331
- end
332
-
333
- it "create multiple saml:AuthnContextDeclRef elements correctly " do
334
- settings.authn_context_decl_ref = ['name/password/uri', 'example/decl/ref']
335
- auth_doc = OneLogin::RubySaml::Authrequest.new.create_authentication_xml_doc(settings)
336
- assert auth_doc.to_s =~ /<saml:AuthnContextDeclRef>name\/password\/uri<\/saml:AuthnContextDeclRef>/
337
- assert auth_doc.to_s =~ /<saml:AuthnContextDeclRef>example\/decl\/ref<\/saml:AuthnContextDeclRef>/
338
- end
339
- end
340
- end