@@ 90,6 90,7 @@ type Grants struct {
all bool
grants map[string]string
+ local string
encoded string
}
@@ 99,6 100,7 @@ func DecodeGrants(ctx context.Context, grants string) (Grants, error) {
return Grants{
all: true,
grants: nil,
+ local: config.ServiceName(ctx),
encoded: "",
}, nil
}
@@ 121,18 123,23 @@ func DecodeGrants(ctx context.Context, grants string) (Grants, error) {
} else {
access = parts[1]
}
- if service == config.ServiceName(ctx) {
- accessMap[scope] = access
- }
+ name := fmt.Sprintf("%s/%s", service, scope)
+ accessMap[name] = access
}
return Grants{
all: false,
grants: accessMap,
+ local: config.ServiceName(ctx),
encoded: grants,
}, nil
}
+// Returns true if these grants include access to a specific OAuth grant.
func (g *Grants) Has(grant string, mode string) bool {
+ if !strings.ContainsRune(grant, '/') {
+ grant = fmt.Sprintf("%s/%s", g.local, grant)
+ }
+
if mode != RO && mode != RW {
panic("Invalid access mode")
}
@@ 154,6 161,31 @@ func (g *Grants) Has(grant string, mode string) bool {
}
}
+// Returns true if this is a universal grant.
+func (g *Grants) HasAll() bool {
+ return g.all
+}
+
+// Returns true of this grant object contains a subset of the permissions of
+// another.
+func (g *Grants) IsSubset(other *Grants) bool {
+ if g.all && !other.all {
+ return false
+ }
+
+ if other.all {
+ return true
+ }
+
+ for scope, access := range g.grants {
+ if !other.Has(scope, access) {
+ return false
+ }
+ }
+
+ return true
+}
+
func (g *Grants) Encode() string {
return g.encoded
}