ruby-saml 0.8.11 → 0.8.12

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.

@@ -1,27 +1,27 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
2
- require 'rexml/document'
3
- require 'responses/logoutresponse_fixtures'
2
+ require File.expand_path(File.join(File.dirname(__FILE__), "responses/logoutresponse_fixtures"))
4
3
 
5
- class LogoutResponseTest < Test::Unit::TestCase
4
+ class LogoutResponseTest < Minitest::Test
6
5
 
7
- context "Logoutresponse" do
8
- context "#new" do
9
- should "raise an exception when response is initialized with nil" do
6
+ describe "Logoutresponse" do
7
+
8
+ describe "#new" do
9
+ it "raise an exception when response is initialized with nil" do
10
10
  assert_raises(ArgumentError) { OneLogin::RubySaml::Logoutresponse.new(nil) }
11
11
  end
12
- should "default to empty settings" do
12
+ it "default to empty settings" do
13
13
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new( valid_response)
14
14
  assert logoutresponse.settings.nil?
15
15
  end
16
- should "accept constructor-injected settings" do
16
+ it "accept constructor-injected settings" do
17
17
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(valid_response, settings)
18
18
  assert !logoutresponse.settings.nil?
19
19
  end
20
- should "accept constructor-injected options" do
20
+ it "accept constructor-injected options" do
21
21
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(valid_response, nil, { :foo => :bar} )
22
22
  assert !logoutresponse.options.empty?
23
23
  end
24
- should "support base64 encoded responses" do
24
+ it "support base64 encoded responses" do
25
25
  expected_response = valid_response
26
26
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(Base64.encode64(expected_response), settings)
27
27
 
@@ -29,8 +29,8 @@ class LogoutResponseTest < Test::Unit::TestCase
29
29
  end
30
30
  end
31
31
 
32
- context "#validate" do
33
- should "validate the response" do
32
+ describe "#validate" do
33
+ it "validate the response" do
34
34
  in_relation_to_request_id = random_id
35
35
 
36
36
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(valid_response({:uuid => in_relation_to_request_id}), settings)
@@ -43,7 +43,7 @@ class LogoutResponseTest < Test::Unit::TestCase
43
43
  assert logoutresponse.success?
44
44
  end
45
45
 
46
- 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
47
47
 
48
48
  expected_request_id = "_some_other_expected_uuid"
49
49
  opts = { :matches_request_id => expected_request_id}
@@ -51,10 +51,10 @@ class LogoutResponseTest < Test::Unit::TestCase
51
51
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(valid_response, settings, opts)
52
52
 
53
53
  assert !logoutresponse.validate
54
- assert_not_equal expected_request_id, logoutresponse.in_response_to
54
+ assert expected_request_id != logoutresponse.in_response_to
55
55
  end
56
56
 
57
- should "invalidate responses with wrong request status" do
57
+ it "invalidate responses with wrong request status" do
58
58
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(unsuccessful_response, settings)
59
59
 
60
60
  assert !logoutresponse.validate
@@ -62,8 +62,8 @@ class LogoutResponseTest < Test::Unit::TestCase
62
62
  end
63
63
  end
64
64
 
65
- context "#validate!" do
66
- should "validates good responses" do
65
+ describe "#validate!" do
66
+ it "validates good responses" do
67
67
  in_relation_to_request_id = random_id
68
68
 
69
69
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(valid_response({:uuid => in_relation_to_request_id}), settings)
@@ -71,7 +71,7 @@ class LogoutResponseTest < Test::Unit::TestCase
71
71
  logoutresponse.validate!
72
72
  end
73
73
 
74
- should "raises validation error when matching for wrong request id" do
74
+ it "raises validation error when matching for wrong request id" do
75
75
 
76
76
  expected_request_id = "_some_other_expected_id"
77
77
  opts = { :matches_request_id => expected_request_id}
@@ -81,19 +81,19 @@ class LogoutResponseTest < Test::Unit::TestCase
81
81
  assert_raises(OneLogin::RubySaml::ValidationError) { logoutresponse.validate! }
82
82
  end
83
83
 
84
- should "raise validation error for wrong request status" do
84
+ it "raise validation error for wrong request status" do
85
85
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(unsuccessful_response, settings)
86
86
 
87
87
  assert_raises(OneLogin::RubySaml::ValidationError) { logoutresponse.validate! }
88
88
  end
89
89
 
90
- should "raise validation error when in bad state" do
90
+ it "raise validation error when in bad state" do
91
91
  # no settings
92
92
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(unsuccessful_response)
93
93
  assert_raises(OneLogin::RubySaml::ValidationError) { logoutresponse.validate! }
94
94
  end
95
95
 
96
- should "raise validation error when in lack of sp_entity_id setting" do
96
+ it "raise validation error when in lack of sp_entity_id setting" do
97
97
  bad_settings = settings
98
98
  bad_settings.issuer = nil
99
99
  bad_settings.sp_entity_id = nil
@@ -101,7 +101,7 @@ class LogoutResponseTest < Test::Unit::TestCase
101
101
  assert_raises(OneLogin::RubySaml::ValidationError) { logoutresponse.validate! }
102
102
  end
103
103
 
104
- should "raise error for invalid xml" do
104
+ it "raise error for invalid xml" do
105
105
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(invalid_xml_response, settings)
106
106
 
107
107
  assert_raises(OneLogin::RubySaml::ValidationError) { logoutresponse.validate! }
@@ -109,10 +109,4 @@ class LogoutResponseTest < Test::Unit::TestCase
109
109
  end
110
110
 
111
111
  end
112
-
113
- # logoutresponse fixtures
114
- def random_id
115
- "_#{UUID.new.generate}"
116
- end
117
-
118
112
  end
@@ -1,13 +1,13 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
2
2
 
3
- class ResponseTest < Test::Unit::TestCase
3
+ class ResponseTest < Minitest::Test
4
4
 
5
- context "Response" do
6
- should "raise an exception when response is initialized with nil" do
5
+ describe "Response" do
6
+ it "raise an exception when response is initialized with nil" do
7
7
  assert_raises(ArgumentError) { OneLogin::RubySaml::Response.new(nil) }
8
8
  end
9
9
 
10
- should "be able to parse a document which contains ampersands" do
10
+ it "be able to parse a document which contains ampersands" do
11
11
  XMLSecurity::SignedDocument.any_instance.stubs(:digests_match?).returns(true)
12
12
  OneLogin::RubySaml::Response.any_instance.stubs(:validate_conditions).returns(true)
13
13
 
@@ -18,7 +18,7 @@ class ResponseTest < Test::Unit::TestCase
18
18
  response.validate!
19
19
  end
20
20
 
21
- should "adapt namespace" do
21
+ it "adapt namespace" do
22
22
  response = OneLogin::RubySaml::Response.new(response_document)
23
23
  assert !response.name_id.nil?
24
24
  response = OneLogin::RubySaml::Response.new(response_document_2)
@@ -27,14 +27,14 @@ class ResponseTest < Test::Unit::TestCase
27
27
  assert !response.name_id.nil?
28
28
  end
29
29
 
30
- should "default to raw input when a response is not Base64 encoded" do
30
+ it "default to raw input when a response is not Base64 encoded" do
31
31
  decoded = Base64.decode64(response_document_2)
32
32
  response = OneLogin::RubySaml::Response.new(decoded)
33
33
  assert response.document
34
34
  end
35
35
 
36
- context "Assertion" do
37
- should "only retreive an assertion with an ID that matches the signature's reference URI" do
36
+ describe "Assertion" do
37
+ it "only retreive an assertion with an ID that matches the signature's reference URI" do
38
38
  response = OneLogin::RubySaml::Response.new(wrapped_response_2)
39
39
  response.stubs(:conditions).returns(nil)
40
40
  settings = OneLogin::RubySaml::Settings.new
@@ -44,77 +44,89 @@ class ResponseTest < Test::Unit::TestCase
44
44
  end
45
45
  end
46
46
 
47
- context "#validate!" do
48
- should "raise when encountering a condition that prevents the document from being valid" do
47
+ describe "#validate!" do
48
+ it "raise when encountering a condition that prevents the document from being valid" do
49
49
  response = OneLogin::RubySaml::Response.new(response_document)
50
- assert_raise(OneLogin::RubySaml::ValidationError) do
50
+ assert_raises(OneLogin::RubySaml::ValidationError) do
51
51
  response.validate!
52
52
  end
53
53
  end
54
54
  end
55
55
 
56
- context "#is_valid?" do
57
- should "return false when response is initialized with blank data" do
56
+ describe "#is_valid?" do
57
+ it "return false when response is initialized with blank data" do
58
58
  response = OneLogin::RubySaml::Response.new('')
59
59
  assert !response.is_valid?
60
60
  end
61
61
 
62
- should "return false if settings have not been set" do
62
+ it "return false if settings have not been set" do
63
63
  response = OneLogin::RubySaml::Response.new(response_document)
64
64
  assert !response.is_valid?
65
65
  end
66
66
 
67
- should "return true when the response is initialized with valid data" do
68
- response = OneLogin::RubySaml::Response.new(response_document_4)
67
+ it "return true when the response is initialized with valid data" do
68
+ response = OneLogin::RubySaml::Response.new(response_document_valid_signed)
69
69
  response.stubs(:conditions).returns(nil)
70
70
  assert !response.is_valid?
71
71
  settings = OneLogin::RubySaml::Settings.new
72
72
  assert !response.is_valid?
73
73
  response.settings = settings
74
74
  assert !response.is_valid?
75
- settings.idp_cert_fingerprint = signature_fingerprint_1
76
- assert response.is_valid?
75
+ response.settings.idp_cert_fingerprint = signature_fingerprint_valid_res
76
+ response.validate!
77
77
  end
78
78
 
79
- should "should be idempotent when the response is initialized with invalid data" do
80
- response = OneLogin::RubySaml::Response.new(response_document_4)
79
+ it "should be idempotent when the response is initialized with invalid data" do
80
+ response = OneLogin::RubySaml::Response.new(response_document_valid_signed)
81
81
  response.stubs(:conditions).returns(nil)
82
82
  settings = OneLogin::RubySaml::Settings.new
83
- response.settings = settings
83
+ response.settings = settings
84
84
  assert !response.is_valid?
85
85
  assert !response.is_valid?
86
86
  end
87
87
 
88
- should "should be idempotent when the response is initialized with valid data" do
89
- response = OneLogin::RubySaml::Response.new(response_document_4)
88
+ it "should be idempotent when the response is initialized with valid data" do
89
+ response = OneLogin::RubySaml::Response.new(response_document_valid_signed)
90
90
  response.stubs(:conditions).returns(nil)
91
91
  settings = OneLogin::RubySaml::Settings.new
92
92
  response.settings = settings
93
- settings.idp_cert_fingerprint = signature_fingerprint_1
93
+ response.settings.idp_cert_fingerprint = signature_fingerprint_valid_res
94
94
  assert response.is_valid?
95
95
  assert response.is_valid?
96
96
  end
97
97
 
98
- should "return true when using certificate instead of fingerprint" do
99
- response = OneLogin::RubySaml::Response.new(response_document_4)
98
+ it "return true when using certificate instead of fingerprint" do
99
+ response = OneLogin::RubySaml::Response.new(response_document_valid_signed)
100
100
  response.stubs(:conditions).returns(nil)
101
101
  settings = OneLogin::RubySaml::Settings.new
102
102
  response.settings = settings
103
- settings.idp_cert = signature_1
103
+ settings.idp_cert = valid_cert
104
104
  assert response.is_valid?
105
105
  end
106
106
 
107
- should "not allow signature wrapping attack" do
107
+ it "not allow signature wrapping attack" do
108
108
  response = OneLogin::RubySaml::Response.new(response_document_4)
109
109
  response.stubs(:conditions).returns(nil)
110
110
  settings = OneLogin::RubySaml::Settings.new
111
111
  settings.idp_cert_fingerprint = signature_fingerprint_1
112
112
  response.settings = settings
113
- assert response.is_valid?
113
+ assert !response.is_valid?
114
114
  assert response.name_id == "test@onelogin.com"
115
115
  end
116
116
 
117
- should "support dynamic namespace resolution on signature elements" do
117
+ it "not allow element wrapping attack" do
118
+ response_wrapped = OneLogin::RubySaml::Response.new(response_document_wrapped)
119
+ response_wrapped.stubs(:conditions).returns(nil)
120
+ response_wrapped.stubs(:validate_subject_confirmation).returns(true)
121
+ settings = OneLogin::RubySaml::Settings.new
122
+ response_wrapped.settings = settings
123
+ response_wrapped.settings.idp_cert_fingerprint = signature_fingerprint_1
124
+
125
+ assert !response_wrapped.is_valid?
126
+ assert_nil response_wrapped.name_id
127
+ end
128
+
129
+ it "support dynamic namespace resolution on signature elements" do
118
130
  response = OneLogin::RubySaml::Response.new(fixture("no_signature_ns.xml"))
119
131
  response.stubs(:conditions).returns(nil)
120
132
  settings = OneLogin::RubySaml::Settings.new
@@ -124,7 +136,7 @@ class ResponseTest < Test::Unit::TestCase
124
136
  assert response.validate!
125
137
  end
126
138
 
127
- should "validate ADFS assertions" do
139
+ it "validate ADFS assertions" do
128
140
  response = OneLogin::RubySaml::Response.new(fixture(:adfs_response_sha256))
129
141
  response.stubs(:conditions).returns(nil)
130
142
  settings = OneLogin::RubySaml::Settings.new
@@ -133,7 +145,7 @@ class ResponseTest < Test::Unit::TestCase
133
145
  assert response.validate!
134
146
  end
135
147
 
136
- should "validate the digest" do
148
+ it "validate the digest" do
137
149
  response = OneLogin::RubySaml::Response.new(r1_response_document_6)
138
150
  response.stubs(:conditions).returns(nil)
139
151
  settings = OneLogin::RubySaml::Settings.new
@@ -142,8 +154,8 @@ class ResponseTest < Test::Unit::TestCase
142
154
  assert response.validate!
143
155
  end
144
156
 
145
- should "validate SAML 2.0 XML structure" do
146
- resp_xml = Base64.decode64(response_document_4).gsub(/emailAddress/,'test')
157
+ it "validate SAML 2.0 XML structure" do
158
+ resp_xml = Base64.decode64(response_document_valid_signed).gsub(/emailAddress/,'test')
147
159
  response = OneLogin::RubySaml::Response.new(Base64.encode64(resp_xml))
148
160
  response.stubs(:conditions).returns(nil)
149
161
  settings = OneLogin::RubySaml::Settings.new
@@ -152,7 +164,7 @@ class ResponseTest < Test::Unit::TestCase
152
164
  assert_raises(OneLogin::RubySaml::ValidationError, 'Digest mismatch'){ response.validate! }
153
165
  end
154
166
 
155
- should "Prevent node text with comment (VU#475445) attack" do
167
+ it "Prevent node text with comment (VU#475445) attack" do
156
168
  response_doc = File.read(File.join(File.dirname(__FILE__), "responses", 'response_node_text_attack.xml.base64'))
157
169
  response = OneLogin::RubySaml::Response.new(response_doc)
158
170
 
@@ -160,42 +172,42 @@ class ResponseTest < Test::Unit::TestCase
160
172
  assert_equal "smith", response.attributes["surname"]
161
173
  end
162
174
 
163
- context '#validate_audience' do
164
- should "return true when sp_entity_id not set or empty" do
165
- response = OneLogin::RubySaml::Response.new(response_document_4)
175
+ describe '#validate_audience' do
176
+ it "return true when sp_entity_id not set or empty" do
177
+ response = OneLogin::RubySaml::Response.new(response_document_valid_signed)
166
178
  response.stubs(:conditions).returns(nil)
167
179
  settings = OneLogin::RubySaml::Settings.new
168
180
  response.settings = settings
169
- settings.idp_cert_fingerprint = signature_fingerprint_1
181
+ settings.idp_cert_fingerprint = signature_fingerprint_valid_res
170
182
  assert response.is_valid?
171
183
  settings.sp_entity_id = ''
172
184
  assert response.is_valid?
173
185
  end
174
186
 
175
- should "return false when sp_entity_id set to incorrectly" do
176
- response = OneLogin::RubySaml::Response.new(response_document_4)
187
+ it "return false when sp_entity_id set to incorrectly" do
188
+ response = OneLogin::RubySaml::Response.new(response_document_valid_signed)
177
189
  response.stubs(:conditions).returns(nil)
178
190
  settings = OneLogin::RubySaml::Settings.new
179
191
  response.settings = settings
180
- settings.idp_cert_fingerprint = signature_fingerprint_1
192
+ settings.idp_cert_fingerprint = signature_fingerprint_valid_res
181
193
  settings.sp_entity_id = 'wrong_audience'
182
194
  assert !response.is_valid?
183
195
  end
184
196
 
185
- should "return true when sp_entity_id set to correctly" do
186
- response = OneLogin::RubySaml::Response.new(response_document_4)
197
+ it "return true when sp_entity_id set to correctly" do
198
+ response = OneLogin::RubySaml::Response.new(response_document_valid_signed)
187
199
  response.stubs(:conditions).returns(nil)
188
200
  settings = OneLogin::RubySaml::Settings.new
189
201
  response.settings = settings
190
- settings.idp_cert_fingerprint = signature_fingerprint_1
191
- settings.sp_entity_id = 'audience'
202
+ settings.idp_cert_fingerprint = signature_fingerprint_valid_res
203
+ settings.sp_entity_id = 'https://someone.example.com/audience'
192
204
  assert response.is_valid?
193
205
  end
194
206
  end
195
207
  end
196
208
 
197
- context "#name_id" do
198
- should "extract the value of the name id element" do
209
+ describe "#name_id" do
210
+ it "extract the value of the name id element" do
199
211
  response = OneLogin::RubySaml::Response.new(response_document)
200
212
  assert_equal "support@onelogin.com", response.name_id
201
213
 
@@ -203,19 +215,19 @@ class ResponseTest < Test::Unit::TestCase
203
215
  assert_equal "someone@example.com", response.name_id
204
216
  end
205
217
 
206
- should "be extractable from an OpenSAML response" do
218
+ it "be extractable from an OpenSAML response" do
207
219
  response = OneLogin::RubySaml::Response.new(fixture(:open_saml))
208
220
  assert_equal "someone@example.org", response.name_id
209
221
  end
210
222
 
211
- should "be extractable from a Simple SAML PHP response" do
223
+ it "be extractable from a Simple SAML PHP response" do
212
224
  response = OneLogin::RubySaml::Response.new(fixture(:simple_saml_php))
213
225
  assert_equal "someone@example.com", response.name_id
214
226
  end
215
227
  end
216
228
 
217
- context "#check_conditions" do
218
- should "check time conditions" do
229
+ describe "#check_conditions" do
230
+ it "check time conditions" do
219
231
  response = OneLogin::RubySaml::Response.new(response_document)
220
232
  assert !response.send(:validate_conditions, true)
221
233
  response = OneLogin::RubySaml::Response.new(response_document_6)
@@ -226,75 +238,74 @@ class ResponseTest < Test::Unit::TestCase
226
238
  assert response.send(:validate_conditions, true)
227
239
  end
228
240
 
229
- should "optionally allow for clock drift" do
241
+ it "optionally allow for clock drift" do
230
242
  # The NotBefore condition in the document is 2011-06-14T18:21:01.516Z
231
- Time.stubs(:now).returns(Time.parse("2011-06-14T18:21:01Z"))
243
+ expected_time = Time.parse("2011-06-14T18:21:01Z")
244
+ Time.stubs(:now).returns(expected_time)
232
245
  response = OneLogin::RubySaml::Response.new(response_document_5, :allowed_clock_drift => 0.515)
233
246
  assert !response.send(:validate_conditions, true)
234
247
 
235
- Time.stubs(:now).returns(Time.parse("2011-06-14T18:21:01Z"))
248
+ expected_time = Time.parse("2011-06-14T18:21:01Z")
249
+ Time.stubs(:now).returns(expected_time)
236
250
  response = OneLogin::RubySaml::Response.new(response_document_5, :allowed_clock_drift => 0.516)
237
251
  assert response.send(:validate_conditions, true)
238
252
  end
239
253
  end
240
254
 
241
- context "#attributes" do
242
- should "extract the first attribute in a hash accessed via its symbol" do
243
- response = OneLogin::RubySaml::Response.new(response_document)
244
- assert_equal "demo", response.attributes[:uid]
255
+ describe "#attributes" do
256
+ before do
257
+ @response = OneLogin::RubySaml::Response.new(response_document)
245
258
  end
246
259
 
247
- should "extract the first attribute in a hash accessed via its name" do
248
- response = OneLogin::RubySaml::Response.new(response_document)
249
- assert_equal "demo", response.attributes["uid"]
260
+ it "extract the first attribute in a hash accessed via its symbol" do
261
+ assert_equal "demo", @response.attributes[:uid]
250
262
  end
251
263
 
252
- should "extract all attributes" do
253
- response = OneLogin::RubySaml::Response.new(response_document)
254
- assert_equal "demo", response.attributes[:uid]
255
- assert_equal "value", response.attributes[:another_value]
264
+ it "extract the first attribute in a hash accessed via its name" do
265
+ assert_equal "demo", @response.attributes["uid"]
256
266
  end
257
267
 
258
- should "work for implicit namespaces" do
259
- response = OneLogin::RubySaml::Response.new(response_document_3)
260
- assert_equal "someone@example.com", response.attributes["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"]
268
+ it "extract all attributes" do
269
+ assert_equal "demo", @response.attributes[:uid]
270
+ assert_equal "value", @response.attributes[:another_value]
261
271
  end
262
272
 
263
- should "not raise on responses without attributes" do
264
- response = OneLogin::RubySaml::Response.new(response_document_4)
265
- assert_equal OneLogin::RubySaml::Attributes.new, response.attributes
273
+ it "work for implicit namespaces" do
274
+ response_3 = OneLogin::RubySaml::Response.new(response_document_3)
275
+ assert_equal "someone@example.com", response_3.attributes["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"]
266
276
  end
267
277
 
268
- should "extract attributes from all AttributeStatement tags" do
278
+ it "not raise on responses without attributes" do
279
+ response_4 = OneLogin::RubySaml::Response.new(response_document_4)
280
+ assert_equal OneLogin::RubySaml::Attributes.new, response_4.attributes
281
+ end
282
+
283
+ it "extract attributes from all AttributeStatement tags" do
269
284
  assert_equal "smith", response_with_multiple_attribute_statements.attributes[:surname]
270
285
  assert_equal "bob", response_with_multiple_attribute_statements.attributes[:firstname]
271
286
  end
272
287
 
273
- should "be manipulable by hash methods such as #merge and not raise an exception" do
274
- response = OneLogin::RubySaml::Response.new(response_document)
275
- response.attributes.merge({ :testing_attribute => "test" })
288
+ it "be manipulable by hash methods such as #merge and not raise an exception" do
289
+ @response.attributes.merge({ :testing_attribute => "test" })
276
290
  end
277
291
 
278
- should "be manipulable by hash methods such as #shift and not raise an exception" do
279
- response = OneLogin::RubySaml::Response.new(response_document)
280
- response.attributes.shift
292
+ it "be manipulable by hash methods such as #shift and not raise an exception" do
293
+ @response.attributes.shift
281
294
  end
282
295
 
283
- should "be manipulable by hash methods such as #merge! and actually contain the value" do
284
- response = OneLogin::RubySaml::Response.new(response_document)
285
- response.attributes.merge!({ :testing_attribute => "test" })
286
- assert response.attributes[:testing_attribute]
296
+ it "be manipulable by hash methods such as #merge! and actually contain the value" do
297
+ @response.attributes.merge!({ :testing_attribute => "test" })
298
+ assert @response.attributes[:testing_attribute]
287
299
  end
288
300
 
289
- should "be manipulable by hash methods such as #shift and actually remove the value" do
290
- response = OneLogin::RubySaml::Response.new(response_document)
291
- removed_value = response.attributes.shift
292
- assert_nil response.attributes[removed_value[0]]
301
+ it "be manipulable by hash methods such as #shift and actually remove the value" do
302
+ removed_value = @response.attributes.shift
303
+ assert_nil @response.attributes[removed_value[0]]
293
304
  end
294
305
  end
295
306
 
296
- context "#session_expires_at" do
297
- should "extract the value of the SessionNotOnOrAfter attribute" do
307
+ describe "#session_expires_at" do
308
+ it "extract the value of the SessionNotOnOrAfter attribute" do
298
309
  response = OneLogin::RubySaml::Response.new(response_document)
299
310
  assert response.session_expires_at.is_a?(Time)
300
311
 
@@ -303,124 +314,162 @@ class ResponseTest < Test::Unit::TestCase
303
314
  end
304
315
  end
305
316
 
306
- context "#issuer" do
307
- should "return the issuer inside the response assertion" do
317
+ describe "#issuer" do
318
+ it "return the issuer inside the response assertion" do
308
319
  response = OneLogin::RubySaml::Response.new(response_document)
309
320
  assert_equal "https://app.onelogin.com/saml/metadata/13590", response.issuer
310
321
  end
311
322
 
312
- should "return the issuer inside the response" do
323
+ it "return the issuer inside the response" do
313
324
  response = OneLogin::RubySaml::Response.new(response_document_2)
314
325
  assert_equal "wibble", response.issuer
315
326
  end
316
327
  end
317
328
 
318
- context "#success" do
319
- should "find a status code that says success" do
329
+ describe "#success" do
330
+ it "find a status code that says success" do
320
331
  response = OneLogin::RubySaml::Response.new(response_document)
321
- response.success?
332
+ assert response.send(:success?)
322
333
  end
323
334
  end
324
335
 
325
- context '#xpath_first_from_signed_assertion' do
326
- should 'not allow arbitrary code execution' do
336
+ describe '#xpath_first_from_signed_assertion' do
337
+ it 'not allow arbitrary code execution' do
327
338
  malicious_response_document = fixture('response_eval', false)
328
339
  response = OneLogin::RubySaml::Response.new(malicious_response_document)
329
340
  response.send(:xpath_first_from_signed_assertion)
330
- assert_equal($evalled, nil)
341
+ assert_nil $evalled
331
342
  end
332
343
  end
333
344
 
334
- context "#multiple values" do
335
- should "extract single value as string" do
345
+ describe "#multiple values" do
346
+ it "extract single value as string" do
336
347
  assert_equal "demo", response_multiple_attr_values.attributes[:uid]
337
348
  end
338
349
 
339
- should "extract single value as string in compatibility mode off" do
350
+ it "extract single value as string in compatibility mode off" do
340
351
  OneLogin::RubySaml::Attributes.single_value_compatibility = false
341
352
  assert_equal ["demo"], response_multiple_attr_values.attributes[:uid]
342
353
  # classes are not reloaded between tests so restore default
343
354
  OneLogin::RubySaml::Attributes.single_value_compatibility = true
344
355
  end
345
356
 
346
- should "extract first of multiple values as string for b/w compatibility" do
357
+ it "extract first of multiple values as string for b/w compatibility" do
347
358
  assert_equal 'value1', response_multiple_attr_values.attributes[:another_value]
348
359
  end
349
360
 
350
- should "extract first of multiple values as string for b/w compatibility in compatibility mode off" do
361
+ it "extract first of multiple values as string for b/w compatibility in compatibility mode off" do
351
362
  OneLogin::RubySaml::Attributes.single_value_compatibility = false
352
363
  assert_equal ['value1', 'value2'], response_multiple_attr_values.attributes[:another_value]
353
364
  OneLogin::RubySaml::Attributes.single_value_compatibility = true
354
365
  end
355
366
 
356
- should "return array with all attributes when asked in XML order" do
367
+ it "return array with all attributes when asked in XML order" do
357
368
  assert_equal ['value1', 'value2'], response_multiple_attr_values.attributes.multi(:another_value)
358
369
  end
359
370
 
360
- should "return array with all attributes when asked in XML order in compatibility mode off" do
371
+ it "return array with all attributes when asked in XML order in compatibility mode off" do
361
372
  OneLogin::RubySaml::Attributes.single_value_compatibility = false
362
373
  assert_equal ['value1', 'value2'], response_multiple_attr_values.attributes.multi(:another_value)
363
374
  OneLogin::RubySaml::Attributes.single_value_compatibility = true
364
375
  end
365
376
 
366
- should "return first of multiple values when multiple Attribute tags in XML" do
377
+ it "return first of multiple values when multiple Attribute tags in XML" do
367
378
  assert_equal 'role1', response_multiple_attr_values.attributes[:role]
368
379
  end
369
380
 
370
- should "return first of multiple values when multiple Attribute tags in XML in compatibility mode off" do
381
+ it "return first of multiple values when multiple Attribute tags in XML in compatibility mode off" do
371
382
  OneLogin::RubySaml::Attributes.single_value_compatibility = false
372
383
  assert_equal ['role1', 'role2', 'role3'], response_multiple_attr_values.attributes[:role]
373
384
  OneLogin::RubySaml::Attributes.single_value_compatibility = true
374
385
  end
375
386
 
376
- should "return all of multiple values in reverse order when multiple Attribute tags in XML" do
387
+ it "return all of multiple values in reverse order when multiple Attribute tags in XML" do
377
388
  assert_equal ['role1', 'role2', 'role3'], response_multiple_attr_values.attributes.multi(:role)
378
389
  end
379
390
 
380
- should "return all of multiple values in reverse order when multiple Attribute tags in XML in compatibility mode off" do
391
+ it "return all of multiple values in reverse order when multiple Attribute tags in XML in compatibility mode off" do
381
392
  OneLogin::RubySaml::Attributes.single_value_compatibility = false
382
393
  assert_equal ['role1', 'role2', 'role3'], response_multiple_attr_values.attributes.multi(:role)
383
394
  OneLogin::RubySaml::Attributes.single_value_compatibility = true
384
395
  end
385
396
 
386
- should "return all of multiple values when multiple Attribute tags in multiple AttributeStatement tags" do
397
+ it "return all of multiple values when multiple Attribute tags in multiple AttributeStatement tags" do
387
398
  OneLogin::RubySaml::Attributes.single_value_compatibility = false
388
399
  assert_equal ['role1', 'role2', 'role3'], response_with_multiple_attribute_statements.attributes.multi(:role)
389
400
  OneLogin::RubySaml::Attributes.single_value_compatibility = true
390
401
  end
391
402
 
392
- should "return nil value correctly" do
403
+ it "return nil value correctly" do
393
404
  assert_nil response_multiple_attr_values.attributes[:attribute_with_nil_value]
394
405
  end
395
406
 
396
- should "return nil value correctly when not in compatibility mode off" do
407
+ it "return nil value correctly when not in compatibility mode off" do
397
408
  OneLogin::RubySaml::Attributes.single_value_compatibility = false
398
- assert_equal [nil], response_multiple_attr_values.attributes[:attribute_with_nil_value]
409
+ assert [nil] == response_multiple_attr_values.attributes[:attribute_with_nil_value]
399
410
  OneLogin::RubySaml::Attributes.single_value_compatibility = true
400
411
  end
401
412
 
402
- should "return multiple values including nil and empty string" do
413
+ it "return multiple values including nil and empty string" do
403
414
  response = OneLogin::RubySaml::Response.new(fixture(:response_with_multiple_attribute_values))
404
415
  assert_equal ["", "valuePresent", nil, nil], response.attributes.multi(:attribute_with_nils_and_empty_strings)
405
416
  end
406
417
 
407
- should "return multiple values from [] when not in compatibility mode off" do
418
+ it "return multiple values from [] when not in compatibility mode off" do
408
419
  OneLogin::RubySaml::Attributes.single_value_compatibility = false
409
420
  assert_equal ["", "valuePresent", nil, nil], response_multiple_attr_values.attributes[:attribute_with_nils_and_empty_strings]
410
421
  OneLogin::RubySaml::Attributes.single_value_compatibility = true
411
422
  end
412
423
 
413
- should "check what happens when trying retrieve attribute that does not exists" do
414
- assert_equal nil, response_multiple_attr_values.attributes[:attribute_not_exists]
415
- assert_equal nil, response_multiple_attr_values.attributes.single(:attribute_not_exists)
416
- assert_equal nil, response_multiple_attr_values.attributes.multi(:attribute_not_exists)
424
+ it "check what happens when trying retrieve attribute that does not exists" do
425
+ assert_nil response_multiple_attr_values.attributes[:attribute_not_exists]
426
+ assert_nil response_multiple_attr_values.attributes.single(:attribute_not_exists)
427
+ assert_nil response_multiple_attr_values.attributes.multi(:attribute_not_exists)
417
428
 
418
429
  OneLogin::RubySaml::Attributes.single_value_compatibility = false
419
- assert_equal nil, response_multiple_attr_values.attributes[:attribute_not_exists]
420
- assert_equal nil, response_multiple_attr_values.attributes.single(:attribute_not_exists)
421
- assert_equal nil, response_multiple_attr_values.attributes.multi(:attribute_not_exists)
430
+ assert_nil response_multiple_attr_values.attributes[:attribute_not_exists]
431
+ assert_nil response_multiple_attr_values.attributes.single(:attribute_not_exists)
432
+ assert_nil response_multiple_attr_values.attributes.multi(:attribute_not_exists)
422
433
  OneLogin::RubySaml::Attributes.single_value_compatibility = true
423
434
  end
424
435
  end
436
+
437
+ describe "signature wrapping attack with encrypted assertion" do
438
+ it "should not be valid" do
439
+ settings = OneLogin::RubySaml::Settings.new
440
+ settings.private_key = valid_key
441
+ signature_wrapping_attack = read_response("encrypted_new_attack.xml.base64")
442
+ response_wrapped = OneLogin::RubySaml::Response.new(signature_wrapping_attack, :settings => settings)
443
+ response_wrapped.stubs(:conditions).returns(nil)
444
+ response_wrapped.stubs(:validate_subject_confirmation).returns(true)
445
+ settings.idp_cert_fingerprint = "385b1eec71143f00db6af936e2ea12a28771d72c"
446
+ assert !response_wrapped.is_valid?
447
+ end
448
+ end
449
+
450
+ describe "signature wrapping attack - concealed SAML response body" do
451
+ it "should not be valid" do
452
+ settings = OneLogin::RubySaml::Settings.new
453
+ signature_wrapping_attack = read_response("response_with_concealed_signed_assertion.xml")
454
+ response_wrapped = OneLogin::RubySaml::Response.new(signature_wrapping_attack, :settings => settings)
455
+ settings.idp_cert_fingerprint = '4b68c453c7d994aad9025c99d5efcf566287fe8d'
456
+ response_wrapped.stubs(:conditions).returns(nil)
457
+ response_wrapped.stubs(:validate_subject_confirmation).returns(true)
458
+ assert !response_wrapped.is_valid?
459
+ assert_raises(OneLogin::RubySaml::ValidationError, "SAML Response must contain 1 assertion"){ response_wrapped.validate! }
460
+ end
461
+ end
462
+
463
+ describe "signature wrapping attack - doubled signed assertion SAML response" do
464
+ it "should not be valid" do
465
+ settings = OneLogin::RubySaml::Settings.new
466
+ signature_wrapping_attack = read_response("response_with_doubled_signed_assertion.xml")
467
+ response_wrapped = OneLogin::RubySaml::Response.new(signature_wrapping_attack, :settings => settings)
468
+ settings.idp_cert_fingerprint = '4b68c453c7d994aad9025c99d5efcf566287fe8d'
469
+ response_wrapped.stubs(:conditions).returns(nil)
470
+ response_wrapped.stubs(:validate_subject_confirmation).returns(true)
471
+ assert !response_wrapped.is_valid?
472
+ end
473
+ end
425
474
  end
426
475
  end