mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 21:43:02 +12:00
e680867be9
fix: use latest spark, and new persisters callback fix: properly validate belongs_to relationships
2287 lines
44 KiB
Text
2287 lines
44 KiB
Text
<!--
|
|
This file was generated by Spark. Do not edit it by hand.
|
|
-->
|
|
# DSL: Ash.Policy.Authorizer
|
|
|
|
An authorization extension for ash resources.
|
|
|
|
To add this extension to a resource, add it to the list of `authorizers` like so:
|
|
|
|
```elixir
|
|
use Ash.Resource,
|
|
...,
|
|
authorizers: [
|
|
Ash.Policy.Authorizer
|
|
]
|
|
```
|
|
|
|
A resource can be given a set of policies, which are enforced on each call to a resource action.
|
|
|
|
For reads, policies can be configured to filter out data that the actor shouldn't see, as opposed to
|
|
resulting in a forbidden error.
|
|
|
|
See the [policies guide](/documentation/topics/policies.md) for practical examples.
|
|
|
|
Policies are solved/managed via a boolean satisfiability solver. To read more about boolean satisfiability,
|
|
see this page: https://en.wikipedia.org/wiki/Boolean_satisfiability_problem. At the end of
|
|
the day, however, it is not necessary to understand exactly how Ash takes your
|
|
authorization requirements and determines if a request is allowed. The
|
|
important thing to understand is that Ash may or may not run any/all of your
|
|
authorization rules as they may be deemed unnecessary. As such, authorization
|
|
checks should have no side effects. Ideally, the checks built-in to ash should
|
|
cover the bulk of your needs.
|
|
|
|
|
|
## policies
|
|
A section for declaring authorization policies.
|
|
|
|
Each policy that applies must pass independently in order for the
|
|
request to be authorized.
|
|
|
|
See the [policies guide](/documentation/topics/policies.md) for more.
|
|
|
|
|
|
### Nested DSLs
|
|
* [policy](#policies-policy)
|
|
* authorize_if
|
|
* forbid_if
|
|
* authorize_unless
|
|
* forbid_unless
|
|
* [bypass](#policies-bypass)
|
|
* authorize_if
|
|
* forbid_if
|
|
* authorize_unless
|
|
* forbid_unless
|
|
|
|
|
|
### Examples
|
|
```
|
|
policies do
|
|
# Anything you can use in a condition, you can use in a check, and vice-versa
|
|
# This policy applies if the actor is a super_user
|
|
# Additionally, this policy is declared as a `bypass`. That means that this check is allowed to fail without
|
|
# failing the whole request, and that if this check *passes*, the entire request passes.
|
|
bypass actor_attribute_equals(:super_user, true) do
|
|
authorize_if always()
|
|
end
|
|
|
|
# This will likely be a common occurrence. Specifically, policies that apply to all read actions
|
|
policy action_type(:read) do
|
|
# unless the actor is an active user, forbid their request
|
|
forbid_unless actor_attribute_equals(:active, true)
|
|
# if the record is marked as public, authorize the request
|
|
authorize_if attribute(:public, true)
|
|
# if the actor is related to the data via that data's `owner` relationship, authorize the request
|
|
authorize_if relates_to_actor_via(:owner)
|
|
end
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Options
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="policies-default_access_type" href="#policies-default_access_type">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
default_access_type
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">:strict | :filter | :runtime</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">:filter</code>
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
The default access type of policies for this resource.
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
|
|
## policies.policy
|
|
```elixir
|
|
policy condition
|
|
```
|
|
|
|
|
|
A policy has a name, a condition, and a list of checks.
|
|
|
|
Checks apply logically in the order they are specified, from top to bottom.
|
|
If no check explicitly authorizes the request, then the request is forbidden.
|
|
This means that, if you want to "blacklist" instead of "whitelist", you likely
|
|
want to add an `authorize_if always()` at the bottom of your policy, like so:
|
|
|
|
```elixir
|
|
policy action_type(:read) do
|
|
forbid_if not_logged_in()
|
|
forbid_if user_is_denylisted()
|
|
forbid_if user_is_in_denylisted_group()
|
|
|
|
authorize_if always()
|
|
end
|
|
```
|
|
|
|
If the policy should always run, use the `always()` check, like so:
|
|
|
|
```elixir
|
|
policy always() do
|
|
...
|
|
end
|
|
```
|
|
|
|
See the [policies guide](/documentation/topics/policies.md) for more.
|
|
|
|
|
|
### Nested DSLs
|
|
* [authorize_if](#policies-policy-authorize_if)
|
|
* [forbid_if](#policies-policy-forbid_if)
|
|
* [authorize_unless](#policies-policy-authorize_unless)
|
|
* [forbid_unless](#policies-policy-forbid_unless)
|
|
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="policies-policy-condition" href="#policies-policy-condition">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
condition
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">`any`</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A check or list of checks that must be true in order for this policy to apply.
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
### Options
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="policies-policy-description" href="#policies-policy-description">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
description
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">String.t</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A description for the policy, used when explaining authorization results
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="policies-policy-access_type" href="#policies-policy-access_type">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
access_type
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">:strict | :filter | :runtime</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
What portion of the checks inside the policy are allowed to run. See the guide for more.
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
## policies.policy.authorize_if
|
|
```elixir
|
|
authorize_if check
|
|
```
|
|
|
|
|
|
If the check is true, the request is authorized, otherwise run remaining checks.
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
authorize_if logged_in()
|
|
```
|
|
|
|
```
|
|
authorize_if actor_attribute_matches_record(:group, :group)
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="policies-policy-authorize_if-check" href="#policies-policy-authorize_if-check">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
check
|
|
</span>
|
|
</a>
|
|
<sup style="color: red">*</sup>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">`any`</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
The check to run. See `Ash.Policy.Check` for more.
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
### Options
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="policies-policy-authorize_if-name" href="#policies-policy-authorize_if-name">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
name
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">String.t</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A short name or description for the check, used when explaining authorization results
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Policy.Check`
|
|
|
|
## policies.policy.forbid_if
|
|
```elixir
|
|
forbid_if check
|
|
```
|
|
|
|
|
|
If the check is true, the request is forbidden, otherwise run remaining checks.
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
forbid_if not_logged_in()
|
|
```
|
|
|
|
```
|
|
forbid_if actor_attribute_matches_record(:group, :blacklisted_groups)
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="policies-policy-forbid_if-check" href="#policies-policy-forbid_if-check">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
check
|
|
</span>
|
|
</a>
|
|
<sup style="color: red">*</sup>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">`any`</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
The check to run. See `Ash.Policy.Check` for more.
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
### Options
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="policies-policy-forbid_if-name" href="#policies-policy-forbid_if-name">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
name
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">String.t</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A short name or description for the check, used when explaining authorization results
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Policy.Check`
|
|
|
|
## policies.policy.authorize_unless
|
|
```elixir
|
|
authorize_unless check
|
|
```
|
|
|
|
|
|
If the check is false, the request is authorized, otherwise run remaining checks.
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
authorize_unless not_logged_in()
|
|
```
|
|
|
|
```
|
|
authorize_unless actor_attribute_matches_record(:group, :blacklisted_groups)
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="policies-policy-authorize_unless-check" href="#policies-policy-authorize_unless-check">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
check
|
|
</span>
|
|
</a>
|
|
<sup style="color: red">*</sup>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">`any`</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
The check to run. See `Ash.Policy.Check` for more.
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
### Options
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="policies-policy-authorize_unless-name" href="#policies-policy-authorize_unless-name">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
name
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">String.t</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A short name or description for the check, used when explaining authorization results
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Policy.Check`
|
|
|
|
## policies.policy.forbid_unless
|
|
```elixir
|
|
forbid_unless check
|
|
```
|
|
|
|
|
|
If the check is true, the request is forbidden, otherwise run remaining checks.
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
forbid_unless logged_in()
|
|
```
|
|
|
|
```
|
|
forbid_unless actor_attribute_matches_record(:group, :group)
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="policies-policy-forbid_unless-check" href="#policies-policy-forbid_unless-check">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
check
|
|
</span>
|
|
</a>
|
|
<sup style="color: red">*</sup>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">`any`</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
The check to run. See `Ash.Policy.Check` for more.
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
### Options
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="policies-policy-forbid_unless-name" href="#policies-policy-forbid_unless-name">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
name
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">String.t</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A short name or description for the check, used when explaining authorization results
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Policy.Check`
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Policy.Policy`
|
|
|
|
## policies.bypass
|
|
```elixir
|
|
bypass condition
|
|
```
|
|
|
|
|
|
A policy that, if passed, will skip all following policies. If failed, authorization moves on to the next policy
|
|
|
|
### Nested DSLs
|
|
* [authorize_if](#policies-bypass-authorize_if)
|
|
* [forbid_if](#policies-bypass-forbid_if)
|
|
* [authorize_unless](#policies-bypass-authorize_unless)
|
|
* [forbid_unless](#policies-bypass-forbid_unless)
|
|
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="policies-bypass-condition" href="#policies-bypass-condition">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
condition
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">`any`</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A check or list of checks that must be true in order for this policy to apply.
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
### Options
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="policies-bypass-description" href="#policies-bypass-description">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
description
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">String.t</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A description for the policy, used when explaining authorization results
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="policies-bypass-access_type" href="#policies-bypass-access_type">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
access_type
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">:strict | :filter | :runtime</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
What portion of the checks inside the policy are allowed to run. See the guide for more.
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
## policies.bypass.authorize_if
|
|
```elixir
|
|
authorize_if check
|
|
```
|
|
|
|
|
|
If the check is true, the request is authorized, otherwise run remaining checks.
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
authorize_if logged_in()
|
|
```
|
|
|
|
```
|
|
authorize_if actor_attribute_matches_record(:group, :group)
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="policies-bypass-authorize_if-check" href="#policies-bypass-authorize_if-check">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
check
|
|
</span>
|
|
</a>
|
|
<sup style="color: red">*</sup>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">`any`</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
The check to run. See `Ash.Policy.Check` for more.
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
### Options
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="policies-bypass-authorize_if-name" href="#policies-bypass-authorize_if-name">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
name
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">String.t</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A short name or description for the check, used when explaining authorization results
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Policy.Check`
|
|
|
|
## policies.bypass.forbid_if
|
|
```elixir
|
|
forbid_if check
|
|
```
|
|
|
|
|
|
If the check is true, the request is forbidden, otherwise run remaining checks.
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
forbid_if not_logged_in()
|
|
```
|
|
|
|
```
|
|
forbid_if actor_attribute_matches_record(:group, :blacklisted_groups)
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="policies-bypass-forbid_if-check" href="#policies-bypass-forbid_if-check">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
check
|
|
</span>
|
|
</a>
|
|
<sup style="color: red">*</sup>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">`any`</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
The check to run. See `Ash.Policy.Check` for more.
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
### Options
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="policies-bypass-forbid_if-name" href="#policies-bypass-forbid_if-name">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
name
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">String.t</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A short name or description for the check, used when explaining authorization results
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Policy.Check`
|
|
|
|
## policies.bypass.authorize_unless
|
|
```elixir
|
|
authorize_unless check
|
|
```
|
|
|
|
|
|
If the check is false, the request is authorized, otherwise run remaining checks.
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
authorize_unless not_logged_in()
|
|
```
|
|
|
|
```
|
|
authorize_unless actor_attribute_matches_record(:group, :blacklisted_groups)
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="policies-bypass-authorize_unless-check" href="#policies-bypass-authorize_unless-check">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
check
|
|
</span>
|
|
</a>
|
|
<sup style="color: red">*</sup>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">`any`</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
The check to run. See `Ash.Policy.Check` for more.
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
### Options
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="policies-bypass-authorize_unless-name" href="#policies-bypass-authorize_unless-name">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
name
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">String.t</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A short name or description for the check, used when explaining authorization results
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Policy.Check`
|
|
|
|
## policies.bypass.forbid_unless
|
|
```elixir
|
|
forbid_unless check
|
|
```
|
|
|
|
|
|
If the check is true, the request is forbidden, otherwise run remaining checks.
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
forbid_unless logged_in()
|
|
```
|
|
|
|
```
|
|
forbid_unless actor_attribute_matches_record(:group, :group)
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="policies-bypass-forbid_unless-check" href="#policies-bypass-forbid_unless-check">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
check
|
|
</span>
|
|
</a>
|
|
<sup style="color: red">*</sup>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">`any`</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
The check to run. See `Ash.Policy.Check` for more.
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
### Options
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="policies-bypass-forbid_unless-name" href="#policies-bypass-forbid_unless-name">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
name
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">String.t</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A short name or description for the check, used when explaining authorization results
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Policy.Check`
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Policy.Policy`
|
|
|
|
|
|
|
|
|
|
## field_policies
|
|
Authorize access to specific fields via policies scoped to fields.
|
|
|
|
If *any* field policies exist then *all* fields must be authorized by a field policy.
|
|
If you want a "deny-list" style, then you can add policies for specific fields
|
|
and add a catch-all policy using the special field name `:*`. All policies that apply
|
|
to a field must be authorized.
|
|
|
|
The only exception to the above behavior is primary keys, which can always be read by everyone.
|
|
|
|
Additionally, keep in mind that adding `Ash.Policy.Authorizer` will require that all actions
|
|
pass policies. If you want to just add field policies, you will need to add a policy that allows
|
|
all access explicitly, i.e
|
|
|
|
```elixir
|
|
policies do
|
|
policy always() do
|
|
authorize_if always()
|
|
end
|
|
end
|
|
```
|
|
|
|
Using expressions: unlike in regular policies, expressions in field policies cannot refer
|
|
to related entities currently. Instead, you will need to create aggregates or expression calculations
|
|
that return the results you want to reference.
|
|
|
|
In results, forbidden fields will be replaced with a special value: `%Ash.ForbiddenField{}`.
|
|
|
|
When these fields are referred to in filters, they will be replaced with an expression that evaluates
|
|
to `nil`. To support this behavior, only expression/filter checks are allowed in field policies.
|
|
|
|
|
|
### Nested DSLs
|
|
* [field_policy_bypass](#field_policies-field_policy_bypass)
|
|
* authorize_if
|
|
* forbid_if
|
|
* authorize_unless
|
|
* forbid_unless
|
|
* [field_policy](#field_policies-field_policy)
|
|
* authorize_if
|
|
* forbid_if
|
|
* authorize_unless
|
|
* forbid_unless
|
|
|
|
|
|
### Examples
|
|
```
|
|
field_policies do
|
|
field_policy :admin_only_field do
|
|
authorize_if actor_attribute_equals(:admin, true)
|
|
end
|
|
end
|
|
|
|
```
|
|
|
|
```
|
|
# Example of denylist style
|
|
field_policies do
|
|
field_policy [:sensitive, :fields] do
|
|
authorize_if actor_attribute_equals(:admin, true)
|
|
end
|
|
|
|
field_policy :* do
|
|
authorize_if always()
|
|
end
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## field_policies.field_policy_bypass
|
|
```elixir
|
|
field_policy_bypass fields, condition \ {Ash.Policy.Check.Static, [result: true]}
|
|
```
|
|
|
|
|
|
A field policy that, if passed, will skip all following field policies for that field or fields. If failed, field authorization moves on to the next policy
|
|
|
|
### Nested DSLs
|
|
* [authorize_if](#field_policies-field_policy_bypass-authorize_if)
|
|
* [forbid_if](#field_policies-field_policy_bypass-forbid_if)
|
|
* [authorize_unless](#field_policies-field_policy_bypass-authorize_unless)
|
|
* [forbid_unless](#field_policies-field_policy_bypass-forbid_unless)
|
|
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="field_policies-field_policy_bypass-fields" href="#field_policies-field_policy_bypass-fields">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
fields
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">atom | list(atom)</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
The field or fields that the policy applies to.
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="field_policies-field_policy_bypass-condition" href="#field_policies-field_policy_bypass-condition">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
condition
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">`any`</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A check or list of checks that must be true in order for this field policy to apply. If not specified, it always applies.
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
### Options
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="field_policies-field_policy_bypass-description" href="#field_policies-field_policy_bypass-description">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
description
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">String.t</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A description for the policy, used when explaining authorization results
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
## field_policies.field_policy_bypass.authorize_if
|
|
```elixir
|
|
authorize_if check
|
|
```
|
|
|
|
|
|
If the check is true, the request is authorized, otherwise run remaining checks.
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
authorize_if logged_in()
|
|
```
|
|
|
|
```
|
|
authorize_if actor_attribute_matches_record(:group, :group)
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="field_policies-field_policy_bypass-authorize_if-check" href="#field_policies-field_policy_bypass-authorize_if-check">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
check
|
|
</span>
|
|
</a>
|
|
<sup style="color: red">*</sup>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">`any`</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
The check to run. See `Ash.Policy.Check` for more.
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
### Options
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="field_policies-field_policy_bypass-authorize_if-name" href="#field_policies-field_policy_bypass-authorize_if-name">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
name
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">String.t</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A short name or description for the check, used when explaining authorization results
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Policy.Check`
|
|
|
|
## field_policies.field_policy_bypass.forbid_if
|
|
```elixir
|
|
forbid_if check
|
|
```
|
|
|
|
|
|
If the check is true, the request is forbidden, otherwise run remaining checks.
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
forbid_if not_logged_in()
|
|
```
|
|
|
|
```
|
|
forbid_if actor_attribute_matches_record(:group, :blacklisted_groups)
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="field_policies-field_policy_bypass-forbid_if-check" href="#field_policies-field_policy_bypass-forbid_if-check">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
check
|
|
</span>
|
|
</a>
|
|
<sup style="color: red">*</sup>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">`any`</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
The check to run. See `Ash.Policy.Check` for more.
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
### Options
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="field_policies-field_policy_bypass-forbid_if-name" href="#field_policies-field_policy_bypass-forbid_if-name">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
name
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">String.t</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A short name or description for the check, used when explaining authorization results
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Policy.Check`
|
|
|
|
## field_policies.field_policy_bypass.authorize_unless
|
|
```elixir
|
|
authorize_unless check
|
|
```
|
|
|
|
|
|
If the check is false, the request is authorized, otherwise run remaining checks.
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
authorize_unless not_logged_in()
|
|
```
|
|
|
|
```
|
|
authorize_unless actor_attribute_matches_record(:group, :blacklisted_groups)
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="field_policies-field_policy_bypass-authorize_unless-check" href="#field_policies-field_policy_bypass-authorize_unless-check">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
check
|
|
</span>
|
|
</a>
|
|
<sup style="color: red">*</sup>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">`any`</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
The check to run. See `Ash.Policy.Check` for more.
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
### Options
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="field_policies-field_policy_bypass-authorize_unless-name" href="#field_policies-field_policy_bypass-authorize_unless-name">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
name
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">String.t</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A short name or description for the check, used when explaining authorization results
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Policy.Check`
|
|
|
|
## field_policies.field_policy_bypass.forbid_unless
|
|
```elixir
|
|
forbid_unless check
|
|
```
|
|
|
|
|
|
If the check is true, the request is forbidden, otherwise run remaining checks.
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
forbid_unless logged_in()
|
|
```
|
|
|
|
```
|
|
forbid_unless actor_attribute_matches_record(:group, :group)
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="field_policies-field_policy_bypass-forbid_unless-check" href="#field_policies-field_policy_bypass-forbid_unless-check">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
check
|
|
</span>
|
|
</a>
|
|
<sup style="color: red">*</sup>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">`any`</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
The check to run. See `Ash.Policy.Check` for more.
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
### Options
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="field_policies-field_policy_bypass-forbid_unless-name" href="#field_policies-field_policy_bypass-forbid_unless-name">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
name
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">String.t</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A short name or description for the check, used when explaining authorization results
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Policy.Check`
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Policy.FieldPolicy`
|
|
|
|
## field_policies.field_policy
|
|
```elixir
|
|
field_policy fields, condition \ {Ash.Policy.Check.Static, [result: true]}
|
|
```
|
|
|
|
|
|
Field policies behave similarly to policies. See `d:Ash.Policy.Authorizer.field_policies`
|
|
for more.
|
|
|
|
|
|
### Nested DSLs
|
|
* [authorize_if](#field_policies-field_policy-authorize_if)
|
|
* [forbid_if](#field_policies-field_policy-forbid_if)
|
|
* [authorize_unless](#field_policies-field_policy-authorize_unless)
|
|
* [forbid_unless](#field_policies-field_policy-forbid_unless)
|
|
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="field_policies-field_policy-fields" href="#field_policies-field_policy-fields">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
fields
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">atom | list(atom)</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
The field or fields that the policy applies to.
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="field_policies-field_policy-condition" href="#field_policies-field_policy-condition">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
condition
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">`any`</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A check or list of checks that must be true in order for this field policy to apply. If not specified, it always applies.
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
### Options
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="field_policies-field_policy-description" href="#field_policies-field_policy-description">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
description
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">String.t</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A description for the policy, used when explaining authorization results
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
## field_policies.field_policy.authorize_if
|
|
```elixir
|
|
authorize_if check
|
|
```
|
|
|
|
|
|
If the check is true, the request is authorized, otherwise run remaining checks.
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
authorize_if logged_in()
|
|
```
|
|
|
|
```
|
|
authorize_if actor_attribute_matches_record(:group, :group)
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="field_policies-field_policy-authorize_if-check" href="#field_policies-field_policy-authorize_if-check">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
check
|
|
</span>
|
|
</a>
|
|
<sup style="color: red">*</sup>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">`any`</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
The check to run. See `Ash.Policy.Check` for more.
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
### Options
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="field_policies-field_policy-authorize_if-name" href="#field_policies-field_policy-authorize_if-name">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
name
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">String.t</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A short name or description for the check, used when explaining authorization results
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Policy.Check`
|
|
|
|
## field_policies.field_policy.forbid_if
|
|
```elixir
|
|
forbid_if check
|
|
```
|
|
|
|
|
|
If the check is true, the request is forbidden, otherwise run remaining checks.
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
forbid_if not_logged_in()
|
|
```
|
|
|
|
```
|
|
forbid_if actor_attribute_matches_record(:group, :blacklisted_groups)
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="field_policies-field_policy-forbid_if-check" href="#field_policies-field_policy-forbid_if-check">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
check
|
|
</span>
|
|
</a>
|
|
<sup style="color: red">*</sup>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">`any`</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
The check to run. See `Ash.Policy.Check` for more.
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
### Options
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="field_policies-field_policy-forbid_if-name" href="#field_policies-field_policy-forbid_if-name">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
name
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">String.t</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A short name or description for the check, used when explaining authorization results
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Policy.Check`
|
|
|
|
## field_policies.field_policy.authorize_unless
|
|
```elixir
|
|
authorize_unless check
|
|
```
|
|
|
|
|
|
If the check is false, the request is authorized, otherwise run remaining checks.
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
authorize_unless not_logged_in()
|
|
```
|
|
|
|
```
|
|
authorize_unless actor_attribute_matches_record(:group, :blacklisted_groups)
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="field_policies-field_policy-authorize_unless-check" href="#field_policies-field_policy-authorize_unless-check">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
check
|
|
</span>
|
|
</a>
|
|
<sup style="color: red">*</sup>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">`any`</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
The check to run. See `Ash.Policy.Check` for more.
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
### Options
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="field_policies-field_policy-authorize_unless-name" href="#field_policies-field_policy-authorize_unless-name">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
name
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">String.t</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A short name or description for the check, used when explaining authorization results
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Policy.Check`
|
|
|
|
## field_policies.field_policy.forbid_unless
|
|
```elixir
|
|
forbid_unless check
|
|
```
|
|
|
|
|
|
If the check is true, the request is forbidden, otherwise run remaining checks.
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
forbid_unless logged_in()
|
|
```
|
|
|
|
```
|
|
forbid_unless actor_attribute_matches_record(:group, :group)
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="field_policies-field_policy-forbid_unless-check" href="#field_policies-field_policy-forbid_unless-check">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
check
|
|
</span>
|
|
</a>
|
|
<sup style="color: red">*</sup>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">`any`</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
The check to run. See `Ash.Policy.Check` for more.
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
### Options
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Default</th>
|
|
<th colspan=2>Docs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="text-align: left">
|
|
<a id="field_policies-field_policy-forbid_unless-name" href="#field_policies-field_policy-forbid_unless-name">
|
|
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
|
|
name
|
|
</span>
|
|
</a>
|
|
|
|
</td>
|
|
<td style="text-align: left">
|
|
<code class="inline">String.t</code>
|
|
</td>
|
|
<td style="text-align: left">
|
|
|
|
</td>
|
|
<td style="text-align: left" colspan=2>
|
|
A short name or description for the check, used when explaining authorization results
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Policy.Check`
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Policy.FieldPolicy`
|
|
|
|
|
|
|
|
|