Some checks failed
check / check (push) Superseded by a newer commit; never tested
146 lines
4.1 KiB
Go
146 lines
4.1 KiB
Go
package middleware
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"time"
|
|
|
|
httpmetrics "github.com/slok/go-http-metrics/metrics"
|
|
)
|
|
|
|
// MetricsMiddlewareForTest builds the metrics recording middleware
|
|
// against a caller-supplied recorder, so a test can gather from its
|
|
// own Prometheus registry rather than the process-wide default one
|
|
// that Middleware.Metrics uses.
|
|
func MetricsMiddlewareForTest(
|
|
rec httpmetrics.Recorder,
|
|
) func(http.Handler) http.Handler {
|
|
return metricsMiddleware(rec)
|
|
}
|
|
|
|
// UnmatchedRouteConst exposes the sentinel that stands in for a
|
|
// request matching no route pattern.
|
|
const UnmatchedRouteConst = unmatchedRoute
|
|
|
|
// InflightHandlerConst exposes the fixed handler label on the
|
|
// inflight gauge.
|
|
const InflightHandlerConst = inflightHandler
|
|
|
|
// NewLoggingResponseWriterForTest wraps newLoggingResponseWriter
|
|
// for use in external test packages.
|
|
func NewLoggingResponseWriterForTest(
|
|
w http.ResponseWriter,
|
|
) *loggingResponseWriter {
|
|
return newLoggingResponseWriter(w)
|
|
}
|
|
|
|
// LoggingResponseWriterStatusCode returns the status code
|
|
// captured by the loggingResponseWriter.
|
|
func LoggingResponseWriterStatusCode(
|
|
lrw *loggingResponseWriter,
|
|
) int {
|
|
return lrw.statusCode
|
|
}
|
|
|
|
// IPFromHostPort exposes ipFromHostPort for testing.
|
|
func IPFromHostPort(hp string) string {
|
|
return ipFromHostPort(hp)
|
|
}
|
|
|
|
// ClientKeyForTest exposes clientKey for testing.
|
|
func ClientKeyForTest(m *Middleware, r *http.Request) string {
|
|
return m.clientKey(r)
|
|
}
|
|
|
|
// IsClientTLS exposes isClientTLS for testing.
|
|
func IsClientTLS(r *http.Request) bool {
|
|
return isClientTLS(r)
|
|
}
|
|
|
|
// LoginRateLimitConst exposes the loginRateLimit constant: the
|
|
// number of FAILED login attempts one client may make against one
|
|
// submitted username per interval.
|
|
const LoginRateLimitConst = loginRateLimit
|
|
|
|
// LoginFailureMaxKeysConst exposes the cap on each of the login
|
|
// guard's key sets.
|
|
const LoginFailureMaxKeysConst = loginFailureMaxKeys
|
|
|
|
// PasswordVerifyConcurrencyConst exposes the bound on concurrent
|
|
// Argon2id verifications.
|
|
const PasswordVerifyConcurrencyConst = passwordVerifyConcurrency
|
|
|
|
// PasswordVerifyMaxWaitersConst exposes the bound on how many
|
|
// requests may queue for a verification slot.
|
|
const PasswordVerifyMaxWaitersConst = passwordVerifyMaxWaiters
|
|
|
|
// LoginGuard is the login failure counter and verification
|
|
// semaphore, exposed for direct testing.
|
|
type LoginGuard = loginGuard
|
|
|
|
// NewLoginGuardForTest builds a guard with test-sized parameters.
|
|
func NewLoginGuardForTest(
|
|
limit int,
|
|
interval time.Duration,
|
|
maxKeys, concurrency, maxWaiters int,
|
|
wait time.Duration,
|
|
) *LoginGuard {
|
|
return newLoginGuard(
|
|
limit, interval, maxKeys, concurrency, maxWaiters, wait,
|
|
)
|
|
}
|
|
|
|
// QueuedWaitersForTest reports how many requests are currently
|
|
// queued for a verification slot.
|
|
func (g *LoginGuard) QueuedWaitersForTest() int {
|
|
return len(g.queue)
|
|
}
|
|
|
|
// SetNowForTest replaces the guard's clock.
|
|
func (g *LoginGuard) SetNowForTest(now func() time.Time) {
|
|
g.mu.Lock()
|
|
defer g.mu.Unlock()
|
|
|
|
g.now = now
|
|
}
|
|
|
|
// FailForTest exposes fail.
|
|
func (g *LoginGuard) FailForTest(clientKey, username string) bool {
|
|
return g.fail(clientKey, username)
|
|
}
|
|
|
|
// SucceedForTest exposes succeed.
|
|
func (g *LoginGuard) SucceedForTest(clientKey, username string) {
|
|
g.succeed(clientKey, username)
|
|
}
|
|
|
|
// AcquireForTest exposes acquire.
|
|
func (g *LoginGuard) AcquireForTest(
|
|
ctx context.Context,
|
|
) (func(), bool) {
|
|
return g.acquire(ctx)
|
|
}
|
|
|
|
// TrackedKeysForTest reports how many failure counters the guard
|
|
// holds, per-username and per-address respectively.
|
|
func (g *LoginGuard) TrackedKeysForTest() (int, int) {
|
|
g.mu.Lock()
|
|
defer g.mu.Unlock()
|
|
|
|
return len(g.byUser), len(g.byAddr)
|
|
}
|
|
|
|
// PasswordChangeRateLimitConst exposes the
|
|
// passwordChangeRateLimit constant.
|
|
const PasswordChangeRateLimitConst = passwordChangeRateLimit
|
|
|
|
// ReceiverAggregateMultiplierConst exposes the
|
|
// receiverAggregateMultiplier constant.
|
|
const ReceiverAggregateMultiplierConst = receiverAggregateMultiplier
|
|
|
|
// ReceiverAggregateLimitForTest exposes receiverAggregateLimit for
|
|
// testing.
|
|
func ReceiverAggregateLimitForTest(perEntrypoint int) int {
|
|
return receiverAggregateLimit(perEntrypoint)
|
|
}
|