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") } }