Skip to content

Commit dea8136

Browse files
committed
Align the behavior of the success? method on Response and LogoutResponse
1 parent c72c2fc commit dea8136

File tree

3 files changed

+35
-12
lines changed

3 files changed

+35
-12
lines changed

lib/onelogin/ruby-saml/logoutresponse.rb

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,7 @@ def initialize(response, settings = nil, options = {})
5252
# @raise [ValidationError] if soft == false and validation fails
5353
#
5454
def success?
55-
unless status_code == "urn:oasis:names:tc:SAML:2.0:status:Success"
56-
return append_error("Bad status code. Expected <urn:oasis:names:tc:SAML:2.0:status:Success>, but was: <#@status_code>")
57-
end
58-
true
55+
return status_code == "urn:oasis:names:tc:SAML:2.0:status:Success"
5956
end
6057

6158
# @return [String|nil] Gets the InResponseTo attribute from the Logout Response if exists.
@@ -65,7 +62,7 @@ def in_response_to
6562
node = REXML::XPath.first(
6663
document,
6764
"/p:LogoutResponse",
68-
{ "p" => PROTOCOL, "a" => ASSERTION }
65+
{ "p" => PROTOCOL }
6966
)
7067
node.nil? ? nil : node.attributes['InResponseTo']
7168
end
@@ -88,7 +85,7 @@ def issuer
8885
#
8986
def status_code
9087
@status_code ||= begin
91-
node = REXML::XPath.first(document, "/p:LogoutResponse/p:Status/p:StatusCode", { "p" => PROTOCOL, "a" => ASSERTION })
88+
node = REXML::XPath.first(document, "/p:LogoutResponse/p:Status/p:StatusCode", { "p" => PROTOCOL })
9289
node.nil? ? nil : node.attributes["Value"]
9390
end
9491
end
@@ -98,7 +95,7 @@ def status_message
9895
node = REXML::XPath.first(
9996
document,
10097
"/p:LogoutResponse/p:Status/p:StatusMessage",
101-
{ "p" => PROTOCOL, "a" => ASSERTION }
98+
{ "p" => PROTOCOL }
10299
)
103100
Utils.element_text(node)
104101
end

test/logout_responses/logoutresponse_fixtures.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,25 @@ def unsuccessful_logout_response_document(opts = {})
4444
</samlp:LogoutResponse>"
4545
end
4646

47+
def unsuccessful_logout_response_with_message_document(opts = {})
48+
opts = default_logout_response_opts.merge(opts)
49+
50+
"<samlp:LogoutResponse
51+
xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
52+
ID=\"#{random_id}\" Version=\"2.0\"
53+
IssueInstant=\"#{opts[:issue_instant]}\"
54+
Destination=\"#{opts[:settings].single_logout_service_url}\"
55+
InResponseTo=\"#{opts[:uuid]}\">
56+
<saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">#{opts[:settings].issuer}</saml:Issuer>
57+
<samlp:Status xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\">
58+
<samlp:StatusCode xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
59+
Value=\"urn:oasis:names:tc:SAML:2.0:status:Requester\">
60+
</samlp:StatusCode>
61+
<samlp:StatusMessage>Logoutrequest expired</samlp:StatusMessage>
62+
</samlp:Status>
63+
</samlp:LogoutResponse>"
64+
end
65+
4766
def invalid_xml_logout_response_document
4867
"<samlp:SomethingAwful
4968
xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"

test/logoutresponse_test.rb

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,15 +107,22 @@ class RubySamlTest < Minitest::Test
107107
assert_includes logoutresponse.errors, "The InResponseTo of the Logout Response: #{logoutresponse.in_response_to}, does not match the ID of the Logout Request sent by the SP: #{expected_request_id}"
108108
end
109109

110-
it "invalidate logout response with wrong request status" do
110+
it "invalidate logout response with unexpected request status" do
111111
logoutresponse = OneLogin::RubySaml::Logoutresponse.new(unsuccessful_logout_response_document, settings)
112112

113113
assert !logoutresponse.success?
114114
assert !logoutresponse.validate
115-
assert_includes logoutresponse.errors, "Bad status code. Expected <urn:oasis:names:tc:SAML:2.0:status:Success>, but was: <urn:oasis:names:tc:SAML:2.0:status:Requester>"
116115
assert_includes logoutresponse.errors, "The status code of the Logout Response was not Success, was Requester"
117116
end
118117

118+
it "invalidate logout response with unexpected request status and status message" do
119+
logoutresponse = OneLogin::RubySaml::Logoutresponse.new(unsuccessful_logout_response_with_message_document, settings)
120+
121+
assert !logoutresponse.success?
122+
assert !logoutresponse.validate
123+
assert_includes logoutresponse.errors, "The status code of the Logout Response was not Success, was Requester -> Logoutrequest expired"
124+
end
125+
119126
it "invalidate logout response when in lack of issuer setting" do
120127
bad_settings = settings
121128
bad_settings.issuer = nil
@@ -137,7 +144,7 @@ class RubySamlTest < Minitest::Test
137144
logoutresponse = OneLogin::RubySaml::Logoutresponse.new(unsuccessful_logout_response_document, settings)
138145
collect_errors = true
139146
assert !logoutresponse.validate(collect_errors)
140-
assert_includes logoutresponse.errors, "Bad status code. Expected <urn:oasis:names:tc:SAML:2.0:status:Success>, but was: <urn:oasis:names:tc:SAML:2.0:status:Requester>"
147+
assert_includes logoutresponse.errors, "The status code of the Logout Response was not Success, was Requester"
141148
assert_includes logoutresponse.errors, "Doesn't match the issuer, expected: <#{logoutresponse.settings.idp_entity_id}>, but was: <http://app.muda.no>"
142149
end
143150

@@ -185,14 +192,14 @@ class RubySamlTest < Minitest::Test
185192
logoutresponse = OneLogin::RubySaml::Logoutresponse.new(unsuccessful_logout_response_document, settings)
186193

187194
assert_raises(OneLogin::RubySaml::ValidationError) { logoutresponse.validate }
188-
assert_includes logoutresponse.errors, "Bad status code. Expected <urn:oasis:names:tc:SAML:2.0:status:Success>, but was: <urn:oasis:names:tc:SAML:2.0:status:Requester>"
195+
assert_includes logoutresponse.errors, "The status code of the Logout Response was not Success, was Requester"
189196
end
190197

191198
it "raise validation error when in bad state" do
192199
# no settings
193200
logoutresponse = OneLogin::RubySaml::Logoutresponse.new(unsuccessful_logout_response_document, settings)
194201
assert_raises(OneLogin::RubySaml::ValidationError) { logoutresponse.validate }
195-
assert_includes logoutresponse.errors, "Bad status code. Expected <urn:oasis:names:tc:SAML:2.0:status:Success>, but was: <urn:oasis:names:tc:SAML:2.0:status:Requester>"
202+
assert_includes logoutresponse.errors, "The status code of the Logout Response was not Success, was Requester"
196203
end
197204

198205
it "raise validation error when in lack of issuer setting" do

0 commit comments

Comments
 (0)