Current section
Files
Jump to
Current section
Files
lib/securex_web/controllers/resource_controller.ex
defmodule SecureXWeb.ResourceController do
@moduledoc false
use SecureXWeb, :controller
alias SecureX.Context
@doc """
Get list of Resources,
## Examples
iex> list_resources()
[
%Resource{
id: "person_farm",
name: "Persons Farm"
},
%Resource{
id: "users",
name: "Users"
},
...
]
"""
@spec list_resources(number(), number()) :: tuple() | struct()
def list_resources(page \\ nil, page_size \\ 10),
do: Context.list_resources(page, page_size)
@doc """
Get a Resource,
## Examples
iex> get(%{"res" => "person_farm"})
%Resource{
id: "person_farm",
name: "Persons Farm"
}
"""
@spec get(map()) :: tuple()
def get(params) when params !== %{} do
case params do
%{res: res_id} -> get_resource(res_id)
%{"res" => res_id} -> get_resource(res_id)
_ -> error(:bad_input)
end
end
def get(_), do: error(:bad_input)
defp get_resource(params) do
case Context.get_resource(params) do
nil -> {:error, :no_role_found}
res -> {:ok, res}
end
end
@doc """
Create a resource,
##example
iex> create(%{"res" => "Person Farm"})
%Resource{
id: "person_farm",
name: "Persons Farm"
}
"""
@spec create(map()) :: tuple()
def create(params) when params !== %{} do
case params do
%{res: res} -> create_res_checks(res)
%{"res" => res} -> create_res_checks(res)
_ -> error(:bad_input)
end
end
def create(_), do: error(:bad_input)
defp create_res_checks(res) do
with nil <- Context.get_resource_by(res),
{:ok, res} <- create_res(res) do
{:ok, res}
else
%{__struct__: _} -> {:error, :alrady_exist}
{:error, error} -> {:error, error}
end
end
defp create_res(res) do
name = res |> String.trim()
res_id =
name
|> String.downcase()
|> String.replace(" ", "_")
Context.create_resource(%{id: res_id, name: camelize(name)})
end
@doc """
Update a resource,
##example
iex> update(%{"res" => "person_farm", name: "Person Organization"})
%Resource{
id: "person_organization",
name: "Person Organization"
}
"""
@spec update(map()) :: tuple()
def update(params) when params !== %{} do
case params do
%{id: res_id} ->
update_res_checks(res_id, params)
%{"id" => res_id} ->
params = keys_to_atoms(params)
update_res_checks(res_id, params)
_ ->
{:error, :bad_input}
end
end
def update(_), do: {:error, :bad_input}
defp update_res_checks(res_id, params) do
with %{__struct__: _} = prev_res <- Context.get_resource(res_id),
{:ok, new_res} <- update_res(prev_res, params) do
{:ok, new_res}
else
nil -> {:error, :alrady_exist}
{:error, error} -> {:error, error}
end
end
defp update_res(prev_res, %{res: new_res}) do
name = new_res |> String.trim()
updated_res =
name
|> String.downcase()
|> String.replace(" ", "_")
if prev_res.id !== updated_res do
{:ok, new_res} = Context.create_resource(%{id: updated_res, name: camelize(name)})
case Context.get_permissions_by_res_id(prev_res.id) do
[] ->
:nothing
permissions ->
Enum.each(permissions, fn per ->
Context.update_permission(per, %{resource_id: updated_res})
end)
end
Context.delete_resource(prev_res)
{:ok, Map.merge(new_res, %{permissions: :successfully_updated_permissions})}
else
{:ok, prev_res}
end
end
@doc """
Delete a Resource,
## Examples
iex> delete(%{"res" => "person_organization")
%Resource{
id: "person_organization",
name: "Person Organization",
permissions: :successfully_removed_permissions
}
"""
@spec delete(map()) :: tuple()
def delete(params) when params !== %{} do
case params do
%{res: res_id} -> delete_res_checks(res_id)
%{"res" => res_id} -> delete_res_checks(res_id)
_ -> {:error, :bad_input}
end
end
def delete(_), do: {:error, :bad_input}
defp delete_res_checks(res_id) do
with %{__struct__: _} = res <- Context.get_resource(res_id),
{:ok, permission} <- delete_permissions(res),
{:ok, res} <- delete_res(res) do
{:ok, Map.merge(res, %{permissions: permission})}
else
nil -> {:error, :doesnt_exist}
{:error, error} -> {:error, error}
end
end
defp delete_permissions(%{id: res_id}) do
case Context.get_permissions_by_res_id(res_id) do
[] ->
{:ok, :already_removed}
permissions ->
Enum.each(permissions, fn per -> Context.delete_permission(per) end)
{:ok, :successfully_removed_permissions}
end
end
defp delete_permissions(_), do: {:ok, :invalid_resource_id}
defp delete_res(res) do
case Context.delete_resource(res) do
{:error, error} -> {:error, error}
{:ok, res} -> {:ok, res}
end
end
end