package authmw import ( "net/http" "code.nochebuena.dev/einherjar/contracts/logging" "code.nochebuena.dev/einherjar/contracts/security" "code.nochebuena.dev/einherjar/core/xerrors" "code.nochebuena.dev/einherjar/web/httputil" ) // AuthzMiddleware gates the request against a single required permission on a named resource. // Returns 401 if no identity is in context; 403 if the permission check fails or the // provider returns an error (fail-closed: provider failure denies access). func AuthzMiddleware(logger logging.Logger, provider security.PermissionProvider, resource string, required security.Permission) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { identity, ok := security.FromContext(r.Context()) if !ok { httputil.Error(logger, w, r, xerrors.Unauthorized("missing identity")) return } mask, err := provider.ResolveMask(r.Context(), identity.UID, resource) if err != nil { httputil.Error(logger, w, r, xerrors.PermissionDenied("permission check failed").WithError(err)) return } if !mask.Has(required) { httputil.Error(logger, w, r, xerrors.PermissionDenied("insufficient permissions")) return } next.ServeHTTP(w, r) }) } }