Update the API Authentication.
continuous-integration/drone/push Build is passing

This commit is contained in:
2024-08-24 16:18:11 +03:00
parent 32ea2c4ff8
commit 8697be9f17
12 changed files with 196 additions and 1 deletions
@@ -0,0 +1,11 @@
defmodule LinkShortenerWeb.Auth.ErrorHandler do
import Plug.Conn
def auth_error(conn, {type, _reason}, _opts) do
body = Poison.encode!(%{error: to_string(type)})
conn
|> put_resp_content_type("application/json")
|> send_resp(401, body)
end
end
+31
View File
@@ -0,0 +1,31 @@
defmodule LinkShortenerWeb.Auth.Guardian do
use Guardian, otp_app: :link_shortener
alias LinkShortener.Accounts
alias LinkShortener.Accounts.User
def subject_for_token(user, _claims) do
{:ok, to_string(user.id)}
end
def resource_from_claims(%{"sub" => id}) do
user = Accounts.get_user!(id)
{:ok, user}
rescue
Ecto.NoResultsError -> {:error, :resource_not_found}
end
def authenticate(email, password) do
with user <- Accounts.get_user_by_email_and_password(email, password) do
case user do
%User{} -> create_token(user)
nil -> {:error, :unauthorized}
end
end
end
defp create_token(user) do
{:ok, token, _claims} = encode_and_sign(user)
{:ok, user, token}
end
end
+9
View File
@@ -0,0 +1,9 @@
defmodule LinkShortenerWeb.Auth.Pipeline do
use Guardian.Plug.Pipeline, otp_app: :link_shortener,
module: LinkShortenerWeb.Auth.Guardian,
error_handler: LinkShortenerWeb.Auth.ErrorHandler
plug Guardian.Plug.VerifyHeader
plug Guardian.Plug.EnsureAuthenticated
plug Guardian.Plug.LoadResource
end
@@ -0,0 +1,26 @@
defmodule LinkShortenerWeb.Api.V1.AccountsController do
use LinkShortenerWeb, :controller
alias LinkShortener.Accounts
alias LinkShortener.Accounts.User
alias LinkShortenerWeb.Auth.Guardian
action_fallback LinkShortenerWeb.FallbackController
def sign_up(conn, %{"user" => user_params}) do
with {:ok, %User{} = user} <- Accounts.register_user(user_params),
{:ok, token, _claims} <- Guardian.encode_and_sign(user) do
conn
|> put_status(:created)
|> render(:user, %{user: user, token: token})
end
end
def sign_in(conn, %{"email" => email, "password" => password}) do
with {:ok, user, token} <- Guardian.authenticate(email, password) do
conn
|> put_status(:created)
|> render(:user, %{user: user, token: token})
end
end
end
@@ -0,0 +1,11 @@
defmodule LinkShortenerWeb.Api.V1.AccountsJSON do
alias LinkShortener.Links.Link
def user(%{user: user, token: token}) do
%{
id: user.id,
email: user.email,
token: token
}
end
end
@@ -21,4 +21,11 @@ defmodule LinkShortenerWeb.FallbackController do
|> put_view(html: LinkShortenerWeb.ErrorHTML, json: LinkShortenerWeb.ErrorJSON)
|> render(:"404")
end
def call(conn, {:error, :unauthorized}) do
conn
|> put_status(:unauthorized)
|> put_view(html: LinkShortenerWeb.ErrorHTML, json: LinkShortenerWeb.ErrorJSON)
|> render(:"401")
end
end
+3
View File
@@ -28,6 +28,9 @@ defmodule LinkShortenerWeb.Router do
pipe_through :api
scope "/v1", Api.V1, as: :v1 do
post "/users/sign_up", AccountsController, :sign_up
post "/users/sign_in", AccountsController, :sign_in
resources "/links", LinkController
end
end