Files
summercms/modules/cabana/subject_events.go
Jakub Zych 9f14cf603c feat(19.7-01): account contributions, prompted record actions and backend subject events
- pact.HasAccountContributions compiled at Activate; GET /account/contributions
  and POST /account/contributions/{name}/actions/{action} behind interactiveOnly
  (AccountContributionView, AccountContributionActionView, AccountActionResultView)
- RecordAction.prompt (RecordActionPrompt) for a pact.AdminRecordAction with a
  Prompt; the record action route accepts payload only for such an action
  (trimmed JSON string, non-empty, capped at max_length) and hands it to Run as
  Value through CRUDService.RecordActionWithValue; a prompt without a label
  fails boot
- fireSubjectChanged: pact.MCPSubjectChanged for revoked tokens, Administrators
  saves that changed role, permissions or superuser, Roles saves that changed
  grants, deactivation and deletion
- phrases backend::lang.form.action_prompt_required/_too_long (en, pl)
- smoke tests TestAccountContributionsSmoke and TestRecordActionPromptSmoke;
  TestRecordActionPromptRun on Postgres; route inventories, CSRF walk and
  OpenAPI conformance cases extended for the two routes
- regenerated admin/openapi/admin.json and admin/src/api/schema.d.ts; cabana
  README, docs/backend/{admin-controllers,users-and-permissions}.md
2026-10-22 16:31:29 +02:00

36 lines
1.1 KiB
Go

package cabana
import (
"context"
"git.golem15.com/golem15/summercms/modules/backpack"
"git.golem15.com/golem15/summercms/modules/pact"
)
// backendSubjectGuard is the guard name backend subject events carry: the
// admin's own bouncer guard.
const backendSubjectGuard = "backend"
// fireSubjectChanged fires one pact.MCPSubjectChanged of the given kind for
// every administrator id through the application's event bus, so the MCP
// endpoint re-lists a linked admin's tools or ends their sessions. A missing
// application or bus is a no-op and a listener's error is logged: the save
// that caused the event never fails because of it.
func fireSubjectChanged(ctx context.Context, app *backpack.App, kind string, adminIDs ...uint) {
if app == nil || app.Events == nil {
return
}
if ctx == nil {
ctx = context.Background()
}
for _, id := range adminIDs {
if id == 0 {
continue
}
event := pact.MCPSubjectChanged{Guard: backendSubjectGuard, UserID: id, Kind: kind}
if err := app.Events.Fire(ctx, event); err != nil {
moduleLog.WarnContext(ctx, "cabana: subject changed listener failed", "kind", kind, "admin_id", id, "error", err)
}
}
}