app/controllers/concerns/saml_idp_logout_concern.rb
# frozen_string_literal: true
require 'saml_idp/logout_response_builder'
module SamlIdpLogoutConcern
extend ActiveSupport::Concern
private
def sign_out_with_flash
track_logout_event
sign_out if user_signed_in?
flash[:success] = t('devise.sessions.signed_out')
redirect_to root_url
end
def handle_valid_sp_logout_request
render_template_for(
Base64.strict_encode64(logout_response),
saml_request.response_url,
'SAMLResponse',
)
sign_out if user_signed_in?
end
def handle_valid_sp_remote_logout_request(user_id:, issuer:)
# Remotely delete the user's current session
session_id = ServiceProviderIdentity.
where(user_id: user_id, service_provider: issuer).pick(:rails_session_id)
if session_id
OutOfBandSessionAccessor.new(session_id).destroy
user = User.find_by(id: user_id)
analytics.remote_logout_completed(
service_provider: issuer,
user_id: user&.uuid,
)
end
sign_out if user_signed_in?
# rubocop:disable Rails/RenderInline
render inline: logout_response, content_type: 'text/xml'
# rubocop:enable Rails/RenderInline
end
def find_user_from_session_index
uuid = saml_request.session_index
issuer = saml_request.issuer
agency_id = ServiceProvider.find_by(issuer: issuer).agency_id
user_id = AgencyIdentity.find_by(agency_id: agency_id, uuid: uuid)&.user_id
# ensure that the user has authenticated to that SP
ServiceProviderIdentity.find_by(user_id: user_id, service_provider: issuer)&.user_id
end
def logout_response
encode_response(
current_user,
signature: saml_response_signature_options,
)
end
def track_logout_event
sp_initiated = saml_request.present?
analytics.logout_initiated(
sp_initiated: sp_initiated,
oidc: false,
saml_request_valid: sp_initiated ? valid_saml_request? : true,
)
end
def track_remote_logout_event(issuer)
analytics.remote_logout_initiated(
service_provider: issuer,
saml_request_valid: valid_saml_request?,
)
end
def saml_response_signature_options
endpoint = SamlEndpoint.new(params[:path_year])
{
x509_certificate: endpoint.x509_certificate,
secret_key: endpoint.secret_key,
}
end
end