From 7aa53d52bd982b5ab233a65048f5fb1823127d4a Mon Sep 17 00:00:00 2001
From: eugenijm <eugenijm@protonmail.com>
Date: Sat, 6 Apr 2019 00:22:42 +0300
Subject: [PATCH] Return 403 on oauth token exchange for a deactivated user

---
 lib/pleroma/web/oauth/oauth_controller.ex |  6 ++++++
 test/web/oauth/oauth_controller_test.exs  | 26 +++++++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/lib/pleroma/web/oauth/oauth_controller.ex b/lib/pleroma/web/oauth/oauth_controller.ex
index 26d53df1a..aac8f97fc 100644
--- a/lib/pleroma/web/oauth/oauth_controller.ex
+++ b/lib/pleroma/web/oauth/oauth_controller.ex
@@ -152,6 +152,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do
     with {_, {:ok, %User{} = user}} <- {:get_user, Authenticator.get_user(conn)},
          %App{} = app <- get_app_from_request(conn, params),
          {:auth_active, true} <- {:auth_active, User.auth_active?(user)},
+         {:user_active, true} <- {:user_active, !user.info.deactivated},
          scopes <- oauth_scopes(params, app.scopes),
          [] <- scopes -- app.scopes,
          true <- Enum.any?(scopes),
@@ -175,6 +176,11 @@ defmodule Pleroma.Web.OAuth.OAuthController do
         |> put_status(:forbidden)
         |> json(%{error: "Your login is missing a confirmed e-mail address"})
 
+      {:user_active, false} ->
+        conn
+        |> put_status(:forbidden)
+        |> json(%{error: "Your account is currently disabled"})
+
       _error ->
         put_status(conn, 400)
         |> json(%{error: "Invalid credentials"})
diff --git a/test/web/oauth/oauth_controller_test.exs b/test/web/oauth/oauth_controller_test.exs
index a9a0b9ed4..a68528420 100644
--- a/test/web/oauth/oauth_controller_test.exs
+++ b/test/web/oauth/oauth_controller_test.exs
@@ -327,6 +327,32 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
       refute Map.has_key?(resp, "access_token")
     end
 
+    test "rejects token exchange for valid credentials belonging to deactivated user" do
+      password = "testpassword"
+
+      user =
+        insert(:user,
+          password_hash: Comeonin.Pbkdf2.hashpwsalt(password),
+          info: %{deactivated: true}
+        )
+
+      app = insert(:oauth_app)
+
+      conn =
+        build_conn()
+        |> post("/oauth/token", %{
+          "grant_type" => "password",
+          "username" => user.nickname,
+          "password" => password,
+          "client_id" => app.client_id,
+          "client_secret" => app.client_secret
+        })
+
+      assert resp = json_response(conn, 403)
+      assert %{"error" => _} = resp
+      refute Map.has_key?(resp, "access_token")
+    end
+
     test "rejects an invalid authorization code" do
       app = insert(:oauth_app)