From f378e93bf4ca4bc9547f242e76e6258e25852972 Mon Sep 17 00:00:00 2001 From: lain Date: Fri, 26 Jun 2020 16:15:27 +0200 Subject: [PATCH 1/5] AccountController: Return scope in proper format. --- lib/pleroma/web/api_spec/operations/account_operation.ex | 4 ++-- .../web/mastodon_api/controllers/account_controller.ex | 2 +- .../mastodon_api/controllers/account_controller_test.exs | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/pleroma/web/api_spec/operations/account_operation.ex b/lib/pleroma/web/api_spec/operations/account_operation.ex index 9bde8fc0d..d94dae374 100644 --- a/lib/pleroma/web/api_spec/operations/account_operation.ex +++ b/lib/pleroma/web/api_spec/operations/account_operation.ex @@ -446,13 +446,13 @@ defp create_response do properties: %{ token_type: %Schema{type: :string}, access_token: %Schema{type: :string}, - scope: %Schema{type: :array, items: %Schema{type: :string}}, + scope: %Schema{type: :string}, created_at: %Schema{type: :integer, format: :"date-time"} }, example: %{ "access_token" => "i9hAVVzGld86Pl5JtLtizKoXVvtTlSCJvwaugCxvZzk", "created_at" => 1_585_918_714, - "scope" => ["read", "write", "follow", "push"], + "scope" => "read write follow push", "token_type" => "Bearer" } } diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 7a88a847c..a87dddddf 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -104,7 +104,7 @@ def create(%{assigns: %{app: app}, body_params: params} = conn, _params) do json(conn, %{ token_type: "Bearer", access_token: token.token, - scope: app.scopes, + scope: app.scopes |> Enum.join(" "), created_at: Token.Utils.format_created_at(token) }) else diff --git a/test/web/mastodon_api/controllers/account_controller_test.exs b/test/web/mastodon_api/controllers/account_controller_test.exs index ebfcedd01..fcc1e792b 100644 --- a/test/web/mastodon_api/controllers/account_controller_test.exs +++ b/test/web/mastodon_api/controllers/account_controller_test.exs @@ -905,7 +905,7 @@ test "Account registration via Application", %{conn: conn} do %{ "access_token" => token, "created_at" => _created_at, - "scope" => _scope, + "scope" => ^scope, "token_type" => "Bearer" } = json_response_and_validate_schema(conn, 200) @@ -1067,7 +1067,7 @@ test "registration from trusted app" do assert %{ "access_token" => access_token, "created_at" => _, - "scope" => ["read", "write", "follow", "push"], + "scope" => "read write follow push", "token_type" => "Bearer" } = response @@ -1185,7 +1185,7 @@ test "creates an account and returns 200 if captcha is valid", %{conn: conn} do assert %{ "access_token" => access_token, "created_at" => _, - "scope" => ["read"], + "scope" => "read", "token_type" => "Bearer" } = conn From bb168ed94a6b4d02879472e30149a494d7b7ebb5 Mon Sep 17 00:00:00 2001 From: lain Date: Mon, 29 Jun 2020 13:39:09 +0200 Subject: [PATCH 2/5] OAuth: Extract view-type functions to a view. --- lib/pleroma/web/oauth/mfa_controller.ex | 3 +- lib/pleroma/web/oauth/mfa_view.ex | 9 ++++++ lib/pleroma/web/oauth/oauth_controller.ex | 18 +++++------ lib/pleroma/web/oauth/oauth_view.ex | 22 +++++++++++++ lib/pleroma/web/oauth/token/response.ex | 39 ----------------------- 5 files changed, 41 insertions(+), 50 deletions(-) diff --git a/lib/pleroma/web/oauth/mfa_controller.ex b/lib/pleroma/web/oauth/mfa_controller.ex index 53e19f82e..f102c93e7 100644 --- a/lib/pleroma/web/oauth/mfa_controller.ex +++ b/lib/pleroma/web/oauth/mfa_controller.ex @@ -13,6 +13,7 @@ defmodule Pleroma.Web.OAuth.MFAController do alias Pleroma.Web.Auth.TOTPAuthenticator alias Pleroma.Web.OAuth.MFAView, as: View alias Pleroma.Web.OAuth.OAuthController + alias Pleroma.Web.OAuth.OAuthView alias Pleroma.Web.OAuth.Token plug(:fetch_session when action in [:show, :verify]) @@ -74,7 +75,7 @@ def challenge(conn, %{"mfa_token" => mfa_token} = params) do {:ok, %{user: user, authorization: auth}} <- MFA.Token.validate(mfa_token), {:ok, _} <- validates_challenge(user, params), {: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 _error -> conn diff --git a/lib/pleroma/web/oauth/mfa_view.ex b/lib/pleroma/web/oauth/mfa_view.ex index 41d5578dc..5d87db268 100644 --- a/lib/pleroma/web/oauth/mfa_view.ex +++ b/lib/pleroma/web/oauth/mfa_view.ex @@ -5,4 +5,13 @@ defmodule Pleroma.Web.OAuth.MFAView do use Pleroma.Web, :view 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 diff --git a/lib/pleroma/web/oauth/oauth_controller.ex b/lib/pleroma/web/oauth/oauth_controller.ex index c557778ca..3da104933 100644 --- a/lib/pleroma/web/oauth/oauth_controller.ex +++ b/lib/pleroma/web/oauth/oauth_controller.ex @@ -6,8 +6,8 @@ defmodule Pleroma.Web.OAuth.OAuthController do use Pleroma.Web, :controller alias Pleroma.Helpers.UriHelper - alias Pleroma.Maps alias Pleroma.MFA + alias Pleroma.Maps alias Pleroma.Plugs.RateLimiter alias Pleroma.Registration alias Pleroma.Repo @@ -17,6 +17,8 @@ defmodule Pleroma.Web.OAuth.OAuthController do alias Pleroma.Web.OAuth.App alias Pleroma.Web.OAuth.Authorization alias Pleroma.Web.OAuth.MFAController + alias Pleroma.Web.OAuth.OAuthView + alias Pleroma.Web.OAuth.MFAView alias Pleroma.Web.OAuth.Scopes alias Pleroma.Web.OAuth.Token alias Pleroma.Web.OAuth.Token.Strategy.RefreshToken @@ -233,9 +235,7 @@ def token_exchange( with {:ok, app} <- Token.Utils.fetch_app(conn), {:ok, %{user: user} = token} <- Token.get_by_refresh_token(app, token), {:ok, token} <- RefreshToken.grant(token) do - response_attrs = %{created_at: Token.Utils.format_created_at(token)} - - json(conn, Token.Response.build(user, token, response_attrs)) + json(conn, OAuthView.render("token.json", %{user: user, token: token})) else _error -> render_invalid_credentials_error(conn) end @@ -247,9 +247,7 @@ def token_exchange(%Plug.Conn{} = conn, %{"grant_type" => "authorization_code"} {:ok, auth} <- Authorization.get_by_token(app, fixed_token), %User{} = user <- User.get_cached_by_id(auth.user_id), {:ok, token} <- Token.exchange_token(app, auth) do - response_attrs = %{created_at: Token.Utils.format_created_at(token)} - - json(conn, Token.Response.build(user, token, response_attrs)) + json(conn, OAuthView.render("token.json", %{user: user, token: token})) else error -> handle_token_exchange_error(conn, error) @@ -267,7 +265,7 @@ def token_exchange( {:ok, auth} <- Authorization.create_authorization(app, user, scopes), {:mfa_required, _, _, false} <- {:mfa_required, user, auth, MFA.require?(user)}, {: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 error -> handle_token_exchange_error(conn, error) @@ -290,7 +288,7 @@ def token_exchange(%Plug.Conn{} = conn, %{"grant_type" => "client_credentials"} with {:ok, app} <- Token.Utils.fetch_app(conn), {:ok, auth} <- Authorization.create_authorization(app, %User{}), {: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 _error -> handle_token_exchange_error(conn, :invalid_credentails) @@ -548,7 +546,7 @@ defp put_session_registration_id(%Plug.Conn{} = conn, registration_id), defp build_and_response_mfa_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 diff --git a/lib/pleroma/web/oauth/oauth_view.ex b/lib/pleroma/web/oauth/oauth_view.ex index 94ddaf913..f55247ebd 100644 --- a/lib/pleroma/web/oauth/oauth_view.ex +++ b/lib/pleroma/web/oauth/oauth_view.ex @@ -5,4 +5,26 @@ defmodule Pleroma.Web.OAuth.OAuthView do use Pleroma.Web, :view 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 diff --git a/lib/pleroma/web/oauth/token/response.ex b/lib/pleroma/web/oauth/token/response.ex index 0e72c31e9..a12a6865c 100644 --- a/lib/pleroma/web/oauth/token/response.ex +++ b/lib/pleroma/web/oauth/token/response.ex @@ -3,43 +3,4 @@ # 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 From e374872fe7d10aa659723ee31003f3e9188edfdd Mon Sep 17 00:00:00 2001 From: lain Date: Mon, 29 Jun 2020 13:49:48 +0200 Subject: [PATCH 3/5] AccountOperation: Correctly describe create response. --- .../web/api_spec/operations/account_operation.ex | 11 +++++++++-- .../mastodon_api/controllers/account_controller.ex | 8 ++------ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/pleroma/web/api_spec/operations/account_operation.ex b/lib/pleroma/web/api_spec/operations/account_operation.ex index d94dae374..f3ffa1ad4 100644 --- a/lib/pleroma/web/api_spec/operations/account_operation.ex +++ b/lib/pleroma/web/api_spec/operations/account_operation.ex @@ -438,6 +438,7 @@ defp create_request do } end + # TODO: This is actually a token respone, but there's no oauth operation file yet. defp create_response do %Schema{ title: "AccountCreateResponse", @@ -446,14 +447,20 @@ defp create_response do properties: %{ token_type: %Schema{type: :string}, access_token: %Schema{type: :string}, + refresh_token: %Schema{type: :string}, scope: %Schema{type: :string}, - created_at: %Schema{type: :integer, format: :"date-time"} + created_at: %Schema{type: :integer, format: :"date-time"}, + me: %Schema{type: :string}, + expires_in: %Schema{type: :integer} }, example: %{ + "token_type" => "Bearer", "access_token" => "i9hAVVzGld86Pl5JtLtizKoXVvtTlSCJvwaugCxvZzk", + "refresh_token" => "i9hAVVzGld86Pl5JtLtizKoXVvtTlSCJvwaugCxvZzz", "created_at" => 1_585_918_714, + "expires_in" => 600, "scope" => "read write follow push", - "token_type" => "Bearer" + "me" => "https://gensokyo.2hu/users/raymoo" } } end diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index a87dddddf..a143675ec 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -28,6 +28,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do alias Pleroma.Web.MastodonAPI.MastodonAPIController alias Pleroma.Web.MastodonAPI.StatusView alias Pleroma.Web.OAuth.Token + alias Pleroma.Web.OAuth.OAuthView alias Pleroma.Web.TwitterAPI.TwitterAPI plug(Pleroma.Web.ApiSpec.CastAndValidate) @@ -101,12 +102,7 @@ def create(%{assigns: %{app: app}, body_params: params} = conn, _params) do :ok <- TwitterAPI.validate_captcha(app, params), {:ok, user} <- TwitterAPI.register_user(params, need_confirmation: true), {:ok, token} <- Token.create_token(app, user, %{scopes: app.scopes}) do - json(conn, %{ - token_type: "Bearer", - access_token: token.token, - scope: app.scopes |> Enum.join(" "), - created_at: Token.Utils.format_created_at(token) - }) + json(conn, OAuthView.render("token.json", %{user: user, token: token})) else {:error, error} -> json_response(conn, :bad_request, %{error: error}) end From f308196b7528fab92b3cfba12ea71c464e2f9ab0 Mon Sep 17 00:00:00 2001 From: lain Date: Mon, 29 Jun 2020 13:52:50 +0200 Subject: [PATCH 4/5] Token Response: Remove empty file. --- lib/pleroma/web/oauth/token/response.ex | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 lib/pleroma/web/oauth/token/response.ex diff --git a/lib/pleroma/web/oauth/token/response.ex b/lib/pleroma/web/oauth/token/response.ex deleted file mode 100644 index a12a6865c..000000000 --- a/lib/pleroma/web/oauth/token/response.ex +++ /dev/null @@ -1,6 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2020 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.OAuth.Token.Response do -end From 59540131c189afb10faf98d1bfeccf8f94985a90 Mon Sep 17 00:00:00 2001 From: lain Date: Mon, 29 Jun 2020 14:09:03 +0200 Subject: [PATCH 5/5] Credo fixes. --- .../web/mastodon_api/controllers/account_controller.ex | 2 +- lib/pleroma/web/oauth/oauth_controller.ex | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index a143675ec..2942ed336 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -27,8 +27,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do alias Pleroma.Web.MastodonAPI.MastodonAPI alias Pleroma.Web.MastodonAPI.MastodonAPIController alias Pleroma.Web.MastodonAPI.StatusView - alias Pleroma.Web.OAuth.Token alias Pleroma.Web.OAuth.OAuthView + alias Pleroma.Web.OAuth.Token alias Pleroma.Web.TwitterAPI.TwitterAPI plug(Pleroma.Web.ApiSpec.CastAndValidate) diff --git a/lib/pleroma/web/oauth/oauth_controller.ex b/lib/pleroma/web/oauth/oauth_controller.ex index 3da104933..7683589cf 100644 --- a/lib/pleroma/web/oauth/oauth_controller.ex +++ b/lib/pleroma/web/oauth/oauth_controller.ex @@ -6,8 +6,8 @@ defmodule Pleroma.Web.OAuth.OAuthController do use Pleroma.Web, :controller alias Pleroma.Helpers.UriHelper - alias Pleroma.MFA alias Pleroma.Maps + alias Pleroma.MFA alias Pleroma.Plugs.RateLimiter alias Pleroma.Registration alias Pleroma.Repo @@ -17,8 +17,8 @@ defmodule Pleroma.Web.OAuth.OAuthController do alias Pleroma.Web.OAuth.App alias Pleroma.Web.OAuth.Authorization alias Pleroma.Web.OAuth.MFAController - alias Pleroma.Web.OAuth.OAuthView alias Pleroma.Web.OAuth.MFAView + alias Pleroma.Web.OAuth.OAuthView alias Pleroma.Web.OAuth.Scopes alias Pleroma.Web.OAuth.Token alias Pleroma.Web.OAuth.Token.Strategy.RefreshToken