Initial commit: Open sourcing all of the Maple Open Technologies code.

This commit is contained in:
Bartlomiej Mika 2025-12-02 14:33:08 -05:00
commit 755d54a99d
2010 changed files with 448675 additions and 0 deletions

View file

@ -0,0 +1,95 @@
package middleware
import (
"context"
"net/http"
"go.uber.org/zap"
"github.com/gocql/gocql"
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config/constants"
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/httperror"
)
func (mid *middleware) PostJWTProcessorMiddleware(fn http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// Get our authorization information.
isAuthorized, ok := ctx.Value(constants.SessionIsAuthorized).(bool)
if ok && isAuthorized {
// CWE-391: Safe type assertion to prevent panic-based DoS
// OWASP A09:2021: Security Logging and Monitoring - Prevents service crashes
sessionID, ok := ctx.Value(constants.SessionID).(string)
if !ok {
mid.logger.Error("Invalid session ID type in context")
problem := httperror.NewInternalServerError("Invalid session context")
problem.WithInstance(r.URL.Path).
WithTraceID(httperror.ExtractRequestID(r))
httperror.RespondWithProblem(w, problem)
return
}
// Parse the user ID from the session ID (which is actually the user ID string from JWT)
userID, err := gocql.ParseUUID(sessionID)
if err != nil {
problem := httperror.NewUnauthorizedError("Invalid user ID in token")
problem.WithInstance(r.URL.Path).
WithTraceID(httperror.ExtractRequestID(r))
httperror.RespondWithProblem(w, problem)
return
}
// Lookup our user profile by ID or return 500 error.
user, err := mid.userGetByIDUseCase.Execute(ctx, userID)
if err != nil {
// Log the actual error for debugging but return generic message to client
mid.logger.Error("Failed to get user by ID",
zap.Error(err),
zap.String("user_id", userID.String()))
problem := httperror.NewInternalServerError("Unable to verify session")
problem.WithInstance(r.URL.Path).
WithTraceID(httperror.ExtractRequestID(r))
httperror.RespondWithProblem(w, problem)
return
}
// If no user was found then that means our session expired and the
// user needs to login or use the refresh token.
if user == nil {
problem := httperror.NewUnauthorizedError("Session expired")
problem.WithInstance(r.URL.Path).
WithTraceID(httperror.ExtractRequestID(r))
httperror.RespondWithProblem(w, problem)
return
}
// // If system administrator disabled the user account then we need
// // to generate a 403 error letting the user know their account has
// // been disabled and you cannot access the protected API endpoint.
// if user.State == 0 {
// http.Error(w, "Account disabled - please contact admin", http.StatusForbidden)
// return
// }
// Save our user information to the context.
// Save our user.
ctx = context.WithValue(ctx, constants.SessionUser, user)
// Save individual pieces of the user profile.
ctx = context.WithValue(ctx, constants.SessionID, sessionID)
ctx = context.WithValue(ctx, constants.SessionUserID, user.ID)
ctx = context.WithValue(ctx, constants.SessionUserRole, user.Role)
ctx = context.WithValue(ctx, constants.SessionUserName, user.Name)
ctx = context.WithValue(ctx, constants.SessionUserFirstName, user.FirstName)
ctx = context.WithValue(ctx, constants.SessionUserLastName, user.LastName)
ctx = context.WithValue(ctx, constants.SessionUserTimezone, user.Timezone)
// ctx = context.WithValue(ctx, constants.SessionUserStoreID, user.StoreID)
// ctx = context.WithValue(ctx, constants.SessionUserStoreName, user.StoreName)
// ctx = context.WithValue(ctx, constants.SessionUserStoreLevel, user.StoreLevel)
// ctx = context.WithValue(ctx, constants.SessionUserStoreTimezone, user.StoreTimezone)
}
fn(w, r.WithContext(ctx))
}
}