hostas/lib/hostas_web/controllers/auth/token_controller.ex

80 lines
2.1 KiB
Elixir
Raw Normal View History

2023-06-06 16:38:52 +00:00
defmodule HostasWeb.Auth.TokenController do
2023-06-07 17:12:33 +00:00
import Ecto.Query, only: [from: 2]
2023-06-06 16:38:52 +00:00
use HostasWeb, :controller
2023-06-07 17:12:33 +00:00
alias Hostas.Repo
alias Hostas.Denizen
alias Hostas.Token
@doc """
Generates an API token. Responds with the token if the user
provides the correct password
"""
def create(conn, %{"handle" => handle, "password" => given_password}) do
case Repo.one(from d in Denizen,
where: d.handle == ^handle,
select: %{id: d.id, password: d.password}) do
nil ->
conn
|> put_status(404)
|> json(%{"error" => "No user with handle #{handle}"})
denizen ->
%{id: denizen_id, password: real_password_hash} = denizen
if Bcrypt.verify_pass(given_password, real_password_hash) do
# Create a random token
token = Base.encode64(:crypto.strong_rand_bytes(256))
# Calculate when the token should expire
{:ok, time_now} = DateTime.now("Etc/UTC")
expiry = DateTime.add(time_now, 30, :day)
|> DateTime.truncate(:second)
# Register the token
{:ok, token_struct} = Repo.insert(
%Token{denizen_id: denizen_id, token: token, expires: expiry})
conn
|> put_status(201)
|> json(Map.take(token_struct, [:token, :expires]))
else
# Reject the request, as passwords don't match
conn
|> put_status(401)
|> json(%{"error" => "Password mismatch"})
end
end
end
def create(conn, params) do
conn
|> put_status(422)
|> json(params)
# |> json(%{"error" => "Missing required parameters"})
end
@doc """
Responds with 200 OK if the requester's `Bearing` header
contains a valid, non-expired API token
"""
def verify(_conn, _params) do
:ok
end
@doc """
Deletes the token the requester used in the `Bearing` header
"""
def revoke(_conn, _params) do
:ok
end
@doc """
Deletes the token the requester used in the `Bearing` header
and responds with a new one if the old one was valid and unexpired
"""
def renew(_conn, _params) do
2023-06-06 16:38:52 +00:00
:ok
end
end