ruby-saml 1.7.2 → 1.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +37 -15
  3. data/README.md +127 -25
  4. data/changelog.md +61 -0
  5. data/lib/onelogin/ruby-saml/attribute_service.rb +1 -1
  6. data/lib/onelogin/ruby-saml/attributes.rb +24 -1
  7. data/lib/onelogin/ruby-saml/authrequest.rb +29 -6
  8. data/lib/onelogin/ruby-saml/idp_metadata_parser.rb +239 -169
  9. data/lib/onelogin/ruby-saml/logging.rb +4 -1
  10. data/lib/onelogin/ruby-saml/logoutrequest.rb +27 -7
  11. data/lib/onelogin/ruby-saml/logoutresponse.rb +32 -16
  12. data/lib/onelogin/ruby-saml/metadata.rb +11 -3
  13. data/lib/onelogin/ruby-saml/response.rb +91 -30
  14. data/lib/onelogin/ruby-saml/saml_message.rb +15 -5
  15. data/lib/onelogin/ruby-saml/setting_error.rb +6 -0
  16. data/lib/onelogin/ruby-saml/settings.rb +82 -9
  17. data/lib/onelogin/ruby-saml/slo_logoutrequest.rb +26 -7
  18. data/lib/onelogin/ruby-saml/slo_logoutresponse.rb +46 -18
  19. data/lib/onelogin/ruby-saml/utils.rb +87 -10
  20. data/lib/onelogin/ruby-saml/version.rb +1 -1
  21. data/lib/xml_security.rb +39 -12
  22. data/ruby-saml.gemspec +16 -8
  23. metadata +40 -274
  24. data/test/certificates/certificate1 +0 -12
  25. data/test/certificates/certificate_without_head_foot +0 -1
  26. data/test/certificates/formatted_certificate +0 -14
  27. data/test/certificates/formatted_chained_certificate +0 -42
  28. data/test/certificates/formatted_private_key +0 -12
  29. data/test/certificates/formatted_rsa_private_key +0 -12
  30. data/test/certificates/invalid_certificate1 +0 -1
  31. data/test/certificates/invalid_certificate2 +0 -1
  32. data/test/certificates/invalid_certificate3 +0 -12
  33. data/test/certificates/invalid_chained_certificate1 +0 -1
  34. data/test/certificates/invalid_private_key1 +0 -1
  35. data/test/certificates/invalid_private_key2 +0 -1
  36. data/test/certificates/invalid_private_key3 +0 -10
  37. data/test/certificates/invalid_rsa_private_key1 +0 -1
  38. data/test/certificates/invalid_rsa_private_key2 +0 -1
  39. data/test/certificates/invalid_rsa_private_key3 +0 -10
  40. data/test/certificates/ruby-saml-2.crt +0 -15
  41. data/test/certificates/ruby-saml.crt +0 -14
  42. data/test/certificates/ruby-saml.key +0 -15
  43. data/test/idp_metadata_parser_test.rb +0 -568
  44. data/test/logging_test.rb +0 -62
  45. data/test/logout_requests/invalid_slo_request.xml +0 -6
  46. data/test/logout_requests/slo_request.xml +0 -4
  47. data/test/logout_requests/slo_request.xml.base64 +0 -1
  48. data/test/logout_requests/slo_request_deflated.xml.base64 +0 -1
  49. data/test/logout_requests/slo_request_with_name_id_format.xml +0 -4
  50. data/test/logout_requests/slo_request_with_session_index.xml +0 -5
  51. data/test/logout_responses/logoutresponse_fixtures.rb +0 -67
  52. data/test/logoutrequest_test.rb +0 -212
  53. data/test/logoutresponse_test.rb +0 -402
  54. data/test/metadata/idp_descriptor.xml +0 -26
  55. data/test/metadata/idp_descriptor_2.xml +0 -56
  56. data/test/metadata/idp_descriptor_3.xml +0 -14
  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 -53
  62. data/test/metadata/no_idp_descriptor.xml +0 -21
  63. data/test/metadata_test.rb +0 -331
  64. data/test/request_test.rb +0 -296
  65. data/test/response_test.rb +0 -1535
  66. data/test/responses/adfs_response_sha1.xml +0 -46
  67. data/test/responses/adfs_response_sha256.xml +0 -46
  68. data/test/responses/adfs_response_sha384.xml +0 -46
  69. data/test/responses/adfs_response_sha512.xml +0 -46
  70. data/test/responses/adfs_response_xmlns.xml +0 -45
  71. data/test/responses/attackxee.xml +0 -13
  72. data/test/responses/invalids/duplicated_attributes.xml.base64 +0 -1
  73. data/test/responses/invalids/empty_destination.xml.base64 +0 -1
  74. data/test/responses/invalids/empty_nameid.xml.base64 +0 -1
  75. data/test/responses/invalids/encrypted_new_attack.xml.base64 +0 -1
  76. data/test/responses/invalids/invalid_audience.xml.base64 +0 -1
  77. data/test/responses/invalids/invalid_issuer_assertion.xml.base64 +0 -1
  78. data/test/responses/invalids/invalid_issuer_message.xml.base64 +0 -1
  79. data/test/responses/invalids/invalid_signature_position.xml.base64 +0 -1
  80. data/test/responses/invalids/invalid_subjectconfirmation_inresponse.xml.base64 +0 -1
  81. data/test/responses/invalids/invalid_subjectconfirmation_nb.xml.base64 +0 -1
  82. data/test/responses/invalids/invalid_subjectconfirmation_noa.xml.base64 +0 -1
  83. data/test/responses/invalids/invalid_subjectconfirmation_recipient.xml.base64 +0 -1
  84. data/test/responses/invalids/multiple_assertions.xml.base64 +0 -2
  85. data/test/responses/invalids/multiple_signed.xml.base64 +0 -1
  86. data/test/responses/invalids/no_authnstatement.xml.base64 +0 -1
  87. data/test/responses/invalids/no_conditions.xml.base64 +0 -1
  88. data/test/responses/invalids/no_id.xml.base64 +0 -1
  89. data/test/responses/invalids/no_issuer_assertion.xml.base64 +0 -1
  90. data/test/responses/invalids/no_issuer_response.xml.base64 +0 -1
  91. data/test/responses/invalids/no_nameid.xml.base64 +0 -1
  92. data/test/responses/invalids/no_saml2.xml.base64 +0 -1
  93. data/test/responses/invalids/no_signature.xml.base64 +0 -1
  94. data/test/responses/invalids/no_status.xml.base64 +0 -1
  95. data/test/responses/invalids/no_status_code.xml.base64 +0 -1
  96. data/test/responses/invalids/no_subjectconfirmation_data.xml.base64 +0 -1
  97. data/test/responses/invalids/no_subjectconfirmation_method.xml.base64 +0 -1
  98. data/test/responses/invalids/response_invalid_signed_element.xml.base64 +0 -1
  99. data/test/responses/invalids/response_with_concealed_signed_assertion.xml +0 -51
  100. data/test/responses/invalids/response_with_doubled_signed_assertion.xml +0 -49
  101. data/test/responses/invalids/signature_wrapping_attack.xml.base64 +0 -1
  102. data/test/responses/invalids/status_code_responder.xml.base64 +0 -1
  103. data/test/responses/invalids/status_code_responer_and_msg.xml.base64 +0 -1
  104. data/test/responses/invalids/wrong_spnamequalifier.xml.base64 +0 -1
  105. data/test/responses/no_signature_ns.xml +0 -48
  106. data/test/responses/open_saml_response.xml +0 -56
  107. data/test/responses/response_assertion_wrapped.xml.base64 +0 -93
  108. data/test/responses/response_audience_self_closed_tag.xml.base64 +0 -1
  109. data/test/responses/response_double_status_code.xml.base64 +0 -1
  110. data/test/responses/response_encrypted_attrs.xml.base64 +0 -1
  111. data/test/responses/response_encrypted_nameid.xml.base64 +0 -1
  112. data/test/responses/response_eval.xml +0 -7
  113. data/test/responses/response_no_cert_and_encrypted_attrs.xml +0 -29
  114. data/test/responses/response_node_text_attack.xml.base64 +0 -1
  115. data/test/responses/response_unsigned_xml_base64 +0 -1
  116. data/test/responses/response_with_ampersands.xml +0 -139
  117. data/test/responses/response_with_ampersands.xml.base64 +0 -93
  118. data/test/responses/response_with_ds_namespace_at_the_root.xml.base64 +0 -1
  119. data/test/responses/response_with_multiple_attribute_statements.xml +0 -72
  120. data/test/responses/response_with_multiple_attribute_values.xml +0 -67
  121. data/test/responses/response_with_retrieval_method.xml +0 -26
  122. data/test/responses/response_with_saml2_namespace.xml.base64 +0 -102
  123. data/test/responses/response_with_signed_assertion.xml.base64 +0 -66
  124. data/test/responses/response_with_signed_assertion_2.xml.base64 +0 -1
  125. data/test/responses/response_with_signed_assertion_3.xml +0 -30
  126. data/test/responses/response_with_signed_message_and_assertion.xml +0 -34
  127. data/test/responses/response_with_undefined_recipient.xml.base64 +0 -1
  128. data/test/responses/response_without_attributes.xml.base64 +0 -79
  129. data/test/responses/response_without_reference_uri.xml.base64 +0 -1
  130. data/test/responses/response_wrapped.xml.base64 +0 -150
  131. data/test/responses/signed_message_encrypted_signed_assertion.xml.base64 +0 -1
  132. data/test/responses/signed_message_encrypted_unsigned_assertion.xml.base64 +0 -1
  133. data/test/responses/signed_nameid_in_atts.xml +0 -47
  134. data/test/responses/signed_unqual_nameid_in_atts.xml +0 -47
  135. data/test/responses/simple_saml_php.xml +0 -71
  136. data/test/responses/starfield_response.xml.base64 +0 -1
  137. data/test/responses/test_sign.xml +0 -43
  138. data/test/responses/unsigned_encrypted_adfs.xml +0 -23
  139. data/test/responses/unsigned_message_aes128_encrypted_signed_assertion.xml.base64 +0 -1
  140. data/test/responses/unsigned_message_aes192_encrypted_signed_assertion.xml.base64 +0 -1
  141. data/test/responses/unsigned_message_aes256_encrypted_signed_assertion.xml.base64 +0 -1
  142. data/test/responses/unsigned_message_des192_encrypted_signed_assertion.xml.base64 +0 -1
  143. data/test/responses/unsigned_message_encrypted_assertion_without_saml_namespace.xml.base64 +0 -1
  144. data/test/responses/unsigned_message_encrypted_signed_assertion.xml.base64 +0 -1
  145. data/test/responses/unsigned_message_encrypted_unsigned_assertion.xml.base64 +0 -1
  146. data/test/responses/valid_response.xml.base64 +0 -1
  147. data/test/responses/valid_response_without_x509certificate.xml.base64 +0 -1
  148. data/test/saml_message_test.rb +0 -56
  149. data/test/settings_test.rb +0 -301
  150. data/test/slo_logoutrequest_test.rb +0 -448
  151. data/test/slo_logoutresponse_test.rb +0 -185
  152. data/test/test_helper.rb +0 -323
  153. data/test/utils_test.rb +0 -254
  154. data/test/xml_security_test.rb +0 -421
data/test/test_helper.rb DELETED
@@ -1,323 +0,0 @@
1
- require 'simplecov'
2
-
3
- SimpleCov.start do
4
- add_filter "test/"
5
- add_filter "vendor/"
6
- add_filter "lib/onelogin/ruby-saml/logging.rb"
7
- end
8
-
9
- require 'stringio'
10
- require 'rubygems'
11
- require 'bundler'
12
- require 'minitest/autorun'
13
- require 'mocha/setup'
14
- require 'timecop'
15
-
16
- Bundler.require :default, :test
17
-
18
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
19
- $LOAD_PATH.unshift(File.dirname(__FILE__))
20
-
21
- require 'onelogin/ruby-saml/logging'
22
-
23
- TEST_LOGGER = Logger.new(StringIO.new)
24
- OneLogin::RubySaml::Logging.logger = TEST_LOGGER
25
-
26
- class Minitest::Test
27
- def fixture(document, base64 = true)
28
- response = Dir.glob(File.join(File.dirname(__FILE__), "responses", "#{document}*")).first
29
- if base64 && response =~ /\.xml$/
30
- Base64.encode64(File.read(response))
31
- else
32
- File.read(response)
33
- end
34
- end
35
-
36
- def read_response(response)
37
- File.read(File.join(File.dirname(__FILE__), "responses", response))
38
- end
39
-
40
- def read_invalid_response(response)
41
- File.read(File.join(File.dirname(__FILE__), "responses", "invalids", response))
42
- end
43
-
44
- def read_logout_request(request)
45
- File.read(File.join(File.dirname(__FILE__), "logout_requests", request))
46
- end
47
-
48
- def read_certificate(certificate)
49
- File.read(File.join(File.dirname(__FILE__), "certificates", certificate))
50
- end
51
-
52
- def response_document_valid_signed
53
- @response_document_valid_signed ||= read_response("valid_response.xml.base64")
54
- end
55
-
56
- def response_document_valid_signed_without_x509certificate
57
- @response_document_valid_signed_without_x509certificate ||= read_response("valid_response_without_x509certificate.xml.base64")
58
- end
59
-
60
- def response_document_without_recipient
61
- @response_document_without_recipient ||= read_response("response_with_undefined_recipient.xml.base64")
62
- end
63
-
64
- def response_document_without_recipient_with_time_updated
65
- doc = Base64.decode64(response_document_without_recipient)
66
- doc.gsub!(/NotBefore=\"(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z\"/, "NotBefore=\"#{(Time.now-300).getutc.strftime("%Y-%m-%dT%XZ")}\"")
67
- doc.gsub!(/NotOnOrAfter=\"(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z\"/, "NotOnOrAfter=\"#{(Time.now+300).getutc.strftime("%Y-%m-%dT%XZ")}\"")
68
- Base64.encode64(doc)
69
- end
70
-
71
- def response_document_without_attributes
72
- @response_document_without_attributes ||= read_response("response_without_attributes.xml.base64")
73
- end
74
-
75
- def response_document_without_reference_uri
76
- @response_document_without_reference_uri ||= read_response("response_without_reference_uri.xml.base64")
77
- end
78
-
79
- def response_document_with_signed_assertion
80
- @response_document_with_signed_assertion ||= read_response("response_with_signed_assertion.xml.base64")
81
- end
82
-
83
- def response_document_with_signed_assertion_2
84
- @response_document_with_signed_assertion_2 ||= read_response("response_with_signed_assertion_2.xml.base64")
85
- end
86
-
87
- def response_document_with_ds_namespace_at_the_root
88
- @response_document_with_ds_namespace_at_the_root ||= read_response("response_with_ds_namespace_at_the_root.xml.base64")
89
- end
90
-
91
- def response_document_unsigned
92
- @response_document_unsigned ||= read_response("response_unsigned_xml_base64")
93
- end
94
-
95
- def response_document_with_saml2_namespace
96
- @response_document_with_saml2_namespace ||= read_response("response_with_saml2_namespace.xml.base64")
97
- end
98
-
99
- def ampersands_document
100
- @ampersands_response ||= read_response("response_with_ampersands.xml.base64")
101
- end
102
-
103
- def response_document_no_cert_and_encrypted_attrs
104
- @response_document_no_cert_and_encrypted_attrs ||= Base64.encode64(read_response("response_no_cert_and_encrypted_attrs.xml"))
105
- end
106
-
107
- def response_document_wrapped
108
- @response_document_wrapped ||= read_response("response_wrapped.xml.base64")
109
- end
110
-
111
- def response_document_assertion_wrapped
112
- @response_document_assertion_wrapped ||= read_response("response_assertion_wrapped.xml.base64")
113
- end
114
-
115
- def response_document_encrypted_nameid
116
- @response_document_encrypted_nameid ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'response_encrypted_nameid.xml.base64'))
117
- end
118
-
119
- def signed_message_encrypted_unsigned_assertion
120
- @signed_message_encrypted_unsigned_assertion ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'signed_message_encrypted_unsigned_assertion.xml.base64'))
121
- end
122
-
123
- def signed_message_encrypted_signed_assertion
124
- @signed_message_encrypted_signed_assertion ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'signed_message_encrypted_signed_assertion.xml.base64'))
125
- end
126
-
127
- def unsigned_message_encrypted_signed_assertion
128
- @unsigned_message_encrypted_signed_assertion ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'unsigned_message_encrypted_signed_assertion.xml.base64'))
129
- end
130
-
131
- def unsigned_message_encrypted_unsigned_assertion
132
- @unsigned_message_encrypted_unsigned_assertion ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'unsigned_message_encrypted_unsigned_assertion.xml.base64'))
133
- end
134
-
135
- def response_document_encrypted_attrs
136
- @response_document_encrypted_attrs ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'response_encrypted_attrs.xml.base64'))
137
- end
138
-
139
- def response_document_double_status_code
140
- @response_document_double_status_code ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'response_double_status_code.xml.base64'))
141
- end
142
-
143
- def signature_fingerprint_1
144
- @signature_fingerprint1 ||= "C5:19:85:D9:47:F1:BE:57:08:20:25:05:08:46:EB:27:F6:CA:B7:83"
145
- end
146
-
147
- # certificate used on response_with_undefined_recipient
148
- def signature_1
149
- @signature1 ||= read_certificate("certificate1")
150
- end
151
-
152
- # certificate used on response_document_with_signed_assertion_2
153
- def certificate_without_head_foot
154
- @certificate_without_head_foot ||= read_certificate("certificate_without_head_foot")
155
- end
156
-
157
- def idp_metadata_descriptor
158
- @idp_metadata_descriptor ||= File.read(File.join(File.dirname(__FILE__), 'metadata', 'idp_descriptor.xml'))
159
- end
160
-
161
- def idp_metadata_descriptor2
162
- @idp_metadata_descriptor2 ||= File.read(File.join(File.dirname(__FILE__), 'metadata', 'idp_descriptor_2.xml'))
163
- end
164
-
165
- def idp_metadata_descriptor3
166
- @idp_metadata_descriptor3 ||= File.read(File.join(File.dirname(__FILE__), 'metadata', 'idp_descriptor_3.xml'))
167
- end
168
-
169
- def no_idp_metadata_descriptor
170
- @no_idp_metadata_descriptor ||= File.read(File.join(File.dirname(__FILE__), 'metadata', 'no_idp_descriptor.xml'))
171
- end
172
-
173
- def idp_metadata_multiple_descriptors
174
- @idp_metadata_multiple_descriptors ||= File.read(File.join(File.dirname(__FILE__), 'metadata', 'idp_multiple_descriptors.xml'))
175
- end
176
-
177
- def idp_metadata_multiple_certs
178
- @idp_metadata_multiple_descriptors ||= File.read(File.join(File.dirname(__FILE__), 'metadata', 'idp_metadata_multi_certs.xml'))
179
- end
180
-
181
- def idp_metadata_multiple_signing_certs
182
- @idp_metadata_multiple_signing_certs ||= File.read(File.join(File.dirname(__FILE__), 'metadata', 'idp_metadata_multi_signing_certs.xml'))
183
- end
184
-
185
- def idp_metadata_same_sign_and_encrypt_cert
186
- @idp_metadata_same_sign_and_encrypt_cert ||= File.read(File.join(File.dirname(__FILE__), 'metadata', 'idp_metadata_same_sign_and_encrypt_cert.xml'))
187
- end
188
-
189
- def idp_metadata_different_sign_and_encrypt_cert
190
- @idp_metadata_different_sign_and_encrypt_cert ||= File.read(File.join(File.dirname(__FILE__), 'metadata', 'idp_metadata_different_sign_and_encrypt_cert.xml'))
191
- end
192
-
193
- def logout_request_document
194
- unless @logout_request_document
195
- xml = read_logout_request("slo_request.xml")
196
- deflated = Zlib::Deflate.deflate(xml, 9)[2..-5]
197
- @logout_request_document = Base64.encode64(deflated)
198
- end
199
- @logout_request_document
200
- end
201
-
202
- def logout_request_document_with_name_id_format
203
- unless @logout_request_document_with_name_id_format
204
- xml = read_logout_request("slo_request_with_name_id_format.xml")
205
- deflated = Zlib::Deflate.deflate(xml, 9)[2..-5]
206
- @logout_request_document_with_name_id_format = Base64.encode64(deflated)
207
- end
208
- @logout_request_document_with_name_id_format
209
- end
210
-
211
- def logout_request_xml_with_session_index
212
- @logout_request_xml_with_session_index ||= File.read(File.join(File.dirname(__FILE__), 'logout_requests', 'slo_request_with_session_index.xml'))
213
- end
214
-
215
- def invalid_logout_request_document
216
- unless @invalid_logout_request_document
217
- xml = File.read(File.join(File.dirname(__FILE__), 'logout_requests', 'invalid_slo_request.xml'))
218
- deflated = Zlib::Deflate.deflate(xml, 9)[2..-5]
219
- @invalid_logout_request_document = Base64.encode64(deflated)
220
- end
221
- @invalid_logout_request_document
222
- end
223
-
224
- def logout_request_base64
225
- @logout_request_base64 ||= File.read(File.join(File.dirname(__FILE__), 'logout_requests', 'slo_request.xml.base64'))
226
- end
227
-
228
- def logout_request_deflated_base64
229
- @logout_request_deflated_base64 ||= File.read(File.join(File.dirname(__FILE__), 'logout_requests', 'slo_request_deflated.xml.base64'))
230
- end
231
-
232
- def ruby_saml_cert
233
- @ruby_saml_cert ||= OpenSSL::X509::Certificate.new(ruby_saml_cert_text)
234
- end
235
-
236
- def ruby_saml_cert2
237
- @ruby_saml_cert2 ||= OpenSSL::X509::Certificate.new(ruby_saml_cert_text2)
238
- end
239
-
240
- def ruby_saml_cert_fingerprint
241
- @ruby_saml_cert_fingerprint ||= Digest::SHA1.hexdigest(ruby_saml_cert.to_der).scan(/../).join(":")
242
- end
243
-
244
- def ruby_saml_cert_text
245
- read_certificate("ruby-saml.crt")
246
- end
247
-
248
- def ruby_saml_cert_text2
249
- read_certificate("ruby-saml-2.crt")
250
- end
251
-
252
- def ruby_saml_key
253
- @ruby_saml_key ||= OpenSSL::PKey::RSA.new(ruby_saml_key_text)
254
- end
255
-
256
- def ruby_saml_key_text
257
- read_certificate("ruby-saml.key")
258
- end
259
-
260
- #
261
- # logoutresponse fixtures
262
- #
263
- def random_id
264
- "_#{OneLogin::RubySaml::Utils.uuid}"
265
- end
266
-
267
- #
268
- # decodes a base64 encoded SAML response for use in SloLogoutresponse tests
269
- #
270
- def decode_saml_response_payload(unauth_url)
271
- payload = CGI.unescape(unauth_url.split("SAMLResponse=").last)
272
- decoded = Base64.decode64(payload)
273
-
274
- zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
275
- inflated = zstream.inflate(decoded)
276
- zstream.finish
277
- zstream.close
278
- inflated
279
- end
280
-
281
- #
282
- # decodes a base64 encoded SAML request for use in Logoutrequest tests
283
- #
284
- def decode_saml_request_payload(unauth_url)
285
- payload = CGI.unescape(unauth_url.split("SAMLRequest=").last)
286
- decoded = Base64.decode64(payload)
287
-
288
- zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
289
- inflated = zstream.inflate(decoded)
290
- zstream.finish
291
- zstream.close
292
- inflated
293
- end
294
-
295
- SCHEMA_DIR = File.expand_path(File.join(__FILE__, '../../lib/schemas'))
296
-
297
- #
298
- # validate an xml document against the given schema
299
- #
300
- def validate_xml!(document, schema)
301
- Dir.chdir(SCHEMA_DIR) do
302
- xsd = if schema.is_a? Nokogiri::XML::Schema
303
- schema
304
- else
305
- Nokogiri::XML::Schema(File.read(schema))
306
- end
307
-
308
- xml = if document.is_a? Nokogiri::XML::Document
309
- document
310
- else
311
- Nokogiri::XML(document) { |c| c.strict }
312
- end
313
-
314
- result = xsd.validate(xml)
315
-
316
- if result.length != 0
317
- raise "Schema validation failed! XSD validation errors: #{result.join(", ")}"
318
- else
319
- true
320
- end
321
- end
322
- end
323
- end
data/test/utils_test.rb DELETED
@@ -1,254 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
2
-
3
- class UtilsTest < Minitest::Test
4
- describe ".format_cert" do
5
- let(:formatted_certificate) {read_certificate("formatted_certificate")}
6
- let(:formatted_chained_certificate) {read_certificate("formatted_chained_certificate")}
7
-
8
- it "returns empty string when the cert is an empty string" do
9
- cert = ""
10
- assert_equal "", OneLogin::RubySaml::Utils.format_cert(cert)
11
- end
12
-
13
- it "returns nil when the cert is nil" do
14
- cert = nil
15
- assert_nil OneLogin::RubySaml::Utils.format_cert(cert)
16
- end
17
-
18
- it "returns the certificate when it is valid" do
19
- assert_equal formatted_certificate, OneLogin::RubySaml::Utils.format_cert(formatted_certificate)
20
- end
21
-
22
- it "reformats the certificate when there are spaces and no line breaks" do
23
- invalid_certificate1 = read_certificate("invalid_certificate1")
24
- assert_equal formatted_certificate, OneLogin::RubySaml::Utils.format_cert(invalid_certificate1)
25
- end
26
-
27
- it "reformats the certificate when there are spaces and no headers" do
28
- invalid_certificate2 = read_certificate("invalid_certificate2")
29
- assert_equal formatted_certificate, OneLogin::RubySaml::Utils.format_cert(invalid_certificate2)
30
- end
31
-
32
- it "reformats the certificate when there line breaks and no headers" do
33
- invalid_certificate3 = read_certificate("invalid_certificate3")
34
- assert_equal formatted_certificate, OneLogin::RubySaml::Utils.format_cert(invalid_certificate3)
35
- end
36
-
37
- it "returns the chained certificate when it is a valid chained certificate" do
38
- assert_equal formatted_chained_certificate, OneLogin::RubySaml::Utils.format_cert(formatted_chained_certificate)
39
- end
40
-
41
- it "reformats the chained certificate when there are spaces and no line breaks" do
42
- invalid_chained_certificate1 = read_certificate("invalid_chained_certificate1")
43
- assert_equal formatted_chained_certificate, OneLogin::RubySaml::Utils.format_cert(invalid_chained_certificate1)
44
- end
45
-
46
- end
47
-
48
- describe ".format_private_key" do
49
- let(:formatted_private_key) do
50
- read_certificate("formatted_private_key")
51
- end
52
-
53
- it "returns empty string when the private key is an empty string" do
54
- private_key = ""
55
- assert_equal "", OneLogin::RubySaml::Utils.format_private_key(private_key)
56
- end
57
-
58
- it "returns nil when the private key is nil" do
59
- private_key = nil
60
- assert_nil OneLogin::RubySaml::Utils.format_private_key(private_key)
61
- end
62
-
63
- it "returns the private key when it is valid" do
64
- assert_equal formatted_private_key, OneLogin::RubySaml::Utils.format_private_key(formatted_private_key)
65
- end
66
-
67
- it "reformats the private key when there are spaces and no line breaks" do
68
- invalid_private_key1 = read_certificate("invalid_private_key1")
69
- assert_equal formatted_private_key, OneLogin::RubySaml::Utils.format_private_key(invalid_private_key1)
70
- end
71
-
72
- it "reformats the private key when there are spaces and no headers" do
73
- invalid_private_key2 = read_certificate("invalid_private_key2")
74
- assert_equal formatted_private_key, OneLogin::RubySaml::Utils.format_private_key(invalid_private_key2)
75
- end
76
-
77
- it "reformats the private key when there line breaks and no headers" do
78
- invalid_private_key3 = read_certificate("invalid_private_key3")
79
- assert_equal formatted_private_key, OneLogin::RubySaml::Utils.format_private_key(invalid_private_key3)
80
- end
81
-
82
- describe "an RSA public key" do
83
- let(:formatted_rsa_private_key) do
84
- read_certificate("formatted_rsa_private_key")
85
- end
86
-
87
- it "returns the private key when it is valid" do
88
- assert_equal formatted_rsa_private_key, OneLogin::RubySaml::Utils.format_private_key(formatted_rsa_private_key)
89
- end
90
-
91
- it "reformats the private key when there are spaces and no line breaks" do
92
- invalid_rsa_private_key1 = read_certificate("invalid_rsa_private_key1")
93
- assert_equal formatted_rsa_private_key, OneLogin::RubySaml::Utils.format_private_key(invalid_rsa_private_key1)
94
- end
95
-
96
- it "reformats the private key when there are spaces and no headers" do
97
- invalid_rsa_private_key2 = read_certificate("invalid_rsa_private_key2")
98
- assert_equal formatted_private_key, OneLogin::RubySaml::Utils.format_private_key(invalid_rsa_private_key2)
99
- end
100
-
101
- it "reformats the private key when there line breaks and no headers" do
102
- invalid_rsa_private_key3 = read_certificate("invalid_rsa_private_key3")
103
- assert_equal formatted_private_key, OneLogin::RubySaml::Utils.format_private_key(invalid_rsa_private_key3)
104
- end
105
- end
106
- end
107
-
108
- describe "build_query" do
109
- it "returns the query string" do
110
- params = {}
111
- params[:type] = "SAMLRequest"
112
- params[:data] = "PHNhbWxwOkF1dGhuUmVxdWVzdCBEZXN0aW5hdGlvbj0naHR0cDovL2V4YW1wbGUuY29tP2ZpZWxkPXZhbHVlJyBJRD0nXzk4NmUxZDEwLWVhY2ItMDEzMi01MGRkLTAwOTBmNWRlZGQ3NycgSXNzdWVJbnN0YW50PScyMDE1LTA2LTAxVDIwOjM0OjU5WicgVmVyc2lvbj0nMi4wJyB4bWxuczpzYW1sPSd1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uJyB4bWxuczpzYW1scD0ndXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sJy8+"
113
- params[:relay_state] = "http://example.com"
114
- params[:sig_alg] = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
115
- query_string = OneLogin::RubySaml::Utils.build_query(params)
116
- assert_equal "SAMLRequest=PHNhbWxwOkF1dGhuUmVxdWVzdCBEZXN0aW5hdGlvbj0naHR0cDovL2V4YW1wbGUuY29tP2ZpZWxkPXZhbHVlJyBJRD0nXzk4NmUxZDEwLWVhY2ItMDEzMi01MGRkLTAwOTBmNWRlZGQ3NycgSXNzdWVJbnN0YW50PScyMDE1LTA2LTAxVDIwOjM0OjU5WicgVmVyc2lvbj0nMi4wJyB4bWxuczpzYW1sPSd1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uJyB4bWxuczpzYW1scD0ndXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sJy8%2B&RelayState=http%3A%2F%2Fexample.com&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1", query_string
117
- end
118
- end
119
-
120
- describe "#verify_signature" do
121
- before do
122
- @params = {}
123
- @params[:cert] = ruby_saml_cert
124
- @params[:sig_alg] = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
125
- @params[:query_string] = "SAMLRequest=PHNhbWxwOkF1dGhuUmVxdWVzdCBEZXN0aW5hdGlvbj0naHR0cDovL2V4YW1wbGUuY29tP2ZpZWxkPXZhbHVlJyBJRD0nXzk4NmUxZDEwLWVhY2ItMDEzMi01MGRkLTAwOTBmNWRlZGQ3NycgSXNzdWVJbnN0YW50PScyMDE1LTA2LTAxVDIwOjM0OjU5WicgVmVyc2lvbj0nMi4wJyB4bWxuczpzYW1sPSd1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uJyB4bWxuczpzYW1scD0ndXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sJy8%2B&RelayState=http%3A%2F%2Fexample.com&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1"
126
- end
127
-
128
- it "returns true when the signature is valid" do
129
- @params[:signature] = "uWJm/T4gKLYEsVu1j/ZmjDeHp9zYPXPXWTXHFJZf2KKnWg57fUw3x2l6KTyRQ+Xjigb+sfYdGnnwmIz6KngXYRnh7nO6inspRLWOwkqQFy9iR9LDlMcfpXV/0g3oAxBxO6tX8MUHqR2R62SYZRGd1rxC9apg4vQiP97+atOI8t4="
130
- assert OneLogin::RubySaml::Utils.verify_signature(@params)
131
- end
132
-
133
- it "returns false when the signature is invalid" do
134
- @params[:signature] = "uWJm/InVaLiDsVu1j/ZmjDeHp9zYPXPXWTXHFJZf2KKnWg57fUw3x2l6KTyRQ+Xjigb+sfYdGnnwmIz6KngXYRnh7nO6inspRLWOwkqQFy9iR9LDlMcfpXV/0g3oAxBxO6tX8MUHqR2R62SYZRGd1rxC9apg4vQiP97+atOI8t4="
135
- assert !OneLogin::RubySaml::Utils.verify_signature(@params)
136
- end
137
- end
138
-
139
- describe "#status_error_msg" do
140
- it "returns a error msg with a status message" do
141
- error_msg = "The status code of the Logout Response was not Success"
142
- status_code = "urn:oasis:names:tc:SAML:2.0:status:Requester"
143
- status_message = "The request could not be performed due to an error on the part of the requester."
144
- status_error_msg = OneLogin::RubySaml::Utils.status_error_msg(error_msg, status_code, status_message)
145
- assert_equal = "The status code of the Logout Response was not Success, was Requester -> The request could not be performed due to an error on the part of the requester.", status_error_msg
146
-
147
- status_error_msg2 = OneLogin::RubySaml::Utils.status_error_msg(error_msg, status_code)
148
- assert_equal = "The status code of the Logout Response was not Success, was Requester", status_error_msg2
149
-
150
- status_error_msg3 = OneLogin::RubySaml::Utils.status_error_msg(error_msg)
151
- assert_equal = "The status code of the Logout Response was not Success", status_error_msg3
152
- end
153
- end
154
-
155
- describe "Utils" do
156
-
157
- describe ".uuid" do
158
- it "returns a uuid starting with an underscore" do
159
- assert_match /^_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/, OneLogin::RubySaml::Utils.uuid
160
- end
161
-
162
- it "doesn't return the same value twice" do
163
- refute_equal OneLogin::RubySaml::Utils.uuid, OneLogin::RubySaml::Utils.uuid
164
- end
165
- end
166
-
167
- describe 'uri_match' do
168
- it 'matches two urls' do
169
- destination = 'http://www.example.com/test?var=stuff'
170
- settings = 'http://www.example.com/test?var=stuff'
171
- assert OneLogin::RubySaml::Utils.uri_match?(destination, settings)
172
- end
173
-
174
- it 'fails to match two urls' do
175
- destination = 'http://www.example.com/test?var=stuff'
176
- settings = 'http://www.example.com/othertest?var=stuff'
177
- assert !OneLogin::RubySaml::Utils.uri_match?(destination, settings)
178
- end
179
-
180
- it "matches two URLs if the scheme case doesn't match" do
181
- destination = 'http://www.example.com/test?var=stuff'
182
- settings = 'HTTP://www.example.com/test?var=stuff'
183
- assert OneLogin::RubySaml::Utils.uri_match?(destination, settings)
184
- end
185
-
186
- it "matches two URLs if the host case doesn't match" do
187
- destination = 'http://www.EXAMPLE.com/test?var=stuff'
188
- settings = 'http://www.example.com/test?var=stuff'
189
- assert OneLogin::RubySaml::Utils.uri_match?(destination, settings)
190
- end
191
-
192
- it "fails to match two URLs if the path case doesn't match" do
193
- destination = 'http://www.example.com/TEST?var=stuff'
194
- settings = 'http://www.example.com/test?var=stuff'
195
- assert !OneLogin::RubySaml::Utils.uri_match?(destination, settings)
196
- end
197
-
198
- it "fails to match two URLs if the query case doesn't match" do
199
- destination = 'http://www.example.com/test?var=stuff'
200
- settings = 'http://www.example.com/test?var=STUFF'
201
- assert !OneLogin::RubySaml::Utils.uri_match?(destination, settings)
202
- end
203
-
204
- it 'matches two non urls' do
205
- destination = 'stuff'
206
- settings = 'stuff'
207
- assert OneLogin::RubySaml::Utils.uri_match?(destination, settings)
208
- end
209
-
210
- it "fails to match two non urls" do
211
- destination = 'stuff'
212
- settings = 'not stuff'
213
- assert !OneLogin::RubySaml::Utils.uri_match?(destination, settings)
214
- end
215
- end
216
-
217
- describe 'element_text' do
218
- it 'returns the element text' do
219
- element = REXML::Document.new('<element>element text</element>').elements.first
220
- assert_equal 'element text', OneLogin::RubySaml::Utils.element_text(element)
221
- end
222
-
223
- it 'returns all segments of the element text' do
224
- element = REXML::Document.new('<element>element <!-- comment -->text</element>').elements.first
225
- assert_equal 'element text', OneLogin::RubySaml::Utils.element_text(element)
226
- end
227
-
228
- it 'returns normalized element text' do
229
- element = REXML::Document.new('<element>element &amp; text</element>').elements.first
230
- assert_equal 'element & text', OneLogin::RubySaml::Utils.element_text(element)
231
- end
232
-
233
- it 'returns the CDATA element text' do
234
- element = REXML::Document.new('<element><![CDATA[element & text]]></element>').elements.first
235
- assert_equal 'element & text', OneLogin::RubySaml::Utils.element_text(element)
236
- end
237
-
238
- it 'returns the element text with newlines and additional whitespace' do
239
- element = REXML::Document.new("<element> element \n text </element>").elements.first
240
- assert_equal " element \n text ", OneLogin::RubySaml::Utils.element_text(element)
241
- end
242
-
243
- it 'returns nil when element is nil' do
244
- assert_nil OneLogin::RubySaml::Utils.element_text(nil)
245
- end
246
-
247
- it 'returns empty string when element has no text' do
248
- element = REXML::Document.new('<element></element>').elements.first
249
- assert_equal '', OneLogin::RubySaml::Utils.element_text(element)
250
- end
251
-
252
- end
253
- end
254
- end