52 lines
1.5 KiB
Go
52 lines
1.5 KiB
Go
package middleware
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
|
|
"github.com/google/uuid"
|
|
|
|
"github.com/dbiz/cdp/data-layer/api/internal/apperr"
|
|
)
|
|
|
|
const ctxKeyWorkspace ctxKey = "workspace_id"
|
|
|
|
// Workspace pulls the active workspace UUID from the X-Workspace-Id header
|
|
// and stores it in context. Returns 400 for missing / malformed values.
|
|
//
|
|
// TODO(auth): wire this to the console session / JWT once the auth scheme
|
|
// for the data-layer is finalized. For now the header drives everything.
|
|
func Workspace(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
raw := r.Header.Get("X-Workspace-Id")
|
|
if raw == "" {
|
|
writeAppErr(w, apperr.BadRequest("missing X-Workspace-Id header", "workspace_id", nil))
|
|
return
|
|
}
|
|
id, err := uuid.Parse(raw)
|
|
if err != nil {
|
|
writeAppErr(w, apperr.BadRequest("invalid X-Workspace-Id", "workspace_id", err))
|
|
return
|
|
}
|
|
ctx := context.WithValue(r.Context(), ctxKeyWorkspace, id.String())
|
|
next.ServeHTTP(w, r.WithContext(ctx))
|
|
})
|
|
}
|
|
|
|
// WorkspaceFromCtx returns the workspace id set by Workspace middleware.
|
|
func WorkspaceFromCtx(ctx context.Context) string {
|
|
v, _ := ctx.Value(ctxKeyWorkspace).(string)
|
|
return v
|
|
}
|
|
|
|
func writeAppErr(w http.ResponseWriter, err *apperr.AppError) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(err.Code)
|
|
body := `{"error":"` + err.Message + `"`
|
|
if err.Field != "" {
|
|
body += `,"field":"` + err.Field + `"`
|
|
}
|
|
body += `}`
|
|
_, _ = w.Write([]byte(body))
|
|
}
|