Add a basic user info endpoint
This commit is contained in:
parent
8129d916e3
commit
be7d4adeec
6 changed files with 68 additions and 0 deletions
|
@ -261,6 +261,11 @@ defmodule Comfycamp.Accounts do
|
||||||
Repo.one(query)
|
Repo.one(query)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def get_user_by_bearer_token(token) do
|
||||||
|
{:ok, query} = UserToken.verify_bearer_token_query(token)
|
||||||
|
Repo.one(query)
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Deletes the signed token with the given context.
|
Deletes the signed token with the given context.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -80,6 +80,19 @@ defmodule Comfycamp.Accounts.UserToken do
|
||||||
{:ok, query}
|
{:ok, query}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Checks if the token is valid and returns its underlying lookup query.
|
||||||
|
"""
|
||||||
|
def verify_bearer_token_query(token) do
|
||||||
|
query =
|
||||||
|
from token in by_token_and_context_query(token, "bearer"),
|
||||||
|
join: user in assoc(token, :user),
|
||||||
|
where: token.inserted_at > ago(1, "day"),
|
||||||
|
select: user
|
||||||
|
|
||||||
|
{:ok, query}
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Builds a token and its hash to be delivered to the user's email.
|
Builds a token and its hash to be delivered to the user's email.
|
||||||
|
|
||||||
|
|
|
@ -118,6 +118,10 @@ defmodule ComfycampWeb.OauthController do
|
||||||
render(conn, :openid_discovery)
|
render(conn, :openid_discovery)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def user_info(conn, _params) do
|
||||||
|
render(conn, :user_info, user: conn.assigns.oauth_user)
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Extract client id and client secret from request parameters or headers.
|
Extract client id and client secret from request parameters or headers.
|
||||||
Returns {:ok, "client_id", "client_secret"} on success.
|
Returns {:ok, "client_id", "client_secret"} on success.
|
||||||
|
|
|
@ -22,6 +22,14 @@ defmodule ComfycampWeb.OauthJSON do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def user_info(%{user: user}) do
|
||||||
|
%{
|
||||||
|
sub: Integer.to_string(user.id),
|
||||||
|
email: user.email,
|
||||||
|
preferred_username: user.username
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
def error(assigns) do
|
def error(assigns) do
|
||||||
%{
|
%{
|
||||||
description: assigns["description"]
|
description: assigns["description"]
|
||||||
|
|
|
@ -15,6 +15,7 @@ defmodule ComfycampWeb.Router do
|
||||||
|
|
||||||
pipeline :api do
|
pipeline :api do
|
||||||
plug :accepts, ["json"]
|
plug :accepts, ["json"]
|
||||||
|
plug :fetch_bearer_token
|
||||||
end
|
end
|
||||||
|
|
||||||
scope "/", ComfycampWeb do
|
scope "/", ComfycampWeb do
|
||||||
|
@ -35,6 +36,13 @@ defmodule ComfycampWeb.Router do
|
||||||
get "/.well-known/openid-configuration", OauthController, :openid_discovery
|
get "/.well-known/openid-configuration", OauthController, :openid_discovery
|
||||||
end
|
end
|
||||||
|
|
||||||
|
scope "/", ComfycampWeb do
|
||||||
|
pipe_through [:api, :require_oauth]
|
||||||
|
|
||||||
|
get "/oauth/userinfo", OauthController, :user_info
|
||||||
|
post "/oauth/userinfo", OauthController, :user_info
|
||||||
|
end
|
||||||
|
|
||||||
# Enable LiveDashboard and Swoosh mailbox preview in development
|
# Enable LiveDashboard and Swoosh mailbox preview in development
|
||||||
if Application.compile_env(:comfycamp, :dev_routes) do
|
if Application.compile_env(:comfycamp, :dev_routes) do
|
||||||
# If you want to use the LiveDashboard in production, you should put
|
# If you want to use the LiveDashboard in production, you should put
|
||||||
|
|
|
@ -110,6 +110,36 @@ defmodule ComfycampWeb.UserAuth do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Authenticate the user by looking at Authorization header
|
||||||
|
and checking Bearer token.
|
||||||
|
"""
|
||||||
|
def fetch_bearer_token(conn, _opts) do
|
||||||
|
case Plug.Conn.get_req_header(conn, "authorization") do
|
||||||
|
["Bearer " <> header] ->
|
||||||
|
user = Accounts.get_user_by_bearer_token(header)
|
||||||
|
assign(conn, :oauth_user, user)
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
conn
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Check that request contains a valid bearer token.
|
||||||
|
Call after fetch_bearer_token plug.
|
||||||
|
"""
|
||||||
|
def require_oauth(conn, _opts) do
|
||||||
|
if conn.assigns[:oauth_user] do
|
||||||
|
conn
|
||||||
|
else
|
||||||
|
conn
|
||||||
|
|> put_status(:unauthorized)
|
||||||
|
|> json(%{error: "You must use a bearer token to access this page."})
|
||||||
|
|> halt()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Handles mounting and authenticating the current_user in LiveViews.
|
Handles mounting and authenticating the current_user in LiveViews.
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue