From 927d1feb05e583fb49ce520d7693628915c390e4 Mon Sep 17 00:00:00 2001 From: LordMathis Date: Sun, 3 Nov 2024 22:02:39 +0100 Subject: [PATCH] Split user and workspace contexts --- backend/internal/api/routes.go | 5 ++- backend/internal/httpcontext/context.go | 2 +- backend/internal/middleware/context.go | 56 +++++++++++++------------ 3 files changed, 34 insertions(+), 29 deletions(-) diff --git a/backend/internal/api/routes.go b/backend/internal/api/routes.go index 1487d05..37d0f51 100644 --- a/backend/internal/api/routes.go +++ b/backend/internal/api/routes.go @@ -27,7 +27,7 @@ func SetupRoutes(r chi.Router, db *db.DB, fs *filesystem.FileSystem, authMiddlew r.Group(func(r chi.Router) { // Apply authentication middleware to all routes in this group r.Use(authMiddleware.Authenticate) - r.Use(middleware.WithHandlerContext(db)) + r.Use(middleware.WithUserContext) // Auth routes r.Post("/auth/logout", handler.Logout(sessionService)) @@ -49,7 +49,8 @@ func SetupRoutes(r chi.Router, db *db.DB, fs *filesystem.FileSystem, authMiddlew r.Put("/last", handler.UpdateLastWorkspace()) // Single workspace routes - r.Route("/{workspaceId}", func(r chi.Router) { + r.Route("/{workspaceName}", func(r chi.Router) { + r.Use(middleware.WithWorkspaceContext(db)) r.Use(authMiddleware.RequireWorkspaceAccess) r.Get("/", handler.GetWorkspace()) diff --git a/backend/internal/httpcontext/context.go b/backend/internal/httpcontext/context.go index 9e41519..1e9b278 100644 --- a/backend/internal/httpcontext/context.go +++ b/backend/internal/httpcontext/context.go @@ -10,7 +10,7 @@ import ( type HandlerContext struct { UserID int UserRole string - Workspace *models.Workspace // Will be nil for non-workspace endpoints + Workspace *models.Workspace } type contextKey string diff --git a/backend/internal/middleware/context.go b/backend/internal/middleware/context.go index 7965918..95a72d4 100644 --- a/backend/internal/middleware/context.go +++ b/backend/internal/middleware/context.go @@ -5,44 +5,48 @@ import ( "novamd/internal/auth" "novamd/internal/db" "novamd/internal/httpcontext" - "novamd/internal/models" "github.com/go-chi/chi/v5" ) -// WithHandlerContext middleware populates the HandlerContext for the request -// This should be placed after authentication middleware -func WithHandlerContext(db *db.DB) func(http.Handler) http.Handler { +// User ID and User Role context +func WithUserContext(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + claims, err := auth.GetUserFromContext(r.Context()) + if err != nil { + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + + hctx := &httpcontext.HandlerContext{ + UserID: claims.UserID, + UserRole: claims.Role, + } + + r = httpcontext.WithHandlerContext(r, hctx) + next.ServeHTTP(w, r) + }) +} + +// Workspace context +func WithWorkspaceContext(db *db.DB) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Get user claims from auth middleware - claims, err := auth.GetUserFromContext(r.Context()) - if err != nil { - http.Error(w, "Unauthorized", http.StatusUnauthorized) + ctx, ok := httpcontext.GetRequestContext(w, r) + if !ok { return } - // Try to get workspace from URL if it exists workspaceName := chi.URLParam(r, "workspaceName") - - var workspace *models.Workspace - if workspaceName != "" { - workspace, err = db.GetWorkspaceByName(claims.UserID, workspaceName) - if err != nil { - http.Error(w, "Internal server error", http.StatusInternalServerError) - return - } + workspace, err := db.GetWorkspaceByName(ctx.UserID, workspaceName) + if err != nil { + http.Error(w, "Workspace not found", http.StatusNotFound) + return } - // Create handler context with user and workspace info - hctx := &httpcontext.HandlerContext{ - UserID: claims.UserID, - UserRole: claims.Role, - Workspace: workspace, - } - - // Add context to request - r = httpcontext.WithHandlerContext(r, hctx) + // Update existing context with workspace + ctx.Workspace = workspace + r = httpcontext.WithHandlerContext(r, ctx) next.ServeHTTP(w, r) }) }