68 lines
2.7 KiB
Go
68 lines
2.7 KiB
Go
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
|
|
}
|