feat(cabana): settings entries that link to an admin controller
pact.SettingsItem gains an additive Controller field, the equivalent of a WinterCMS registerSettings 'url' => Backend::url(...) entry. A link entry declares no Model, Form or NewModel and needs no AdminFS; start-up fails when it combines Controller with a singleton form or a model, or names an unregistered controller. Settings codes stay one namespace. GET /settings lists a link entry with its controller only when the principal passes the item's permissions and may open the controller. Registry.Setting never returns a link entry, so the singleton settings endpoints answer 404 for its code. SettingsEntry carries controller, empty for singletons; the OpenAPI document, generated SPA types and settings fixture follow, and the pact and cabana READMEs and the settings docs describe the link.
This commit is contained in:
@@ -29,6 +29,9 @@ type SettingsEntry struct {
|
||||
Order int `json:"order"`
|
||||
Keywords []string `json:"keywords"`
|
||||
Model string `json:"model"`
|
||||
// Controller is the admin controller a link entry opens; empty for a
|
||||
// singleton settings form.
|
||||
Controller string `json:"controller"`
|
||||
}
|
||||
|
||||
// Metadata returns only entries the backend principal may open. Denied
|
||||
@@ -65,7 +68,9 @@ func (r *Registry) Metadata(ctx context.Context, principal *bouncer.Principal, t
|
||||
})
|
||||
for _, compiled := range r.settings {
|
||||
item := compiled.Item
|
||||
if !Allows(principal, item.Permissions) {
|
||||
// A link entry is listed only when the principal can also open its
|
||||
// controller, so a denied controller ID never leaks.
|
||||
if !Allows(principal, item.Permissions) || (item.Controller != "" && !r.canOpen(principal, item.Controller)) {
|
||||
continue
|
||||
}
|
||||
keywords := append([]string(nil), item.Keywords...)
|
||||
@@ -77,6 +82,7 @@ func (r *Registry) Metadata(ctx context.Context, principal *bouncer.Principal, t
|
||||
Description: translateKey(ctx, tr, item.Description),
|
||||
Category: translateKey(ctx, tr, item.Category), Icon: item.Icon,
|
||||
Order: item.Order, Keywords: keywords, Model: item.Model,
|
||||
Controller: item.Controller,
|
||||
})
|
||||
}
|
||||
sort.SliceStable(settings, func(i, j int) bool {
|
||||
|
||||
Reference in New Issue
Block a user