X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fweb%2Fo_auth%2Fo_auth_controller.ex;h=8f32e7219965f719a4984fa12a26a36fa6c66f82;hb=07a48b9293e4046c50b5d424d60a1bf16c7cc198;hp=215d97b3ab22ae1a07f36551437092f17dd8a227;hpb=c4439c630f46153c9f118d7f7e752d880206d262;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 215d97b3a..8f32e7219 100644 --- a/lib/pleroma/web/o_auth/o_auth_controller.ex +++ b/lib/pleroma/web/o_auth/o_auth_controller.ex @@ -12,8 +12,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do 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 +23,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 +32,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 +47,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) @@ -62,18 +59,39 @@ defmodule Pleroma.Web.OAuth.OAuthController do # after user already authorized to MastodonFE. # So we have to check client and token. def authorize( - %Plug.Conn{assigns: %{token: %Token{} = token}} = conn, + %Plug.Conn{assigns: %{token: %Token{} = token, user: %User{} = user}} = conn, %{"client_id" => client_id} = params ) do with %Token{} = t <- Repo.get_by(Token, token: token.token) |> Repo.preload(:app), ^client_id <- t.app.client_id do handle_existing_authorization(conn, params) + else + _ -> + maybe_reuse_token(conn, params, user.id) + end + end + + def authorize(%Plug.Conn{} = conn, params) do + # if we have a user in the session, attempt to authenticate as them + # otherwise show the login form + maybe_reuse_token(conn, params, AuthHelper.get_session_user(conn)) + end + + defp maybe_reuse_token(conn, params, user_id) when is_binary(user_id) do + with %User{} = user <- User.get_cached_by_id(user_id), + %App{} = app <- Repo.get_by(App, client_id: params["client_id"]), + {:ok, %Token{} = token} <- Token.get_preeexisting_by_app_and_user(app, user), + {:ok, %Authorization{} = auth} <- + Authorization.get_preeexisting_by_app_and_user(app, user) do + conn + |> assign(:token, token) + |> after_create_authorization(auth, %{"authorization" => params}) else _ -> do_authorize(conn, params) end end - def authorize(%Plug.Conn{} = conn, params), do: do_authorize(conn, params) + defp maybe_reuse_token(conn, params, _user), do: do_authorize(conn, params) defp do_authorize(%Plug.Conn{} = conn, params) do app = Repo.get_by(App, client_id: params["client_id"]) @@ -104,7 +122,8 @@ defmodule Pleroma.Web.OAuth.OAuthController do scopes: scopes, redirect_uri: params["redirect_uri"], state: params["state"], - params: params + params: params, + view_module: OAuthView }) end @@ -150,7 +169,9 @@ defmodule Pleroma.Web.OAuth.OAuthController do def create_authorization(%Plug.Conn{} = conn, %{"authorization" => _} = params, opts) do with {:ok, auth, user} <- do_create_authorization(conn, params, opts[:user]), {:mfa_required, _, _, false} <- {:mfa_required, user, auth, MFA.require?(user)} do - after_create_authorization(conn, auth, params) + conn + |> AuthHelper.put_session_user(user.id) + |> after_create_authorization(auth, params) else error -> handle_create_authorization_error(conn, error, params) @@ -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, %{ @@ -271,7 +292,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do fixed_token = Token.Utils.fix_padding(params["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 + {:ok, token} <- Token.get_or_exchange_token(auth, app, user) do after_token_exchange(conn, %{user: user, token: token}) else error -> @@ -323,6 +344,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do def after_token_exchange(%Plug.Conn{} = conn, %{token: token} = view_params) do conn |> AuthHelper.put_session_token(token.token) + |> AuthHelper.put_session_user(token.user_id) |> json(OAuthView.render("token.json", view_params)) end @@ -427,7 +449,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 @@ -536,10 +558,9 @@ defmodule Pleroma.Web.OAuth.OAuthController do else {:error, changeset} -> message = - Enum.map(changeset.errors, fn {field, {error, _}} -> + Enum.map_join(changeset.errors, "; ", fn {field, {error, _}} -> "#{field} #{error}" end) - |> Enum.join("; ") message = String.replace( @@ -601,7 +622,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