闭社主体 forked from https://github.com/tootsuite/mastodon
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

81 lines
1.8 KiB

  1. # frozen_string_literal: true
  2. class Auth::SessionsController < Devise::SessionsController
  3. include Devise::Controllers::Rememberable
  4. layout 'auth'
  5. skip_before_action :require_no_authentication, only: [:create]
  6. prepend_before_action :authenticate_with_two_factor, if: :two_factor_enabled?, only: [:create]
  7. def create
  8. super do |resource|
  9. remember_me(resource)
  10. flash[:notice] = nil
  11. end
  12. end
  13. def destroy
  14. super
  15. flash[:notice] = nil
  16. end
  17. protected
  18. def find_user
  19. if session[:otp_user_id]
  20. User.find(session[:otp_user_id])
  21. elsif user_params[:email]
  22. User.find_by(email: user_params[:email])
  23. end
  24. end
  25. def user_params
  26. params.require(:user).permit(:email, :password, :otp_attempt)
  27. end
  28. def after_sign_in_path_for(_resource)
  29. last_url = stored_location_for(:user)
  30. if [about_path].include?(last_url)
  31. root_path
  32. else
  33. last_url || root_path
  34. end
  35. end
  36. def two_factor_enabled?
  37. find_user.try(:otp_required_for_login?)
  38. end
  39. def valid_otp_attempt?(user)
  40. user.validate_and_consume_otp!(user_params[:otp_attempt]) ||
  41. user.invalidate_otp_backup_code!(user_params[:otp_attempt])
  42. end
  43. def authenticate_with_two_factor
  44. user = self.resource = find_user
  45. if user_params[:otp_attempt].present? && session[:otp_user_id]
  46. authenticate_with_two_factor_via_otp(user)
  47. elsif user && user.valid_password?(user_params[:password])
  48. prompt_for_two_factor(user)
  49. end
  50. end
  51. def authenticate_with_two_factor_via_otp(user)
  52. if valid_otp_attempt?(user)
  53. session.delete(:otp_user_id)
  54. remember_me(user)
  55. sign_in(user)
  56. else
  57. flash.now[:alert] = I18n.t('users.invalid_otp_token')
  58. prompt_for_two_factor(user)
  59. end
  60. end
  61. def prompt_for_two_factor(user)
  62. session[:otp_user_id] = user.id
  63. render :two_factor
  64. end
  65. end