diff --git a/lib/spid/rack/slo.rb b/lib/spid/rack/slo.rb index cc35f48..e35ec50 100644 --- a/lib/spid/rack/slo.rb +++ b/lib/spid/rack/slo.rb @@ -38,12 +38,7 @@ def store_session_failure session["errors"] = responser.errors end - def response - if valid_response? - clear_session - else - store_session_failure - end + def response_sp_initiated [ 302, { "Location" => relay_state }, @@ -51,6 +46,24 @@ def response ] end + def response_idp_initiated + [ + 200, + {}, + responser.response + ] + end + + def validate_session + valid_response? ? clear_session : store_session_failure + end + + def response + validate_session + return response_idp_initiated if idp_initiated? + response_sp_initiated + end + def relay_state if !request.params["RelayState"].nil? && request.params["RelayState"] != "" @@ -90,15 +103,34 @@ def saml_response request.params["SAMLResponse"] end + def saml_request + request.params["SAMLRequest"] + end + + def idp_initiated? + !saml_request.nil? + end + def responser @responser ||= begin - sp_initiated_slo_response unless saml_response.nil? + if idp_initiated? + idp_initiated_slo_request + else + sp_initiated_slo_response + end end end private + def idp_initiated_slo_request + ::Spid::Slo::IdpRequest.new( + body: saml_request, + session_index: session["session_index"] + ) + end + def sp_initiated_slo_response ::Spid::Slo::Response.new( body: saml_response, diff --git a/lib/spid/slo/idp_request.rb b/lib/spid/slo/idp_request.rb index 08cc359..ec39e33 100644 --- a/lib/spid/slo/idp_request.rb +++ b/lib/spid/slo/idp_request.rb @@ -15,6 +15,16 @@ def initialize(body:, session_index:) @session_index = session_index end + def response + [ + idp_logout_response.to_saml + ] + end + + def valid? + validator.call + end + def identity_provider @identity_provider ||= IdentityProviderManager.find_by_entity(issuer) @@ -24,6 +34,45 @@ def service_provider @service_provider ||= Spid.configuration.service_provider end + + def issuer + idp_logout_request.issuer + end + + def settings + @settings ||= Spid::Saml2::Settings.new( + service_provider: service_provider, + identity_provider: identity_provider + ) + end + + def validator + @validator ||= + begin + Spid::Saml2::IdpLogoutRequestValidator.new( + request: idp_logout_request + ) + end + end + + def idp_logout_request + @idp_logout_request ||= + begin + Spid::Saml2::IdpLogoutRequest.new( + saml_message: saml_message + ) + end + end + + def idp_logout_response + @idp_logout_response ||= + begin + Spid::Saml2::IdpLogoutResponse.new( + settings: settings, + request_uuid: idp_logout_request.id + ) + end + end end end end diff --git a/spec/fixtures/slo-request.base64 b/spec/fixtures/slo-request.base64 new file mode 100644 index 0000000..a95f945 --- /dev/null +++ b/spec/fixtures/slo-request.base64 @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/spec/requests/rack/slo_spec.rb b/spec/requests/rack/slo_spec.rb index 07829d0..5dd4736 100644 --- a/spec/requests/rack/slo_spec.rb +++ b/spec/requests/rack/slo_spec.rb @@ -42,14 +42,6 @@ File.read(generate_fixture_path("slo-response.base64")) end - let(:spid_session) do - { - "slo_request_uuid" => request_uuid - } - end - - let(:request_uuid) { "_21df91a89767879fc0f7df6a1490c6000c81644d" } - let(:response) do request.get( path, @@ -69,6 +61,14 @@ { SAMLResponse: saml_response, RelayState: "/path/to/return" } end + let(:spid_session) do + { + "slo_request_uuid" => request_uuid + } + end + + let(:request_uuid) { "_21df91a89767879fc0f7df6a1490c6000c81644d" } + it "responds with 302" do expect(response.status).to eq 302 end @@ -115,5 +115,29 @@ end end end + + context "when request is a idp-initiated response from identity provider" do + let(:params) do + { SAMLRequest: saml_request } + end + + let(:spid_session) { {} } + + let(:expected_body) do + %r{} + end + + let(:saml_request) do + File.read(generate_fixture_path("slo-request.base64")) + end + + it "responds with 200" do + expect(response.status).to eq 200 + end + + it "returns the saml logout response" do + expect(response.body).to match expected_body + end + end end end