MCPcopy Create free account
hub / github.com/bytebase/bytebase / countRecentLoginFailures

Method countRecentLoginFailures

backend/api/v1/auth_service.go:779–819  ·  view source on GitHub ↗

countRecentLoginFailures counts the number of failed login attempts for a given email within the specified time window, matching any of the provided error messages.

(ctx context.Context, email string, window time.Duration, errMessages ...string)

Source from the content-addressed store, hash-verified

777// countRecentLoginFailures counts the number of failed login attempts for a given email
778// within the specified time window, matching any of the provided error messages.
779func (s *AuthService) countRecentLoginFailures(ctx context.Context, email string, window time.Duration, errMessages ...string) (int, error) {
780 if len(errMessages) == 0 {
781 return 0, errors.New("at least one error message is required")
782 }
783
784 windowStart := time.Now().Add(-window)
785
786 // Build filter query for login failures.
787 filterQ := qb.Q().Space("TRUE")
788 filterQ.And("payload->>'method' = ?", "/bytebase.v1.AuthService/Login")
789 filterQ.And("payload->>'resource' = ?", email)
790 filterQ.And("(payload->'status'->>'code')::int != 0")
791
792 // Build OR condition for error messages.
793 if len(errMessages) == 1 {
794 filterQ.And("payload->'status'->>'message' = ?", errMessages[0])
795 } else {
796 // For multiple messages, build: (msg = ? OR msg = ? OR ...)
797 orConditions := qb.Q()
798 for i, msg := range errMessages {
799 if i == 0 {
800 orConditions.Space("payload->'status'->>'message' = ?", msg)
801 } else {
802 orConditions.Or("payload->'status'->>'message' = ?", msg)
803 }
804 }
805 filterQ.And("(?)", orConditions)
806 }
807
808 filterQ.And("created_at >= ?", windowStart)
809
810 // Search across all workspaces — lockout is per-email, not per-workspace.
811 logs, err := s.store.SearchAuditLogs(ctx, &store.AuditLogFind{
812 FilterQ: filterQ,
813 })
814 if err != nil {
815 return 0, errors.Wrapf(err, "failed to search audit logs for login failures")
816 }
817
818 return len(logs), nil
819}
820
821// checkPasswordLockout checks if the user has exceeded the password failure rate limit.
822// Returns an error if the user is locked out due to too many failed password attempts.

Callers 2

checkPasswordLockoutMethod · 0.95
checkMFALockoutMethod · 0.95

Calls 5

QFunction · 0.92
SpaceMethod · 0.80
AndMethod · 0.80
OrMethod · 0.80
SearchAuditLogsMethod · 0.65

Tested by

no test coverage detected