From 7fe334c0f881b27db617aedaf233f6ae58d72278 Mon Sep 17 00:00:00 2001 From: sefidel Date: Tue, 20 Feb 2024 05:48:01 +0900 Subject: project: Initial commit --- pkgs/akkoma/0003-Fix-OAuth-consumer-mode.patch | 248 +++++++++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100644 pkgs/akkoma/0003-Fix-OAuth-consumer-mode.patch (limited to 'pkgs/akkoma/0003-Fix-OAuth-consumer-mode.patch') diff --git a/pkgs/akkoma/0003-Fix-OAuth-consumer-mode.patch b/pkgs/akkoma/0003-Fix-OAuth-consumer-mode.patch new file mode 100644 index 0000000..b88cfd0 --- /dev/null +++ b/pkgs/akkoma/0003-Fix-OAuth-consumer-mode.patch @@ -0,0 +1,248 @@ +From 548364d124e729ed3ec97ef2ad063b7adace5730 Mon Sep 17 00:00:00 2001 +From: sefidel +Date: Mon, 19 Feb 2024 21:11:31 +0900 +Subject: [PATCH 3/3] Fix OAuth consumer mode + +Original commit: https://akkoma.dev/AkkomaGang/akkoma/pulls/668 +Backported to v3.10.4 + +Signed-off-by: sefidel +--- + docs/docs/configuration/cheatsheet.md | 9 ++++ + lib/pleroma/web/o_auth/o_auth_controller.ex | 37 ++++++++------- + mix.exs | 2 +- + mix.lock | 2 +- + .../web/o_auth/o_auth_controller_test.exs | 47 ++++++++++++++----- + 5 files changed, 67 insertions(+), 30 deletions(-) + +diff --git a/docs/docs/configuration/cheatsheet.md b/docs/docs/configuration/cheatsheet.md +index 73fdf9eea..2f53f0c78 100644 +--- a/docs/docs/configuration/cheatsheet.md ++++ b/docs/docs/configuration/cheatsheet.md +@@ -958,6 +958,15 @@ config :ueberauth, Ueberauth, + ] + ``` + ++You may also need to set up your frontend to use oauth logins. For example, for `akkoma-fe`: ++ ++```elixir ++config :pleroma, :frontend_configurations, ++ pleroma_fe: %{ ++ loginMethod: "token" ++ } ++``` ++ + ## Link parsing + + ### :uri_schemes +diff --git a/lib/pleroma/web/o_auth/o_auth_controller.ex b/lib/pleroma/web/o_auth/o_auth_controller.ex +index ba33dc9e7..29aa8c10e 100644 +--- a/lib/pleroma/web/o_auth/o_auth_controller.ex ++++ b/lib/pleroma/web/o_auth/o_auth_controller.ex +@@ -39,6 +39,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do + action_fallback(Pleroma.Web.OAuth.FallbackController) + + @oob_token_redirect_uri "urn:ietf:wg:oauth:2.0:oob" ++ @state_cookie_name "akkoma_oauth_state" + + # Note: this definition is only called from error-handling methods with `conn.params` as 2nd arg + def authorize(%Plug.Conn{} = conn, %{"authorization" => _} = params) do +@@ -443,13 +444,10 @@ def prepare_request(%Plug.Conn{} = conn, %{ + |> Map.put("scope", scope) + |> Jason.encode!() + +- params = +- auth_attrs +- |> Map.drop(~w(scope scopes client_id redirect_uri)) +- |> Map.put("state", state) +- + # Handing the request to Ueberauth +- redirect(conn, to: ~p"/oauth/#{provider}?#{params}") ++ conn ++ |> put_resp_cookie(@state_cookie_name, state) ++ |> redirect(to: ~p"/oauth/#{provider}") + end + + def request(%Plug.Conn{} = conn, params) do +@@ -468,20 +466,26 @@ def request(%Plug.Conn{} = conn, params) do + end + + def callback(%Plug.Conn{assigns: %{ueberauth_failure: failure}} = conn, params) do +- params = callback_params(params) ++ params = callback_params(conn, params) + messages = for e <- Map.get(failure, :errors, []), do: e.message + message = Enum.join(messages, "; ") + +- conn +- |> put_flash( +- :error, +- dgettext("errors", "Failed to authenticate: %{message}.", message: message) +- ) +- |> redirect(external: redirect_uri(conn, params["redirect_uri"])) ++ error_message = dgettext("errors", "Failed to authenticate: %{message}.", message: message) ++ ++ if params["redirect_uri"] do ++ conn ++ |> put_flash( ++ :error, ++ error_message ++ ) ++ |> redirect(external: redirect_uri(conn, params["redirect_uri"])) ++ else ++ send_resp(conn, :bad_request, error_message) ++ end + end + + def callback(%Plug.Conn{} = conn, params) do +- params = callback_params(params) ++ params = callback_params(conn, params) + + with {:ok, registration} <- Authenticator.get_registration(conn) do + auth_attrs = Map.take(params, ~w(client_id redirect_uri scope scopes state)) +@@ -511,8 +515,9 @@ def callback(%Plug.Conn{} = conn, params) do + end + end + +- defp callback_params(%{"state" => state} = params) do +- Map.merge(params, Jason.decode!(state)) ++ defp callback_params(%Plug.Conn{} = conn, params) do ++ fetch_cookies(conn) ++ Map.merge(params, Jason.decode!(Map.get(conn.req_cookies, @state_cookie_name, "{}"))) + end + + def registration_details(%Plug.Conn{} = conn, %{"authorization" => auth_attrs}) do +diff --git a/mix.exs b/mix.exs +index 01a6e8a82..563c61c30 100644 +--- a/mix.exs ++++ b/mix.exs +@@ -156,7 +156,7 @@ defp deps do + {:ex_syslogger, "~> 2.0.0"}, + {:floki, "~> 0.34"}, + {:timex, "~> 3.7"}, +- {:ueberauth, "~> 0.10"}, ++ {:ueberauth, "== 0.10.5"}, + {:linkify, git: "https://akkoma.dev/AkkomaGang/linkify.git"}, + {:http_signatures, "~> 0.1.1"}, + {:telemetry, "~> 1.2"}, +diff --git a/mix.lock b/mix.lock +index 4fe25553d..cb6a6e040 100644 +--- a/mix.lock ++++ b/mix.lock +@@ -121,7 +121,7 @@ + "timex": {:hex, :timex, "3.7.11", "bb95cb4eb1d06e27346325de506bcc6c30f9c6dea40d1ebe390b262fad1862d1", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.20", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.1", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "8b9024f7efbabaf9bd7aa04f65cf8dcd7c9818ca5737677c7b76acbc6a94d1aa"}, + "trailing_format_plug": {:hex, :trailing_format_plug, "0.0.7", "64b877f912cf7273bed03379936df39894149e35137ac9509117e59866e10e45", [:mix], [{:plug, "> 0.12.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bd4fde4c15f3e993a999e019d64347489b91b7a9096af68b2bdadd192afa693f"}, + "tzdata": {:hex, :tzdata, "1.1.1", "20c8043476dfda8504952d00adac41c6eda23912278add38edc140ae0c5bcc46", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "a69cec8352eafcd2e198dea28a34113b60fdc6cb57eb5ad65c10292a6ba89787"}, +- "ueberauth": {:hex, :ueberauth, "0.10.7", "5a31cbe11e7ce5c7484d745dc9e1f11948e89662f8510d03c616de03df581ebd", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "0bccf73e2ffd6337971340832947ba232877aa8122dba4c95be9f729c8987377"}, ++ "ueberauth": {:hex, :ueberauth, "0.10.5", "806adb703df87e55b5615cf365e809f84c20c68aa8c08ff8a416a5a6644c4b02", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "3efd1f31d490a125c7ed453b926f7c31d78b97b8a854c755f5c40064bf3ac9e1"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"}, + "unsafe": {:hex, :unsafe, "1.0.2", "23c6be12f6c1605364801f4b47007c0c159497d0446ad378b5cf05f1855c0581", [:mix], [], "hexpm", "b485231683c3ab01a9cd44cb4a79f152c6f3bb87358439c6f68791b85c2df675"}, + "vex": {:hex, :vex, "0.9.2", "fe061acc9e0907d983d46b51bf35d58176f0fe6eb7ba3b33c9336401bf42b6d1", [:mix], [], "hexpm", "76e709a9762e98c6b462dfce92e9b5dfbf712839227f2da8add6dd11549b12cb"}, +diff --git a/test/pleroma/web/o_auth/o_auth_controller_test.exs b/test/pleroma/web/o_auth/o_auth_controller_test.exs +index e0ba339db..d0703f44c 100644 +--- a/test/pleroma/web/o_auth/o_auth_controller_test.exs ++++ b/test/pleroma/web/o_auth/o_auth_controller_test.exs +@@ -81,9 +81,7 @@ test "GET /oauth/prepare_request encodes parameters as `state` and redirects", % + + assert html_response(conn, 302) + +- redirect_query = URI.parse(redirected_to(conn)).query +- assert %{"state" => state_param} = URI.decode_query(redirect_query) +- assert {:ok, state_components} = Jason.decode(state_param) ++ assert {:ok, state_components} = Jason.decode(conn.resp_cookies["akkoma_oauth_state"].value) + + expected_client_id = app.client_id + expected_redirect_uri = app.redirect_uris +@@ -97,7 +95,7 @@ test "GET /oauth/prepare_request encodes parameters as `state` and redirects", % + end + + test "with user-bound registration, GET /oauth//callback redirects to `redirect_uri` with `code`", +- %{app: app, conn: conn} do ++ %{app: app, conn: _} do + registration = insert(:registration) + redirect_uri = OAuthController.default_redirect_uri(app) + +@@ -109,15 +107,17 @@ test "with user-bound registration, GET /oauth//callback redirects to + } + + conn = +- conn ++ build_conn() ++ |> put_req_cookie("akkoma_oauth_state", Jason.encode!(state_params)) ++ |> Plug.Session.call(Plug.Session.init(@session_opts)) ++ |> fetch_session() + |> assign(:ueberauth_auth, %{provider: registration.provider, uid: registration.uid}) + |> get( + "/oauth/twitter/callback", + %{ + "oauth_token" => "G-5a3AAAAAAAwMH9AAABaektfSM", + "oauth_verifier" => "QZl8vUqNvXMTKpdmUnGejJxuHG75WWWs", +- "provider" => "twitter", +- "state" => Jason.encode!(state_params) ++ "provider" => "twitter" + } + ) + +@@ -162,17 +162,19 @@ test "with user-unbound registration, GET /oauth//callback renders reg + + test "on authentication error, GET /oauth//callback redirects to `redirect_uri`", %{ + app: app, +- conn: conn ++ conn: _ + } do + state_params = %{ + "scope" => Enum.join(app.scopes, " "), + "client_id" => app.client_id, +- "redirect_uri" => OAuthController.default_redirect_uri(app), +- "state" => "" ++ "redirect_uri" => OAuthController.default_redirect_uri(app) + } + + conn = +- conn ++ build_conn() ++ |> put_req_cookie("akkoma_oauth_state", Jason.encode!(state_params)) ++ |> Plug.Session.call(Plug.Session.init(@session_opts)) ++ |> fetch_session() + |> assign(:ueberauth_failure, %{errors: [%{message: "(error description)"}]}) + |> get( + "/oauth/twitter/callback", +@@ -180,7 +182,7 @@ test "on authentication error, GET /oauth//callback redirects to `redi + "oauth_token" => "G-5a3AAAAAAAwMH9AAABaektfSM", + "oauth_verifier" => "QZl8vUqNvXMTKpdmUnGejJxuHG75WWWs", + "provider" => "twitter", +- "state" => Jason.encode!(state_params) ++ "state" => "" + } + ) + +@@ -191,6 +193,27 @@ test "on authentication error, GET /oauth//callback redirects to `redi + "Failed to authenticate: (error description)." + end + ++ test "on authentication error with no prior state, GET /oauth//callback returns 400", ++ %{ ++ app: _, ++ conn: conn ++ } do ++ conn = ++ conn ++ |> assign(:ueberauth_failure, %{errors: [%{message: "(error description)"}]}) ++ |> get( ++ "/oauth/twitter/callback", ++ %{ ++ "oauth_token" => "G-5a3AAAAAAAwMH9AAABaektfSM", ++ "oauth_verifier" => "QZl8vUqNvXMTKpdmUnGejJxuHG75WWWs", ++ "provider" => "twitter", ++ "state" => "" ++ } ++ ) ++ ++ assert response(conn, 400) ++ end ++ + test "GET /oauth/registration_details renders registration details form", %{ + app: app, + conn: conn +-- +2.43.0 + -- cgit 1.4.1