diff options
author | Alex Gleason <alex@alexgleason.me> | 2020-07-19 19:37:54 -0500 |
---|---|---|
committer | Alex Gleason <alex@alexgleason.me> | 2020-07-19 19:37:54 -0500 |
commit | d11c0ede3a2f8ffbca23e7382296cd9125f1365d (patch) | |
tree | 6123951765bcdecaf5ed5597e98551619aea03f9 | |
parent | 9f48dfb70515b1548f0b30e6c7dbe1776b0d9435 (diff) | |
download | pleroma-d11c0ede3a2f8ffbca23e7382296cd9125f1365d.tar.gz |
Let the OAuth form remember you, fixes #1909
-rw-r--r-- | lib/pleroma/web/oauth/oauth_controller.ex | 21 | ||||
-rw-r--r-- | lib/pleroma/web/router.ex | 2 | ||||
-rw-r--r-- | lib/pleroma/web/templates/o_auth/o_auth/show.html.eex | 60 | ||||
-rw-r--r-- | priv/static/instance/static.css | 17 | ||||
-rw-r--r-- | test/web/oauth/oauth_controller_test.exs | 37 |
5 files changed, 110 insertions, 27 deletions
diff --git a/lib/pleroma/web/oauth/oauth_controller.ex b/lib/pleroma/web/oauth/oauth_controller.ex index 7683589cf..5c93f96f1 100644 --- a/lib/pleroma/web/oauth/oauth_controller.ex +++ b/lib/pleroma/web/oauth/oauth_controller.ex @@ -76,8 +76,17 @@ defmodule Pleroma.Web.OAuth.OAuthController do available_scopes = (app && app.scopes) || [] scopes = Scopes.fetch_scopes(params, available_scopes) + user = + with %{assigns: %{user: %User{} = user}} <- conn do + user + else + _ -> nil + end + # Note: `params` might differ from `conn.params`; use `@params` not `@conn.params` in template render(conn, Authenticator.auth_template(), %{ + app: app && Map.delete(app, :client_secret), + user: user, response_type: params["response_type"], client_id: params["client_id"], available_scopes: available_scopes, @@ -121,11 +130,13 @@ defmodule Pleroma.Web.OAuth.OAuthController do end end - def create_authorization( - %Plug.Conn{} = conn, - %{"authorization" => _} = params, - opts \\ [] - ) do + def create_authorization(_, _, opts \\ []) + + def create_authorization(%Plug.Conn{assigns: %{user: %User{} = user}} = conn, params, []) do + create_authorization(conn, params, user: user) + end + + 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) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 05841a8c4..bb74affa3 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -278,9 +278,9 @@ defmodule Pleroma.Web.Router do scope [] do pipe_through([:oauth, :after_auth]) get("/authorize", OAuthController, :authorize) + post("/authorize", OAuthController, :create_authorization) end - post("/authorize", OAuthController, :create_authorization) post("/token", OAuthController, :token_exchange) post("/revoke", OAuthController, :token_revoke) get("/registration_details", OAuthController, :registration_details) diff --git a/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex index b17142ff8..d7efbf184 100644 --- a/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex +++ b/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex @@ -5,32 +5,51 @@ <p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p> <% end %> -<h2>OAuth Authorization</h2> <%= form_for @conn, o_auth_path(@conn, :authorize), [as: "authorization"], fn f -> %> -<%= if @params["registration"] in ["true", true] do %> - <h3>This is the first time you visit! Please enter your Pleroma handle.</h3> - <p>Choose carefully! You won't be able to change this later. You will be able to change your display name, though.</p> - <div class="input"> - <%= label f, :nickname, "Pleroma Handle" %> - <%= text_input f, :nickname, placeholder: "lain" %> +<%= if @user do %> + <div class="account-header"> + <div class="avatar"> + <img src="<%= Pleroma.User.avatar_url(@user) %>"> + </div> + <div class="name"> + Signed in as: + <div class="username">@<%= @user.nickname %></div> + </div> </div> - <%= hidden_input f, :name, value: @params["name"] %> - <%= hidden_input f, :password, value: @params["password"] %> - <br> -<% else %> - <div class="input"> - <%= label f, :name, "Username" %> - <%= text_input f, :name %> - </div> - <div class="input"> - <%= label f, :password, "Password" %> - <%= password_input f, :password %> - </div> - <%= submit "Log In" %> +<% end %> + +<%= if @app do %> + <p>Application <strong><%= @app.client_name %></strong> is requesting access to your account.</p> <%= render @view_module, "_scopes.html", Map.merge(assigns, %{form: f}) %> <% end %> +<%= if @user do %> + <%= submit "Authorize" %> +<% else %> + <%= if @params["registration"] in ["true", true] do %> + <h3>This is the first time you visit! Please enter your Pleroma handle.</h3> + <p>Choose carefully! You won't be able to change this later. You will be able to change your display name, though.</p> + <div class="input"> + <%= label f, :nickname, "Pleroma Handle" %> + <%= text_input f, :nickname, placeholder: "lain" %> + </div> + <%= hidden_input f, :name, value: @params["name"] %> + <%= hidden_input f, :password, value: @params["password"] %> + <br> + <% else %> + <div class="input"> + <%= label f, :name, "Username" %> + <%= text_input f, :name %> + </div> + <div class="input"> + <%= label f, :password, "Password" %> + <%= password_input f, :password %> + </div> + <%= submit "Log In" %> + <% end %> +<% end %> + <%= hidden_input f, :client_id, value: @client_id %> <%= hidden_input f, :response_type, value: @response_type %> <%= hidden_input f, :redirect_uri, value: @redirect_uri %> @@ -40,4 +59,3 @@ <%= if Pleroma.Config.oauth_consumer_enabled?() do %> <%= render @view_module, Pleroma.Web.Auth.Authenticator.oauth_consumer_template(), assigns %> <% end %> - diff --git a/priv/static/instance/static.css b/priv/static/instance/static.css index 8e2e071ef..decd3edb8 100644 --- a/priv/static/instance/static.css +++ b/priv/static/instance/static.css @@ -175,6 +175,23 @@ button:hover { font-size: 16px; } +.account-header { + display: flex; + margin: 20px 0; + text-align: left; +} + +.account-header .avatar { + display: flex; + max-width: 60px; + margin-right: 10px; +} + +.account-header .avatar img { + width: 100%; + border-radius: 4px; +} + @media all and (max-width: 440px) { .container { margin-top: 0 diff --git a/test/web/oauth/oauth_controller_test.exs b/test/web/oauth/oauth_controller_test.exs index d389e4ce0..9e6eb9805 100644 --- a/test/web/oauth/oauth_controller_test.exs +++ b/test/web/oauth/oauth_controller_test.exs @@ -606,6 +606,43 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do end end + test "authorize from cookie" do + app_scopes = ["read", "write"] + app = insert(:oauth_app) + redirect_uri = OAuthController.default_redirect_uri(app) + user = insert(:user) + + conn = + build_conn() + |> Plug.Session.call(Plug.Session.init(@session_opts)) + |> fetch_session() + |> put_session(:user_id, user.id) + |> post( + "/oauth/authorize", + %{ + "authorization" => %{ + "name" => user.nickname, + "client_id" => app.client_id, + "redirect_uri" => redirect_uri, + "scope" => app_scopes, + "state" => "statepassed" + } + } + ) + + assert Enum.count(Repo.all(Pleroma.Web.OAuth.Authorization)) == 1 + + target = redirected_to(conn) + assert target =~ redirect_uri + + query = URI.parse(target).query |> URI.query_decoder() |> Map.new() + + assert %{"state" => "statepassed", "code" => code} = query + auth = Repo.get_by(Authorization, token: code) + assert auth + assert auth.scopes == app_scopes + end + test "redirect to on two-factor auth page" do otp_secret = TOTP.generate_secret() |