monorepo/cloud/maplefile-backend/internal/interface/http/middleware/middleware.go

87 lines
2.6 KiB
Go

// 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.
}