Add users and network settings tabs with admin protections.

List and delete accounts with last-admin and Administrators-group guards, and expose editable network settings via the configuration UI.
This commit is contained in:
2026-07-18 15:18:01 +02:00
parent f049f766d9
commit 2605c3b346
49 changed files with 5440 additions and 209 deletions
+71
View File
@@ -0,0 +1,71 @@
package api
import (
"encoding/base64"
"net/http"
"net/http/httptest"
"testing"
"time"
"codeberg.org/SquidSE/ClusterCanvas/service/internal/auth"
"codeberg.org/SquidSE/ClusterCanvas/service/internal/settings"
)
func seedCompletedSetup(t *testing.T, configDir string) *http.Cookie {
t.Helper()
keyBytes := make([]byte, 32)
for index := range keyBytes {
keyBytes[index] = byte(index + 1)
}
t.Setenv(settings.ConfigKeyEnvVar, base64.StdEncoding.EncodeToString(keyBytes))
now := time.Now().UTC()
passwordHash, err := auth.HashPassword("correct horse battery staple extra")
if err != nil {
t.Fatalf("HashPassword: %v", err)
}
user := settings.UserCredential{
ID: "test-user-id",
Username: "Admin",
PasswordHash: passwordHash,
Enabled: true,
GroupNames: []string{settings.AdministratorsGroupName},
CreatedAt: now,
PasswordChangedAt: now,
}
if err := settings.SavePasswords(configDir, settings.PasswordStore{Users: []settings.UserCredential{user}}, keyBytes); err != nil {
t.Fatalf("SavePasswords: %v", err)
}
security := settings.DefaultSecuritySettings()
payload := settings.Settings{
SetupCompleted: true,
Groups: []settings.Group{},
Security: security,
Network: settings.DefaultNetworkSettings(),
}
if err := settings.SaveSettings(configDir, payload); err != nil {
t.Fatalf("SaveSettings: %v", err)
}
manager := auth.NewSessionManager(configDir, keyBytes)
recorder := httptest.NewRecorder()
if _, err := manager.CreateSession(recorder, user.ID, security); err != nil {
t.Fatalf("CreateSession: %v", err)
}
for _, cookie := range recorder.Result().Cookies() {
if cookie.Name == auth.SessionCookieName {
return cookie
}
}
t.Fatal("session cookie not set")
return nil
}
func withSession(request *http.Request, cookie *http.Cookie) *http.Request {
request.AddCookie(cookie)
return request
}