From 2f34b747b3f765a37d7b23e70de42005c0b62f58 Mon Sep 17 00:00:00 2001
From: Eugen Rochko <eugen@zeonfederated.com>
Date: Thu, 23 Aug 2018 23:26:29 +0200
Subject: [PATCH] Allow mods to disable login, improve message when login
 disabled (#8329)

* Allow moderators to disable/enable login

* Instead of rejecting login, show forbidden error when login disabled

Avoid confusion because when login is rejected, the message is that
the account is not activated, which is wrong.

* Fix tests
---
 app/controllers/api/base_controller.rb      | 2 ++
 app/controllers/application_controller.rb   | 6 +++---
 app/controllers/auth/sessions_controller.rb | 2 +-
 app/models/user.rb                          | 4 ----
 app/policies/user_policy.rb                 | 4 ++--
 spec/models/user_spec.rb                    | 2 +-
 6 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb
index 770a69921a8..0b373508726 100644
--- a/app/controllers/api/base_controller.rb
+++ b/app/controllers/api/base_controller.rb
@@ -7,6 +7,8 @@ class Api::BaseController < ApplicationController
   include RateLimitHeaders
 
   skip_before_action :store_current_location
+  skip_before_action :check_user_permissions
+
   protect_from_forgery with: :null_session
 
   rescue_from ActiveRecord::RecordInvalid, Mastodon::ValidationError do |e|
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 7ddd26ec03c..d266fa1bd37 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -24,7 +24,7 @@ class ApplicationController < ActionController::Base
   rescue_from Mastodon::NotPermittedError, with: :forbidden
 
   before_action :store_current_location, except: :raise_not_found, unless: :devise_controller?
-  before_action :check_suspension, if: :user_signed_in?
+  before_action :check_user_permissions, if: :user_signed_in?
 
   def raise_not_found
     raise ActionController::RoutingError, "No route matches #{params[:unmatched_route]}"
@@ -48,8 +48,8 @@ class ApplicationController < ActionController::Base
     forbidden unless current_user&.staff?
   end
 
-  def check_suspension
-    forbidden if current_user.account.suspended?
+  def check_user_permissions
+    forbidden if current_user.disabled? || current_user.account.suspended?
   end
 
   def after_sign_out_path_for(_resource_or_scope)
diff --git a/app/controllers/auth/sessions_controller.rb b/app/controllers/auth/sessions_controller.rb
index 2e721160bbc..62b4a6377e7 100644
--- a/app/controllers/auth/sessions_controller.rb
+++ b/app/controllers/auth/sessions_controller.rb
@@ -6,7 +6,7 @@ class Auth::SessionsController < Devise::SessionsController
   layout 'auth'
 
   skip_before_action :require_no_authentication, only: [:create]
-  skip_before_action :check_suspension, only: [:destroy]
+  skip_before_action :check_user_permissions, only: [:destroy]
   prepend_before_action :authenticate_with_two_factor, if: :two_factor_enabled?, only: [:create]
   before_action :set_instance_presenter, only: [:new]
   before_action :set_body_classes
diff --git a/app/models/user.rb b/app/models/user.rb
index a2cf2565fd5..75b7e9e7c40 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -216,10 +216,6 @@ class User < ApplicationRecord
     save!
   end
 
-  def active_for_authentication?
-    super && !disabled?
-  end
-
   def setting_default_privacy
     settings.default_privacy || (account.locked? ? 'private' : 'public')
   end
diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb
index dabdf707a4b..57af5c61c86 100644
--- a/app/policies/user_policy.rb
+++ b/app/policies/user_policy.rb
@@ -18,11 +18,11 @@ class UserPolicy < ApplicationPolicy
   end
 
   def enable?
-    admin?
+    staff?
   end
 
   def disable?
-    admin? && !record.admin?
+    staff? && !record.admin?
   end
 
   def promote?
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 93a6c26fb25..015e90edcde 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -512,7 +512,7 @@ RSpec.describe User, type: :model do
       context 'when user is confirmed' do
         let(:confirmed_at) { Time.zone.now }
 
-        it { is_expected.to be false }
+        it { is_expected.to be true }
       end
 
       context 'when user is not confirmed' do