- administrators_harness_test.go: newScreensEnv with extra plugins, seedAdmin, seedRole, login, isolateSuperusers, row snapshots and error decoders; the harness moved out of backend_screens_smoke_test.go and gained cleanup - export_test.go: SuperuserLockKey for the last-superuser race - TestAdministratorsSuperuserFlag (D-05) through the assembled handler
93 lines
3.7 KiB
Go
93 lines
3.7 KiB
Go
package cabana_test
|
|
|
|
import (
|
|
"net/http"
|
|
"testing"
|
|
|
|
"git.golem15.com/golem15/summercms/modules/cabana"
|
|
)
|
|
|
|
// manageUsers is the role grant of a delegated administrator.
|
|
var manageUsers = map[string]int{cabana.PermissionManageUsers: 1}
|
|
|
|
// newAdminBody is a create body with a valid, confirmed password.
|
|
func newAdminBody(login string, extra map[string]any) map[string]any {
|
|
body := map[string]any{
|
|
"login": login, "email": login + "@example.test", "first_name": "New", "last_name": "Admin",
|
|
"password": "pass-1234", "password_confirmation": "pass-1234",
|
|
}
|
|
for key, value := range extra {
|
|
body[key] = value
|
|
}
|
|
return body
|
|
}
|
|
|
|
// cleanupLogin soft-deletes and demotes an administrator a test created
|
|
// through the API, by login.
|
|
func (e *screensEnv) cleanupLogin(t *testing.T, login string) {
|
|
t.Helper()
|
|
t.Cleanup(func() {
|
|
e.gdb.Exec(`UPDATE backend_users SET is_superuser = FALSE, deleted_at = COALESCE(deleted_at, NOW()) WHERE login = ?`, login)
|
|
})
|
|
}
|
|
|
|
// countLogin counts the administrators with login, deleted ones included.
|
|
func (e *screensEnv) countLogin(t *testing.T, login string) int64 {
|
|
t.Helper()
|
|
var n int64
|
|
if err := e.gdb.Raw(`SELECT count(*) FROM backend_users WHERE login = ?`, login).Scan(&n).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return n
|
|
}
|
|
|
|
// TestAdministratorsSuperuserFlag (D-05): only an administrator acting as a
|
|
// superuser may send the superuser switch, on create and on update, whatever
|
|
// its value; a superuser grants and removes the flag.
|
|
func TestAdministratorsSuperuserFlag(t *testing.T) {
|
|
env := newScreensEnv(t)
|
|
super := env.seedAdmin(t, adminSeed{Name: "flag-super", Superuser: true})
|
|
superToken := env.login(t, super.Login)
|
|
delegate := env.seedAdmin(t, adminSeed{Name: "flag-delegate", RolePermissions: manageUsers})
|
|
delegateToken := env.login(t, delegate.Login)
|
|
target := env.seedAdmin(t, adminSeed{Name: "flag-target"})
|
|
|
|
for _, flag := range []bool{true, false} {
|
|
login := env.unique("flag-create")
|
|
env.cleanupLogin(t, login)
|
|
env.expectFieldRefusal(t, http.StatusForbidden, http.MethodPost, usersPath, delegateToken,
|
|
newAdminBody(login, map[string]any{"is_superuser": flag}), "is_superuser", enSuperuserForbidden, true)
|
|
if n := env.countLogin(t, login); n != 0 {
|
|
t.Fatalf("a refused create (is_superuser=%v) left %d rows", flag, n)
|
|
}
|
|
|
|
before := env.userRow(t, target.ID)
|
|
env.expectFieldRefusal(t, http.StatusForbidden, http.MethodPut, userURL(target.ID), delegateToken,
|
|
map[string]any{"login": target.Login, "email": target.Email, "first_name": "Changed", "is_superuser": flag},
|
|
"is_superuser", enSuperuserForbidden, true)
|
|
env.unchanged(t, target.ID, before, "a refused is_superuser update")
|
|
}
|
|
|
|
// A superuser grants the flag on create...
|
|
login := env.unique("flag-granted")
|
|
env.cleanupLogin(t, login)
|
|
created := env.expect(t, http.StatusCreated, http.MethodPost, usersPath, superToken,
|
|
newAdminBody(login, map[string]any{"is_superuser": true}))
|
|
id := uint(dataOf(created)["id"].(float64))
|
|
if got := env.storedUser(t, id); !got.IsSuperuser {
|
|
t.Fatalf("created superuser = %+v", got)
|
|
}
|
|
// ...and removes it from that other superuser through update.
|
|
env.expect(t, http.StatusOK, http.MethodPut, userURL(id), superToken,
|
|
map[string]any{"login": login, "email": login + "@example.test", "is_superuser": false})
|
|
if got := env.storedUser(t, id); got.IsSuperuser {
|
|
t.Fatal("the superuser flag was not removed")
|
|
}
|
|
// The same superuser grants it on update.
|
|
env.expect(t, http.StatusOK, http.MethodPut, userURL(target.ID), superToken,
|
|
map[string]any{"login": target.Login, "email": target.Email, "is_superuser": true})
|
|
if got := env.storedUser(t, target.ID); !got.IsSuperuser {
|
|
t.Fatal("the superuser flag was not granted on update")
|
|
}
|
|
}
|