Initial commit: Open sourcing all of the Maple Open Technologies code.
This commit is contained in:
commit
755d54a99d
2010 changed files with 448675 additions and 0 deletions
|
|
@ -0,0 +1,177 @@
|
|||
// File Path: monorepo/cloud/maplepress-backend/internal/service/securityevent/logger.go
|
||||
package securityevent
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/domain/securityevent"
|
||||
)
|
||||
|
||||
// Logger handles logging of security events
|
||||
// CWE-778: Ensures sufficient logging of security events for audit and forensics
|
||||
type Logger interface {
|
||||
// LogEvent logs a security event
|
||||
LogEvent(ctx context.Context, event *securityevent.SecurityEvent) error
|
||||
|
||||
// LogAccountLocked logs an account lockout event
|
||||
LogAccountLocked(ctx context.Context, emailHash, clientIP string, failedAttempts int, lockoutDuration string) error
|
||||
|
||||
// LogAccountUnlocked logs an account unlock event
|
||||
LogAccountUnlocked(ctx context.Context, emailHash, unlockedBy string) error
|
||||
|
||||
// LogFailedLogin logs a failed login attempt
|
||||
LogFailedLogin(ctx context.Context, emailHash, clientIP string, remainingAttempts int) error
|
||||
|
||||
// LogExcessiveFailedLogin logs excessive failed login attempts
|
||||
LogExcessiveFailedLogin(ctx context.Context, emailHash, clientIP string, attemptCount int) error
|
||||
|
||||
// LogSuccessfulLogin logs a successful login
|
||||
LogSuccessfulLogin(ctx context.Context, emailHash, clientIP string) error
|
||||
|
||||
// LogIPRateLimitExceeded logs IP rate limit exceeded
|
||||
LogIPRateLimitExceeded(ctx context.Context, clientIP string) error
|
||||
}
|
||||
|
||||
type securityEventLogger struct {
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
// NewSecurityEventLogger creates a new security event logger
|
||||
func NewSecurityEventLogger(logger *zap.Logger) Logger {
|
||||
return &securityEventLogger{
|
||||
logger: logger.Named("security-events"),
|
||||
}
|
||||
}
|
||||
|
||||
// ProvideSecurityEventLogger provides a SecurityEventLogger for dependency injection
|
||||
func ProvideSecurityEventLogger(logger *zap.Logger) Logger {
|
||||
return NewSecurityEventLogger(logger)
|
||||
}
|
||||
|
||||
// LogEvent logs a security event
|
||||
func (s *securityEventLogger) LogEvent(ctx context.Context, event *securityevent.SecurityEvent) error {
|
||||
// Map severity to log level
|
||||
logFunc := s.logger.Info
|
||||
switch event.Severity {
|
||||
case securityevent.SeverityLow:
|
||||
logFunc = s.logger.Info
|
||||
case securityevent.SeverityMedium:
|
||||
logFunc = s.logger.Warn
|
||||
case securityevent.SeverityHigh, securityevent.SeverityCritical:
|
||||
logFunc = s.logger.Error
|
||||
}
|
||||
|
||||
// Build log fields
|
||||
fields := []zap.Field{
|
||||
zap.String("event_id", event.ID),
|
||||
zap.String("event_type", string(event.EventType)),
|
||||
zap.String("severity", string(event.Severity)),
|
||||
zap.String("email_hash", event.EmailHash),
|
||||
zap.String("client_ip", event.ClientIP),
|
||||
zap.Time("timestamp", event.Timestamp),
|
||||
}
|
||||
|
||||
if event.UserAgent != "" {
|
||||
fields = append(fields, zap.String("user_agent", event.UserAgent))
|
||||
}
|
||||
|
||||
// Add metadata fields
|
||||
for key, value := range event.Metadata {
|
||||
fields = append(fields, zap.Any(key, value))
|
||||
}
|
||||
|
||||
logFunc(event.Message, fields...)
|
||||
|
||||
// TODO: In production, also persist to a security event database/SIEM
|
||||
// This could be implemented as a repository pattern:
|
||||
// - Store in Cassandra for long-term retention
|
||||
// - Send to SIEM (Splunk, ELK, etc.) for analysis
|
||||
// - Send to monitoring/alerting system
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// LogAccountLocked logs an account lockout event
|
||||
func (s *securityEventLogger) LogAccountLocked(ctx context.Context, emailHash, clientIP string, failedAttempts int, lockoutDuration string) error {
|
||||
event := securityevent.NewSecurityEvent(
|
||||
securityevent.EventTypeAccountLocked,
|
||||
securityevent.SeverityHigh,
|
||||
emailHash,
|
||||
clientIP,
|
||||
"Account locked due to excessive failed login attempts",
|
||||
)
|
||||
event.WithMetadata("failed_attempts", failedAttempts)
|
||||
event.WithMetadata("lockout_duration", lockoutDuration)
|
||||
|
||||
return s.LogEvent(ctx, event)
|
||||
}
|
||||
|
||||
// LogAccountUnlocked logs an account unlock event
|
||||
func (s *securityEventLogger) LogAccountUnlocked(ctx context.Context, emailHash, unlockedBy string) error {
|
||||
event := securityevent.NewSecurityEvent(
|
||||
securityevent.EventTypeAccountUnlocked,
|
||||
securityevent.SeverityMedium,
|
||||
emailHash,
|
||||
"",
|
||||
"Account manually unlocked by administrator",
|
||||
)
|
||||
event.WithMetadata("unlocked_by", unlockedBy)
|
||||
|
||||
return s.LogEvent(ctx, event)
|
||||
}
|
||||
|
||||
// LogFailedLogin logs a failed login attempt
|
||||
func (s *securityEventLogger) LogFailedLogin(ctx context.Context, emailHash, clientIP string, remainingAttempts int) error {
|
||||
event := securityevent.NewSecurityEvent(
|
||||
securityevent.EventTypeFailedLogin,
|
||||
securityevent.SeverityMedium,
|
||||
emailHash,
|
||||
clientIP,
|
||||
"Failed login attempt - invalid credentials",
|
||||
)
|
||||
event.WithMetadata("remaining_attempts", remainingAttempts)
|
||||
|
||||
return s.LogEvent(ctx, event)
|
||||
}
|
||||
|
||||
// LogExcessiveFailedLogin logs excessive failed login attempts
|
||||
func (s *securityEventLogger) LogExcessiveFailedLogin(ctx context.Context, emailHash, clientIP string, attemptCount int) error {
|
||||
event := securityevent.NewSecurityEvent(
|
||||
securityevent.EventTypeExcessiveFailedLogin,
|
||||
securityevent.SeverityHigh,
|
||||
emailHash,
|
||||
clientIP,
|
||||
"Excessive failed login attempts detected",
|
||||
)
|
||||
event.WithMetadata("attempt_count", attemptCount)
|
||||
|
||||
return s.LogEvent(ctx, event)
|
||||
}
|
||||
|
||||
// LogSuccessfulLogin logs a successful login
|
||||
func (s *securityEventLogger) LogSuccessfulLogin(ctx context.Context, emailHash, clientIP string) error {
|
||||
event := securityevent.NewSecurityEvent(
|
||||
securityevent.EventTypeSuccessfulLogin,
|
||||
securityevent.SeverityLow,
|
||||
emailHash,
|
||||
clientIP,
|
||||
"Successful login",
|
||||
)
|
||||
|
||||
return s.LogEvent(ctx, event)
|
||||
}
|
||||
|
||||
// LogIPRateLimitExceeded logs IP rate limit exceeded
|
||||
func (s *securityEventLogger) LogIPRateLimitExceeded(ctx context.Context, clientIP string) error {
|
||||
event := securityevent.NewSecurityEvent(
|
||||
securityevent.EventTypeIPRateLimitExceeded,
|
||||
securityevent.SeverityMedium,
|
||||
"",
|
||||
clientIP,
|
||||
"IP rate limit exceeded for login attempts",
|
||||
)
|
||||
|
||||
return s.LogEvent(ctx, event)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue