Merge branch '1723-token-fixes' into 'develop'

AccountController: Return scope in proper format.

Closes #1723

See merge request pleroma/pleroma!2694
This commit is contained in:
lain 2020-07-09 13:10:05 +00:00
commit 8ca1f3e8c6
8 changed files with 56 additions and 68 deletions

View file

@ -447,6 +447,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
} }
end end
# TODO: This is actually a token respone, but there's no oauth operation file yet.
defp create_response do defp create_response do
%Schema{ %Schema{
title: "AccountCreateResponse", title: "AccountCreateResponse",
@ -455,14 +456,20 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
properties: %{ properties: %{
token_type: %Schema{type: :string}, token_type: %Schema{type: :string},
access_token: %Schema{type: :string}, access_token: %Schema{type: :string},
scope: %Schema{type: :array, items: %Schema{type: :string}}, refresh_token: %Schema{type: :string},
created_at: %Schema{type: :integer, format: :"date-time"} scope: %Schema{type: :string},
created_at: %Schema{type: :integer, format: :"date-time"},
me: %Schema{type: :string},
expires_in: %Schema{type: :integer}
}, },
example: %{ example: %{
"token_type" => "Bearer",
"access_token" => "i9hAVVzGld86Pl5JtLtizKoXVvtTlSCJvwaugCxvZzk", "access_token" => "i9hAVVzGld86Pl5JtLtizKoXVvtTlSCJvwaugCxvZzk",
"refresh_token" => "i9hAVVzGld86Pl5JtLtizKoXVvtTlSCJvwaugCxvZzz",
"created_at" => 1_585_918_714, "created_at" => 1_585_918_714,
"scope" => ["read", "write", "follow", "push"], "expires_in" => 600,
"token_type" => "Bearer" "scope" => "read write follow push",
"me" => "https://gensokyo.2hu/users/raymoo"
} }
} }
end end

View file

@ -27,6 +27,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
alias Pleroma.Web.MastodonAPI.MastodonAPI alias Pleroma.Web.MastodonAPI.MastodonAPI
alias Pleroma.Web.MastodonAPI.MastodonAPIController alias Pleroma.Web.MastodonAPI.MastodonAPIController
alias Pleroma.Web.MastodonAPI.StatusView alias Pleroma.Web.MastodonAPI.StatusView
alias Pleroma.Web.OAuth.OAuthView
alias Pleroma.Web.OAuth.Token alias Pleroma.Web.OAuth.Token
alias Pleroma.Web.TwitterAPI.TwitterAPI alias Pleroma.Web.TwitterAPI.TwitterAPI
@ -101,12 +102,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
:ok <- TwitterAPI.validate_captcha(app, params), :ok <- TwitterAPI.validate_captcha(app, params),
{:ok, user} <- TwitterAPI.register_user(params, need_confirmation: true), {:ok, user} <- TwitterAPI.register_user(params, need_confirmation: true),
{:ok, token} <- Token.create_token(app, user, %{scopes: app.scopes}) do {:ok, token} <- Token.create_token(app, user, %{scopes: app.scopes}) do
json(conn, %{ json(conn, OAuthView.render("token.json", %{user: user, token: token}))
token_type: "Bearer",
access_token: token.token,
scope: app.scopes,
created_at: Token.Utils.format_created_at(token)
})
else else
{:error, error} -> json_response(conn, :bad_request, %{error: error}) {:error, error} -> json_response(conn, :bad_request, %{error: error})
end end

View file

@ -13,6 +13,7 @@ defmodule Pleroma.Web.OAuth.MFAController do
alias Pleroma.Web.Auth.TOTPAuthenticator alias Pleroma.Web.Auth.TOTPAuthenticator
alias Pleroma.Web.OAuth.MFAView, as: View alias Pleroma.Web.OAuth.MFAView, as: View
alias Pleroma.Web.OAuth.OAuthController alias Pleroma.Web.OAuth.OAuthController
alias Pleroma.Web.OAuth.OAuthView
alias Pleroma.Web.OAuth.Token alias Pleroma.Web.OAuth.Token
plug(:fetch_session when action in [:show, :verify]) plug(:fetch_session when action in [:show, :verify])
@ -74,7 +75,7 @@ defmodule Pleroma.Web.OAuth.MFAController do
{:ok, %{user: user, authorization: auth}} <- MFA.Token.validate(mfa_token), {:ok, %{user: user, authorization: auth}} <- MFA.Token.validate(mfa_token),
{:ok, _} <- validates_challenge(user, params), {:ok, _} <- validates_challenge(user, params),
{: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, OAuthView.render("token.json", %{user: user, token: token}))
else else
_error -> _error ->
conn conn

View file

@ -5,4 +5,13 @@
defmodule Pleroma.Web.OAuth.MFAView do defmodule Pleroma.Web.OAuth.MFAView do
use Pleroma.Web, :view use Pleroma.Web, :view
import Phoenix.HTML.Form import Phoenix.HTML.Form
alias Pleroma.MFA
def render("mfa_response.json", %{token: token, user: user}) do
%{
error: "mfa_required",
mfa_token: token.token,
supported_challenge_types: MFA.supported_methods(user)
}
end
end end

View file

@ -17,6 +17,8 @@ defmodule Pleroma.Web.OAuth.OAuthController do
alias Pleroma.Web.OAuth.App alias Pleroma.Web.OAuth.App
alias Pleroma.Web.OAuth.Authorization alias Pleroma.Web.OAuth.Authorization
alias Pleroma.Web.OAuth.MFAController alias Pleroma.Web.OAuth.MFAController
alias Pleroma.Web.OAuth.MFAView
alias Pleroma.Web.OAuth.OAuthView
alias Pleroma.Web.OAuth.Scopes alias Pleroma.Web.OAuth.Scopes
alias Pleroma.Web.OAuth.Token alias Pleroma.Web.OAuth.Token
alias Pleroma.Web.OAuth.Token.Strategy.RefreshToken alias Pleroma.Web.OAuth.Token.Strategy.RefreshToken
@ -233,9 +235,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do
with {:ok, app} <- Token.Utils.fetch_app(conn), with {:ok, app} <- Token.Utils.fetch_app(conn),
{:ok, %{user: user} = token} <- Token.get_by_refresh_token(app, token), {:ok, %{user: user} = token} <- Token.get_by_refresh_token(app, token),
{:ok, token} <- RefreshToken.grant(token) do {:ok, token} <- RefreshToken.grant(token) do
response_attrs = %{created_at: Token.Utils.format_created_at(token)} json(conn, OAuthView.render("token.json", %{user: user, token: token}))
json(conn, Token.Response.build(user, token, response_attrs))
else else
_error -> render_invalid_credentials_error(conn) _error -> render_invalid_credentials_error(conn)
end end
@ -247,9 +247,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do
{:ok, auth} <- Authorization.get_by_token(app, fixed_token), {:ok, auth} <- Authorization.get_by_token(app, fixed_token),
%User{} = user <- User.get_cached_by_id(auth.user_id), %User{} = user <- User.get_cached_by_id(auth.user_id),
{:ok, token} <- Token.exchange_token(app, auth) do {:ok, token} <- Token.exchange_token(app, auth) do
response_attrs = %{created_at: Token.Utils.format_created_at(token)} json(conn, OAuthView.render("token.json", %{user: user, token: token}))
json(conn, Token.Response.build(user, token, response_attrs))
else else
error -> error ->
handle_token_exchange_error(conn, error) handle_token_exchange_error(conn, error)
@ -267,7 +265,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do
{:ok, auth} <- Authorization.create_authorization(app, user, scopes), {:ok, auth} <- Authorization.create_authorization(app, user, scopes),
{:mfa_required, _, _, false} <- {:mfa_required, user, auth, MFA.require?(user)}, {:mfa_required, _, _, false} <- {:mfa_required, user, auth, MFA.require?(user)},
{: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, OAuthView.render("token.json", %{user: user, token: token}))
else else
error -> error ->
handle_token_exchange_error(conn, error) handle_token_exchange_error(conn, error)
@ -290,7 +288,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do
with {:ok, app} <- Token.Utils.fetch_app(conn), with {:ok, app} <- Token.Utils.fetch_app(conn),
{:ok, auth} <- Authorization.create_authorization(app, %User{}), {:ok, auth} <- Authorization.create_authorization(app, %User{}),
{:ok, token} <- Token.exchange_token(app, auth) do {:ok, token} <- Token.exchange_token(app, auth) do
json(conn, Token.Response.build_for_client_credentials(token)) json(conn, OAuthView.render("token.json", %{token: token}))
else else
_error -> _error ->
handle_token_exchange_error(conn, :invalid_credentails) handle_token_exchange_error(conn, :invalid_credentails)
@ -548,7 +546,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do
defp build_and_response_mfa_token(user, auth) do defp build_and_response_mfa_token(user, auth) do
with {:ok, token} <- MFA.Token.create_token(user, auth) do with {:ok, token} <- MFA.Token.create_token(user, auth) do
Token.Response.build_for_mfa_token(user, token) MFAView.render("mfa_response.json", %{token: token, user: user})
end end
end end

View file

@ -5,4 +5,26 @@
defmodule Pleroma.Web.OAuth.OAuthView do defmodule Pleroma.Web.OAuth.OAuthView do
use Pleroma.Web, :view use Pleroma.Web, :view
import Phoenix.HTML.Form import Phoenix.HTML.Form
alias Pleroma.Web.OAuth.Token.Utils
def render("token.json", %{token: token} = opts) do
response = %{
token_type: "Bearer",
access_token: token.token,
refresh_token: token.refresh_token,
expires_in: expires_in(),
scope: Enum.join(token.scopes, " "),
created_at: Utils.format_created_at(token)
}
if user = opts[:user] do
response
|> Map.put(:me, user.ap_id)
else
response
end
end
defp expires_in, do: Pleroma.Config.get([:oauth2, :token_expires_in], 600)
end end

View file

@ -1,45 +0,0 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.OAuth.Token.Response do
@moduledoc false
alias Pleroma.MFA
alias Pleroma.User
alias Pleroma.Web.OAuth.Token.Utils
@doc false
def build(%User{} = user, token, opts \\ %{}) do
%{
token_type: "Bearer",
access_token: token.token,
refresh_token: token.refresh_token,
expires_in: expires_in(),
scope: Enum.join(token.scopes, " "),
me: user.ap_id
}
|> Map.merge(opts)
end
def build_for_client_credentials(token) do
%{
token_type: "Bearer",
access_token: token.token,
refresh_token: token.refresh_token,
created_at: Utils.format_created_at(token),
expires_in: expires_in(),
scope: Enum.join(token.scopes, " ")
}
end
def build_for_mfa_token(user, mfa_token) do
%{
error: "mfa_required",
mfa_token: mfa_token.token,
supported_challenge_types: MFA.supported_methods(user)
}
end
defp expires_in, do: Pleroma.Config.get([:oauth2, :token_expires_in], 600)
end

View file

@ -937,7 +937,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
%{ %{
"access_token" => token, "access_token" => token,
"created_at" => _created_at, "created_at" => _created_at,
"scope" => _scope, "scope" => ^scope,
"token_type" => "Bearer" "token_type" => "Bearer"
} = json_response_and_validate_schema(conn, 200) } = json_response_and_validate_schema(conn, 200)
@ -1099,7 +1099,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
assert %{ assert %{
"access_token" => access_token, "access_token" => access_token,
"created_at" => _, "created_at" => _,
"scope" => ["read", "write", "follow", "push"], "scope" => "read write follow push",
"token_type" => "Bearer" "token_type" => "Bearer"
} = response } = response
@ -1217,7 +1217,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
assert %{ assert %{
"access_token" => access_token, "access_token" => access_token,
"created_at" => _, "created_at" => _,
"scope" => ["read"], "scope" => "read",
"token_type" => "Bearer" "token_type" => "Bearer"
} = } =
conn conn