@@ -68,8 +68,13 @@ defmodule Pleroma.Config do | |||||
def enforce_oauth_admin_scope_usage?, do: !!get([:auth, :enforce_oauth_admin_scope_usage]) | def enforce_oauth_admin_scope_usage?, do: !!get([:auth, :enforce_oauth_admin_scope_usage]) | ||||
def oauth_admin_scopes(scope) do | |||||
["admin:#{scope}"] ++ | |||||
if enforce_oauth_admin_scope_usage?(), do: [], else: [scope] | |||||
def oauth_admin_scopes(scopes) when is_list(scopes) do | |||||
Enum.flat_map( | |||||
scopes, | |||||
fn scope -> | |||||
["admin:#{scope}"] ++ | |||||
if enforce_oauth_admin_scope_usage?(), do: [], else: [scope] | |||||
end | |||||
) | |||||
end | end | ||||
end | end |
@@ -17,13 +17,7 @@ defmodule Pleroma.Plugs.OAuthScopesPlug do | |||||
op = options[:op] || :| | op = options[:op] || :| | ||||
token = assigns[:token] | token = assigns[:token] | ||||
scopes = | |||||
if options[:admin] do | |||||
Config.oauth_admin_scopes(scopes) | |||||
else | |||||
scopes | |||||
end | |||||
scopes = transform_scopes(scopes, options) | |||||
matched_scopes = token && filter_descendants(scopes, token.scopes) | matched_scopes = token && filter_descendants(scopes, token.scopes) | ||||
cond do | cond do | ||||
@@ -69,6 +63,15 @@ defmodule Pleroma.Plugs.OAuthScopesPlug do | |||||
) | ) | ||||
end | end | ||||
@doc "Transforms scopes by applying supported options (e.g. :admin)" | |||||
def transform_scopes(scopes, options) do | |||||
if options[:admin] do | |||||
Config.oauth_admin_scopes(scopes) | |||||
else | |||||
scopes | |||||
end | |||||
end | |||||
defp maybe_perform_instance_privacy_check(%Plug.Conn{} = conn, options) do | defp maybe_perform_instance_privacy_check(%Plug.Conn{} = conn, options) do | ||||
if options[:skip_instance_privacy_check] do | if options[:skip_instance_privacy_check] do | ||||
conn | conn | ||||
@@ -224,4 +224,42 @@ defmodule Pleroma.Plugs.OAuthScopesPlugTest do | |||||
assert f.(["admin:read"], ["write", "admin"]) == ["admin:read"] | assert f.(["admin:read"], ["write", "admin"]) == ["admin:read"] | ||||
end | end | ||||
end | end | ||||
describe "transform_scopes/2" do | |||||
clear_config([:auth, :enforce_oauth_admin_scope_usage]) | |||||
setup do | |||||
{:ok, %{f: &OAuthScopesPlug.transform_scopes/2}} | |||||
end | |||||
test "with :admin option, prefixes all requested scopes with `admin:` " <> | |||||
"and [optionally] keeps only prefixed scopes, " <> | |||||
"depending on `[:auth, :enforce_oauth_admin_scope_usage]` setting", | |||||
%{f: f} do | |||||
Pleroma.Config.put([:auth, :enforce_oauth_admin_scope_usage], false) | |||||
assert f.(["read"], %{admin: true}) == ["admin:read", "read"] | |||||
assert f.(["read", "write"], %{admin: true}) == [ | |||||
"admin:read", | |||||
"read", | |||||
"admin:write", | |||||
"write" | |||||
] | |||||
Pleroma.Config.put([:auth, :enforce_oauth_admin_scope_usage], true) | |||||
assert f.(["read:accounts"], %{admin: true}) == ["admin:read:accounts"] | |||||
assert f.(["read", "write:reports"], %{admin: true}) == [ | |||||
"admin:read", | |||||
"admin:write:reports" | |||||
] | |||||
end | |||||
test "with no supported options, returns unmodified scopes", %{f: f} do | |||||
assert f.(["read"], %{}) == ["read"] | |||||
assert f.(["read", "write"], %{}) == ["read", "write"] | |||||
end | |||||
end | |||||
end | end |