package users import ( "context" "errors" "fmt" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" "github.com/ultisuite/ulti-backend/internal/auth" "github.com/ultisuite/ulti-backend/internal/permission" ) // IsPlatformAdmin reports whether the user row is marked platform_admin. func IsPlatformAdmin(ctx context.Context, db *pgxpool.Pool, externalID string) (bool, error) { if db == nil || externalID == "" { return false, nil } var admin bool err := db.QueryRow(ctx, ` SELECT platform_admin FROM users WHERE external_id = $1 `, externalID).Scan(&admin) if errors.Is(err, pgx.ErrNoRows) { return false, nil } if err != nil { return false, err } return admin, nil } // GrantPlatformAdmin sets platform_admin for the given external_id. func GrantPlatformAdmin(ctx context.Context, db *pgxpool.Pool, externalID string) error { if db == nil { return fmt.Errorf("database not configured") } if externalID == "" { return fmt.Errorf("missing external id") } tag, err := db.Exec(ctx, ` UPDATE users SET platform_admin = true, updated_at = NOW() WHERE external_id = $1 `, externalID) if err != nil { return err } if tag.RowsAffected() == 0 { return pgx.ErrNoRows } return nil } // ApplyPlatformAdminGroups adds admin RBAC groups when the user is platform_admin. func ApplyPlatformAdminGroups(ctx context.Context, db *pgxpool.Pool, claims *auth.Claims) error { if claims == nil || db == nil { return nil } admin, err := IsPlatformAdmin(ctx, db, claims.Sub) if err != nil { return err } if admin { claims.Groups = permission.WithPlatformAdmin(claims.Groups) } return nil } func bootstrapFirstUserAdmin(ctx context.Context, db *pgxpool.Pool, userID string) error { var hasAdmin bool if err := db.QueryRow(ctx, `SELECT EXISTS(SELECT 1 FROM users WHERE platform_admin = true)`).Scan(&hasAdmin); err != nil { return err } if hasAdmin { return nil } _, err := db.Exec(ctx, ` UPDATE users SET platform_admin = true, updated_at = NOW() WHERE id = $1 `, userID) return err }