Documentation
¶
Index ¶
- Constants
- func Auth(resolver KeyResolver) func(http.Handler) http.Handler
- func Chain(mws ...func(http.Handler) http.Handler) func(http.Handler) http.Handler
- func Logging(logger *slog.Logger) func(http.Handler) http.Handler
- func MaxBody(maxBytes int64) func(http.Handler) http.Handler
- func Recovery(logger *slog.Logger) func(http.Handler) http.Handler
- func RequestID(next http.Handler) http.Handler
- func Scope() func(http.Handler) http.Handler
- func Workspace() func(http.Handler) http.Handler
- type DevKeyResolver
- type KeyResolver
Constants ¶
const DefaultMaxBodyBytes int64 = 1 << 20
DefaultMaxBodyBytes caps request bodies at 1 MiB by default.
Variables ¶
This section is empty.
Functions ¶
func Auth ¶
func Auth(resolver KeyResolver) func(http.Handler) http.Handler
Auth enforces bearer-token authentication using the given resolver. On success, attaches the resolved workspace ID to the request context. Skips /healthz so probes always succeed regardless of auth state.
func Chain ¶
Chain composes middleware left-to-right so the leftmost wraps outermost: Chain(A, B, C)(h) runs A(B(C(h))).
func Logging ¶
Logging emits one structured log line per request with method, path, status, duration, and request ID. Skips /healthz to avoid probe spam.
func MaxBody ¶
MaxBody caps the request body at maxBytes. Writes past the cap fail with http.ErrBodyReadAfterClose. 0 disables the cap.
func Recovery ¶
Recovery catches panics from downstream handlers, logs the panic + stack trace via slog, and returns a 500 with a structured error envelope. Placed outermost so it catches panics in other middleware.
func RequestID ¶
RequestID honors an inbound X-Request-Id header or mints a new UUID. The value is stamped on the response header and stored in the request context for downstream access via reqctx.GetRequestID(ctx).
func Scope ¶
Scope reads optional X-Brainjar-Project and X-Brainjar-Session headers, validates them as slugs, and attaches them to the context. Empty headers are fine — handlers that need them enforce presence.
Types ¶
type DevKeyResolver ¶
type DevKeyResolver struct {
Key string
WorkspaceID models.WorkspaceID
}
DevKeyResolver accepts a single hardcoded API key and resolves it to a fixed workspace. Meant for local dev and integration tests only; real auth lands in M6 via ApiKeyApp.
func DevKeyResolverFromEnv ¶
func DevKeyResolverFromEnv(defaultWorkspace models.WorkspaceID) *DevKeyResolver
DevKeyResolverFromEnv builds a DevKeyResolver from the environment. BRAINJAR_DEV_API_KEY holds the plaintext key; defaultWorkspace is the workspace the key resolves to. Returns a resolver that always fails when the env var is unset.
func (*DevKeyResolver) Resolve ¶
func (r *DevKeyResolver) Resolve(_ context.Context, plaintext string) (models.WorkspaceID, error)
Resolve implements KeyResolver. Returns Unauthorized for any key other than r.Key, or when r.Key is empty (no dev key configured).
type KeyResolver ¶
type KeyResolver interface {
Resolve(ctx context.Context, plaintext string) (models.WorkspaceID, error)
}
KeyResolver resolves a plaintext API key to its workspace. M6 plugs in ApiKeyApp.Resolve; until then, DevKeyResolver covers integration testing.