fix: enhance Validate method to support environment token as fallback for emergency token validation
This commit is contained in:
@@ -147,34 +147,42 @@ func (s *EmergencyTokenService) Validate(token string) (*models.EmergencyToken,
|
||||
return nil, fmt.Errorf("token is empty")
|
||||
}
|
||||
|
||||
envToken := os.Getenv(EmergencyTokenEnvVar)
|
||||
hasValidEnvToken := envToken != "" && len(strings.TrimSpace(envToken)) >= MinTokenLength
|
||||
|
||||
// Try database token first (highest priority)
|
||||
var tokenRecord models.EmergencyToken
|
||||
err := s.db.First(&tokenRecord).Error
|
||||
if err == nil {
|
||||
// Found database token - validate hash
|
||||
tokenHash := sha256.Sum256([]byte(token))
|
||||
if bcrypt.CompareHashAndPassword([]byte(tokenRecord.TokenHash), tokenHash[:]) != nil {
|
||||
return nil, fmt.Errorf("invalid token")
|
||||
if bcrypt.CompareHashAndPassword([]byte(tokenRecord.TokenHash), tokenHash[:]) == nil {
|
||||
// Check expiration
|
||||
if tokenRecord.IsExpired() {
|
||||
return nil, fmt.Errorf("token expired")
|
||||
}
|
||||
|
||||
// Update last used timestamp and use count
|
||||
now := time.Now()
|
||||
tokenRecord.LastUsedAt = &now
|
||||
tokenRecord.UseCount++
|
||||
if err := s.db.Save(&tokenRecord).Error; err != nil {
|
||||
logger.Log().WithError(err).Warn("Failed to update token usage statistics")
|
||||
}
|
||||
|
||||
return &tokenRecord, nil
|
||||
}
|
||||
|
||||
// Check expiration
|
||||
if tokenRecord.IsExpired() {
|
||||
return nil, fmt.Errorf("token expired")
|
||||
// If DB token doesn't match, allow explicit environment token as break-glass fallback.
|
||||
if hasValidEnvToken && envToken == token {
|
||||
logger.Log().Debug("Emergency token validated from environment variable while database token exists")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Update last used timestamp and use count
|
||||
now := time.Now()
|
||||
tokenRecord.LastUsedAt = &now
|
||||
tokenRecord.UseCount++
|
||||
if err := s.db.Save(&tokenRecord).Error; err != nil {
|
||||
logger.Log().WithError(err).Warn("Failed to update token usage statistics")
|
||||
}
|
||||
|
||||
return &tokenRecord, nil
|
||||
return nil, fmt.Errorf("invalid token")
|
||||
}
|
||||
|
||||
// Fallback to environment variable for backward compatibility
|
||||
envToken := os.Getenv(EmergencyTokenEnvVar)
|
||||
if envToken == "" || len(strings.TrimSpace(envToken)) == 0 {
|
||||
return nil, fmt.Errorf("no token configured")
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ func TestEmergencyTokenService_Validate_EnvironmentFallback(t *testing.T) {
|
||||
assert.Nil(t, tokenRecord, "Env var tokens return nil record")
|
||||
}
|
||||
|
||||
func TestEmergencyTokenService_Validate_DatabaseTakesPrecedence(t *testing.T) {
|
||||
func TestEmergencyTokenService_Validate_EnvironmentBreakGlassFallback(t *testing.T) {
|
||||
db := setupEmergencyTokenTestDB(t)
|
||||
svc := NewEmergencyTokenService(db)
|
||||
|
||||
@@ -239,9 +239,9 @@ func TestEmergencyTokenService_Validate_DatabaseTakesPrecedence(t *testing.T) {
|
||||
_, err = svc.Validate(dbResp.Token)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Environment token should NOT validate (database takes precedence)
|
||||
// Environment token should still validate as break-glass fallback
|
||||
_, err = svc.Validate(envToken)
|
||||
assert.Error(t, err)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestEmergencyTokenService_GetStatus(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user