package storage import ( "context" "time" ) // LoginAttempt represents a deduplicated login attempt. type LoginAttempt struct { ID int64 Username string Password string IP string Count int FirstSeen time.Time LastSeen time.Time } // Session represents an authenticated SSH session. type Session struct { ID string IP string Username string ShellName string ConnectedAt time.Time DisconnectedAt *time.Time HumanScore *float64 } // SessionLog represents a single log entry for a session. type SessionLog struct { ID int64 SessionID string Timestamp time.Time Input string Output string } // DashboardStats holds aggregate counts for the web dashboard. type DashboardStats struct { TotalAttempts int64 UniqueIPs int64 TotalSessions int64 ActiveSessions int64 } // TopEntry represents a value and its count for top-N queries. type TopEntry struct { Value string Count int64 } // Store is the interface for persistent storage of honeypot data. type Store interface { // RecordLoginAttempt upserts a login attempt, incrementing the count // for existing (username, password, ip) combinations. RecordLoginAttempt(ctx context.Context, username, password, ip string) error // CreateSession creates a new session record and returns its UUID. CreateSession(ctx context.Context, ip, username, shellName string) (string, error) // EndSession sets the disconnected_at timestamp for a session. EndSession(ctx context.Context, sessionID string, disconnectedAt time.Time) error // UpdateHumanScore sets the human detection score for a session. UpdateHumanScore(ctx context.Context, sessionID string, score float64) error // AppendSessionLog adds a log entry to a session. AppendSessionLog(ctx context.Context, sessionID, input, output string) error // DeleteRecordsBefore removes all records older than the given cutoff // and returns the total number of deleted rows. DeleteRecordsBefore(ctx context.Context, cutoff time.Time) (int64, error) // GetDashboardStats returns aggregate counts for the dashboard. GetDashboardStats(ctx context.Context) (*DashboardStats, error) // GetTopUsernames returns the top N usernames by total attempt count. GetTopUsernames(ctx context.Context, limit int) ([]TopEntry, error) // GetTopPasswords returns the top N passwords by total attempt count. GetTopPasswords(ctx context.Context, limit int) ([]TopEntry, error) // GetTopIPs returns the top N IPs by total attempt count. GetTopIPs(ctx context.Context, limit int) ([]TopEntry, error) // GetRecentSessions returns the most recent sessions ordered by connected_at DESC. // If activeOnly is true, only sessions with no disconnected_at are returned. GetRecentSessions(ctx context.Context, limit int, activeOnly bool) ([]Session, error) // Close releases any resources held by the store. Close() error }