package middleware import ( "RenewCMS/api/pkg/access" "RenewCMS/api/pkg/claims" "RenewCMS/internal/domain/user" "RenewCMS/internal/infrastructure/useCases" "errors" "net/http" ) func OptionalAccess(getUser *useCases.GetUserUseCase, check *useCases.CheckPermissionUseCase) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { r = access.WithCurrentUser(r) account, signedIn, err := verifiedAccount(getUser, r) if err != nil { http.Error(w, "Internal server error", http.StatusInternalServerError) return } if !signedIn { next.ServeHTTP(w, r) return } grants, err := check.Grants(account) if err != nil { http.Error(w, "Internal server error", http.StatusInternalServerError) return } caller := access.Caller{UserID: account.ID, Grants: grants} next.ServeHTTP(w, r.WithContext(access.WithCaller(r.Context(), caller))) }) } } func verifiedAccount(getUser *useCases.GetUserUseCase, r *http.Request) (user.User, bool, error) { userID, ok := claims.UserId(r) if !ok { return user.User{}, false, nil } account, err := access.LoadUser(getUser, r, userID) if errors.Is(err, user.ErrUserNotFound) { return user.User{}, false, nil } if err != nil { return user.User{}, false, err } tokenVersion, ok := claims.TokenVersion(r) if !ok || tokenVersion != account.TokenVersion { return user.User{}, false, nil } return account, account.IsVerified, nil }