diff options
author | Maksim <parallel588@gmail.com> | 2019-05-06 17:51:03 +0000 |
---|---|---|
committer | lambda <lain@soykaf.club> | 2019-05-06 17:51:03 +0000 |
commit | 1040caf096347b638b9fda5b23fcccde87b32ede (patch) | |
tree | db56c5118b7e853f27d5bd0d0782ab72f532d821 /lib/pleroma/web/oauth/oauth_controller.ex | |
parent | aacac9da0beddcf797958acca330747b8f2d1f06 (diff) | |
download | pleroma-1040caf096347b638b9fda5b23fcccde87b32ede.tar.gz |
fix format
Modified-by: Maksim Pechnikov <parallel588@gmail.com>
Diffstat (limited to 'lib/pleroma/web/oauth/oauth_controller.ex')
-rw-r--r-- | lib/pleroma/web/oauth/oauth_controller.ex | 159 |
1 files changed, 88 insertions, 71 deletions
diff --git a/lib/pleroma/web/oauth/oauth_controller.ex b/lib/pleroma/web/oauth/oauth_controller.ex index 688eaca11..e3c01217d 100644 --- a/lib/pleroma/web/oauth/oauth_controller.ex +++ b/lib/pleroma/web/oauth/oauth_controller.ex @@ -13,11 +13,15 @@ defmodule Pleroma.Web.OAuth.OAuthController do alias Pleroma.Web.OAuth.App alias Pleroma.Web.OAuth.Authorization alias Pleroma.Web.OAuth.Token + alias Pleroma.Web.OAuth.Token.Strategy.RefreshToken + alias Pleroma.Web.OAuth.Token.Strategy.Revoke, as: RevokeToken import Pleroma.Web.ControllerHelper, only: [oauth_scopes: 2] if Pleroma.Config.oauth_consumer_enabled?(), do: plug(Ueberauth) + @expires_in Pleroma.Config.get([:oauth2, :token_expires_in], 600) + plug(:fetch_session) plug(:fetch_flash) @@ -138,25 +142,33 @@ defmodule Pleroma.Web.OAuth.OAuthController do Authenticator.handle_error(conn, error) end + @doc "Renew access_token with refresh_token" + def token_exchange( + conn, + %{"grant_type" => "refresh_token", "refresh_token" => token} = params + ) do + with %App{} = app <- get_app_from_request(conn, params), + {:ok, %{user: user} = token} <- Token.get_by_refresh_token(app, token), + {:ok, token} <- RefreshToken.grant(token) do + response_attrs = %{created_at: Token.Utils.format_created_at(token)} + + json(conn, response_token(user, token, response_attrs)) + else + _error -> + put_status(conn, 400) + |> json(%{error: "Invalid credentials"}) + end + end + def token_exchange(conn, %{"grant_type" => "authorization_code"} = params) do with %App{} = app <- get_app_from_request(conn, params), - fixed_token = fix_padding(params["code"]), - %Authorization{} = auth <- - Repo.get_by(Authorization, token: fixed_token, app_id: app.id), + 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), - {:ok, inserted_at} <- DateTime.from_naive(token.inserted_at, "Etc/UTC") do - response = %{ - token_type: "Bearer", - access_token: token.token, - refresh_token: token.refresh_token, - created_at: DateTime.to_unix(inserted_at), - expires_in: 60 * 10, - scope: Enum.join(token.scopes, " "), - me: user.ap_id - } - - json(conn, response) + {:ok, token} <- Token.exchange_token(app, auth) do + response_attrs = %{created_at: Token.Utils.format_created_at(token)} + + json(conn, response_token(user, token, response_attrs)) else _error -> put_status(conn, 400) @@ -177,16 +189,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do true <- Enum.any?(scopes), {:ok, auth} <- Authorization.create_authorization(app, user, scopes), {:ok, token} <- Token.exchange_token(app, auth) do - response = %{ - token_type: "Bearer", - access_token: token.token, - refresh_token: token.refresh_token, - expires_in: 60 * 10, - scope: Enum.join(token.scopes, " "), - me: user.ap_id - } - - json(conn, response) + json(conn, response_token(user, token)) else {:auth_active, false} -> # Per https://github.com/tootsuite/mastodon/blob/ @@ -218,10 +221,12 @@ defmodule Pleroma.Web.OAuth.OAuthController do token_exchange(conn, params) end - def token_revoke(conn, %{"token" => token} = params) do + # Bad request + def token_exchange(conn, params), do: bad_request(conn, params) + + def token_revoke(conn, %{"token" => _token} = params) do with %App{} = app <- get_app_from_request(conn, params), - %Token{} = token <- Repo.get_by(Token, token: token, app_id: app.id), - {:ok, %Token{}} <- Repo.delete(token) do + {:ok, _token} <- RevokeToken.revoke(app, params) do json(conn, %{}) else _error -> @@ -230,6 +235,15 @@ defmodule Pleroma.Web.OAuth.OAuthController do end end + def token_revoke(conn, params), do: bad_request(conn, params) + + # Response for bad request + defp bad_request(conn, _) do + conn + |> put_status(500) + |> json(%{error: "Bad request"}) + end + @doc "Prepares OAuth request to provider for Ueberauth" def prepare_request(conn, %{"provider" => provider, "authorization" => auth_attrs}) do scope = @@ -278,25 +292,22 @@ defmodule Pleroma.Web.OAuth.OAuthController do params = callback_params(params) with {:ok, registration} <- Authenticator.get_registration(conn) do - user = Repo.preload(registration, :user).user auth_attrs = Map.take(params, ~w(client_id redirect_uri scope scopes state)) - if user do - create_authorization( - conn, - %{"authorization" => auth_attrs}, - user: user - ) - else - registration_params = - Map.merge(auth_attrs, %{ - "nickname" => Registration.nickname(registration), - "email" => Registration.email(registration) - }) + case Repo.get_assoc(registration, :user) do + {:ok, user} -> + create_authorization(conn, %{"authorization" => auth_attrs}, user: user) - conn - |> put_session(:registration_id, registration.id) - |> registration_details(%{"authorization" => registration_params}) + _ -> + registration_params = + Map.merge(auth_attrs, %{ + "nickname" => Registration.nickname(registration), + "email" => Registration.email(registration) + }) + + conn + |> put_session(:registration_id, registration.id) + |> registration_details(%{"authorization" => registration_params}) end else _ -> @@ -399,36 +410,30 @@ defmodule Pleroma.Web.OAuth.OAuthController do end end - # XXX - for whatever reason our token arrives urlencoded, but Plug.Conn should be - # decoding it. Investigate sometime. - defp fix_padding(token) do - token - |> URI.decode() - |> Base.url_decode64!(padding: false) - |> Base.url_encode64(padding: false) + defp get_app_from_request(conn, params) do + conn + |> fetch_client_credentials(params) + |> fetch_client end - defp get_app_from_request(conn, params) do - # Per RFC 6749, HTTP Basic is preferred to body params - {client_id, client_secret} = - with ["Basic " <> encoded] <- get_req_header(conn, "authorization"), - {:ok, decoded} <- Base.decode64(encoded), - [id, secret] <- - String.split(decoded, ":") - |> Enum.map(fn s -> URI.decode_www_form(s) end) do - {id, secret} - else - _ -> {params["client_id"], params["client_secret"]} - end + defp fetch_client({id, secret}) when is_binary(id) and is_binary(secret) do + Repo.get_by(App, client_id: id, client_secret: secret) + end - if client_id && client_secret do - Repo.get_by( - App, - client_id: client_id, - client_secret: client_secret - ) + defp fetch_client({_id, _secret}), do: nil + + defp fetch_client_credentials(conn, params) do + # Per RFC 6749, HTTP Basic is preferred to body params + with ["Basic " <> encoded] <- get_req_header(conn, "authorization"), + {:ok, decoded} <- Base.decode64(encoded), + [id, secret] <- + Enum.map( + String.split(decoded, ":"), + fn s -> URI.decode_www_form(s) end + ) do + {id, secret} else - nil + _ -> {params["client_id"], params["client_secret"]} end end @@ -441,4 +446,16 @@ defmodule Pleroma.Web.OAuth.OAuthController do defp put_session_registration_id(conn, registration_id), do: put_session(conn, :registration_id, registration_id) + + defp response_token(%User{} = user, token, opts \\ %{}) do + %{ + token_type: "Bearer", + access_token: token.token, + refresh_token: token.refresh_token, + expires_in: @expires_in, + scope: Enum.join(token.scopes, " "), + me: user.ap_id + } + |> Map.merge(opts) + end end |