feat: add config-driven super-admin bootstrap to Go backend
This commit is contained in:
1 parent
8affa4b25a
commit
ff055c972d
5 files changed
+345
No files matched your search
@@ -0,0 +1,67 @@
|
||||
package application
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"git.nianxx.cn/wangxuming/NianAIGC/backend/internal/administration"
|
||||
"git.nianxx.cn/wangxuming/NianAIGC/backend/internal/postgres"
|
||||
)
|
||||
|
||||
// BootstrapAdminConfig describes the config-driven first super administrator.
|
||||
// When every field is present and the process runs against PostgreSQL,
|
||||
// application startup creates this account exactly once and skips the
|
||||
// bootstrap when a super administrator already exists.
|
||||
type BootstrapAdminConfig struct {
|
||||
Phone string
|
||||
Password string
|
||||
DisplayName string
|
||||
}
|
||||
|
||||
// Configured reports whether every bootstrap field is present.
|
||||
func (c BootstrapAdminConfig) Configured() bool {
|
||||
return c.Phone != "" && c.Password != "" && c.DisplayName != ""
|
||||
}
|
||||
|
||||
// ParseBootstrapAdminConfig reads ZHINIAN_BOOTSTRAP_ADMIN_PHONE,
|
||||
// ZHINIAN_BOOTSTRAP_ADMIN_PASSWORD, and ZHINIAN_BOOTSTRAP_ADMIN_NAME. The
|
||||
// variable names mirror the previous scripts/bootstrap-admin.mjs contract;
|
||||
// the display name defaults to 平台超级管理员.
|
||||
func ParseBootstrapAdminConfig(getenv func(string) string) BootstrapAdminConfig {
|
||||
if getenv == nil {
|
||||
return BootstrapAdminConfig{}
|
||||
}
|
||||
return BootstrapAdminConfig{
|
||||
Phone: strings.TrimSpace(getenv("ZHINIAN_BOOTSTRAP_ADMIN_PHONE")),
|
||||
Password: getenv("ZHINIAN_BOOTSTRAP_ADMIN_PASSWORD"),
|
||||
DisplayName: firstNonEmpty(strings.TrimSpace(getenv("ZHINIAN_BOOTSTRAP_ADMIN_NAME")), "平台超级管理员"),
|
||||
}
|
||||
}
|
||||
|
||||
// BootstrapSuperAdmin creates the configured first super administrator once.
|
||||
// It is a no-op when the backend is not PostgreSQL, when the configuration is
|
||||
// incomplete, or when a super administrator already exists (including
|
||||
// disabled ones, so a retired administrator cannot trigger a duplicate).
|
||||
// Failures are returned to the caller and fail application startup, so a
|
||||
// misconfigured bootstrap is visible instead of silently missing.
|
||||
func BootstrapSuperAdmin(ctx context.Context, backend postgres.Backend, service *administration.Service, config BootstrapAdminConfig) (bool, error) {
|
||||
if backend != postgres.BackendPostgres || !config.Configured() {
|
||||
return false, nil
|
||||
}
|
||||
existing, err := service.ListAccounts(ctx, administration.Actor{Role: administration.RoleSuperAdmin}, administration.AccountFilters{Role: administration.RoleSuperAdmin, IncludeDisabled: true})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if len(existing) > 0 {
|
||||
return false, nil
|
||||
}
|
||||
if _, err := service.CreateAccount(ctx, administration.Actor{Role: administration.RoleSuperAdmin}, administration.CreateAccountInput{
|
||||
Phone: config.Phone,
|
||||
DisplayName: config.DisplayName,
|
||||
Password: config.Password,
|
||||
Role: administration.RoleSuperAdmin,
|
||||
}); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
Reference in new issue
Block a user