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