handles_authentication.rb 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. module Gql::Mutations::Concerns::HandlesAuthentication
  3. extend ActiveSupport::Concern
  4. included do # rubocop:disable Metrics/BlockLength
  5. # reimplementation of `authenticate_with_password`
  6. def authenticate(login:, password:, two_factor_authentication: nil, two_factor_recovery: nil, remember_me: false)
  7. auth = begin
  8. if two_factor_authentication.present?
  9. Auth.new(login, password, **two_factor_authentication)
  10. elsif two_factor_recovery.present?
  11. Auth.new(login, password, two_factor_method: 'recovery_codes', two_factor_payload: two_factor_recovery[:recovery_code])
  12. else
  13. Auth.new(login, password)
  14. end
  15. end
  16. begin
  17. auth.valid!
  18. rescue Auth::Error::TwoFactorRequired => e
  19. return {
  20. two_factor_required: {
  21. default_two_factor_authentication_method: e.default_two_factor_authentication_method,
  22. available_two_factor_authentication_methods: e.available_two_factor_authentication_methods,
  23. recovery_codes_available: e.recovery_codes_available
  24. }
  25. }
  26. rescue Auth::Error::Base => e
  27. return error_response({ message: e.message })
  28. end
  29. create_session(auth&.user, remember_me)
  30. authenticate_result
  31. end
  32. def authenticate_result
  33. {
  34. session: {
  35. id: context[:controller].session.id,
  36. after_auth: Auth::AfterAuth.run(context.current_user, context[:controller].session)
  37. }
  38. }
  39. end
  40. def create_session(user, remember_me, authentication_type = 'password')
  41. context[:controller].session.delete(:switched_from_user_id)
  42. # authentication_check_prerequesits is private
  43. context[:controller].send(:authentication_check_prerequesits, user, 'session')
  44. context[:current_user] = user
  45. initiate_session_for(user, remember_me, authentication_type)
  46. end
  47. def initiate_session_for(user, remember_me, authentication_type)
  48. # TODO: Check if this can be moved to a central place, because it's also the same code in the sessions controller.
  49. context[:controller].request.env['rack.session.options'][:expire_after] = 1.year if remember_me
  50. initiate_session_data(authentication_type)
  51. user.activity_stream_log('session started', user.id, true)
  52. end
  53. def initiate_session_data(authentication_type)
  54. context[:controller].session[:persistent] = true
  55. context[:controller].session[:authentication_type] = authentication_type
  56. end
  57. end
  58. end