feat: register the Users admin screen with the privileged-member guard

- permissions (the four Winter codes and manage_privileged_groups),
  the user navigation item and the embedded admin YAML
- Users controller: list with deactivated users, row states, the
  groups, created date and activated filters, and the form's name,
  surname and email
- a member of a group in golem15.user.privileged_groups (default
  admin) keeps their email, password and row unless the administrator
  holds golem15.users.manage_privileged_groups; the refusal is a 403
  that saves nothing
This commit is contained in:
Jakub Zych
2026-10-05 13:01:18 +02:00
parent e22f7660f3
commit b410a7fea9
17 changed files with 739 additions and 2 deletions

View File

@@ -34,7 +34,9 @@ import (
)
const (
sessionSecret = "summercms-test-only-hs256-secret"
sessionSecret = "summercms-test-only-hs256-secret"
// adminHarnessSecret signs backend tokens in tests that mount the admin API.
adminHarnessSecret = "summercms-test-only-admin-hs256-secret"
invalidLoginBody = `{"error":true,"message":"Invalid email or password"}`
prvHash = "a867434cbc213adfbe78a02bed7082a6bd99c883"
)
@@ -43,7 +45,10 @@ var (
sessionOnce sync.Once
sessionGDB *gorm.DB
sessionSQL *sql.DB
sessionErr error
// sessionDSN is the container's connection string; the admin harness
// opens its own database in the same container with it.
sessionDSN string
sessionErr error
)
func TestLogin(t *testing.T) {
@@ -507,6 +512,9 @@ func sessionConfig(t *testing.T) *compass.Config {
Environ: []string{
"SUMMER_ENV=development",
"SUMMER_GOLEM15__USER__JWT__SECRET=" + sessionSecret,
// The plugin registers admin controllers, so assembling its
// routes mounts the admin API, which needs its own secret.
"SUMMER_ADMIN__JWT__SECRET=" + adminHarnessSecret,
},
})
if err != nil {
@@ -538,6 +546,7 @@ func sessionDB(t *testing.T) (*gorm.DB, *sql.DB) {
sessionErr = err
return
}
sessionDSN = dsn
sqlDB, err := sql.Open("pgx", dsn)
if err != nil {
sessionErr = err