MCPcopy Create free account
hub / github.com/PerpetualSoftware/pad / filterUserGrantsForCaller

Method filterUserGrantsForCaller

internal/server/server.go:2693–2743  ·  view source on GitHub ↗

filterUserGrantsForCaller narrows collGrants/itemGrants — the TARGET user's grants, already loaded by the caller — down to what the CALLER can see. Only meaningful when caller != target; handleListUserGrants skips calling this for self-queries (a user can always see their own grants). BUG-1928: han

(r *http.Request, workspaceID string, collGrants []models.CollectionGrant, itemGrants []models.ItemGrant)

Source from the content-addressed store, hash-verified

2691// call (state-agnostic; no deleted_at filter) rather than N per-grant
2692// lookups.
2693func (s *Server) filterUserGrantsForCaller(r *http.Request, workspaceID string, collGrants []models.CollectionGrant, itemGrants []models.ItemGrant) ([]models.CollectionGrant, []models.ItemGrant, error) {
2694 fullCollIDs, grantedItemIDs, err := s.guestResourceFilter(r, workspaceID)
2695 if err != nil {
2696 return nil, nil, err
2697 }
2698 if fullCollIDs == nil && grantedItemIDs == nil {
2699 // Unrestricted caller (admin/cookie session, or a member with
2700 // full collection access) — no filtering, and no further store
2701 // calls needed.
2702 return collGrants, itemGrants, nil
2703 }
2704
2705 filteredColl := make([]models.CollectionGrant, 0, len(collGrants))
2706 for _, g := range collGrants {
2707 if isCollectionVisible(g.CollectionID, fullCollIDs) {
2708 filteredColl = append(filteredColl, g)
2709 }
2710 }
2711
2712 filteredItem := make([]models.ItemGrant, 0, len(itemGrants))
2713 if len(itemGrants) > 0 {
2714 itemIDs := make([]string, len(itemGrants))
2715 for i, g := range itemGrants {
2716 itemIDs[i] = g.ItemID
2717 }
2718 refs, err := s.store.GetItemCollectionRefs(workspaceID, itemIDs)
2719 if err != nil {
2720 return nil, nil, err
2721 }
2722 collByItem := make(map[string]string, len(refs))
2723 for _, ref := range refs {
2724 collByItem[ref.ID] = ref.CollectionID
2725 }
2726 for _, g := range itemGrants {
2727 collID, ok := collByItem[g.ItemID]
2728 if !ok {
2729 // item_grants.item_id is ON DELETE CASCADE, so a grant
2730 // row can't outlive its item — this should be
2731 // unreachable. Exclude defensively rather than show a
2732 // grant with no resolvable parent.
2733 continue
2734 }
2735 item := &models.Item{ID: g.ItemID, CollectionID: collID}
2736 if s.isItemVisibleToGuest(r, workspaceID, item, fullCollIDs, grantedItemIDs) {
2737 filteredItem = append(filteredItem, g)
2738 }
2739 }
2740 }
2741
2742 return filteredColl, filteredItem, nil
2743}
2744
2745// requireEditPermission checks if the user has edit access to the given item.
2746// For regular members (editor/owner), this uses the standard role check.

Callers 1

handleListUserGrantsMethod · 0.95

Calls 5

guestResourceFilterMethod · 0.95
isItemVisibleToGuestMethod · 0.95
isCollectionVisibleFunction · 0.85
GetItemCollectionRefsMethod · 0.80
makeFunction · 0.50

Tested by

no test coverage detected