package service import ( apperrors "carrotskin/internal/errors" "carrotskin/internal/repository" "context" "fmt" "time" "go.uber.org/zap" ) // CertificateService 证书服务接口 type CertificateService interface { // GeneratePlayerCertificate 生成玩家证书 GeneratePlayerCertificate(ctx context.Context, uuid string) (map[string]interface{}, error) // GetPublicKey 获取公钥 GetPublicKey(ctx context.Context) (string, error) } // yggdrasilCertificateService 证书服务实现 type yggdrasilCertificateService struct { profileRepo repository.ProfileRepository signatureService *signatureService logger *zap.Logger } // NewCertificateService 创建证书服务实例 func NewCertificateService( profileRepo repository.ProfileRepository, signatureService *signatureService, logger *zap.Logger, ) CertificateService { return &yggdrasilCertificateService{ profileRepo: profileRepo, signatureService: signatureService, logger: logger, } } // GeneratePlayerCertificate 生成玩家证书 func (s *yggdrasilCertificateService) GeneratePlayerCertificate(ctx context.Context, uuid string) (map[string]interface{}, error) { if uuid == "" { return nil, apperrors.ErrUUIDRequired } s.logger.Info("开始生成玩家证书", zap.String("uuid", uuid), ) // 获取密钥对 keyPair, err := s.profileRepo.GetKeyPair(uuid) if err != nil { s.logger.Info("获取用户密钥对失败,将创建新密钥对", zap.Error(err), zap.String("uuid", uuid), ) keyPair = nil } // 如果没有找到密钥对或密钥对已过期,创建一个新的 now := time.Now().UTC() if keyPair == nil || keyPair.Refresh.Before(now) || keyPair.PrivateKey == "" || keyPair.PublicKey == "" { s.logger.Info("为用户创建新的密钥对", zap.String("uuid", uuid), ) keyPair, err = s.signatureService.NewKeyPair() if err != nil { s.logger.Error("生成玩家证书密钥对失败", zap.Error(err), zap.String("uuid", uuid), ) return nil, fmt.Errorf("生成玩家证书密钥对失败: %w", err) } // 保存密钥对到数据库 err = s.profileRepo.UpdateKeyPair(uuid, keyPair) if err != nil { s.logger.Warn("更新用户密钥对失败", zap.Error(err), zap.String("uuid", uuid), ) // 继续执行,即使保存失败 } } // 计算expiresAt的毫秒时间戳 expiresAtMillis := keyPair.Expiration.UnixMilli() // 返回玩家证书 certificate := map[string]interface{}{ "keyPair": map[string]interface{}{ "privateKey": keyPair.PrivateKey, "publicKey": keyPair.PublicKey, }, "publicKeySignature": keyPair.PublicKeySignature, "publicKeySignatureV2": keyPair.PublicKeySignatureV2, "expiresAt": expiresAtMillis, "refreshedAfter": keyPair.Refresh.UnixMilli(), } s.logger.Info("成功生成玩家证书", zap.String("uuid", uuid), ) return certificate, nil } // GetPublicKey 获取公钥 func (s *yggdrasilCertificateService) GetPublicKey(ctx context.Context) (string, error) { return s.signatureService.GetPublicKeyFromRedis() }