This commit is contained in:
2025-08-23 23:15:30 -04:00
parent e5bccc85c2
commit 02323a8b5c
7 changed files with 305 additions and 77 deletions

View File

@ -49,39 +49,46 @@ func (hv *HeaderValidator) ValidateAuthenticationHeaders(r *http.Request) (*Vali
return nil, errors.NewAuthenticationError("User authentication required")
}
if timestamp == "" || signature == "" {
hv.logger.Warn("Missing authentication signature headers",
// In development mode, skip signature validation for trusted headers
if hv.config.IsDevelopment() {
hv.logger.Debug("Development mode: skipping signature validation",
zap.String("user_email", userEmail))
return nil, errors.NewAuthenticationError("Authentication signature required")
}
} else {
// Production mode: require full signature validation
if timestamp == "" || signature == "" {
hv.logger.Warn("Missing authentication signature headers",
zap.String("user_email", userEmail))
return nil, errors.NewAuthenticationError("Authentication signature required")
}
// Validate timestamp (prevent replay attacks)
timestampInt, err := strconv.ParseInt(timestamp, 10, 64)
if err != nil {
hv.logger.Warn("Invalid timestamp format",
zap.String("timestamp", timestamp),
zap.String("user_email", userEmail))
return nil, errors.NewAuthenticationError("Invalid timestamp format")
}
// Validate timestamp (prevent replay attacks)
timestampInt, err := strconv.ParseInt(timestamp, 10, 64)
if err != nil {
hv.logger.Warn("Invalid timestamp format",
zap.String("timestamp", timestamp),
zap.String("user_email", userEmail))
return nil, errors.NewAuthenticationError("Invalid timestamp format")
}
timestampTime := time.Unix(timestampInt, 0)
now := time.Now()
// Allow 5 minutes clock skew
maxAge := 5 * time.Minute
if now.Sub(timestampTime) > maxAge || timestampTime.After(now.Add(1*time.Minute)) {
hv.logger.Warn("Timestamp outside acceptable window",
zap.Time("timestamp", timestampTime),
zap.Time("now", now),
zap.String("user_email", userEmail))
return nil, errors.NewAuthenticationError("Request timestamp outside acceptable window")
}
timestampTime := time.Unix(timestampInt, 0)
now := time.Now()
// Allow 5 minutes clock skew
maxAge := 5 * time.Minute
if now.Sub(timestampTime) > maxAge || timestampTime.After(now.Add(1*time.Minute)) {
hv.logger.Warn("Timestamp outside acceptable window",
zap.Time("timestamp", timestampTime),
zap.Time("now", now),
zap.String("user_email", userEmail))
return nil, errors.NewAuthenticationError("Request timestamp outside acceptable window")
}
// Validate HMAC signature
if !hv.validateSignature(userEmail, timestamp, signature) {
hv.logger.Warn("Invalid authentication signature",
zap.String("user_email", userEmail))
return nil, errors.NewAuthenticationError("Invalid authentication signature")
// Validate HMAC signature
if !hv.validateSignature(userEmail, timestamp, signature) {
hv.logger.Warn("Invalid authentication signature",
zap.String("user_email", userEmail))
return nil, errors.NewAuthenticationError("Invalid authentication signature")
}
}
// Validate email format
@ -94,11 +101,24 @@ func (hv *HeaderValidator) ValidateAuthenticationHeaders(r *http.Request) (*Vali
hv.logger.Debug("Authentication headers validated successfully",
zap.String("user_email", userEmail))
// Set defaults for development mode
var timestampTime time.Time
var signatureValue string
if hv.config.IsDevelopment() {
timestampTime = time.Now()
signatureValue = "dev-mode-bypass"
} else {
timestampInt, _ := strconv.ParseInt(timestamp, 10, 64)
timestampTime = time.Unix(timestampInt, 0)
signatureValue = signature
}
return &ValidatedUserContext{
UserID: userEmail,
Email: userEmail,
Timestamp: timestampTime,
Signature: signature,
Signature: signatureValue,
}, nil
}