Runique Admin
Documentation / Runique Admin / Roles and permissions

Roles and permissions

Overview

Admin access rests on the account's rank, three flags of eihwaz_users of which at most one is true (a CHECK constraint in the database):

RankFlagWhat it can do
Superuseris_superuserEverything, the only one bypassing rights (never the invariants). The developer's account, to delete at delivery
Dirigeantis_dirigeantEvery right on the models, with no bypass. Grants the admins' rights
Adminis_adminWhat the dirigeant ticks on its account, table by table and column by column
LambdanoneA site account. Enters the admin only as a member of a staff group

can_access_admin() is true for rank admin or above, or for a lambda member of an is_staff group. An account must also be active and activated.


Where rights come from

CurrentUser::rights_on("resource") is the only way to ask what an account may do, in the admin as in your views. The source depends on the rank alone:

RankSource of rights
SuperuserEverything, with bypass
DirigeantEverything, no bypass
AdminIts own grid, set by the dirigeant (eihwaz_groupes_droits, rows tied to its account)
LambdaThe union (logical OR) of its groups' rights — never on the framework's tables (accounts, groups, rights, memberships)

Rights are set per table and per column:

RightLevelEffect
can_readtable + columnsSee the resource and the ticked columns
can_createtable + columnsCreate, filling the ticked columns
can_updatetable + columnsUpdate the ticked columns
can_deletetableDelete
can_update_own / can_delete_owntableOwn rows only, when the model declares an owner (meta: { owner: … })

A column added to the model later is readable or writable only once ticked. Secret columns (password) are never offered.

Rights are not declared in ModelAdmin: the whole grid lives in the database.


Groups and staff

Groups are for lambda accounts: public site roles, and rights on the developer's tables in the admin. A lambda member of a group marked is_staff enters the admin and sees its allowed resources there, plus a read-only summary of its own groups and rights. No group ever has a right on the framework's tables, whoever configures it.

Immediate revocation

The account (active, rank), its groups and rights are read from the database on every admin request: the session only keeps the user's identity. Removing a right or a group, deactivating an account or lowering its rank takes effect on its next request, whatever path made the change (admin, CLI, SQL, another instance). A deactivated account, or one that lost admin access, has its session closed.


Framework tables: `users`, `groupes`, `groupes_droits`

Accounts, groups, rights and memberships are reserved to ranks: the superuser, the dirigeant, and an admin only for the tables and columns the dirigeant ticked for it. No group can get a right on those tables, and nobody can grant it one, superuser included: a lambda, staff or not, does no operation on them.

One exception: a lambda reading a row linked to an account (through a foreign key) sees that account's username, read-only.


Access logic

signed in, active and activated?
  └─ no  → redirect /admin/login
  └─ yes → can_access_admin()? (rank ≥ admin, or member of a staff group)
               └─ no  → redirect /admin/login
               └─ yes → rights_on(resource)
                          superuser → everything, bypass included
                          dirigeant → everything
                          admin     → its grid (table × column)
                          lambda    → union of its groups, never a framework table
                        └─ can_read? no  → resource missing from the nav
                                     yes → list, ticked columns only
                                           can_create / can_update / can_delete
                                           (_own: own rows)

Rank flags

is_superuser, is_dirigeant and is_admin are not admin form fields. Boot refuses them in fields. Rank is changed from the account page: a dirigeant may give admin or lambda, a superuser may give dirigeant, admin or lambda. The rank given stays strictly below the one who writes it. That action takes groups back when rank is lost, drops the rights grid of an admin who steps down, and keeps at least one active dirigeant while an admin remains. is_superuser is not given there: it is set with runique create-superuser, by a direct insert.

The rank filter limits which rows a proof may touch, from the rank already stored: an admin touches neither an admin, nor a dirigeant, nor a superuser; a dirigeant touches neither a dirigeant nor a superuser; a superuser does not touch another superuser.

write::insert refuses a Set(true) on one of these flags. write::update refuses any Set, true or false: a promotion or a demotion through that path would skip the rules above. A SeaORM insert or update on the connection never enters the gate.

Notes

  • ModelAdmin does not declare permissions: configuration is entirely in the database.
  • Permissions are aggregated with logical OR across all of the user's groups.
  • A user can have can_read without can_create — they see the list but cannot create.
  • Secret columns and ranks stay out of forms, including for a superuser (refused at boot). The rank-flag detail is above.