plug_indie/lib/parser.ex

105 lines
2.7 KiB
Elixir
Raw Normal View History

defmodule PlugMicropub.Parser do
import Plug.Conn
def get_action(conn) do
{action, body_params} = Map.pop(conn.body_params, "action")
conn = %Plug.Conn{conn | body_params: body_params}
case action do
nil ->
{:ok, :create, conn}
action when action in ["delete", "undelete", "update"] ->
{:ok, String.to_existing_atom(action), conn}
_ ->
{:error, :invalid_request, "Invalid action supplied."}
end
end
def get_query(conn) do
case Map.fetch(conn.query_params, "q") do
{:ok, query} when query in ["config", "source", "syndicate-to"] ->
{:ok, String.to_existing_atom(query)}
_ ->
{:error, :invalid_request, "Invalid query supplied."}
end
end
def get_file(conn) do
case Map.fetch(conn.body_params, "file") do
{:ok, file} -> {:ok, file}
:error -> {:error, :invalid_request, "Invalid file supplied."}
end
end
def get_access_token(conn) do
{access_token, body_params} = Map.pop(conn.body_params, "access_token")
conn = %Plug.Conn{conn | body_params: body_params}
case access_token do
nil -> parse_auth_header(conn)
access_token -> {:ok, access_token, conn}
end
end
defp parse_auth_header(conn) do
with [header] <- get_req_header(conn, "authorization"),
"Bearer" <> token <- header,
do: {:ok, String.trim(token), conn},
else: (_ -> {:error, :unauthorized, "Authentication from header failed."})
end
def parse_create_body("application/json", params) do
with {:ok, ["h-" <> type]} <- Map.fetch(params, "type"),
{:ok, properties} when is_map(properties) <- Map.fetch(params, "properties") do
{:ok, type, Map.new(properties)}
else
_ ->
{:error, :invalid_request}
end
end
def parse_create_body(_, params) do
with {type, params} when is_binary(type) <- Map.pop(params, "h") do
properties =
params
|> Enum.map(fn {k, v} -> {k, List.wrap(v)} end)
|> Map.new()
{:ok, type, properties}
else
_ -> {:error, :invalid_request}
end
end
def parse_update_properties(properties) do
properties = Map.take(properties, ["replace", "add", "delete"])
valid? =
Enum.all?(properties, fn
{"delete", prop} when is_list(prop) ->
Enum.all?(prop, &is_binary/1)
{_k, prop} when is_map(prop) ->
Enum.all?(prop, fn
{_k, v} when is_list(v) -> true
_ -> false
end)
_ ->
false
end)
if valid? do
replace = Map.get(properties, "replace", %{})
add = Map.get(properties, "add", %{})
delete = Map.get(properties, "delete", %{})
{:ok, replace, add, delete}
else
:error
end
end
end