- pact.HasAdminActionExtensions / AdminActionExtension: plugins add record actions to any admin controller by ID, merged at boot before permission validation (unknown target, no preview, duplicate name stop the boot) - internal summercms.cabana pseudo-plugin, appended only when some plugin registers admin controllers: Administrators list and preview, settings link under System, backend.manage_users and backend.manage_roles with no role grants - backend::lang user, user.role and permissions copy (en, pl) - smoke tests: compile-time seam and settings, Postgres list/preview/action
71 lines
2.4 KiB
Go
71 lines
2.4 KiB
Go
package cabana
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
|
|
"git.golem15.com/golem15/summercms/modules/backpack"
|
|
"git.golem15.com/golem15/summercms/modules/pact"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// usersAdmin is the Administrators screen (summercms.cabana.users), the
|
|
// WinterCMS Backend\Controllers\Users controller over backend_users. Every
|
|
// route needs backend.manage_users. screens gives access to the activating
|
|
// app and the compiled registry at request time.
|
|
type usersAdmin struct {
|
|
screens *backendScreens
|
|
}
|
|
|
|
var (
|
|
_ pact.AdminController = usersAdmin{}
|
|
_ pact.AdminPermissioned = usersAdmin{}
|
|
_ pact.AdminRecordSource = usersAdmin{}
|
|
_ pact.FormRecordTitle = usersAdmin{}
|
|
_ FieldRelationProvider = usersAdmin{}
|
|
)
|
|
|
|
func (usersAdmin) ID() string { return AdministratorsControllerID }
|
|
|
|
func (usersAdmin) ModelName() string { return BackendUserMorphType }
|
|
|
|
func (usersAdmin) ConfigDir() string { return "controllers/users" }
|
|
|
|
func (usersAdmin) RequiredPermissions() []string { return []string{PermissionManageUsers} }
|
|
|
|
func (usersAdmin) NewRecord() any { return &BackendUser{} }
|
|
|
|
// application is the activating app, or nil.
|
|
func (c usersAdmin) application() *backpack.App { return c.screens.application() }
|
|
|
|
// registry is the compiled registry, or nil before compilation finished.
|
|
func (c usersAdmin) registry() *Registry { return c.screens.registry() }
|
|
|
|
// FormRecordTitle names an administrator "First Last" when either name is
|
|
// set, otherwise by the login.
|
|
func (usersAdmin) FormRecordTitle(_ context.Context, _ *gorm.DB, record any) (string, error) {
|
|
user, ok := record.(*BackendUser)
|
|
if !ok || user == nil {
|
|
return "", errors.New("cabana: administrators: record is not a backend user")
|
|
}
|
|
if name := strings.TrimSpace(strings.TrimSpace(user.FirstName) + " " + strings.TrimSpace(user.LastName)); name != "" {
|
|
return name, nil
|
|
}
|
|
return user.Login, nil
|
|
}
|
|
|
|
// AdminFieldRelations binds the role picker. role_id is a protected column,
|
|
// so the contract opts in to writing it through this one field; the
|
|
// submitted id is still checked against the options and the role locks.
|
|
func (usersAdmin) AdminFieldRelations() []FieldRelationContract {
|
|
return []FieldRelationContract{{
|
|
Field: "role",
|
|
Kind: "belongsTo",
|
|
NewRelated: func() any { return &BackendUserRole{} },
|
|
ForeignKey: "role_id",
|
|
LabelColumn: "name",
|
|
WritableForeignKey: true,
|
|
}}
|
|
}
|