X-Git-Url: https://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fweb%2Fo_auth%2Fo_auth_controller.ex;h=6a8006d31d44e3be878cb8b4c1a2ac1cf0433940;hb=aa681d7e15f6170e7e92d86146d5ba96be6433bc;hp=6e3c7e1a1c75c71372cc85e25e2ba7a5f9c1679f;hpb=1438fd958325c3d469315c478f06def9e4dd0de3;p=akkoma diff --git a/lib/pleroma/web/o_auth/o_auth_controller.ex b/lib/pleroma/web/o_auth/o_auth_controller.ex index 6e3c7e1a1..6a8006d31 100644 --- a/lib/pleroma/web/o_auth/o_auth_controller.ex +++ b/lib/pleroma/web/o_auth/o_auth_controller.ex @@ -1,19 +1,17 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2020 Pleroma Authors +# Copyright © 2017-2021 Pleroma Authors # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.OAuth.OAuthController do use Pleroma.Web, :controller - alias Pleroma.Helpers.AuthHelper alias Pleroma.Helpers.UriHelper alias Pleroma.Maps alias Pleroma.MFA alias Pleroma.Registration alias Pleroma.Repo alias Pleroma.User - alias Pleroma.Web.Auth.Authenticator - alias Pleroma.Web.ControllerHelper + alias Pleroma.Web.Auth.WrapperAuthenticator, as: Authenticator alias Pleroma.Web.OAuth.App alias Pleroma.Web.OAuth.Authorization alias Pleroma.Web.OAuth.MFAController @@ -24,6 +22,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do alias Pleroma.Web.OAuth.Token.Strategy.RefreshToken alias Pleroma.Web.OAuth.Token.Strategy.Revoke, as: RevokeToken alias Pleroma.Web.Plugs.RateLimiter + alias Pleroma.Web.Utils.Params require Logger @@ -32,10 +31,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do plug(:fetch_session) plug(:fetch_flash) - plug(:skip_plug, [ - Pleroma.Web.Plugs.OAuthScopesPlug, - Pleroma.Web.Plugs.EnsurePublicOrAuthenticatedPlug - ]) + plug(:skip_auth) plug(RateLimiter, [name: :authentication] when action == :create_authorization) @@ -50,7 +46,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do end def authorize(%Plug.Conn{assigns: %{token: %Token{}}} = conn, %{"force_login" => _} = params) do - if ControllerHelper.truthy_param?(params["force_login"]) do + if Params.truthy_param?(params["force_login"]) do do_authorize(conn, params) else handle_existing_authorization(conn, params) @@ -75,37 +71,62 @@ defmodule Pleroma.Web.OAuth.OAuthController do def authorize(%Plug.Conn{} = conn, params), do: do_authorize(conn, params) + defp maybe_remove_token(%Plug.Conn{assigns: %{token: %{app: id}}} = conn, %App{id: id}) do + conn + end + + defp maybe_remove_token(conn, _app) do + conn + |> assign(:token, nil) + end + defp do_authorize(%Plug.Conn{} = conn, params) do app = Repo.get_by(App, client_id: params["client_id"]) + conn = maybe_remove_token(conn, app) available_scopes = (app && app.scopes) || [] scopes = Scopes.fetch_scopes(params, available_scopes) - user = - with %{assigns: %{user: %User{} = user}} <- conn do - user - else - _ -> nil - end + # if we already have a token for this specific setup, we can use that + with false <- Params.truthy_param?(params["force_login"]), + %App{} <- app, + %{assigns: %{user: %Pleroma.User{} = user}} <- conn, + {:ok, %Token{} = token} <- Token.get_preexisting_by_app_and_user(app, user), + true <- scopes == token.scopes do + token = Repo.preload(token, :app) - scopes = - if scopes == [] do - available_scopes - else - scopes - end - - # Note: `params` might differ from `conn.params`; use `@params` not `@conn.params` in template - render(conn, Authenticator.auth_template(), %{ - user: user, - app: app && Map.delete(app, :client_secret), - response_type: params["response_type"], - client_id: params["client_id"], - available_scopes: available_scopes, - scopes: scopes, - redirect_uri: params["redirect_uri"], - state: params["state"], - params: params - }) + conn + |> assign(:token, token) + |> handle_existing_authorization(params) + else + _ -> + user = + with %{assigns: %{user: %User{} = user}} <- conn do + user + else + _ -> nil + end + + scopes = + if scopes == [] do + available_scopes + else + scopes + end + + # Note: `params` might differ from `conn.params`; use `@params` not `@conn.params` in template + render(conn, Authenticator.auth_template(), %{ + user: user, + app: app && Map.delete(app, :client_secret), + response_type: params["response_type"], + client_id: params["client_id"], + available_scopes: available_scopes, + scopes: scopes, + redirect_uri: params["redirect_uri"], + state: params["state"], + params: params, + view_module: OAuthView + }) + end end defp handle_existing_authorization( @@ -163,7 +184,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do # Enforcing the view to reuse the template when calling from other controllers conn |> put_view(OAuthView) - |> render("oob_authorization_created.html", %{auth: auth}) + |> render("oob_authorization_created.html", %{auth: auth, view_module: OAuthView}) end def after_create_authorization(%Plug.Conn{} = conn, %Authorization{} = auth, %{ @@ -320,9 +341,8 @@ defmodule Pleroma.Web.OAuth.OAuthController do # Bad request def token_exchange(%Plug.Conn{} = conn, params), do: bad_request(conn, params) - def after_token_exchange(%Plug.Conn{} = conn, %{token: token} = view_params) do + def after_token_exchange(%Plug.Conn{} = conn, %{token: _token} = view_params) do conn - |> AuthHelper.put_session_token(token.token) |> json(OAuthView.render("token.json", view_params)) end @@ -381,15 +401,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do def token_revoke(%Plug.Conn{} = conn, %{"token" => token}) do with {:ok, %Token{} = oauth_token} <- Token.get_by_token(token), - {:ok, oauth_token} <- RevokeToken.revoke(oauth_token) do - conn = - with session_token = AuthHelper.get_session_token(conn), - %Token{token: ^session_token} <- oauth_token do - AuthHelper.delete_session_token(conn) - else - _ -> conn - end - + {:ok, _oauth_token} <- RevokeToken.revoke(oauth_token) do json(conn, %{}) else _error -> @@ -427,7 +439,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do |> Map.put("state", state) # Handing the request to Ueberauth - redirect(conn, to: o_auth_path(conn, :request, provider, params)) + redirect(conn, to: Routes.o_auth_path(conn, :request, provider, params)) end def request(%Plug.Conn{} = conn, params) do @@ -601,7 +613,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do end # Special case: Local MastodonFE - defp redirect_uri(%Plug.Conn{} = conn, "."), do: auth_url(conn, :login) + defp redirect_uri(%Plug.Conn{} = conn, "."), do: Routes.auth_url(conn, :login) defp redirect_uri(%Plug.Conn{}, redirect_uri), do: redirect_uri