]> cat aescling's git repositories - mastodon.git/commitdiff
Add option to disable two factor auth in admin accounts panel. (#2584)
authorKaylee <kaylee@codethat.sucks>
Tue, 2 May 2017 19:07:12 +0000 (20:07 +0100)
committerEugen Rochko <eugen@zeonfederated.com>
Tue, 2 May 2017 19:07:12 +0000 (21:07 +0200)
* Add option to disable two factor auth in admin accounts panel.
Closes #2578

* Add @mjankowski's suggestions.
* Moves destroy actions behind User#disable_two_factor!
* Adds spec coverage for Admin:TwoFactorAuthenticationsController and User#disable_two_factor!

app/controllers/admin/two_factor_authentications_controller.rb [new file with mode: 0644]
app/models/user.rb
app/views/admin/accounts/show.html.haml
config/locales/en.yml
config/routes.rb
spec/controllers/admin/two_factor_authentications_controller_spec.rb [new file with mode: 0644]
spec/models/user_spec.rb

diff --git a/app/controllers/admin/two_factor_authentications_controller.rb b/app/controllers/admin/two_factor_authentications_controller.rb
new file mode 100644 (file)
index 0000000..69c08f6
--- /dev/null
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module Admin
+  class TwoFactorAuthenticationsController < BaseController
+    before_action :set_user
+
+    def destroy
+      @user.disable_two_factor!
+      redirect_to admin_accounts_path
+    end
+
+    private
+
+    def set_user
+      @user = User.find(params[:user_id])
+    end
+  end
+end
index f6e080d4e5526ee4b72c3198a32b295160b7eba3..f8e8a2efa24a97397857422f0df38c7ff85bb502 100644 (file)
@@ -56,6 +56,12 @@ class User < ApplicationRecord
     confirmed_at.present?
   end
 
+  def disable_two_factor!
+    self.otp_required_for_login = false
+    otp_backup_codes&.clear
+    save!
+  end
+
   def send_devise_notification(notification, *args)
     devise_mailer.send(notification, self, *args).deliver_later
   end
index 0b3348960b60ed75aa64bee9143b84be43e36787..1a9bd2c4839dc7c6720d732a835755dd61793740 100644 (file)
@@ -70,6 +70,8 @@
 - if @account.local?
   %div{ style: 'float: right' }
     = link_to t('admin.accounts.reset_password'), admin_account_reset_path(@account.id), method: :create, class: 'button'
+    - if @account.user&.otp_required_for_login?
+      = link_to t('admin.accounts.disable_two_factor_authentication'), admin_user_two_factor_authentication_path(@account.user.id), method: :delete, class: 'button'
 
 %div{ style: 'float: left' }
   - if @account.silenced?
index ccf231cd8f9a24cbddc04185dcfc9960d114202d..26ecac7bcde2d9b994d606e180166688f3ec4b3a 100644 (file)
@@ -84,6 +84,7 @@ en:
       public: Public
       push_subscription_expires: PuSH subscription expires
       reset_password: Reset password
+      disable_two_factor_authentication: Disable 2FA
       salmon_url: Salmon URL
       show:
         created_reports: Reports created by this account
index 9adaffcafd92f244056fda9a0920f838676a7bbb..1492f99fbdbbb411327f2836b89be8c764e51201 100644 (file)
@@ -89,6 +89,10 @@ Rails.application.routes.draw do
       resource :suspension, only: [:create, :destroy]
       resource :confirmation, only: [:create]
     end
+
+    resources :users, only: [] do
+      resource :two_factor_authentication, only: [:destroy]
+    end
   end
 
   get '/admin', to: redirect('/admin/settings', status: 302)
diff --git a/spec/controllers/admin/two_factor_authentications_controller_spec.rb b/spec/controllers/admin/two_factor_authentications_controller_spec.rb
new file mode 100644 (file)
index 0000000..69f2603
--- /dev/null
@@ -0,0 +1,17 @@
+require 'rails_helper'
+
+describe Admin::TwoFactorAuthenticationsController do
+  render_views
+
+  let(:user) { Fabricate(:user) }
+  before do
+    sign_in Fabricate(:user, admin: true), scope: :user
+  end
+
+  describe 'DELETE #destroy' do
+    it 'redirects to admin accounts page' do
+      delete :destroy, params: { user_id: user.id }
+      expect(response).to redirect_to(admin_accounts_path)
+    end
+  end
+end
index a86bf4ece6b7ba5627f8e91ded06d41820520e19..fffd92e3d8a06ee0e07418b78e507136f80c2d30 100644 (file)
@@ -126,6 +126,20 @@ RSpec.describe User, type: :model do
     end
   end
 
+  describe '#disable_two_factor!' do
+    it 'sets otp_required_for_login to false' do
+      user = Fabricate.build(:user, otp_required_for_login: true)
+      user.disable_two_factor!
+      expect(user.otp_required_for_login).to be false
+    end
+
+    it 'clears otp_backup_codes' do
+      user = Fabricate.build(:user, otp_backup_codes: %w[dummy dummy])
+      user.disable_two_factor!
+      expect(user.otp_backup_codes.empty?).to be true
+    end
+  end
+
   describe 'whitelist' do
     around(:each) do |example|
       old_whitelist = Rails.configuration.x.email_whitelist