two_factor.rb 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. class Auth::TwoFactor
  3. attr_reader :user, :all_authentication_methods
  4. def self.authentication_method_classes
  5. @authentication_method_classes ||= Auth::TwoFactor::AuthenticationMethod
  6. .descendants
  7. .sort_by { |elem| elem.const_get(:ORDER) }
  8. end
  9. def initialize(user)
  10. @user = user
  11. @all_authentication_methods = self.class.authentication_method_classes
  12. .map { |authentication_method| authentication_method.new(user) }
  13. end
  14. def enabled?
  15. enabled_authentication_methods.present?
  16. end
  17. def available_authentication_methods
  18. enabled_authentication_methods.select(&:available?)
  19. end
  20. def enabled_authentication_methods
  21. all_authentication_methods.select(&:enabled?)
  22. end
  23. def verify?(method, payload)
  24. return false if method.nil?
  25. method_object = if method == 'recovery_codes'
  26. recovery_codes_object
  27. else
  28. authentication_method_object(method)
  29. end
  30. return false if method_object.nil?
  31. result = method_object.verify(payload)
  32. return false if !result[:verified]
  33. method_object.update_user_config(result.except(:verified))
  34. true
  35. end
  36. def initiate_authentication(method)
  37. return {} if method.nil?
  38. method_object = method_object(method)
  39. return {} if method_object.nil?
  40. result = method_object.initiate_authentication
  41. return {} if result.nil?
  42. result
  43. end
  44. def verify_configuration?(method, payload, configuration)
  45. return false if method.nil?
  46. authentication_method_object = authentication_method_object(method)
  47. return false if authentication_method_object.nil?
  48. result = authentication_method_object.verify(payload, configuration)
  49. return false if !result[:verified]
  50. authentication_method_object.create_user_config(result.except(:verified))
  51. true
  52. end
  53. def authentication_method_object(method_name)
  54. all_authentication_methods.find { |method| method.method_name == method_name }
  55. end
  56. def user_authentication_methods
  57. enabled_authentication_methods
  58. .select { |method| user_two_factor_configuration.include?(method.method_name) }
  59. end
  60. def user_default_authentication_method
  61. default_method = user_authentication_methods
  62. .find { |method| method.method_name == user.two_factor_default }
  63. return default_method if default_method
  64. user_authentication_methods.first
  65. end
  66. def user_setup_required?
  67. enabled? && !user_configured? && Setting.get('two_factor_authentication_enforce_role_ids').any? { |role_id| user.role_ids.include? role_id.to_i }
  68. end
  69. def user_configured?
  70. !user_default_authentication_method.nil?
  71. end
  72. def user_recovery_codes_exists?
  73. return false if !recovery_codes_enabled?
  74. recovery_codes_object.exists?
  75. end
  76. def recovery_codes_enabled?
  77. recovery_codes_object.enabled?
  78. end
  79. private
  80. def recovery_codes_object
  81. @recovery_codes_object ||= Auth::TwoFactor::RecoveryCodes.new(user)
  82. end
  83. def user_two_factor_configuration
  84. user.two_factor_preferences.authentication_methods.pluck(:method)
  85. end
  86. end