From fcd1da40a1da8591dede78d65e2212181b497a49 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Sat, 2 Jul 2022 23:35:58 +0200 Subject: [PATCH] Move 2FA settings actions into `OtpAuthenticationController` --- .../otp_authentication_controller.rb | 47 +++++++++++++++++++ app/controllers/user_controller.rb | 44 +---------------- config/routes.rb | 11 +++-- 3 files changed, 55 insertions(+), 47 deletions(-) create mode 100644 app/controllers/settings/two_factor_authentication/otp_authentication_controller.rb diff --git a/app/controllers/settings/two_factor_authentication/otp_authentication_controller.rb b/app/controllers/settings/two_factor_authentication/otp_authentication_controller.rb new file mode 100644 index 00000000..c32f6664 --- /dev/null +++ b/app/controllers/settings/two_factor_authentication/otp_authentication_controller.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +class Settings::TwoFactorAuthentication::OtpAuthenticationController < ApplicationController + before_action :authenticate_user! + + def index + if current_user.otp_module_disabled? + current_user.otp_secret_key = User.otp_random_secret(25) + current_user.save + + qr_code = RQRCode::QRCode.new(current_user.provisioning_uri("Retrospring:#{current_user.screen_name}", issuer: "Retrospring")) + + @qr_svg = qr_code.as_svg({ offset: 4, module_size: 4, color: "000;fill:var(--primary)" }).html_safe + else + @recovery_code_count = current_user.totp_recovery_codes.count + end + end + + def update + req_params = params.require(:user).permit(:otp_validation) + current_user.otp_module = :enabled + + if current_user.authenticate_otp(req_params[:otp_validation], drift: APP_CONFIG.fetch(:otp_drift_period, 30).to_i) + @recovery_keys = TotpRecoveryCode.generate_for(current_user) + current_user.save! + + render "settings/two_factor_authentication/otp_authentication/recovery_keys" + else + flash[:error] = t(".error") + redirect_to settings_two_factor_authentication_otp_authentication_path + end + end + + def destroy + current_user.otp_module = :disabled + current_user.save! + current_user.totp_recovery_codes.delete_all + flash[:success] = t(".success") + redirect_to settings_two_factor_authentication_otp_authentication_path + end + + def reset + current_user.totp_recovery_codes.delete_all + @recovery_keys = TotpRecoveryCode.generate_for(current_user) + render "settings/two_factor_authentication/otp_authentication/recovery_keys" + end +end diff --git a/app/controllers/user_controller.rb b/app/controllers/user_controller.rb index 1a690087..7b9eb2d9 100644 --- a/app/controllers/user_controller.rb +++ b/app/controllers/user_controller.rb @@ -1,5 +1,5 @@ class UserController < ApplicationController - before_action :authenticate_user!, only: %w[data edit_security update_2fa destroy_2fa reset_user_recovery_codes edit_mute edit_blocks] + before_action :authenticate_user!, only: %w[data edit_mute edit_blocks] def show @user = User.where('LOWER(screen_name) = ?', params[:username].downcase).includes(:profile).first! @@ -69,48 +69,6 @@ class UserController < ApplicationController def data end - def edit_security - if current_user.otp_module_disabled? - current_user.otp_secret_key = User.otp_random_secret(25) - current_user.save - - qr_code = RQRCode::QRCode.new(current_user.provisioning_uri("Retrospring:#{current_user.screen_name}", issuer: "Retrospring")) - - @qr_svg = qr_code.as_svg({ offset: 4, module_size: 4, color: "000;fill:var(--primary)" }).html_safe - else - @recovery_code_count = current_user.totp_recovery_codes.count - end - end - - def update_2fa - req_params = params.require(:user).permit(:otp_validation) - current_user.otp_module = :enabled - - if current_user.authenticate_otp(req_params[:otp_validation], drift: APP_CONFIG.fetch(:otp_drift_period, 30).to_i) - @recovery_keys = TotpRecoveryCode.generate_for(current_user) - current_user.save! - - render "settings/security/recovery_keys" - else - flash[:error] = t(".error") - redirect_to edit_user_security_path - end - end - - def destroy_2fa - current_user.otp_module = :disabled - current_user.save! - current_user.totp_recovery_codes.delete_all - flash[:success] = t(".success") - redirect_to edit_user_security_path - end - - def reset_user_recovery_codes - current_user.totp_recovery_codes.delete_all - @recovery_keys = TotpRecoveryCode.generate_for(current_user) - render 'settings/security/recovery_keys' - end - # region Muting def edit_mute @rules = MuteRule.where(user: current_user) diff --git a/config/routes.rb b/config/routes.rb index ed09e9d9..3b3d35a3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -76,14 +76,17 @@ Rails.application.routes.draw do get :export, to: 'export#index' post :export, to: 'export#create' + + namespace :two_factor_authentication do + get :otp_authentication, to: 'otp_authentication#index' + patch :otp_authentication, to: 'otp_authentication#update' + delete :otp_authentication, to: 'otp_authentication#destroy' + match 'otp_authentication/reset', to: 'otp_authentication#reset', via: :delete + end end resolve('Theme') { [:settings_theme] } # to make link_to/form_for work nicely when passing a `Theme` object to it, see also: https://api.rubyonrails.org/v6.1.5.1/classes/ActionDispatch/Routing/Mapper/CustomUrls.html#method-i-resolve resolve('Profile') { [:settings_profile] } - match '/settings/security', to: 'user#edit_security', via: :get, as: :edit_user_security - match '/settings/security/2fa', to: 'user#update_2fa', via: :patch, as: :update_user_2fa - match '/settings/security/2fa', to: 'user#destroy_2fa', via: :delete, as: :destroy_user_2fa - match '/settings/security/recovery', to: 'user#reset_user_recovery_codes', via: :delete, as: :reset_user_recovery_codes match '/settings/muted', to: 'user#edit_mute', via: :get, as: :edit_user_mute_rules match '/settings/blocks', to: 'user#edit_blocks', via: :get, as: :edit_user_blocks