fix oauth consumer mode

the previous code passed a state parameter to ueberauth with info
about where to go after the user logged in, etc.
since ueberauth 0.7, this parameter is ignored and oauth state is used
for actual CSRF reasons.

we now set a cookie with the state we need to keep track of, and read
it once the callback happens.
This commit is contained in:
Aria 2023-12-17 19:27:36 +00:00
parent e2f749b5b0
commit eb0dbf6b79

View file

@ -443,13 +443,10 @@ def prepare_request(%Plug.Conn{} = conn, %{
|> Map.put("scope", scope) |> Map.put("scope", scope)
|> Jason.encode!() |> Jason.encode!()
params =
auth_attrs
|> Map.drop(~w(scope scopes client_id redirect_uri))
|> Map.put("state", state)
# Handing the request to Ueberauth # Handing the request to Ueberauth
redirect(conn, to: ~p"/oauth/#{provider}?#{params}") conn
|> put_resp_cookie("akkoma_oauth_state", state)
|> redirect(to: ~p"/oauth/#{provider}")
end end
def request(%Plug.Conn{} = conn, params) do def request(%Plug.Conn{} = conn, params) do
@ -468,7 +465,7 @@ def request(%Plug.Conn{} = conn, params) do
end end
def callback(%Plug.Conn{assigns: %{ueberauth_failure: failure}} = conn, params) do 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 messages = for e <- Map.get(failure, :errors, []), do: e.message
message = Enum.join(messages, "; ") message = Enum.join(messages, "; ")
@ -481,7 +478,7 @@ def callback(%Plug.Conn{assigns: %{ueberauth_failure: failure}} = conn, params)
end end
def callback(%Plug.Conn{} = conn, params) do def callback(%Plug.Conn{} = conn, params) do
params = callback_params(params) params = callback_params(conn, params)
with {:ok, registration} <- Authenticator.get_registration(conn) do with {:ok, registration} <- Authenticator.get_registration(conn) do
auth_attrs = Map.take(params, ~w(client_id redirect_uri scope scopes state)) auth_attrs = Map.take(params, ~w(client_id redirect_uri scope scopes state))
@ -511,8 +508,9 @@ def callback(%Plug.Conn{} = conn, params) do
end end
end end
defp callback_params(%{"state" => state} = params) do defp callback_params(%Plug.Conn{} = conn, params) do
Map.merge(params, Jason.decode!(state)) fetch_cookies(conn)
Map.merge(params, Jason.decode!(Map.get(conn.req_cookies, "akkoma_oauth_state", "{}")))
end end
def registration_details(%Plug.Conn{} = conn, %{"authorization" => auth_attrs}) do def registration_details(%Plug.Conn{} = conn, %{"authorization" => auth_attrs}) do