docs(19.6.1-04): state Administrators outranking on the D-14 seam

- cabana, not the contributor, applies guardOutranked before a contributed Run
- A contribution to summercms.cabana.users is 403 user.outranked when the target outranks the caller

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jakub Zych
2026-10-22 13:30:40 +02:00
parent 068adaabf9
commit cb460b6000
4 changed files with 9 additions and 4 deletions

View File

@@ -137,7 +137,7 @@ func (p *Plugin) Schedule() []pact.ScheduledCommand {
| `pact.AdminRecordActionInput` | What a record action receives: `RecordID` and `Record`, the record loaded and row-locked through the form scope. |
| `pact.AdminRecordActionResult` | What a record action returns: an optional message for the toast. |
| `pact.HasAdminRecordActions` | Registers a controller's record actions for the `recordActions` list of `config_form.yaml`. |
| `pact.AdminActionExtension` | Record actions a plugin adds to one admin controller by its `Controller` ID; offered on the target's preview screen after the owner's actions, each checked against the target's `RequiredPermissions` and its own `Permissions`. |
| `pact.AdminActionExtension` | Record actions a plugin adds to one admin controller by its `Controller` ID; offered on the target's preview screen after the owner's actions, each checked against the target's `RequiredPermissions` and its own `Permissions`. A contribution to `summercms.cabana.users` is refused with `user.outranked` when the target administrator outranks the caller. |
| `pact.HasAdminActionExtensions` | Implemented by a plugin (not a controller) that adds actions to admin controllers, its own or another plugin's. An unknown controller ID, a target without a preview block or a duplicate name stops the boot. |
| `pact.ReorderAfterSave` | Optional controller hook `ReorderAfterSave(ctx, partition)`: runs after a reorder save wrote the new order, inside the same transaction (`cabana.TxFromContext` works); an error rolls the reorder back. |
| `pact.AdminPartialData` | Supplies the view model a controller partial template renders; never the GORM model. |

View File

@@ -387,8 +387,12 @@ type HasAdminRecordActions interface {
// through the target's FormExtendQuery scope inside the action's transaction
// and hands it to Run, which reads that transaction with
// cabana.TxFromContext. An administrator needs the target controller's
// RequiredPermissions and the action's own Permissions. A record action
// carries no input beyond the record.
// RequiredPermissions and the action's own Permissions. When Controller is
// the admin's Administrators screen (summercms.cabana.users), cabana runs
// its outranking check inside the action transaction before the
// contributor's Run; a non-superuser whose grants do not cover the
// target's effective grants gets 403 with backend::lang.user.outranked and
// Run is not called. A record action carries no input beyond the record.
//
// The admin compiles extensions at boot, only when it is active (some
// plugin registers admin controllers). An unknown controller ID, a target