Rajska v0.7.0 Rajska.ObjectScopeAuthorization View Source
Absinthe Phase to perform object scoping.
Authorizes all Absinthe's objects requested in a query by checking the value of the field defined in each object meta scope
.
Usage
Create your Authorization module and add it and ObjectScopeAuthorization to your Absinthe Pipeline. Then set the scope of an object:
object :user do
meta :scope_by, :id
meta :rule, :default
field :id, :integer
field :email, :string
field :name, :string
field :company, :company
end
object :company do
meta :scope_by, :user_id
meta :rule, :default
field :id, :integer
field :user_id, :integer
field :name, :string
field :wallet, :wallet
end
object :wallet do
meta :scope_by, :id
meta :rule, :read_only
field :id, :integer
field :total, :integer
end
To define custom rules for the scoping, use Rajska.Authorization.has_user_access?/4
. For example:
defmodule Authorization do
use Rajska,
valid_roles: [:user, :admin]
@impl true
def has_user_access?(%{role: :admin}, _struct, {_field, _field_value}, _rule), do: true
def has_user_access?(%{id: user_id}, User, {:id, id}, _rule) when user_id === id, do: true
def has_user_access?(_current_user, User, {_field, _field_value}, _rule), do: false
end
Keep in mind that the field_value
provided to has_user_access?/4
can be nil
. This case can be handled as you wish.
For example, to not raise any authorization errors and just return nil
:
defmodule Authorization do
use Rajska,
valid_roles: [:user, :admin]
@impl true
def has_user_access?(_user, _scope, {_field, nil}, _rule), do: true
def has_user_access?(%{role: :admin}, User, {_field, _field_value}, _rule), do: true
def has_user_access?(%{id: user_id}, User, {:id, id}, _rule) when user_id === id, do: true
def has_user_access?(_current_user, User, {_field, _field_value}, _rule), do: false
end
The rule
keyword is not mandatory and will be pattern matched in has_user_access?/4
:
defmodule Authorization do
use Rajska,
valid_roles: [:user, :admin]
@impl true
def has_user_access?(%{id: user_id}, Wallet, {_field, _field_value}, :read_only), do: true
def has_user_access?(%{id: user_id}, Wallet, {_field, _field_value}, :default), do: false
end
This way different rules can be set to the same struct.
See Rajska.Authorization
for rule
default settings.
Link to this section Summary
Link to this section Functions
flag_invalid(node)
View Source
flag_invalid(Absinthe.Blueprint.node_t()) :: Absinthe.Blueprint.node_t()
flag_invalid(Absinthe.Blueprint.node_t()) :: Absinthe.Blueprint.node_t()
flag_invalid(node, flag)
View Source
flag_invalid(Absinthe.Blueprint.node_t(), atom()) :: Absinthe.Blueprint.node_t()
flag_invalid(Absinthe.Blueprint.node_t(), atom()) :: Absinthe.Blueprint.node_t()
inherit_invalid(node, children, add_flag) View Source
put_flag(node, flag) View Source
run(bp, options \\ [])
View Source
run(Absinthe.Blueprint.t() | Absinthe.Phase.Error.t(), Keyword.t()) ::
{:ok, map()}
run(Absinthe.Blueprint.t() | Absinthe.Phase.Error.t(), Keyword.t()) :: {:ok, map()}
Callback implementation for Absinthe.Phase.run/2
.