package services import ( "cmii-uav-watchdog-common/models" "errors" "log" "time" ) // HeartbeatService 心跳服务 type HeartbeatService struct { authService *AuthService totpService *TOTPService } // NewHeartbeatService 创建心跳服务 func NewHeartbeatService() *HeartbeatService { return &HeartbeatService{ authService: NewAuthService(), totpService: NewTOTPService(), } } // ProcessHeartbeat 处理心跳请求 func (hs *HeartbeatService) ProcessHeartbeat(req models.HeartbeatRequest) (*models.HeartbeatResponse, error) { // 检查时间戳是否有效 if !hs.isTimestampValid(req.Timestamp) { return nil, errors.New("无效的时间戳") } secondTOTPSecret := hs.authService.authorizationInfo.SecondTOTPSecret if secondTOTPSecret == "" { return nil, errors.New("二级TOTP密钥为空") } // 添加主机信息到集合 hs.authService.AddHostInfo(req.HostInfo) // 检查是否携带totp,如果为空立即返回 if req.TOTPCode == "" { return &models.HeartbeatResponse{ Authorized: false, TOTPCode: "", Timestamp: time.Now().Unix(), SecondTOTPSecret: secondTOTPSecret, }, nil } // 检查totp验证码是否有效 if !hs.totpService.VerifyTierTwoTOTPCode(req.TOTPCode, secondTOTPSecret) { // 解析认证主机的相关信息 // 计算 请求时间与当前时间的时间差 diff := time.Now().Unix() - req.Timestamp log.Printf("心跳请求时间与当前时间的时间差: %d", diff) return nil, errors.New("无效的TOTP验证码,请检查系统时间是否正确!") } // 检查主机是否已授权 authorized := hs.authService.IsHostAuthorized(req.HostInfo) // 生成TOTP验证码 totpCode, err := hs.totpService.GenerateTierTwoTOTPCode(secondTOTPSecret) if err != nil { return nil, err } // 返回心跳响应 return &models.HeartbeatResponse{ Authorized: authorized, TOTPCode: totpCode, Timestamp: time.Now().Unix(), }, nil } // isTimestampValid 检查时间戳是否有效 func (hs *HeartbeatService) isTimestampValid(timestamp int64) bool { now := time.Now().Unix() diff := now - timestamp // 允许5分钟的时间偏差 return diff < 300 && diff > -300 }