drop admin scopes on create app instead of rejecting
authorFloatingGhost <hannah@coffee-and-dreams.uk>
Sat, 17 Dec 2022 23:14:49 +0000 (23:14 +0000)
committerFloatingGhost <hannah@coffee-and-dreams.uk>
Sat, 17 Dec 2022 23:14:49 +0000 (23:14 +0000)
CHANGELOG.md
config/description.exs
lib/pleroma/web/o_auth/o_auth_controller.ex
lib/pleroma/web/o_auth/scopes.ex
test/pleroma/web/o_auth/o_auth_controller_test.exs

index 6dcbc4b14b8eee829e23d153988058053f3e4291..5019fc2f294724ee9207c48a25c0c5ddd3519bb6 100644 (file)
@@ -18,6 +18,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 ### Changed
 - Return HTTP error 413 when uploading an avatar or banner that's above the configured upload limit instead of a 500.
 - Non-admin users now cannot register `admin` scope tokens (not security-critical, they didn't work before, but you _could_ create them)
+  - Admin scopes will be dropped on create
 - Rich media will now backoff for 20 minutes after a failure
 
 ### Upgrade notes
index eb61c7218f83e0bef9c4190deedffbd38add67db..c43e25468f7db023866f6ca5197a479731e00c55 100644 (file)
@@ -2664,8 +2664,7 @@ config :pleroma, :config_description, [
       %{
         key: :pool_size,
         type: :integer,
-        description:
-          "Number of concurrent outbound HTTP requests to allow. Default 50.",
+        description: "Number of concurrent outbound HTTP requests to allow. Default 50.",
         suggestions: [50]
       },
       %{
index 3943ca44973e67884f5a64212f8e332637081947..277df1c46683932b08b9669cfe97f7b34a6642a4 100644 (file)
@@ -605,6 +605,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do
   defp do_create_authorization(%User{} = user, %App{} = app, requested_scopes)
        when is_list(requested_scopes) do
     with {:account_status, :active} <- {:account_status, User.account_status(user)},
+         requested_scopes <- Scopes.filter_admin_scopes(requested_scopes, user),
          {:ok, scopes} <- validate_scopes(user, app, requested_scopes),
          {:ok, auth} <- Authorization.create_authorization(app, user, scopes) do
       {:ok, auth}
index 7fe04b9127fd9905bb01b5738a58b33c57ed643f..ccd8d4665d8a4d0bd5f2f1fa9d58dc66fe05e1a8 100644 (file)
@@ -69,6 +69,17 @@ defmodule Pleroma.Web.OAuth.Scopes do
     end
   end
 
+  @spec filter_admin_scopes([String.t()], Pleroma.User.t()) :: [String.t()]
+  @doc """
+  Remove admin scopes for non-admins
+  """
+  def filter_admin_scopes(scopes, %Pleroma.User{is_admin: true}), do: scopes
+
+  def filter_admin_scopes(scopes, _user) do
+    drop_scopes = OAuthScopesPlug.filter_descendants(scopes, ["admin"])
+    Enum.reject(scopes, fn scope -> Enum.member?(drop_scopes, scope) end)
+  end
+
   defp validate_scopes_are_supported(scopes, app_scopes) do
     case OAuthScopesPlug.filter_descendants(scopes, app_scopes) do
       ^scopes -> {:ok, scopes}
index d3cc0acb2a39316a058804af3a12268563310644..bc2d929e564203f925a67a9f3062c5a09a0ab489 100644 (file)
@@ -693,7 +693,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
 
   describe "POST /oauth/authorize" do
     test "redirects with oauth authorization, " <>
-           "granting requested app-supported scopes to both admin users" do
+           "granting requested app-supported scopes to admin users" do
       app_scopes = ["read", "write", "admin", "secret_scope"]
       app = insert(:oauth_app, scopes: app_scopes)
       redirect_uri = OAuthController.default_redirect_uri(app)
@@ -735,7 +735,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
       redirect_uri = OAuthController.default_redirect_uri(app)
 
       non_admin = insert(:user, is_admin: false)
-      scopes_subset = ["read:subscope", "write"]
+      scopes_subset = ["read:subscope", "write", "admin", "admin:metrics"]
 
       # In case scope param is missing, expecting _all_ app-supported scopes to be granted
       conn =
@@ -762,7 +762,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
       assert %{"state" => "statepassed", "code" => code} = query
       auth = Repo.get_by(Authorization, token: code)
       assert auth
-      assert auth.scopes == scopes_subset
+      assert auth.scopes == ["read:subscope", "write"]
     end
 
     test "authorize from cookie" do