PhoenixKit.Users.Permissions.AdminGrants (phoenix_kit v2.64.1)

Copy Markdown View Source

Boot-time grant of permission keys to the Admin role, with retry and a way to wait for it.

Started by PhoenixKit.Supervisor. On start it runs PhoenixKit.Users.Permissions.auto_grant_new_keys_to_admin/0 and backfill_media_sub_permissions/0, then waits for PhoenixKit.Dashboard.Registry to finish loading its tabs (which register and grant their own keys).

A key that hits a database error is not dropped until the next restart: it is kept as pending and tried again after a backoff (1 second, doubled on each attempt, 6 attempts by default: about 63 seconds in all). The retry is a server-side timer rather than a retry on the next access because nothing reads these grants lazily — a request that needs the key would simply be denied — and because a transient failure (pool exhaustion, a database restart) usually clears within seconds. Each grant is idempotent and sets its auto_granted_perm:<key> flag only on success, so a retry never overrides an Owner's later revocation. A failure reported later from outside the sweep (Permissions.auto_grant_to_admin_roles/1 called by the tab registry or by register_custom_key/2) joins the same retry.

Only a database error (an exception or an exit) is retried. A rejected changeset, or a missing sandbox owner (a test suite that already switched to :manual), would fail again, so it is logged once and counted as failed. Each key logs at error level on its first pass, at warning on a retry, and giving up logs one error with the keys still missing.

A key given up on stays reported (by await/2) until the next restart: the server cannot see a grant made behind its back.

The server is :permanent: every step that touches the database rescues, so it does not crash-loop and take PhoenixKit.Supervisor with it.

PhoenixKit.Users.Permissions.await_admin_grants/1 waits for the result; the retries take about 63 seconds, so a shorter timeout can return :timeout while they are still running.

Summary

Functions

Queues a key (or :media_subs) whose grant just failed for a retry. A no-op when the server is not running.

Options: :name, :retry_base_ms (first backoff, default 1000), :max_attempts (default 6) and :sync_registry (default true), :sweep_fun and :registry_fun (test seams for the sweep and the registry wait).

Functions

await(timeout \\ 5000, server \\ __MODULE__)

@spec await(timeout(), GenServer.server()) ::
  :ok | {:error, :timeout | {:failed, list()} | {:exit, term()}}

See PhoenixKit.Users.Permissions.await_admin_grants/1.

report_failure(key, server \\ __MODULE__)

@spec report_failure(String.t() | :media_subs, GenServer.server()) :: :ok

Queues a key (or :media_subs) whose grant just failed for a retry. A no-op when the server is not running.

start_link(opts \\ [])

Options: :name, :retry_base_ms (first backoff, default 1000), :max_attempts (default 6) and :sync_registry (default true), :sweep_fun and :registry_fun (test seams for the sweep and the registry wait).