feat(10.1-01): serve controller JS/CSS and run registered toolbar actions
- boardwalk exports ContentType and SetSecurityHeaders
- pact.AdminClientAssets files are read and hashed at boot and served by exact
key under {prefix}/assets/{vendor}/{plugin}/ with nosniff, CSP, CORP,
no-cache and an ETag; a miss falls through to the SPA
- list and form schemas carry assets URLs with a ?v= hash
- toolbar.buttons resolves create, delete and registered actions after decode;
toolbarActions is permission-filtered per admin
- POST .../toolbar/{action} behind requireAjax and action permissions
This commit is contained in:
@@ -52,24 +52,25 @@ func checkReservedSegments(items []controllerRef) error {
|
||||
|
||||
func compileRegistry(items []controllerRef) (*Registry, error) {
|
||||
byID := make(map[string]*CompiledController, len(items))
|
||||
assets := map[string]*pluginAsset{}
|
||||
for _, item := range items {
|
||||
id := item.ctl.ID()
|
||||
if _, exists := byID[id]; exists {
|
||||
return nil, fmt.Errorf("cabana: duplicate admin controller %s", id)
|
||||
}
|
||||
assets, ok := item.plugin.(pact.AdminAssets)
|
||||
if !ok || assets == nil || assets.AdminFS() == nil {
|
||||
fsys, ok := item.plugin.(pact.AdminAssets)
|
||||
if !ok || fsys == nil || fsys.AdminFS() == nil {
|
||||
return nil, fmt.Errorf("cabana: plugin %s has admin controllers but no AdminFS", item.plugin.ID())
|
||||
}
|
||||
list, err := compileList(item.plugin.ID(), item.ctl, assets.AdminFS())
|
||||
list, err := compileList(item.plugin.ID(), item.ctl, fsys.AdminFS())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
form, err := compileFormIfPresent(item.plugin.ID(), item.ctl, assets.AdminFS())
|
||||
form, err := compileFormIfPresent(item.plugin.ID(), item.ctl, fsys.AdminFS())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
relations, err := compileRelations(item.plugin.ID(), item.ctl, assets.AdminFS(), form)
|
||||
relations, err := compileRelations(item.plugin.ID(), item.ctl, fsys.AdminFS(), form)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -92,12 +93,18 @@ func compileRegistry(items []controllerRef) (*Registry, error) {
|
||||
if err := BindWritableFields(compiled); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := compileExtension(item.plugin.ID(), compiled, assets.AdminFS()); err != nil {
|
||||
if err := compileExtension(item.plugin.ID(), compiled, fsys.AdminFS()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Two controllers of one plugin declaring the same file share an entry.
|
||||
for _, file := range append(append([]*pluginAsset(nil), compiled.scripts...), compiled.styles...) {
|
||||
if _, exists := assets[file.key]; !exists {
|
||||
assets[file.key] = file
|
||||
}
|
||||
}
|
||||
byID[id] = compiled
|
||||
}
|
||||
return &Registry{byID: byID}, nil
|
||||
return &Registry{byID: byID, assets: assets}, nil
|
||||
}
|
||||
|
||||
func withoutAction(actions []string, drop string) []string {
|
||||
|
||||
Reference in New Issue
Block a user