Skip to content
Steve Pallen edited this page Nov 19, 2016 · 2 revisions

Authorization can be added to an project using ex_admin by implementing the ExAdmin.Authorization protocol. Here is an example of the lib/my_project/authorization.ex file you can place in your project's lib directory. This example authorizes based on the admin boolean field in the User model.

alias MyProject.Authentication, as: Auth
alias MyProject.Authorization, as: Authz

defimpl ExAdmin.Authorization, for: MyProject.User do
  def authorize_query(resource, conn, query, _action, _id),
    do: Authz.authorize_user_query(resource, conn, query)
  def authorize_action(_resource, conn, action),
    do: Authz.authorize_actions(action, Auth.current_user(conn),
          except: [:create, :new, :destroy, :delete])
end

defimpl ExAdmin.Authorization, for: MyProject.License do
  def authorize_query(_resource, _conn, query, _action, _id), do: query
  def authorize_action(_resource, conn, action),
    do: Authz.authorize_actions(action, Auth.current_user(conn),
          except: [:destroy, :delete])
end
defimpl ExAdmin.Authorization, for: MyProject.Option do
  def authorize_query(_resource, _conn, query, _action, _id), do: query
  def authorize_action(_resource, conn, action),
    do: Authz.authorize_actions(action, Auth.current_user(conn),
          only: [:index, :show])
end
defimpl ExAdmin.Authorization, for: MyProject.Product do
  def authorize_query(_resource, _conn, query, _action, _id), do: query
  def authorize_action(_resource, conn, action),
    do: Authz.authorize_actions(action, Auth.current_user(conn),
          only: [:index, :show])
end
defimpl ExAdmin.Authorization, for: MyProject.Version do
  def authorize_query(_resource, _conn, query, _action, _id), do: query
  def authorize_action(_resource, conn, action),
    do: Authz.authorize_actions(action, Auth.current_user(conn),
          only: [:index, :show])
end
defimpl ExAdmin.Authorization, for: MyProject.Account do
  def authorize_query(_resource, _conn, query, _action, _id), do: query
  def authorize_action(_resource, conn, action),
    do: Authz.authorize_actions(action, Auth.current_user(conn),
          except: [:delete, :destroy])
end

defmodule MyProject.Authorization do
  import Ecto.Query

  def authorize_user_query(%{admin: true}, _conn, query), do: query
  def authorize_user_query(user, _conn, query) do
    id = user.id
    where(query, [u], u.id == ^id)
  end

  def authorize_actions(_, %{admin: true}, _), do: true
  def authorize_actions(action, _, actions) when is_atom(action) do
    only = actions[:only]
    except = actions[:except]
    cond do
      is_list(only) -> action in only
      is_list(except) -> not action in except
      true -> false
    end
  end
end