Fix grpcserver rate limiter: move to Server field

The package-level defaultRateLimiter drained its token bucket
across all test cases, causing later tests to hit ResourceExhausted.
Move rateLimiter from a package-level var to a *grpcRateLimiter field
on Server; New() allocates a fresh instance (10 req/s, burst 10) per
server. Each test's newTestEnv() constructs its own Server, so tests
no longer share limiter state.

Production behaviour is unchanged: a single Server is constructed at
startup and lives for the process lifetime.
This commit is contained in:
2026-03-11 19:20:32 -07:00
parent a80242ae3e
commit 4596ea08ab
12 changed files with 276 additions and 123 deletions

View File

@@ -836,6 +836,51 @@ func (db *DB) ListAuditEventsPaged(p AuditQueryParams) ([]*AuditEventView, int64
return events, total, nil
}
// GetAuditEventByID fetches a single audit event by its integer primary key,
// with actor/target usernames resolved via LEFT JOIN. Returns ErrNotFound if
// no row matches.
func (db *DB) GetAuditEventByID(id int64) (*AuditEventView, error) {
row := db.sql.QueryRow(`
SELECT al.id, al.event_time, al.event_type,
al.actor_id, al.target_id,
al.ip_address, al.details,
COALESCE(a1.username, ''), COALESCE(a2.username, '')
FROM audit_log al
LEFT JOIN accounts a1 ON al.actor_id = a1.id
LEFT JOIN accounts a2 ON al.target_id = a2.id
WHERE al.id = ?
`, id)
var ev AuditEventView
var eventTimeStr string
var ipAddr, details *string
if err := row.Scan(
&ev.ID, &eventTimeStr, &ev.EventType,
&ev.ActorID, &ev.TargetID,
&ipAddr, &details,
&ev.ActorUsername, &ev.TargetUsername,
); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, ErrNotFound
}
return nil, fmt.Errorf("db: get audit event %d: %w", id, err)
}
var err error
ev.EventTime, err = parseTime(eventTimeStr)
if err != nil {
return nil, err
}
if ipAddr != nil {
ev.IPAddress = *ipAddr
}
if details != nil {
ev.Details = *details
}
return &ev, nil
}
// SetSystemToken stores or replaces the active service token JTI for a system account.
func (db *DB) SetSystemToken(accountID int64, jti string, expiresAt time.Time) error {
n := now()