Documentation
¶
Index ¶
- Constants
- Variables
- func GetRole(r *http.Request) (string, bool)
- func GetUserID(r *http.Request) (string, bool)
- func GetUsername(r *http.Request) (string, bool)
- func ManageContentCapability(postType string) string
- func NewCapabilityResolver(roles RoleCapabilities) kernel.CapabilityResolver
- func Principal(r *http.Request) (kernel.Principal, bool)
- func RequireCapability(resolve kernel.CapabilityResolver, capability string) func(http.Handler) http.Handler
- type APIKeyAuthMiddleware
- type APIKeyVerifier
- type AdminMiddleware
- type AuthMiddleware
- type CORSMiddleware
- type CSRFMiddleware
- type Capability
- type CommentatorMiddleware
- type NoCookieMiddleware
- type RateLimitMiddleware
- type RoleCapabilities
- type SecurityHeadersMiddleware
- type UserContext
- type UserLookup
Constants ¶
const ( UserIDKey contextKey = "user_id" UsernameKey contextKey = "username" RoleKey contextKey = "role" )
const ( RoleAdmin = constants.RoleAdmin RoleContributor = constants.RoleContributor RoleCommentator = constants.RoleCommentator )
Role constants for easy reference in middleware
const ( CapabilityAdmin = capability.CapabilityAdmin CapabilityMedia = capability.CapabilityMedia CapabilityComments = capability.CapabilityComments CapabilityPublishContent = capability.CapabilityPublishContent CapabilityManageContent = capability.CapabilityManageContent )
Variables ¶
var ( ErrMissingToken = errors.New("missing authorization token") ErrInvalidToken = errors.New("invalid authorization token") )
Functions ¶
func GetUsername ¶
GetUsername retrieves the username from the request context
func ManageContentCapability ¶ added in v1.0.0
ManageContentCapability builds the per-type manage capability.
func NewCapabilityResolver ¶ added in v1.0.0
func NewCapabilityResolver(roles RoleCapabilities) kernel.CapabilityResolver
NewCapabilityResolver builds the kernel resolver over the role registry. A principal is granted a capability when ANY of its roles grants it. Empty principals, unknown roles, and unknown capabilities all deny (fail closed). A nil registry yields a deny-all resolver.
func Principal ¶ added in v1.0.0
Principal retrieves the kernel identity from the request context. It is populated by both auth realms via newUserContext; ok is false on anonymous requests where no auth middleware ran.
func RequireCapability ¶ added in v1.0.0
func RequireCapability( resolve kernel.CapabilityResolver, capability string, ) func(http.Handler) http.Handler
RequireCapability enforces a capability on an already-authenticated request. Mount it after auth middleware: a missing principal, a nil resolver, or a denial all answer 403 INSUFFICIENT_PERMISSIONS, matching the RequireRole message so protected surfaces keep one denial shape.
Types ¶
type APIKeyAuthMiddleware ¶
type APIKeyAuthMiddleware struct {
// contains filtered or unexported fields
}
APIKeyAuthMiddleware authenticates Bearer API-key tokens and injects the owning user into request context using the SAME keys the JWT middleware uses (UserIDKey/UsernameKey/RoleKey via newUserContext), so downstream ctxUser lookups and RBAC are auth-agnostic (architecture Important gap #1). It is mounted onto the Bearer-only /api/v1 group by Story 2.1.
func NewAPIKeyAuthMiddleware ¶
func NewAPIKeyAuthMiddleware( verifier APIKeyVerifier, userLookup UserLookup, logger *util.Logger, ) *APIKeyAuthMiddleware
NewAPIKeyAuthMiddleware constructs the middleware. A nil logger degrades to a discard sink (mirrors NewNoCookieMiddleware) so the middleware is safe to construct in any context.
func (*APIKeyAuthMiddleware) Handler ¶
func (m *APIKeyAuthMiddleware) Handler(next http.Handler) http.Handler
Handler authenticates the request via Bearer API key and, on success, injects the owning user into context and delegates to next. On any failure it writes a 401 envelope with the correct code and does NOT call next.
type APIKeyVerifier ¶
type APIKeyVerifier interface {
Verify(ctx context.Context, fullKey string) (*apikey.APIKey, error)
UpdateLastUsed(ctx context.Context, id int, ip string) error
}
APIKeyVerifier is the narrow interface the middleware depends on for key verification. *apikey.Service satisfies it (Verify + UpdateLastUsed). Defined here — not in the domain — so the middleware owns its own seam and the domain stays HTTP-agnostic (mirrors the handlers.APIKeyService pattern).
type AdminMiddleware ¶
type AdminMiddleware struct {
// contains filtered or unexported fields
}
AdminMiddleware represents admin authorization middleware
func NewAdminMiddleware ¶
func NewAdminMiddleware(authMiddleware *AuthMiddleware) *AdminMiddleware
NewAdminMiddleware creates a new admin authorization middleware
func (*AdminMiddleware) AdminOnly ¶
func (m *AdminMiddleware) AdminOnly(next http.Handler) http.Handler
AdminOnly validates JWT token and checks if user has Admin role This is a convenience wrapper around RequireRole("Admin")
func (*AdminMiddleware) ModerationOnly ¶
func (m *AdminMiddleware) ModerationOnly(next http.Handler) http.Handler
ModerationOnly validates JWT token and checks if user has Admin role
type AuthMiddleware ¶
type AuthMiddleware struct {
// contains filtered or unexported fields
}
AuthMiddleware represents authentication middleware
func NewAuthMiddleware ¶
func NewAuthMiddleware(jwtManager *auth.JWTManager) *AuthMiddleware
NewAuthMiddleware creates a new authentication middleware
func (*AuthMiddleware) OptionalAuth ¶
func (m *AuthMiddleware) OptionalAuth(next http.Handler) http.Handler
OptionalAuth validates JWT token if present, but doesn't require it Adds user context if token is valid, otherwise continues without user context
func (*AuthMiddleware) RequireAuth ¶
func (m *AuthMiddleware) RequireAuth(next http.Handler) http.Handler
RequireAuth validates JWT token and adds user context to request
func (*AuthMiddleware) RequireRole ¶
RequireRole validates JWT token and checks if user has required role
type CORSMiddleware ¶
type CORSMiddleware struct {
// contains filtered or unexported fields
}
func NewCORSMiddleware ¶
func NewCORSMiddleware(allowedOrigins []string, logger *util.Logger) *CORSMiddleware
type CSRFMiddleware ¶
type CSRFMiddleware struct {
// contains filtered or unexported fields
}
func NewCSRFMiddleware ¶
func NewCSRFMiddleware( logger *util.Logger, trustedOrigins []string, jwtManager *auth.JWTManager, ) *CSRFMiddleware
type Capability ¶ added in v1.0.0
type Capability = capability.Capability
Capability names a permission the kernel resolver decides. It aliases the kernel vocabulary (kernel/capability) so existing references keep working; new code should import kernel/capability directly.
type CommentatorMiddleware ¶
type CommentatorMiddleware struct {
// contains filtered or unexported fields
}
CommentatorMiddleware handles authorization for Commentator role
func NewCommentatorMiddleware ¶
func NewCommentatorMiddleware(authMiddleware *AuthMiddleware) *CommentatorMiddleware
NewCommentatorMiddleware creates a new commentator authorization middleware
func (*CommentatorMiddleware) CommentatorOnly ¶
func (m *CommentatorMiddleware) CommentatorOnly(next http.Handler) http.Handler
CommentatorOnly validates JWT token and checks if user has Commentator (or higher) role Commentators can view published content and submit comments, but cannot access admin features
type NoCookieMiddleware ¶
type NoCookieMiddleware struct {
// contains filtered or unexported fields
}
func NewNoCookieMiddleware ¶
func NewNoCookieMiddleware(logger *util.Logger) *NoCookieMiddleware
type RateLimitMiddleware ¶
type RateLimitMiddleware struct {
// contains filtered or unexported fields
}
func NewRateLimitMiddleware ¶
func NewRateLimitMiddleware( enabled bool, authPerMinute, apiPerMinute, publicPerMinute int, ) *RateLimitMiddleware
func (*RateLimitMiddleware) APIKeyHandler ¶
func (m *RateLimitMiddleware) APIKeyHandler(next http.Handler) http.Handler
APIKeyHandler rate-limits the Bearer /api/v1 group per API key (via keyByAPIKeyOrIP), reusing the existing apiPerMinute limit and 1-minute window. It emits the v1 RATE_LIMITED envelope code when the budget is exhausted. When the middleware is disabled it passes through (matching Handler/AuthHandler/PublicHandler).
func (*RateLimitMiddleware) AuthHandler ¶
func (m *RateLimitMiddleware) AuthHandler(next http.Handler) http.Handler
func (*RateLimitMiddleware) Handler ¶
func (m *RateLimitMiddleware) Handler(next http.Handler) http.Handler
func (*RateLimitMiddleware) PublicHandler ¶
func (m *RateLimitMiddleware) PublicHandler(next http.Handler) http.Handler
type RoleCapabilities ¶ added in v1.0.0
type RoleCapabilities interface {
IsAdmin(name string) bool
CanPublish(name string) bool
CanMedia(name string) bool
CanComment(name string) bool
CanManageType(name, postTypeSlug string) bool
}
RoleCapabilities is the narrow interface the resolver depends on for role lookups. *role.Service satisfies it. Defined here — not in the domain — so the middleware owns its own seam and the domain stays HTTP-agnostic (mirrors the APIKeyVerifier pattern).
type SecurityHeadersMiddleware ¶ added in v0.7.0
type SecurityHeadersMiddleware struct {
// contains filtered or unexported fields
}
func NewSecurityHeadersMiddleware ¶ added in v0.7.0
func NewSecurityHeadersMiddleware(cspHeaderName, cspHeaderValue, xFrameOptions string) *SecurityHeadersMiddleware
type UserContext ¶
UserContext represents user information stored in request context
type UserLookup ¶
type UserLookup interface {
GetUserByID(ctx context.Context, userID int) (*userdomain.User, error)
}
UserLookup is the narrow interface for resolving the owning user. The middleware needs only GetUserByID. repository.UserRepo satisfies it.