balls/lib/balls_pds/plug/object_authorization_plug.ex

51 lines
1.5 KiB
Elixir

defmodule BallsPDS.Plug.ObjectAuthorizationPlug do
require Logger
import Plug.Conn
import BallsPDS.Plug.ObjectPlug, only: [is_acl_get?: 1]
alias BallsPDS.Ecto.Schema.Object
def init(opts), do: opts
def call(%Plug.Conn{:method => "GET"} = conn, _opts) do
with {:acl, false} <- {:acl, is_acl_get?(conn)},
{:object, object = %Object{}} <- {:object, conn.assigns[:object]},
{:subject, subject} <- {:subject, conn.assigns[:subject]},
{:authorized, true} <- {:authorized, Object.is_authorized_read?(object, subject)} do
conn
else
{:acl, true} ->
conn
{:object, nil} ->
send_resp(conn, 404, "Not found") |> halt()
{:authorized, false} ->
conn
|> put_resp_header("www-authenticate", "Bearer")
|> send_resp(401, "Get out")
|> halt()
end
end
def call(%Plug.Conn{:method => "POST"} = conn, _opts) do
with {:object, %Object{}} <- {:object, conn.assigns[:object]},
{:subject, subject} when not is_nil(subject) <- {:subject, conn.assigns[:subject]},
{:authorized, true} <-
{:authorized, subject === Application.get_env(:balls_pds, :owner_ap_id)} do
conn
else
{:object, nil} ->
Logger.error("Missing object in connection.")
conn |> send_resp(500, "Error") |> halt()
{:subject, nil} ->
Logger.error("Missing subject in connection.")
conn |> send_resp(401, "Get out") |> halt()
end
end
def call(conn, _opts) do
conn |> send_resp(405, "Get out") |> halt()
end
end