-
Notifications
You must be signed in to change notification settings - Fork 247
/
foundsubject.go
127 lines (101 loc) · 3.96 KB
/
foundsubject.go
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 ...*core.ObjectAndRelation) FoundSubject {
return FoundSubject{subject.Subject, nil, subject.CaveatExpression, tuple.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 *core.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
// relations are the relations under which the subject lives that informed the locating
// of this subject for the root ONR.
relationships *tuple.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() *core.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.Namespace, 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
}
// Relationships returns all the relationships in which the subject was found as per the expand.
func (fs FoundSubject) Relationships() []*core.ObjectAndRelation {
return fs.relationships.AsSlice()
}
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()
}
// 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 *core.ObjectAndRelation) (FoundSubject, bool) {
return fs.subjects.Get(subject)
}