Skip to content

Commit 3f89d19

Browse files
committed
Support customizable statusCode on generated LogoutResponse
1 parent 25cbddd commit 3f89d19

2 files changed

Lines changed: 24 additions & 12 deletions

File tree

lib/onelogin/ruby-saml/slo_logoutresponse.rb

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@ def initialize
2727
# @param request_id [String] The ID of the LogoutRequest sent by this SP to the IdP. That ID will be placed as the InResponseTo in the logout response
2828
# @param logout_message [String] The Message to be placed as StatusMessage in the logout response
2929
# @param params [Hash] Some extra parameters to be added in the GET for example the RelayState
30+
# @param logout_status_code [String] The StatusCode to be placed as StatusMessage in the logout response
3031
# @return [String] Logout Request string that includes the SAMLRequest
3132
#
32-
def create(settings, request_id = nil, logout_message = nil, params = {})
33-
params = create_params(settings, request_id, logout_message, params)
33+
def create(settings, request_id = nil, logout_message = nil, params = {}, logout_status_code = nil)
34+
params = create_params(settings, request_id, logout_message, params, logout_status_code)
3435
params_prefix = (settings.idp_slo_target_url =~ /\?/) ? '&' : '?'
3536
url = settings.idp_slo_response_service_url || settings.idp_slo_target_url
3637
saml_response = CGI.escape(params.delete("SAMLResponse"))
@@ -48,9 +49,10 @@ def create(settings, request_id = nil, logout_message = nil, params = {})
4849
# @param request_id [String] The ID of the LogoutRequest sent by this SP to the IdP. That ID will be placed as the InResponseTo in the logout response
4950
# @param logout_message [String] The Message to be placed as StatusMessage in the logout response
5051
# @param params [Hash] Some extra parameters to be added in the GET for example the RelayState
52+
# @param logout_status_code [String] The StatusCode to be placed as StatusMessage in the logout response
5153
# @return [Hash] Parameters
5254
#
53-
def create_params(settings, request_id = nil, logout_message = nil, params = {})
55+
def create_params(settings, request_id = nil, logout_message = nil, params = {}, logout_status_code = nil)
5456
# The method expects :RelayState but sometimes we get 'RelayState' instead.
5557
# Based on the HashWithIndifferentAccess value in Rails we could experience
5658
# conflicts so this line will solve them.
@@ -61,7 +63,7 @@ def create_params(settings, request_id = nil, logout_message = nil, params = {})
6163
params.delete('RelayState')
6264
end
6365

64-
response_doc = create_logout_response_xml_doc(settings, request_id, logout_message)
66+
response_doc = create_logout_response_xml_doc(settings, request_id, logout_message, logout_status_code)
6567
response_doc.context[:attribute_quote] = :quote if settings.double_quote_xml_attribute_values
6668

6769
response = ""
@@ -97,14 +99,15 @@ def create_params(settings, request_id = nil, logout_message = nil, params = {})
9799
# @param settings [OneLogin::RubySaml::Settings|nil] Toolkit settings
98100
# @param request_id [String] The ID of the LogoutRequest sent by this SP to the IdP. That ID will be placed as the InResponseTo in the logout response
99101
# @param logout_message [String] The Message to be placed as StatusMessage in the logout response
102+
# @param logout_status_code [String] The StatusCode to be placed as StatusMessage in the logout response
100103
# @return [String] The SAMLResponse String.
101104
#
102-
def create_logout_response_xml_doc(settings, request_id = nil, logout_message = nil)
103-
document = create_xml_document(settings, request_id, logout_message)
105+
def create_logout_response_xml_doc(settings, request_id = nil, logout_message = nil, logout_status_code = nil)
106+
document = create_xml_document(settings, request_id, logout_message, logout_status_code)
104107
sign_document(document, settings)
105108
end
106109

107-
def create_xml_document(settings, request_id = nil, logout_message = nil)
110+
def create_xml_document(settings, request_id = nil, logout_message = nil, status_code = nil)
108111
time = Time.now.utc.strftime('%Y-%m-%dT%H:%M:%SZ')
109112

110113
response_doc = XMLSecurity::Document.new
@@ -124,14 +127,15 @@ def create_xml_document(settings, request_id = nil, logout_message = nil)
124127
issuer.text = settings.sp_entity_id
125128
end
126129

127-
# add success message
130+
# add status
128131
status = root.add_element 'samlp:Status'
129132

130-
# success status code
131-
status_code = status.add_element 'samlp:StatusCode'
132-
status_code.attributes['Value'] = 'urn:oasis:names:tc:SAML:2.0:status:Success'
133+
# status code
134+
status_code ||= 'urn:oasis:names:tc:SAML:2.0:status:Success'
135+
status_code_elem = status.add_element 'samlp:StatusCode'
136+
status_code_elem.attributes['Value'] = status_code
133137

134-
# success status message
138+
# status message
135139
logout_message ||= 'Successfully Signed Out'
136140
status_message = status.add_element 'samlp:StatusMessage'
137141
status_message.text = logout_message

test/slo_logoutresponse_test.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@ class SloLogoutresponseTest < Minitest::Test
6565
assert_match /<samlp:StatusMessage>Custom Logout Message<\/samlp:StatusMessage>/, inflated
6666
end
6767

68+
it "set a custom logout message and an status on the response" do
69+
unauth_url = OneLogin::RubySaml::SloLogoutresponse.new.create(settings, nil, "Custom Logout Message", {}, "urn:oasis:names:tc:SAML:2.0:status:PartialLogout")
70+
71+
inflated = decode_saml_response_payload(unauth_url)
72+
assert_match /<samlp:StatusMessage>Custom Logout Message<\/samlp:StatusMessage>/, inflated
73+
assert_match /<samlp:StatusCode Value='urn:oasis:names:tc:SAML:2.0:status:PartialLogout/, inflated
74+
end
75+
6876
it "uses the response location when set" do
6977
settings.idp_slo_response_service_url = "http://unauth.com/logout/return"
7078

0 commit comments

Comments
 (0)