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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
package developmentmembership
import (
"sort"
"strings"
core "github.com/authzed/spicedb/pkg/proto/core/v1"
"github.com/authzed/spicedb/pkg/tuple"
)
// NewFoundSubject creates a new FoundSubject for a subject and a set of its resources.
func NewFoundSubject(subject *core.DirectSubject, resources ...tuple.ObjectAndRelation) FoundSubject {
return FoundSubject{tuple.FromCoreObjectAndRelation(subject.Subject), nil, subject.CaveatExpression, NewONRSet(resources...)}
}
// FoundSubject contains a single found subject and all the relationships in which that subject
// is a member which were found via the ONRs expansion.
type FoundSubject struct {
// subject is the subject found.
subject tuple.ObjectAndRelation
// excludedSubjects are any subjects excluded. Only should be set if subject is a wildcard.
excludedSubjects []FoundSubject
// caveatExpression is the conditional expression on the found subject.
caveatExpression *core.CaveatExpression
// resources are the resources under which the subject lives that informed the locating
// of this subject for the root ONR.
resources ONRSet
}
// GetSubjectId is named to match the Subject interface for the BaseSubjectSet.
//
//nolint:all
func (fs FoundSubject) GetSubjectId() string {
return fs.subject.ObjectID
}
func (fs FoundSubject) GetCaveatExpression() *core.CaveatExpression {
return fs.caveatExpression
}
func (fs FoundSubject) GetExcludedSubjects() []FoundSubject {
return fs.excludedSubjects
}
// Subject returns the Subject of the FoundSubject.
func (fs FoundSubject) Subject() tuple.ObjectAndRelation {
return fs.subject
}
// WildcardType returns the object type for the wildcard subject, if this is a wildcard subject.
func (fs FoundSubject) WildcardType() (string, bool) {
if fs.subject.ObjectID == tuple.PublicWildcard {
return fs.subject.ObjectType, true
}
return "", false
}
// ExcludedSubjectsFromWildcard returns those subjects excluded from the wildcard subject.
// If not a wildcard subject, returns false.
func (fs FoundSubject) ExcludedSubjectsFromWildcard() ([]FoundSubject, bool) {
if fs.subject.ObjectID == tuple.PublicWildcard {
return fs.excludedSubjects, true
}
return nil, false
}
func (fs FoundSubject) excludedSubjectStrings() []string {
excludedStrings := make([]string, 0, len(fs.excludedSubjects))
for _, excludedSubject := range fs.excludedSubjects {
excludedSubjectString := tuple.StringONR(excludedSubject.subject)
if excludedSubject.GetCaveatExpression() != nil {
excludedSubjectString += "[...]"
}
excludedStrings = append(excludedStrings, excludedSubjectString)
}
sort.Strings(excludedStrings)
return excludedStrings
}
// ToValidationString returns the FoundSubject in a format that is consumable by the validationfile
// package.
func (fs FoundSubject) ToValidationString() string {
onrString := tuple.StringONR(fs.Subject())
validationString := onrString
if fs.caveatExpression != nil {
validationString = validationString + "[...]"
}
excluded, isWildcard := fs.ExcludedSubjectsFromWildcard()
if isWildcard && len(excluded) > 0 {
validationString = validationString + " - {" + strings.Join(fs.excludedSubjectStrings(), ", ") + "}"
}
return validationString
}
func (fs FoundSubject) String() string {
return fs.ToValidationString()
}
// ParentResources returns all the resources in which the subject was found as per the expand.
func (fs FoundSubject) ParentResources() []tuple.ObjectAndRelation {
return fs.resources.AsSlice()
}
// FoundSubjects contains the subjects found for a specific ONR.
type FoundSubjects struct {
// subjects is a map from the Subject ONR (as a string) to the FoundSubject information.
subjects *TrackingSubjectSet
}
// ListFound returns a slice of all the FoundSubject's.
func (fs FoundSubjects) ListFound() []FoundSubject {
return fs.subjects.ToSlice()
}
// LookupSubject returns the FoundSubject for a matching subject, if any.
func (fs FoundSubjects) LookupSubject(subject tuple.ObjectAndRelation) (FoundSubject, bool) {
return fs.subjects.Get(subject)
}
|