summaryrefslogtreecommitdiff
path: root/vendor/github.com/authzed/spicedb/internal/services/v1/grouping.go
blob: 99b681d2ec4aa7a26a3088e9d7e6bb1eb42ee86b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package v1

import (
	"context"

	v1 "github.com/authzed/authzed-go/proto/authzed/api/v1"

	"github.com/authzed/spicedb/internal/graph/computed"
	"github.com/authzed/spicedb/pkg/datastore"
	"github.com/authzed/spicedb/pkg/tuple"
)

type groupedCheckParameters struct {
	params      *computed.CheckParameters
	resourceIDs []string
}

type groupingParameters struct {
	atRevision           datastore.Revision
	maximumAPIDepth      uint32
	maxCaveatContextSize int
	withTracing          bool
}

// groupItems takes a slice of CheckBulkPermissionsRequestItem and groups them based
// on using the same permission, subject type, subject id, and caveat.
func groupItems(ctx context.Context, params groupingParameters, items []*v1.CheckBulkPermissionsRequestItem) (map[string]*groupedCheckParameters, error) {
	res := make(map[string]*groupedCheckParameters)

	for _, item := range items {
		hash, err := computeCheckBulkPermissionsItemHashWithoutResourceID(item)
		if err != nil {
			return nil, err
		}

		if _, ok := res[hash]; !ok {
			caveatContext, err := GetCaveatContext(ctx, item.Context, params.maxCaveatContextSize)
			if err != nil {
				return nil, err
			}

			res[hash] = &groupedCheckParameters{
				params:      checkParametersFromCheckBulkPermissionsRequestItem(item, params, caveatContext),
				resourceIDs: []string{item.Resource.ObjectId},
			}
		} else {
			res[hash].resourceIDs = append(res[hash].resourceIDs, item.Resource.ObjectId)
		}
	}

	return res, nil
}

func checkParametersFromCheckBulkPermissionsRequestItem(
	bc *v1.CheckBulkPermissionsRequestItem,
	params groupingParameters,
	caveatContext map[string]any,
) *computed.CheckParameters {
	debugOption := computed.NoDebugging
	if params.withTracing {
		debugOption = computed.BasicDebuggingEnabled
	}

	return &computed.CheckParameters{
		ResourceType:  tuple.RR(bc.Resource.ObjectType, bc.Permission),
		Subject:       tuple.ONR(bc.Subject.Object.ObjectType, bc.Subject.Object.ObjectId, normalizeSubjectRelation(bc.Subject)),
		CaveatContext: caveatContext,
		AtRevision:    params.atRevision,
		MaximumDepth:  params.maximumAPIDepth,
		DebugOption:   debugOption,
	}
}