ruby-saml 0.8.8 → 0.8.13

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ruby-saml might be problematic. Click here for more details.

Files changed (45) hide show
  1. checksums.yaml +7 -7
  2. data/Gemfile +11 -1
  3. data/README.md +5 -2
  4. data/Rakefile +0 -14
  5. data/lib/onelogin/ruby-saml/authrequest.rb +86 -20
  6. data/lib/onelogin/ruby-saml/logoutrequest.rb +95 -20
  7. data/lib/onelogin/ruby-saml/logoutresponse.rb +5 -28
  8. data/lib/onelogin/ruby-saml/metadata.rb +5 -5
  9. data/lib/onelogin/ruby-saml/response.rb +187 -4
  10. data/lib/onelogin/ruby-saml/setting_error.rb +6 -0
  11. data/lib/onelogin/ruby-saml/settings.rb +146 -10
  12. data/lib/onelogin/ruby-saml/slo_logoutresponse.rb +158 -0
  13. data/lib/onelogin/ruby-saml/utils.rb +169 -0
  14. data/lib/onelogin/ruby-saml/version.rb +1 -1
  15. data/lib/ruby-saml.rb +2 -1
  16. data/lib/xml_security.rb +330 -78
  17. data/test/certificates/ruby-saml-2.crt +15 -0
  18. data/test/certificates/ruby-saml.crt +14 -0
  19. data/test/certificates/ruby-saml.key +15 -0
  20. data/test/logoutrequest_test.rb +177 -44
  21. data/test/logoutresponse_test.rb +25 -29
  22. data/test/request_test.rb +100 -37
  23. data/test/response_test.rb +213 -111
  24. data/test/responses/adfs_response_xmlns.xml +45 -0
  25. data/test/responses/encrypted_new_attack.xml.base64 +1 -0
  26. data/test/responses/invalids/multiple_signed.xml.base64 +1 -0
  27. data/test/responses/invalids/no_signature.xml.base64 +1 -0
  28. data/test/responses/invalids/response_with_concealed_signed_assertion.xml +51 -0
  29. data/test/responses/invalids/response_with_doubled_signed_assertion.xml +49 -0
  30. data/test/responses/invalids/signature_wrapping_attack.xml.base64 +1 -0
  31. data/test/responses/logoutresponse_fixtures.rb +6 -6
  32. data/test/responses/response_with_concealed_signed_assertion.xml +51 -0
  33. data/test/responses/response_with_doubled_signed_assertion.xml +49 -0
  34. data/test/responses/response_with_signed_assertion_3.xml +30 -0
  35. data/test/responses/response_with_signed_message_and_assertion.xml +34 -0
  36. data/test/responses/response_with_undefined_recipient.xml.base64 +1 -0
  37. data/test/responses/response_wrapped.xml.base64 +150 -0
  38. data/test/responses/valid_response.xml.base64 +1 -0
  39. data/test/responses/valid_response_without_x509certificate.xml.base64 +1 -0
  40. data/test/settings_test.rb +7 -7
  41. data/test/slo_logoutresponse_test.rb +226 -0
  42. data/test/test_helper.rb +117 -12
  43. data/test/utils_test.rb +10 -10
  44. data/test/xml_security_test.rb +310 -68
  45. metadata +88 -45
@@ -0,0 +1,15 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIICVDCCAb2gAwIBAgIBADANBgkqhkiG9w0BAQ0FADBHMQswCQYDVQQGEwJ1czEQ
3
+ MA4GA1UECAwHZXhhbXBsZTEQMA4GA1UECgwHZXhhbXBsZTEUMBIGA1UEAwwLZXhh
4
+ bXBsZS5jb20wHhcNMTcwNDA3MDgzMDAzWhcNMjcwNDA1MDgzMDAzWjBHMQswCQYD
5
+ VQQGEwJ1czEQMA4GA1UECAwHZXhhbXBsZTEQMA4GA1UECgwHZXhhbXBsZTEUMBIG
6
+ A1UEAwwLZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKhP
7
+ S4/0azxbQekHHewQGKD7Pivr3CDpsrKxY3xlVanxj427OwzOb5KUVzsDEazumt6s
8
+ ZFY8HfidsjXY4EYA4ZzyL7ciIAR5vlAsIYN9nJ4AwVDnN/RjVwj+TN6BqWPLpVIp
9
+ Hc6Dl005HyE0zJnk1DZDn2tQVrIzbD3FhCp7YeotAgMBAAGjUDBOMB0GA1UdDgQW
10
+ BBRYZx4thASfNvR/E7NsCF2IaZ7wIDAfBgNVHSMEGDAWgBRYZx4thASfNvR/E7Ns
11
+ CF2IaZ7wIDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4GBACz4aobx9aG3
12
+ kh+rNyrlgM3K6dYfnKG1/YH5sJCAOvg8kDr0fQAQifH8lFVWumKUMoAe0bFTfwWt
13
+ p/VJ8MprrEJth6PFeZdczpuv+fpLcNj2VmNVJqvQYvS4m36OnBFh1QFZW8UrbFIf
14
+ dtm2nuZ+twSKqfKwjLdqcoX0p39h7Uw/
15
+ -----END CERTIFICATE-----
@@ -0,0 +1,14 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIICGzCCAYQCCQCNNcQXom32VDANBgkqhkiG9w0BAQUFADBSMQswCQYDVQQGEwJV
3
+ UzELMAkGA1UECBMCSU4xFTATBgNVBAcTDEluZGlhbmFwb2xpczERMA8GA1UEChMI
4
+ T25lTG9naW4xDDAKBgNVBAsTA0VuZzAeFw0xNDA0MjMxODQxMDFaFw0xNTA0MjMx
5
+ ODQxMDFaMFIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTjEVMBMGA1UEBxMMSW5k
6
+ aWFuYXBvbGlzMREwDwYDVQQKEwhPbmVMb2dpbjEMMAoGA1UECxMDRW5nMIGfMA0G
7
+ CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDo6m+QZvYQ/xL0ElLgupK1QDcYL4f5Pckw
8
+ sNgS9pUvV7fzTqCHk8ThLxTk42MQ2McJsOeUJVP728KhymjFCqxgP4VuwRk9rpAl
9
+ 0+mhy6MPdyjyA6G14jrDWS65ysLchK4t/vwpEDz0SQlEoG1kMzllSm7zZS3XregA
10
+ 7DjNaUYQqwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBALM2vGCiQ/vm+a6v40+VX2zd
11
+ qHA2Q/1vF1ibQzJ54MJCOVWvs+vQXfZFhdm0OPM2IrDU7oqvKPqP6xOAeJK6H0yP
12
+ 7M4YL3fatSvIYmmfyXC9kt3Svz/NyrHzPhUnJ0ye/sUSXxnzQxwcm/9PwAqrQaA3
13
+ QpQkH57ybF/OoryPe+2h
14
+ -----END CERTIFICATE-----
@@ -0,0 +1,15 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIICXAIBAAKBgQDo6m+QZvYQ/xL0ElLgupK1QDcYL4f5PckwsNgS9pUvV7fzTqCH
3
+ k8ThLxTk42MQ2McJsOeUJVP728KhymjFCqxgP4VuwRk9rpAl0+mhy6MPdyjyA6G1
4
+ 4jrDWS65ysLchK4t/vwpEDz0SQlEoG1kMzllSm7zZS3XregA7DjNaUYQqwIDAQAB
5
+ AoGBALGR6bRBit+yV5TUU3MZSrf8WQSLWDLgs/33FQSAEYSib4+DJke2lKbI6jkG
6
+ UoSJgFUXFbaQLtMY2+3VDsMKPBdAge9gIdvbkC4yoKjLGm/FBDOxxZcfLpR+9OPq
7
+ U3qM9D0CNuliBWI7Je+p/zs09HIYucpDXy9E18KA1KNF6rfhAkEA9KoNam6wAKnm
8
+ vMzz31ws3RuIOUeo2rx6aaVY95+P9tTxd6U+pNkwxy1aCGP+InVSwlYNA1aQ4Axi
9
+ /GdMIWMkxwJBAPO1CP7cQNZQmu7yusY+GUObDII5YK9WLaY4RAicn5378crPBFxv
10
+ Ukqf9G6FHo7u88iTCIp+vwa3Hn9Tumg3iP0CQQDgUXWBasCVqzCxU5wY4tMDWjXY
11
+ hpoLCpmVeRML3dDJt004rFm2HKe7Rhpw7PTZNQZOxUSjFeA4e0LaNf838UWLAkB8
12
+ QfbHM3ffjhOg96PhhjINdVWoZCb230LBOHj/xxPfUmFTHcBEfQIBSJMxcrBFAnLL
13
+ 9qPpMXymqOFk3ETz9DTlAj8E0qGbp78aVbTOtuwEwNJII+RPw+Zkc+lKR+yaWkAz
14
+ fIXw527NPHH3+rnBG72wyZr9ud4LAum9jh+5No1LQpk=
15
+ -----END RSA PRIVATE KEY-----
@@ -1,14 +1,16 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
2
2
 
3
- class RequestTest < Test::Unit::TestCase
3
+ class LogoutRequestTest < Minitest::Test
4
4
 
5
- context "Logoutrequest" do
6
- settings = OneLogin::RubySaml::Settings.new
5
+ describe "Logoutrequest" do
6
+ let(:settings) { OneLogin::RubySaml::Settings.new }
7
7
 
8
- should "create the deflated SAMLRequest URL parameter" do
8
+ before do
9
9
  settings.idp_slo_target_url = "http://unauth.com/logout"
10
10
  settings.name_identifier_value = "f00f00"
11
+ end
11
12
 
13
+ it "create the deflated SAMLRequest URL parameter" do
12
14
  unauth_url = OneLogin::RubySaml::Logoutrequest.new.create(settings)
13
15
  assert unauth_url =~ /^http:\/\/unauth\.com\/logout\?SAMLRequest=/
14
16
 
@@ -17,8 +19,7 @@ class RequestTest < Test::Unit::TestCase
17
19
  assert_match /^<samlp:LogoutRequest/, inflated
18
20
  end
19
21
 
20
- should "support additional params" do
21
-
22
+ it "support additional params" do
22
23
  unauth_url = OneLogin::RubySaml::Logoutrequest.new.create(settings, { :hello => nil })
23
24
  assert unauth_url =~ /&hello=$/
24
25
 
@@ -26,9 +27,8 @@ class RequestTest < Test::Unit::TestCase
26
27
  assert unauth_url =~ /&foo=bar$/
27
28
  end
28
29
 
29
- should "set sessionindex" do
30
- settings.idp_slo_target_url = "http://example.com"
31
- sessionidx = UUID.new.generate
30
+ it "set sessionindex" do
31
+ sessionidx = random_id
32
32
  settings.sessionindex = sessionidx
33
33
 
34
34
  unauth_url = OneLogin::RubySaml::Logoutrequest.new.create(settings, { :name_id => "there" })
@@ -38,9 +38,7 @@ class RequestTest < Test::Unit::TestCase
38
38
  assert_match %r(#{sessionidx}</samlp:SessionIndex>), inflated
39
39
  end
40
40
 
41
- should "set name_identifier_value" do
42
- settings = OneLogin::RubySaml::Settings.new
43
- settings.idp_slo_target_url = "http://example.com"
41
+ it "set name_identifier_value" do
44
42
  settings.name_identifier_format = "transient"
45
43
  name_identifier_value = "abc123"
46
44
  settings.name_identifier_value = name_identifier_value
@@ -52,41 +50,25 @@ class RequestTest < Test::Unit::TestCase
52
50
  assert_match %r(#{name_identifier_value}</saml:NameID>), inflated
53
51
  end
54
52
 
55
- should "require name_identifier_value" do
56
- settings = OneLogin::RubySaml::Settings.new
57
- settings.idp_slo_target_url = "http://example.com"
58
- settings.name_identifier_format = nil
59
-
60
- assert_raises(OneLogin::RubySaml::ValidationError) { OneLogin::RubySaml::Logoutrequest.new.create(settings) }
61
- end
62
-
63
- context "when the target url doesn't contain a query string" do
64
- should "create the SAMLRequest parameter correctly" do
65
- settings = OneLogin::RubySaml::Settings.new
53
+ describe "when the target url doesn't contain a query string" do
54
+ it "create the SAMLRequest parameter correctly" do
66
55
  settings.idp_slo_target_url = "http://example.com"
67
- settings.name_identifier_value = "f00f00"
68
-
69
56
  unauth_url = OneLogin::RubySaml::Logoutrequest.new.create(settings)
70
57
  assert unauth_url =~ /^http:\/\/example.com\?SAMLRequest/
71
58
  end
72
59
  end
73
60
 
74
- context "when the target url contains a query string" do
75
- should "create the SAMLRequest parameter correctly" do
76
- settings = OneLogin::RubySaml::Settings.new
61
+ describe "when the target url contains a query string" do
62
+ it "create the SAMLRequest parameter correctly" do
77
63
  settings.idp_slo_target_url = "http://example.com?field=value"
78
- settings.name_identifier_value = "f00f00"
79
-
80
64
  unauth_url = OneLogin::RubySaml::Logoutrequest.new.create(settings)
81
65
  assert unauth_url =~ /^http:\/\/example.com\?field=value&SAMLRequest/
82
66
  end
83
67
  end
84
68
 
85
- context "consumation of logout may need to track the transaction" do
86
- should "have access to the request uuid" do
87
- settings = OneLogin::RubySaml::Settings.new
69
+ describe "consumation of logout may need to track the transaction" do
70
+ it "have access to the request uuid" do
88
71
  settings.idp_slo_target_url = "http://example.com?field=value"
89
- settings.name_identifier_value = "f00f00"
90
72
 
91
73
  unauth_req = OneLogin::RubySaml::Logoutrequest.new
92
74
  unauth_url = unauth_req.create(settings)
@@ -95,17 +77,168 @@ class RequestTest < Test::Unit::TestCase
95
77
  assert_match %r[ID='#{unauth_req.uuid}'], inflated
96
78
  end
97
79
  end
98
- end
99
80
 
100
- def decode_saml_request_payload(unauth_url)
101
- payload = CGI.unescape(unauth_url.split("SAMLRequest=").last)
102
- decoded = Base64.decode64(payload)
103
81
 
104
- zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
105
- inflated = zstream.inflate(decoded)
106
- zstream.finish
107
- zstream.close
108
- inflated
109
- end
82
+ describe "when the settings indicate to sign (embedded) logout request" do
83
+
84
+ before do
85
+ # sign the logout request
86
+ settings.security[:logout_requests_signed] = true
87
+ settings.security[:embed_sign] = true
88
+ settings.certificate = ruby_saml_cert_text
89
+ settings.private_key = ruby_saml_key_text
90
+ end
91
+
92
+ it "doesn't sign through create_xml_document" do
93
+ unauth_req = OneLogin::RubySaml::Logoutrequest.new
94
+ inflated = unauth_req.create_xml_document(settings).to_s
95
+
96
+ refute_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>], inflated
97
+ refute_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1'/>], inflated
98
+ refute_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/>], inflated
99
+ end
100
+
101
+ it "sign unsigned request" do
102
+ unauth_req = OneLogin::RubySaml::Logoutrequest.new
103
+ unauth_req_doc = unauth_req.create_xml_document(settings)
104
+ inflated = unauth_req_doc.to_s
105
+
106
+ refute_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>], inflated
107
+ refute_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1'/>], inflated
108
+ refute_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/>], inflated
109
+
110
+ inflated = unauth_req.sign_document(unauth_req_doc, settings).to_s
111
+
112
+ assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>], inflated
113
+ assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1'/>], inflated
114
+ assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/>], inflated
115
+ end
116
+
117
+ it "signs through create_logout_request_xml_doc" do
118
+ unauth_req = OneLogin::RubySaml::Logoutrequest.new
119
+ inflated = unauth_req.create_logout_request_xml_doc(settings).to_s
120
+
121
+ assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>], inflated
122
+ assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1'/>], inflated
123
+ assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/>], inflated
124
+ end
125
+
126
+ it "created a signed logout request" do
127
+ settings.compress_request = true
128
+
129
+ unauth_req = OneLogin::RubySaml::Logoutrequest.new
130
+ unauth_url = unauth_req.create(settings)
131
+
132
+ inflated = decode_saml_request_payload(unauth_url)
133
+ assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>], inflated
134
+ assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1'/>], inflated
135
+ assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/>], inflated
136
+ end
137
+
138
+ it "create a signed logout request with 256 digest and signature method" do
139
+ settings.compress_request = false
140
+ settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
141
+ settings.security[:digest_method] = XMLSecurity::Document::SHA256
110
142
 
143
+ params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings)
144
+ request_xml = Base64.decode64(params["SAMLRequest"])
145
+
146
+ assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>], request_xml
147
+ assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'/>], request_xml
148
+ assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2001/04/xmlenc#sha256'/>], request_xml
149
+ end
150
+
151
+ it "create a signed logout request with 512 digest and signature method RSA_SHA384" do
152
+ settings.compress_request = false
153
+ settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA384
154
+ settings.security[:digest_method] = XMLSecurity::Document::SHA512
155
+
156
+ params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings)
157
+ request_xml = Base64.decode64(params["SAMLRequest"])
158
+
159
+ assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>], request_xml
160
+ assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2001/04/xmldsig-more#rsa-sha384'/>], request_xml
161
+ assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2001/04/xmlenc#sha512'/>], request_xml
162
+ end
163
+ end
164
+
165
+ describe "#create_params when the settings indicate to sign the logout request" do
166
+
167
+ let(:cert) { OpenSSL::X509::Certificate.new(ruby_saml_cert_text) }
168
+
169
+ before do
170
+ # sign the logout request
171
+ settings.security[:logout_requests_signed] = true
172
+ settings.security[:embed_sign] = false
173
+ settings.certificate = ruby_saml_cert_text
174
+ settings.private_key = ruby_saml_key_text
175
+ end
176
+
177
+ it "create a signature parameter with RSA_SHA1 / SHA1 and validate it" do
178
+ settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
179
+
180
+ params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
181
+ assert params['SAMLRequest']
182
+ assert params[:RelayState]
183
+ assert params['Signature']
184
+ assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA1
185
+
186
+ query_string = "SAMLRequest=#{CGI.escape(params['SAMLRequest'])}"
187
+ query_string << "&RelayState=#{CGI.escape(params[:RelayState])}"
188
+ query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}"
189
+
190
+ signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg'])
191
+ assert_equal signature_algorithm, OpenSSL::Digest::SHA1
192
+ assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string)
193
+ end
194
+
195
+ it "create a signature parameter with RSA_SHA256 / SHA256 and validate it" do
196
+ settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
197
+
198
+ params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
199
+ assert params['Signature']
200
+ assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA256
201
+
202
+ query_string = "SAMLRequest=#{CGI.escape(params['SAMLRequest'])}"
203
+ query_string << "&RelayState=#{CGI.escape(params[:RelayState])}"
204
+ query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}"
205
+
206
+ signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg'])
207
+ assert_equal signature_algorithm, OpenSSL::Digest::SHA256
208
+ assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string)
209
+ end
210
+
211
+ it "create a signature parameter with RSA_SHA384 / SHA384 and validate it" do
212
+ settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA384
213
+
214
+ params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
215
+ assert params['Signature']
216
+ assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA384
217
+
218
+ query_string = "SAMLRequest=#{CGI.escape(params['SAMLRequest'])}"
219
+ query_string << "&RelayState=#{CGI.escape(params[:RelayState])}"
220
+ query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}"
221
+
222
+ signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg'])
223
+ assert_equal signature_algorithm, OpenSSL::Digest::SHA384
224
+ assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string)
225
+ end
226
+
227
+ it "create a signature parameter with RSA_SHA512 / SHA512 and validate it" do
228
+ settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA512
229
+
230
+ params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
231
+ assert params['Signature']
232
+ assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA512
233
+
234
+ query_string = "SAMLRequest=#{CGI.escape(params['SAMLRequest'])}"
235
+ query_string << "&RelayState=#{CGI.escape(params[:RelayState])}"
236
+ query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}"
237
+
238
+ signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg'])
239
+ assert_equal signature_algorithm, OpenSSL::Digest::SHA512
240
+ assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string)
241
+ end
242
+ end
243
+ end
111
244
  end
@@ -1,26 +1,27 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
2
- require 'rexml/document'
3
- require 'responses/logoutresponse_fixtures'
4
- class RubySamlTest < Test::Unit::TestCase
2
+ require File.expand_path(File.join(File.dirname(__FILE__), "responses/logoutresponse_fixtures"))
5
3
 
6
- context "Logoutresponse" do
7
- context "#new" do
8
- should "raise an exception when response is initialized with nil" do
4
+ class LogoutResponseTest < Minitest::Test
5
+
6
+ describe "Logoutresponse" do
7
+
8
+ describe "#new" do
9
+ it "raise an exception when response is initialized with nil" do
9
10
  assert_raises(ArgumentError) { OneLogin::RubySaml::Logoutresponse.new(nil) }
10
11
  end
11
- should "default to empty settings" do
12
+ it "default to empty settings" do
12
13
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new( valid_response)
13
14
  assert logoutresponse.settings.nil?
14
15
  end
15
- should "accept constructor-injected settings" do
16
+ it "accept constructor-injected settings" do
16
17
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(valid_response, settings)
17
18
  assert !logoutresponse.settings.nil?
18
19
  end
19
- should "accept constructor-injected options" do
20
+ it "accept constructor-injected options" do
20
21
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(valid_response, nil, { :foo => :bar} )
21
22
  assert !logoutresponse.options.empty?
22
23
  end
23
- should "support base64 encoded responses" do
24
+ it "support base64 encoded responses" do
24
25
  expected_response = valid_response
25
26
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(Base64.encode64(expected_response), settings)
26
27
 
@@ -28,21 +29,21 @@ class RubySamlTest < Test::Unit::TestCase
28
29
  end
29
30
  end
30
31
 
31
- context "#validate" do
32
- should "validate the response" do
32
+ describe "#validate" do
33
+ it "validate the response" do
33
34
  in_relation_to_request_id = random_id
34
35
 
35
36
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(valid_response({:uuid => in_relation_to_request_id}), settings)
36
37
 
37
38
  assert logoutresponse.validate
38
39
 
39
- assert_equal settings.issuer, logoutresponse.issuer
40
+ assert_equal settings.sp_entity_id, logoutresponse.issuer
40
41
  assert_equal in_relation_to_request_id, logoutresponse.in_response_to
41
42
 
42
43
  assert logoutresponse.success?
43
44
  end
44
45
 
45
- should "invalidate responses with wrong id when given option :matches_uuid" do
46
+ it "invalidate responses with wrong id when given option :matches_uuid" do
46
47
 
47
48
  expected_request_id = "_some_other_expected_uuid"
48
49
  opts = { :matches_request_id => expected_request_id}
@@ -50,10 +51,10 @@ class RubySamlTest < Test::Unit::TestCase
50
51
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(valid_response, settings, opts)
51
52
 
52
53
  assert !logoutresponse.validate
53
- assert_not_equal expected_request_id, logoutresponse.in_response_to
54
+ assert expected_request_id != logoutresponse.in_response_to
54
55
  end
55
56
 
56
- should "invalidate responses with wrong request status" do
57
+ it "invalidate responses with wrong request status" do
57
58
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(unsuccessful_response, settings)
58
59
 
59
60
  assert !logoutresponse.validate
@@ -61,8 +62,8 @@ class RubySamlTest < Test::Unit::TestCase
61
62
  end
62
63
  end
63
64
 
64
- context "#validate!" do
65
- should "validates good responses" do
65
+ describe "#validate!" do
66
+ it "validates good responses" do
66
67
  in_relation_to_request_id = random_id
67
68
 
68
69
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(valid_response({:uuid => in_relation_to_request_id}), settings)
@@ -70,7 +71,7 @@ class RubySamlTest < Test::Unit::TestCase
70
71
  logoutresponse.validate!
71
72
  end
72
73
 
73
- should "raises validation error when matching for wrong request id" do
74
+ it "raises validation error when matching for wrong request id" do
74
75
 
75
76
  expected_request_id = "_some_other_expected_id"
76
77
  opts = { :matches_request_id => expected_request_id}
@@ -80,26 +81,27 @@ class RubySamlTest < Test::Unit::TestCase
80
81
  assert_raises(OneLogin::RubySaml::ValidationError) { logoutresponse.validate! }
81
82
  end
82
83
 
83
- should "raise validation error for wrong request status" do
84
+ it "raise validation error for wrong request status" do
84
85
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(unsuccessful_response, settings)
85
86
 
86
87
  assert_raises(OneLogin::RubySaml::ValidationError) { logoutresponse.validate! }
87
88
  end
88
89
 
89
- should "raise validation error when in bad state" do
90
+ it "raise validation error when in bad state" do
90
91
  # no settings
91
92
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(unsuccessful_response)
92
93
  assert_raises(OneLogin::RubySaml::ValidationError) { logoutresponse.validate! }
93
94
  end
94
95
 
95
- should "raise validation error when in lack of issuer setting" do
96
+ it "raise validation error when in lack of sp_entity_id setting" do
96
97
  bad_settings = settings
97
98
  bad_settings.issuer = nil
99
+ bad_settings.sp_entity_id = nil
98
100
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(unsuccessful_response, bad_settings)
99
101
  assert_raises(OneLogin::RubySaml::ValidationError) { logoutresponse.validate! }
100
102
  end
101
103
 
102
- should "raise error for invalid xml" do
104
+ it "raise error for invalid xml" do
103
105
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(invalid_xml_response, settings)
104
106
 
105
107
  assert_raises(OneLogin::RubySaml::ValidationError) { logoutresponse.validate! }
@@ -107,10 +109,4 @@ class RubySamlTest < Test::Unit::TestCase
107
109
  end
108
110
 
109
111
  end
110
-
111
- # logoutresponse fixtures
112
- def random_id
113
- "_#{UUID.new.generate}"
114
- end
115
-
116
112
  end