Packages

ash

3.27.8
3.29.3 3.29.2 3.29.1 3.29.0 3.28.0 3.27.8 3.27.7 3.27.6 3.27.5 3.27.4 3.27.3 3.27.2 3.27.1 3.27.0 3.26.0 3.25.2 3.25.1 3.25.0 retired 3.24.7 3.24.6 3.24.5 3.24.4 3.24.3 3.24.2 3.24.1 3.24.0 3.23.1 3.23.0 3.22.2 3.22.1 3.22.0 3.21.3 3.21.2 3.21.1 3.21.0 3.20.0 3.19.3 3.19.2 3.19.1 3.19.0 3.18.0 3.17.1 3.17.0 3.16.0 3.15.0 3.14.1 3.14.0 retired 3.13.2 3.13.1 3.13.0 3.12.0 3.11.3 3.11.2 3.11.1 3.11.0 3.10.1 3.10.0 3.9.0 3.8.0 3.7.6 3.7.5 3.7.4 3.7.3 3.7.2 3.7.1 3.7.0 retired 3.6.3 retired 3.6.2 3.6.1 3.6.0 3.5.43 3.5.42 3.5.41 3.5.40 3.5.39 3.5.38 3.5.37 3.5.36 3.5.35 3.5.34 3.5.33 3.5.32 3.5.31 3.5.30 3.5.29 3.5.28 3.5.27 3.5.26 3.5.25 3.5.24 3.5.23 3.5.22 3.5.21 3.5.20 3.5.19 3.5.18 3.5.17 3.5.16 3.5.15 3.5.14 3.5.13 3.5.12 3.5.11 3.5.10 3.5.9 3.5.8 3.5.7 3.5.6 3.5.5 3.5.4 3.5.3 3.5.2 3.5.1 3.5.0 3.4.74 retired 3.4.73 3.4.72 3.4.71 3.4.70 3.4.69 3.4.68 3.4.67 3.4.66 3.4.65 3.4.64 3.4.63 3.4.62 3.4.61 3.4.60 3.4.59 3.4.58 3.4.57 3.4.56 3.4.55 3.4.54 3.4.53 3.4.52 3.4.51 3.4.50 3.4.49 3.4.48 3.4.47 3.4.46 3.4.45 3.4.44 3.4.43 3.4.42 3.4.41 3.4.40 3.4.39 3.4.38 3.4.37 3.4.36 3.4.35 3.4.34 3.4.33 3.4.32 3.4.31 3.4.30 3.4.29 3.4.28 3.4.27 3.4.26 3.4.25 3.4.24 3.4.23 3.4.22 3.4.21 3.4.20 3.4.19 3.4.18 3.4.17 3.4.16 3.4.15 3.4.14 3.4.13 3.4.12 3.4.11 3.4.10 3.4.9 3.4.8 3.4.7 3.4.6 3.4.5 3.4.4 3.4.3 3.4.2 3.4.1 3.4.0 3.3.3 3.3.2 3.3.1 3.3.0 3.2.6 3.2.5 3.2.4 3.2.3 3.2.2 3.2.1 3.2.0 3.1.8 3.1.7 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.16 3.0.15 3.0.14 3.0.13 3.0.12 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.4 3.0.3 3.0.2 3.0.1 3.0.0 3.0.0-rc.46 3.0.0-rc.45 3.0.0-rc.44 3.0.0-rc.43 3.0.0-rc.42 3.0.0-rc.41 3.0.0-rc.40 3.0.0-rc.39 3.0.0-rc.38 3.0.0-rc.37 3.0.0-rc.36 3.0.0-rc.35 3.0.0-rc.34 3.0.0-rc.33 3.0.0-rc.32 3.0.0-rc.31 3.0.0-rc.29 3.0.0-rc.28 3.0.0-rc.27 3.0.0-rc.26 3.0.0-rc.25 3.0.0-rc.24 3.0.0-rc.23 3.0.0-rc.22 3.0.0-rc.21 3.0.0-rc.20 3.0.0-rc.19 3.0.0-rc.18 3.0.0-rc.17 3.0.0-rc.16 3.0.0-rc.15 3.0.0-rc.14 3.0.0-rc.13 3.0.0-rc.12 3.0.0-rc.11 3.0.0-rc.10 3.0.0-rc.9 3.0.0-rc.8 3.0.0-rc.7 3.0.0-rc.6 3.0.0-rc.5 3.0.0-rc.4 3.0.0-rc.3 3.0.0-rc.1 3.0.0-rc.0 2.21.15 2.21.14 2.21.13 2.21.12 2.21.11 2.21.10 2.21.9 2.21.8 2.21.7 2.21.6 2.21.5 2.21.4 2.21.3 2.21.2 2.21.1 2.21.0 2.20.3 2.20.2 2.20.1 2.20.0 2.19.14 2.19.13 2.19.12 2.19.11 2.19.10 2.19.9 2.19.8 2.19.7 2.19.6 2.19.5 2.19.4 2.19.3 retired 2.19.2 retired 2.19.1 retired 2.19.0 retired 2.18.2 2.18.1 2.18.0 2.17.24 2.17.23 2.17.22 2.17.21 2.17.20 2.17.19 2.17.18 2.17.17 2.17.16 2.17.15 2.17.14 2.17.13 2.17.12 2.17.11 2.17.10 2.17.9 2.17.8 2.17.7 2.17.6 2.17.5 2.17.4 2.17.3 2.17.2 2.17.1 2.17.0 2.16.1 2.16.0 2.15.20 2.15.19 2.15.18 2.15.17 2.15.16 2.15.15 2.15.14 2.15.13 2.15.12 2.15.11 2.15.10 2.15.9 2.15.8 2.15.7 2.15.6 2.15.5 2.15.4 2.15.2 2.15.1 2.15.0 2.14.21 2.14.20 2.14.19 2.14.18 2.14.17 2.14.16 2.14.15 2.14.14 2.14.13 2.14.12 2.14.11 2.14.10 2.14.9 2.14.8 2.14.7 2.14.6 2.14.5 2.14.4 2.14.3 2.14.2 2.14.1 2.14.0 2.13.4 retired 2.13.3 2.13.2 2.13.1 2.13.0 2.12.1 2.12.0 2.11.11 2.11.10 2.11.9 2.11.8 2.11.7 2.11.6 2.11.5 2.11.4 2.11.3 2.11.2 2.11.1 2.11.0 2.11.0-rc.3 2.11.0-rc.2 2.11.0-rc.1 2.11.0-rc.0 2.10.2 2.10.1 2.10.0 2.9.29 2.9.28 2.9.27 2.9.26 2.9.25 2.9.24 2.9.23 2.9.22 2.9.21 2.9.20 2.9.19 2.9.18 2.9.17 2.9.16 2.9.15 2.9.14 2.9.13 2.9.12 2.9.11 2.9.10 2.9.9 2.9.8 2.9.7 2.9.6 2.9.5 2.9.4 2.9.3 2.9.2 2.9.1 2.9.0 2.8.1 2.8.0 2.7.1 2.7.0 2.6.31 2.6.30 2.6.29 2.6.28 2.6.27 2.6.26 2.6.25 2.6.24 2.6.23 2.6.22 2.6.21 2.6.20 2.6.19 2.6.18 2.6.17 2.6.16 2.6.15 2.6.14 2.6.13 2.6.11 2.6.10 2.6.9 2.6.8 2.6.7 2.6.6 2.6.5 2.6.4 2.6.3 2.6.2 2.6.1 2.6.0 2.5.16 2.5.15 2.5.14 2.5.13 2.5.12 2.5.11 2.5.10 2.5.9 2.5.8 2.5.7 2.5.6 2.5.5 2.5.4 2.5.3 2.5.2 2.5.1 2.5.0 2.5.0-rc.6 2.5.0-rc.5 2.5.0-rc.4 2.5.0-rc.3 2.5.0-rc.2 2.5.0-rc.1 2.5.0-rc.0 2.4.30 2.4.29 2.4.28 2.4.27 2.4.26 2.4.25 2.4.24 2.4.23 2.4.22 2.4.21 2.4.20 2.4.19 2.4.18 2.4.17 2.4.16 2.4.15 2.4.14 2.4.13 2.4.12 2.4.11 2.4.10 2.4.9 2.4.8 2.4.7 2.4.6 2.4.5 2.4.4 2.4.3 2.4.2 2.4.1 2.4.0 2.3.0 2.2.0 2.1.0 2.0.0 2.0.0-rc.15 2.0.0-rc.14 2.0.0-rc.13 2.0.0-rc.12 2.0.0-rc.11 2.0.0-rc.10 2.0.0-rc.9 2.0.0-rc.8 2.0.0-rc.7 2.0.0-rc.6 2.0.0-rc.5 2.0.0-rc.4 2.0.0-rc.3 2.0.0-rc.2 2.0.0-rc.1 2.0.0-rc.0 2.0.0-pre.8 2.0.0-pre.7 2.0.0-pre.6 2.0.0-pre.5 2.0.0-pre.4 2.0.0-pre.3 2.0.0-pre.2 2.0.0-pre.1 2.0.0-pre.0 1.53.3 1.53.2 1.53.0 1.52.0-rc.22 1.52.0-rc.21 1.52.0-rc.20 1.52.0-rc.19 1.52.0-rc.18 1.52.0-rc.17 1.52.0-rc.16 1.52.0-rc.15 1.52.0-rc.14 1.52.0-rc.13 1.52.0-rc.12 1.52.0-rc.11 1.52.0-rc.10 1.52.0-rc.9 1.52.0-rc.8 1.52.0-rc.7 1.52.0-rc.6 1.52.0-rc.5 1.52.0-rc.4 1.52.0-rc.3 1.52.0-rc.2 1.52.0-rc.1 1.52.0-rc.0 1.51.2 1.51.1 retired 1.51.0 1.50.21 1.50.20 1.50.19 1.50.18 1.50.17 1.50.16 1.50.15 1.50.14 1.50.13 1.50.12 1.50.11 1.50.10 1.50.9 1.50.8 1.50.7 1.50.6 1.50.5 1.50.4 1.50.3 1.50.2 1.50.1 1.50.0 1.49.0 1.48.0-rc.30 1.48.0-rc.29 1.48.0-rc.28 1.48.0-rc.27 1.48.0-rc.26 1.48.0-rc.25 1.48.0-rc.24 1.48.0-rc.23 1.48.0-rc.22 1.48.0-rc.21 1.48.0-rc.20 1.48.0-rc.19 1.48.0-rc.18 1.48.0-rc.17 1.48.0-rc.16 1.48.0-rc.15 1.48.0-rc.14 1.48.0-rc.13 1.48.0-rc.12 1.48.0-rc.11 1.48.0-rc.10 1.48.0-rc.9 1.48.0-rc.8 1.48.0-rc.7 1.48.0-rc.6 1.48.0-rc.5 1.48.0-rc.4 1.48.0-rc.3 1.48.0-rc.2 1.48.0-rc.1 1.48.0-rc.0 1.47.12 1.47.11 1.47.10 1.47.9 1.47.8 1.47.7 1.47.6 1.47.5 1.47.4 1.47.3 1.47.2 1.47.1 1.47.0 1.46.13 1.46.12 1.46.11 1.46.10 1.46.9 1.46.8 1.46.7 1.46.6 1.46.5 1.46.4 1.46.3 1.46.2 1.46.1 1.46.0 1.45.0-rc9 1.45.0-rc8 1.45.0-rc7 1.45.0-rc6 1.45.0-rc5 1.45.0-rc4 1.45.0-rc3 1.45.0-rc20 1.45.0-rc2 1.45.0-rc19 1.45.0-rc18 1.45.0-rc17 1.45.0-rc16 1.45.0-rc15 1.45.0-rc14 1.45.0-rc13 1.45.0-rc12 1.45.0-rc11 1.45.0-rc10 1.45.0-rc1 1.45.0-rc0 1.44.13 1.44.12 1.44.11 1.44.10 1.44.9 1.44.8 1.44.7 1.44.6 1.44.5 1.44.4 1.44.3 1.44.2 1.44.1 1.44.0 1.43.12 1.43.11 1.43.10 1.43.9 1.43.8 1.43.7 1.43.6 1.43.5 1.43.4 1.43.3 1.43.2 1.43.1 1.43.0 1.42.0 1.41.12 1.41.11 1.41.10 1.41.9 1.41.8 1.41.7 1.41.6 1.41.5 1.41.4 1.41.3 1.41.2 1.41.1 1.41.0 1.40.0 1.39.7 1.39.6 1.39.5 1.39.4 1.39.3 1.39.2 1.39.1 1.39.0 1.38.0 1.37.2 1.37.1 1.37.0 1.36.22 1.36.21 1.36.19 1.36.18 1.36.17 1.36.16 1.36.15 1.36.14 1.36.13 1.36.12 1.36.11 1.36.10 1.36.9 1.36.8 1.36.7 1.36.6 1.36.5 1.36.4 1.36.3 1.36.2 1.36.0 1.35.1 1.35.0 1.34.9 1.34.8 1.34.7 1.34.6 1.34.5 1.34.4 1.34.3 1.34.2 1.34.1 1.34.0 1.33.0 1.32.2 1.32.1 1.32.0 1.31.1 1.31.0 1.30.2 1.30.1 1.29.0-rc1 1.29.0-rc0 1.28.1 1.28.0 1.27.1 1.27.0 1.26.13 1.26.12 1.26.11 1.26.10 1.26.9 1.26.8 1.26.7 1.26.6 1.26.5 1.26.4 1.26.2 1.26.1 1.26.0 1.25.8 1.25.7 1.25.6 1.25.5 1.25.4 1.25.3 1.25.2 1.25.1 1.25.0 1.24.2 1.24.1 1.24.0 1.23.3 1.23.2 1.23.1 1.23.0 1.22.1 1.22.0 1.20.1 1.20.0 1.19.1 1.19.0 1.18.1 1.18.0 1.17.1 1.17.0 1.16.2 1.15.1 1.15.0 1.14.0 1.13.4 1.13.3 1.13.2 1.13.1 1.13.0 1.12.0 1.11.1 1.11.0 1.10.0 1.9.0 1.8.0 1.7.0 1.6.8 1.6.7 1.6.6 1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.1 1.5.0 1.4.1 1.4.0 1.3.1 1.3.0 1.2.1 1.2.0 1.1.3 1.1.2 1.1.0 1.0.3 1.0.2 1.0.1 1.0.0 0.13.1 0.13.0 0.12.0 0.10.0 0.9.1 0.9.0 0.8.0 0.7.0 0.6.5 0.6.4 0.6.3 0.6.2 0.6.1 0.6.0 0.5.2 0.5.1 0.5.0 0.4.0 0.3.0 0.2.0 0.1.9 0.1.8 0.1.3 0.1.1 0.1.0

A declarative, extensible framework for building Elixir applications.

Security advisory: This version has known vulnerabilities. View advisories

Current section

Files

Jump to
ash lib ash policy check.ex
Raw

lib/ash/policy/check.ex

# SPDX-FileCopyrightText: 2019 ash contributors <https://github.com/ash-project/ash/graphs/contributors>
#
# SPDX-License-Identifier: MIT
defmodule Ash.Policy.Check do
@moduledoc """
A behaviour for declaring checks, which can be used to easily construct
authorization rules.
If a check can be expressed simply, i.e as a function of the actor, or the context of the request,
see `Ash.Policy.SimpleCheck` for an easy way to write that check.
If a check can be expressed with a filter statement, see `Ash.Policy.FilterCheck`
for an easy way to write that check.
"""
@type actor :: any
@type options :: Keyword.t()
@type authorizer :: Ash.Policy.Authorizer.t()
@type check_type :: :simple | :filter | :manual
@type ref :: {module(), Keyword.t()} | module()
defstruct [:check, :check_module, :check_opts, :type, :__spark_metadata__]
@doc false
def transform(%{check: {check_module, opts}} = policy) do
case init(check_module, opts) do
{:ok, opts} ->
{:ok,
%{policy | check: {check_module, opts}, check_module: check_module, check_opts: opts}}
{:error, error} ->
{:error, error}
end
end
@type context() :: %{resource: Ash.Resource.t()}
@type t :: %__MODULE__{
check: ref(),
check_module: module(),
check_opts: options(),
type: check_type(),
__spark_metadata__: Spark.Dsl.Entity.spark_meta()
}
@doc """
Strict checks should be cheap, and should never result in external calls (like database or domain)
It should return `{:ok, true}` if it can tell that the request is authorized, and `{:ok, false}` if
it can tell that it is not. If unsure, it should return `{:ok, :unknown}`
"""
@callback strict_check(actor(), authorizer(), options()) ::
{:ok, boolean | :unknown} | {:error, term}
@doc """
An optional callback, that allows the check to work with policies set to `access_type :filter`
Return a keyword list filter that will be applied to the query being made, and will scope the results to match the rule.
Returning `:unknown` signals that this check cannot be expressed as a pre-flight filter and
must be evaluated post-action via `check/4`. The check author must also implement `check/4`
(the `Ash.Policy.FilterCheck` default does so automatically). For read actions and for
update/destroy actions inside a transaction, the existing runtime-check machinery handles
the deferral; for create actions, this triggers a post-insert authorization step inside the
action's transaction.
"""
@callback auto_filter(actor(), authorizer(), options()) ::
Keyword.t() | Ash.Expr.t() | :unknown | nil | false
@doc """
An optional callback, that allows the check to work with policies set to `access_type :runtime`
Takes a list of records, and returns the subset of authorized records.
"""
@callback check(actor(), list(Ash.Resource.Record.t()), map, options) ::
list(Ash.Resource.Record.t())
@doc "Describe the check in human readable format, given the options"
@callback describe(options()) :: String.t()
@doc "Expands the description of the check, given the actor and subject"
@callback expand_description(
actor(),
authorizer(),
options()
) :: {:ok, String.t()} | :none
@doc "Whether or not the expanded description should replace the basic description in breakdowns"
@callback prefer_expanded_description?() :: boolean()
@doc "Whether or not your check requires the original data of a changeset (if applicable)"
@callback requires_original_data?(authorizer(), options()) :: boolean()
@doc """
The type of the check
`:manual` checks must be written by hand as standard check modules
`:filter` checks can use `Ash.Policy.FilterCheck` for simplicity
`:simple` checks can use `Ash.Policy.SimpleCheck` for simplicity
"""
@callback type() :: check_type()
@callback eager_evaluate?() :: boolean()
@doc """
Simplify a check reference into a SAT expression of simpler check references.
This is used by the SAT solver to break down complex checks into simpler components
for more efficient policy evaluation. For example, a check that matches multiple
action types could be simplified into an OR expression of separate checks for each
action type. Or ActorAbsent could simplify into `not(ActorPresent)`.
"""
@callback simplify(ref(), context()) :: Crux.Expression.t(ref())
@doc """
Determine if the first check reference implies the second check reference.
This is used by the SAT solver to optimize policy evaluation by understanding
when one check being true guarantees another check is also true.
"""
@callback implies?(ref(), ref(), context()) :: boolean()
@doc """
Determine if two check references are mutually exclusive (conflicting).
This is used by the SAT solver to optimize policy evaluation by understanding
when two checks cannot both be true at the same time.
"""
@callback conflicts?(ref(), ref(), context()) :: boolean()
@doc """
Initialize and validate the opts for the check module.
This callback is called at compile time when the check is defined in a policy.
It allows checks to verify and normalize their options before they are used.
"""
@callback init(opts :: Keyword.t()) :: {:ok, Keyword.t()} | {:error, String.t()}
@optional_callbacks check: 4,
auto_filter: 3,
expand_description: 3,
simplify: 2,
implies?: 3,
conflicts?: 3
@doc false
@spec strict_check(module(), actor(), authorizer(), options()) ::
{:ok, boolean() | :unknown} | {:error, term()}
def strict_check(module, actor, authorizer, opts) do
Ash.BehaviourHelpers.call_and_validate_return(
module,
:strict_check,
[actor, authorizer, opts],
[{:ok, true}, {:ok, false}, {:ok, :unknown}, {:error, :_}],
behaviour: __MODULE__,
callback_name: "strict_check/3"
)
end
@doc false
@spec check(module(), actor(), [Ash.Resource.Record.t()], map(), options()) ::
[Ash.Resource.Record.t()]
def check(module, actor, records, context, opts) do
result = apply(module, :check, [actor, records, context, opts])
if is_list(result) do
result
else
raise Ash.Error.Framework.InvalidReturnType,
message: """
Invalid value returned from #{inspect(module)}.check/4.
The callback #{inspect(__MODULE__)}.check/4 expects a list of records.
"""
end
end
@doc false
@spec auto_filter(module(), actor(), authorizer(), options()) ::
Keyword.t() | Ash.Expr.t() | nil
def auto_filter(module, actor, authorizer, opts) do
result = apply(module, :auto_filter, [actor, authorizer, opts])
if is_list(result) or is_struct(result) or is_tuple(result) or is_nil(result) or
result == false or result == :unknown do
result
else
raise Ash.Error.Framework.InvalidReturnType,
message: """
Invalid value returned from #{inspect(module)}.auto_filter/3.
The callback #{inspect(__MODULE__)}.auto_filter/3 expects a keyword list, Ash.Expr.t(), :unknown, nil, or false.
"""
end
end
@doc false
@spec auto_filter_not(module(), actor(), authorizer(), options()) ::
Keyword.t() | Ash.Expr.t() | nil
def auto_filter_not(module, actor, authorizer, opts) do
result = apply(module, :auto_filter_not, [actor, authorizer, opts])
if is_list(result) or is_struct(result) or is_tuple(result) or is_nil(result) or
result == false or result == :unknown do
result
else
raise Ash.Error.Framework.InvalidReturnType,
message: """
Invalid value returned from #{inspect(module)}.auto_filter_not/3.
The callback #{inspect(__MODULE__)}.auto_filter_not/3 expects a keyword list, Ash.Expr.t(), :unknown, nil, or false.
"""
end
end
@doc false
@spec describe(module(), options()) :: String.t()
def describe(module, opts) do
result = apply(module, :describe, [opts])
if is_binary(result) do
result
else
raise Ash.Error.Framework.InvalidReturnType,
message: """
Invalid value returned from #{inspect(module)}.describe/1.
The callback #{inspect(__MODULE__)}.describe/1 expects a String.t().
"""
end
end
@doc false
@spec init(module(), Keyword.t()) :: {:ok, Keyword.t()} | {:error, String.t()}
def init(module, opts) do
Ash.BehaviourHelpers.call_and_validate_return(
module,
:init,
[opts],
[{:ok, :_}, {:error, :_}],
behaviour: __MODULE__,
callback_name: "init/1"
)
end
@doc false
@spec expand_description(module(), actor(), authorizer(), options()) ::
{:ok, String.t()} | :none
def expand_description(module, actor, authorizer, opts) do
if function_exported?(module, :expand_description, 3) do
Ash.BehaviourHelpers.call_and_validate_return(
module,
:expand_description,
[actor, authorizer, opts],
[{:ok, :_}, :none],
behaviour: __MODULE__,
callback_name: "expand_description/3"
)
else
:none
end
end
@doc false
@spec requires_original_data?(module(), authorizer(), options()) :: boolean()
def requires_original_data?(module, authorizer, opts) do
Ash.BehaviourHelpers.call_and_validate_return(
module,
:requires_original_data?,
[authorizer, opts],
[true, false],
behaviour: __MODULE__,
callback_name: "requires_original_data?/2"
)
end
@doc false
@spec type(module()) :: check_type()
def type(module) do
Ash.BehaviourHelpers.call_and_validate_return(
module,
:type,
[],
[:simple, :filter, :manual],
behaviour: __MODULE__,
callback_name: "type/0"
)
end
@doc false
@spec simplify(module(), ref(), context()) :: Crux.Expression.t(ref())
def simplify(module, ref, context) do
if function_exported?(module, :simplify, 2) do
result = apply(module, :simplify, [ref, context])
if result != nil do
result
else
raise Ash.Error.Framework.InvalidReturnType,
message: """
Invalid value returned from #{inspect(module)}.simplify/2.
The callback #{inspect(__MODULE__)}.simplify/2 must not return nil.
"""
end
else
ref
end
end
@doc false
@spec implies?(module(), ref(), ref(), context()) :: boolean()
def implies?(module, left, right, context) do
if function_exported?(module, :implies?, 3) do
Ash.BehaviourHelpers.call_and_validate_return(
module,
:implies?,
[left, right, context],
[true, false],
behaviour: __MODULE__,
callback_name: "implies?/3"
)
else
false
end
end
@doc false
@spec conflicts?(module(), ref(), ref(), context()) :: boolean()
def conflicts?(module, left, right, context) do
if function_exported?(module, :conflicts?, 3) do
Ash.BehaviourHelpers.call_and_validate_return(
module,
:conflicts?,
[left, right, context],
[true, false],
behaviour: __MODULE__,
callback_name: "conflicts?/3"
)
else
false
end
end
@doc false
@spec prefer_expanded_description?(module()) :: boolean()
def prefer_expanded_description?(module) do
Ash.BehaviourHelpers.call_and_validate_return(
module,
:prefer_expanded_description?,
[],
[true, false],
behaviour: __MODULE__,
callback_name: "prefer_expanded_description?/0"
)
end
@doc false
@spec eager_evaluate?(module()) :: boolean()
def eager_evaluate?(module) do
Ash.BehaviourHelpers.call_and_validate_return(
module,
:eager_evaluate?,
[],
[true, false],
behaviour: __MODULE__,
callback_name: "eager_evaluate?/0"
)
end
def defines_check?(module) do
:erlang.function_exported(module, :check, 4)
end
def defines_auto_filter?(module) do
:erlang.function_exported(module, :auto_filter, 3)
end
defmacro __using__(_opts) do
quote do
@behaviour Ash.Policy.Check
import Ash.Expr
require Ash.Query
def type, do: :manual
def init(opts), do: {:ok, opts}
def requires_original_data?(_, _), do: false
def prefer_expanded_description?, do: false
def eager_evaluate?, do: false
def simplify(ref, _context), do: ref
def implies?(_, _, _context), do: false
def conflicts?(_, _, _context), do: false
defoverridable type: 0,
init: 1,
requires_original_data?: 2,
prefer_expanded_description?: 0,
eager_evaluate?: 0,
simplify: 2,
implies?: 3,
conflicts?: 3
end
end
end