// codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/interface/http/middleware/middleware.go package middleware import ( "context" "net/http" uc_user "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/usecase/user" "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/security/jwt" "go.uber.org/zap" ) type Middleware interface { Attach(fn http.HandlerFunc) http.HandlerFunc Shutdown(ctx context.Context) } type middleware struct { logger *zap.Logger jwt jwt.JWTProvider userGetByIDUseCase uc_user.UserGetByIDUseCase } func NewMiddleware( logger *zap.Logger, jwtp jwt.JWTProvider, uc1 uc_user.UserGetByIDUseCase, ) Middleware { logger = logger.With(zap.String("module", "maplefile")) logger = logger.Named("MapleFile Middleware") return &middleware{ logger: logger, jwt: jwtp, userGetByIDUseCase: uc1, } } // Attach function attaches to HTTP router to apply for every API call. func (mid *middleware) Attach(fn http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // Apply base middleware to all requests handler := mid.applyBaseMiddleware(fn) // Check if the path requires authentication if isProtectedPath(mid.logger, r.URL.Path) { // Apply auth middleware for protected paths handler = mid.PostJWTProcessorMiddleware(handler) handler = mid.JWTProcessorMiddleware(handler) // handler = mid.EnforceBlacklistMiddleware(handler) } handler(w, r) } } // Attach function attaches to HTTP router to apply for every API call. func (mid *middleware) applyBaseMiddleware(fn http.HandlerFunc) http.HandlerFunc { // Apply middleware in reverse order (bottom up) handler := fn handler = mid.URLProcessorMiddleware(handler) handler = mid.RequestBodySizeLimitMiddleware(handler) return handler } // RequestBodySizeLimitMiddleware limits the size of request bodies to prevent DoS attacks. // Default limit is 10MB for most requests, which is sufficient for JSON metadata payloads. func (mid *middleware) RequestBodySizeLimitMiddleware(fn http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // 10MB limit for request bodies // This is sufficient for JSON metadata while preventing abuse const maxBodySize = 10 * 1024 * 1024 // 10MB if r.Body != nil { r.Body = http.MaxBytesReader(w, r.Body, maxBodySize) } fn(w, r) } } // Shutdown shuts down the middleware. func (mid *middleware) Shutdown(ctx context.Context) { // Log a message to indicate that the HTTP server is shutting down. }