@@ -30,13 +30,13 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do | |||
plug( | |||
OAuthScopesPlug, | |||
%{scopes: ["read:accounts"]} | |||
%{scopes: ["admin:read:accounts", "read:accounts"]} | |||
when action in [:list_users, :user_show, :right_get, :invites] | |||
) | |||
plug( | |||
OAuthScopesPlug, | |||
%{scopes: ["write:accounts"]} | |||
%{scopes: ["admin:write:accounts", "write:accounts"]} | |||
when action in [ | |||
:get_invite_token, | |||
:revoke_invite, | |||
@@ -58,35 +58,35 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do | |||
plug( | |||
OAuthScopesPlug, | |||
%{scopes: ["read:reports"]} when action in [:list_reports, :report_show] | |||
%{scopes: ["admin:read:reports", "read:reports"]} when action in [:list_reports, :report_show] | |||
) | |||
plug( | |||
OAuthScopesPlug, | |||
%{scopes: ["write:reports"]} | |||
%{scopes: ["admin:reports", "write:reports"]} | |||
when action in [:report_update_state, :report_respond] | |||
) | |||
plug( | |||
OAuthScopesPlug, | |||
%{scopes: ["read:statuses"]} when action == :list_user_statuses | |||
%{scopes: ["admin:read:statuses", "read:statuses"]} when action == :list_user_statuses | |||
) | |||
plug( | |||
OAuthScopesPlug, | |||
%{scopes: ["write:statuses"]} | |||
%{scopes: ["admin:write:statuses", "write:statuses"]} | |||
when action in [:status_update, :status_delete] | |||
) | |||
plug( | |||
OAuthScopesPlug, | |||
%{scopes: ["read"]} | |||
%{scopes: ["admin:read", "read"]} | |||
when action in [:config_show, :migrate_to_db, :migrate_from_db, :list_log] | |||
) | |||
plug( | |||
OAuthScopesPlug, | |||
%{scopes: ["write"]} | |||
%{scopes: ["admin:write", "write"]} | |||
when action in [:relay_follow, :relay_unfollow, :config_update] | |||
) | |||
@@ -222,7 +222,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do | |||
{:user_active, true} <- {:user_active, !user.deactivated}, | |||
{:password_reset_pending, false} <- | |||
{:password_reset_pending, user.password_reset_pending}, | |||
{:ok, scopes} <- validate_scopes(app, params), | |||
{:ok, scopes} <- validate_scopes(app, params, user), | |||
{:ok, auth} <- Authorization.create_authorization(app, user, scopes), | |||
{:ok, token} <- Token.exchange_token(app, auth) do | |||
json(conn, Token.Response.build(user, token)) | |||
@@ -471,7 +471,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do | |||
{:get_user, (user && {:ok, user}) || Authenticator.get_user(conn)}, | |||
%App{} = app <- Repo.get_by(App, client_id: client_id), | |||
true <- redirect_uri in String.split(app.redirect_uris), | |||
{:ok, scopes} <- validate_scopes(app, auth_attrs), | |||
{:ok, scopes} <- validate_scopes(app, auth_attrs, user), | |||
{:auth_active, true} <- {:auth_active, User.auth_active?(user)} do | |||
Authorization.create_authorization(app, user, scopes) | |||
end | |||
@@ -487,12 +487,12 @@ defmodule Pleroma.Web.OAuth.OAuthController do | |||
defp put_session_registration_id(%Plug.Conn{} = conn, registration_id), | |||
do: put_session(conn, :registration_id, registration_id) | |||
@spec validate_scopes(App.t(), map()) :: | |||
@spec validate_scopes(App.t(), map(), User.t()) :: | |||
{:ok, list()} | {:error, :missing_scopes | :unsupported_scopes} | |||
defp validate_scopes(app, params) do | |||
defp validate_scopes(%App{} = app, params, %User{} = user) do | |||
params | |||
|> Scopes.fetch_scopes(app.scopes) | |||
|> Scopes.validate(app.scopes) | |||
|> Scopes.validate(app.scopes, user) | |||
end | |||
def default_redirect_uri(%App{} = app) do | |||
@@ -7,6 +7,9 @@ defmodule Pleroma.Web.OAuth.Scopes do | |||
Functions for dealing with scopes. | |||
""" | |||
alias Pleroma.Plugs.OAuthScopesPlug | |||
alias Pleroma.User | |||
@doc """ | |||
Fetch scopes from request params. | |||
@@ -53,15 +56,36 @@ defmodule Pleroma.Web.OAuth.Scopes do | |||
@doc """ | |||
Validates scopes. | |||
""" | |||
@spec validate(list() | nil, list()) :: | |||
@spec validate(list() | nil, list(), User.t()) :: | |||
{:ok, list()} | {:error, :missing_scopes | :unsupported_scopes} | |||
def validate([], _app_scopes), do: {:error, :missing_scopes} | |||
def validate(nil, _app_scopes), do: {:error, :missing_scopes} | |||
def validate(blank_scopes, _app_scopes, _user) when blank_scopes in [nil, []], | |||
do: {:error, :missing_scopes} | |||
def validate(scopes, app_scopes) do | |||
case Pleroma.Plugs.OAuthScopesPlug.filter_descendants(scopes, app_scopes) do | |||
def validate(scopes, app_scopes, %User{} = user) do | |||
with {:ok, _} <- ensure_scopes_support(scopes, app_scopes), | |||
{:ok, scopes} <- authorize_admin_scopes(scopes, app_scopes, user) do | |||
{:ok, scopes} | |||
end | |||
end | |||
defp ensure_scopes_support(scopes, app_scopes) do | |||
case OAuthScopesPlug.filter_descendants(scopes, app_scopes) do | |||
^scopes -> {:ok, scopes} | |||
_ -> {:error, :unsupported_scopes} | |||
end | |||
end | |||
defp authorize_admin_scopes(scopes, app_scopes, %User{} = user) do | |||
if user.is_admin || !contains_admin_scopes?(scopes) || !contains_admin_scopes?(app_scopes) do | |||
{:ok, scopes} | |||
else | |||
{:error, :unsupported_scopes} | |||
end | |||
end | |||
defp contains_admin_scopes?(scopes) do | |||
scopes | |||
|> OAuthScopesPlug.filter_descendants(["admin"]) | |||
|> Enum.any?() | |||
end | |||
end |
@@ -7,7 +7,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIController do | |||
plug( | |||
OAuthScopesPlug, | |||
%{scopes: ["write"]} | |||
%{scopes: ["admin:write", "write"]} | |||
when action in [ | |||
:create, | |||
:delete, | |||