AbsinthePermission.Evaluator (AbsinthePermission v1.0.0)

Copy Markdown View Source

Pure (no side effects beyond the user-supplied loader functions) evaluation of compiled rules against a request.

Inputs

  • rules — list of AbsinthePermission.Rule.t/0
  • loads — list of AbsinthePermission.Load.t/0 to resolve before rules run
  • schema — schema module; used to look up loader functions
  • args — map of GraphQL arguments
  • context — Absinthe context map; expected to contain :current_user and :permissions

Output

A AbsinthePermission.Decision.t/0 describing the verdict and why.

Semantics

  • Rules whose condition does not fire are skipped silently.
  • Rules whose condition fires AND whose permission is held by the caller are recorded as matched.
  • Rules whose condition fires AND whose permission is NOT held cause an immediate :deny decision, with error_message / permission / matched_rules populated.
  • Multiple rules combine with AND semantics — ALL fired rules must pass.

Summary

Functions

Evaluate a condition against the request state.

Evaluate an expression to a runtime value.

Evaluate post-op rules against an already-resolved value.

Evaluate pre-op rules. Resolves loads first, then runs each rule in order. Returns {:ok, decision} on the happy path or {:error, decision} when a load fails.

Check whether user_perms satisfies the rule's permission spec.

Resolve all loads by calling their registered loader. Returns {:ok, %{name => record_or_nil}} or {:error, reason}.

Types

args()

@type args() :: %{optional(atom()) => any()} | keyword()

ctx()

@type ctx() :: %{optional(atom()) => any()}

Functions

condition_fires?(expr, args, ctx, loaded)

@spec condition_fires?(AbsinthePermission.Condition.t(), map(), ctx(), map()) ::
  boolean()

Evaluate a condition against the request state.

eval_expr(other, args, ctx, loaded)

@spec eval_expr(any(), map(), ctx(), map()) :: any()

Evaluate an expression to a runtime value.

evaluate_post(rules, value, args, context, field_id \\ nil)

@spec evaluate_post([AbsinthePermission.Rule.t()], any(), args(), ctx(), atom() | nil) ::
  {:allow | :nullify | :deny, AbsinthePermission.Decision.t()}

Evaluate post-op rules against an already-resolved value.

For redaction (on_deny: :null), returns {:nullify, decision} if the rule denies. For :error, returns {:deny, decision}. Otherwise returns {:allow, decision} and the value passes through unchanged.

evaluate_pre(rules, loads, schema, args, context, field_id \\ nil)

Evaluate pre-op rules. Resolves loads first, then runs each rule in order. Returns {:ok, decision} on the happy path or {:error, decision} when a load fails.

has_permission?(arg1, user_perms)

@spec has_permission?(AbsinthePermission.Rule.permission(), [String.t()]) :: boolean()

Check whether user_perms satisfies the rule's permission spec.

resolve_loads(loads, schema, args, ctx)

@spec resolve_loads([AbsinthePermission.Load.t()], module(), map(), ctx()) ::
  {:ok, %{required(atom()) => any()}} | {:error, String.t()}

Resolve all loads by calling their registered loader. Returns {:ok, %{name => record_or_nil}} or {:error, reason}.