two_factor.rb 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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.descendants.sort_by(&:name)
  6. end
  7. def initialize(user)
  8. @user = user
  9. @all_authentication_methods = self.class.authentication_method_classes.map { |authentication_method| authentication_method.new(user) }
  10. end
  11. def enabled?
  12. enabled_authentication_methods.present?
  13. end
  14. def available_authentication_methods
  15. enabled_authentication_methods.select(&:available?)
  16. end
  17. def enabled_authentication_methods
  18. all_authentication_methods.select(&:enabled?)
  19. end
  20. def verify?(method, payload)
  21. return false if method.nil?
  22. method_object = begin
  23. if method.eql?('recovery_codes')
  24. recovery_codes_object
  25. else
  26. authentication_method_object(method)
  27. end
  28. end
  29. return false if method_object.nil?
  30. result = method_object.verify(payload)
  31. return false if !result[:verified]
  32. method_object.update_user_config(result.except(:verified))
  33. true
  34. end
  35. def initiate_authentication(method)
  36. return {} if method.nil?
  37. method_object = method_object(method)
  38. return {} if method_object.nil?
  39. result = method_object.initiate_authentication
  40. return {} if result.nil?
  41. result
  42. end
  43. def verify_configuration?(method, payload, configuration)
  44. return false if method.nil?
  45. authentication_method_object = authentication_method_object(method)
  46. return false if authentication_method_object.nil?
  47. result = authentication_method_object.verify(payload, configuration)
  48. return false if !result[:verified]
  49. authentication_method_object.create_user_config(result.except(:verified))
  50. true
  51. end
  52. def authentication_method_object(method)
  53. all_authentication_methods.find { |all_authentication_method| all_authentication_method.method_name.eql?(method) }
  54. end
  55. def user_authentication_methods
  56. enabled_authentication_methods.select { |method| user_two_factor_configuration.key?(method.method_name.to_sym) }
  57. end
  58. def user_default_authentication_method
  59. default_method = user.preferences.dig(:two_factor_authentication, :default)
  60. return if default_method.nil?
  61. user_authentication_methods.find { |method| method.method_name.eql?(default_method) }
  62. end
  63. def user_setup_required?
  64. enabled? && !user_configured? && Setting.get('two_factor_authentication_enforce_role_ids').any? { |role_id| user.role_ids.include? role_id.to_i }
  65. end
  66. def user_configured?
  67. !user_default_authentication_method.nil?
  68. end
  69. def user_recovery_codes_exists?
  70. return false if !recovery_codes_enabled?
  71. recovery_codes_object.exists?
  72. end
  73. def recovery_codes_enabled?
  74. recovery_codes_object.enabled?
  75. end
  76. private
  77. def recovery_codes_object
  78. @recovery_codes_object ||= Auth::TwoFactor::RecoveryCodes.new(user)
  79. end
  80. def user_two_factor_configuration
  81. return if user.two_factor_preferences.authentication_methods.nil?
  82. user.two_factor_preferences.authentication_methods.to_h do |two_factor_pref|
  83. [
  84. two_factor_pref.method.to_sym,
  85. two_factor_pref.configuration,
  86. ]
  87. end
  88. end
  89. end