logout.rb 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. module Gql::Mutations
  3. class Logout < BaseMutation
  4. description 'End the current session'
  5. field :success, Boolean, null: false, description: 'Was the logout successful?'
  6. field :external_logout_url, String, null: true, description: 'External logout URL (e.g. for SAML)?'
  7. # Don't require an authenticated user, because that is not present in maintenance_mode,
  8. # when users still need to be correctly logged out.
  9. def self.authorize(...)
  10. true
  11. end
  12. def self.requires_csrf_verification?
  13. false
  14. end
  15. def resolve(...)
  16. # Special handling for SAML logout (we need to redirect to the ISP).
  17. if saml_session?
  18. begin
  19. return saml_destroy
  20. rescue => e
  21. Rails.logger.error "SAML SLO failed: #{e.message}"
  22. end
  23. end
  24. context[:controller].reset_session
  25. context[:current_user] = nil
  26. context[:controller].request.env['rack.session.options'][:expire_after] = nil
  27. { success: true }
  28. end
  29. def saml_destroy
  30. { success: true, external_logout_url: saml_logout_url }
  31. end
  32. def saml_session?
  33. (session['saml_uid'] || session['saml_session_index']) && OmniAuth::Strategies::SamlDatabase.setup.fetch('idp_slo_service_url', nil)
  34. end
  35. def saml_logout_url
  36. options = OmniAuth::Strategies::SamlDatabase.setup
  37. settings = OneLogin::RubySaml::Settings.new(options)
  38. logout_request = OneLogin::RubySaml::Logoutrequest.new
  39. # Since we created a new SAML request, save the transaction_id
  40. # to compare it with the response we get back
  41. session['saml_transaction_id'] = logout_request.uuid
  42. settings.name_identifier_value = session['saml_uid']
  43. settings.sessionindex = session['saml_session_index']
  44. saml_remember_origin
  45. logout_request.create(settings)
  46. end
  47. def saml_remember_origin
  48. session['omniauth.origin'] = context[:controller].request.env['HTTP_REFERER']
  49. end
  50. def session
  51. @session ||= context[:controller].session
  52. end
  53. end
  54. end