fix(09): WR-01 match wildcard required permissions and treat several codes as any, like Winter
This commit is contained in:
@@ -121,9 +121,12 @@ func (r *Registry) Setting(code string) (*CompiledSetting, bool) {
|
||||
return setting, ok && setting != nil
|
||||
}
|
||||
|
||||
// Allows reports whether principal satisfies every required permission code.
|
||||
// A nil principal fails. Superusers pass. An empty requirement list allows
|
||||
// any authenticated principal. Grants ending in ".*" match by prefix.
|
||||
// Allows reports whether principal satisfies any of the required permission
|
||||
// codes, the way Winter's hasAnyAccess does. A nil principal fails. Superusers
|
||||
// pass. An empty requirement list allows any authenticated principal. Both
|
||||
// sides may use a wildcard: a grant ending in ".*" covers every code with that
|
||||
// prefix, and a required code ending in ".*" (or starting with "*") is met by
|
||||
// any granted code that matches it.
|
||||
func Allows(principal *bouncer.Principal, required []string) bool {
|
||||
if principal == nil {
|
||||
return false
|
||||
@@ -132,23 +135,43 @@ func Allows(principal *bouncer.Principal, required []string) bool {
|
||||
return true
|
||||
}
|
||||
for _, code := range required {
|
||||
if !granted(principal.PermissionGrants, code) {
|
||||
return false
|
||||
if granted(principal.PermissionGrants, code) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
// granted ports Winter's User::hasPermission for one code. Only enabled
|
||||
// grants are in the map, so the "(int) $value === 1" test is already applied.
|
||||
func granted(grants map[string]bool, code string) bool {
|
||||
switch {
|
||||
case len(code) > 1 && strings.HasSuffix(code, "*"):
|
||||
prefix := strings.TrimSuffix(code, "*")
|
||||
for key, on := range grants {
|
||||
if on && key != prefix && strings.HasPrefix(key, prefix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
case len(code) > 1 && strings.HasPrefix(code, "*"):
|
||||
suffix := strings.TrimPrefix(code, "*")
|
||||
for key, on := range grants {
|
||||
if on && key != suffix && strings.HasSuffix(key, suffix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
if grants[code] {
|
||||
return true
|
||||
}
|
||||
for key, on := range grants {
|
||||
if !on || !strings.HasSuffix(key, ".*") {
|
||||
if !on || len(key) < 2 || !strings.HasSuffix(key, "*") {
|
||||
continue
|
||||
}
|
||||
prefix := strings.TrimSuffix(key, "*")
|
||||
if strings.HasPrefix(code, prefix) {
|
||||
if prefix != code && strings.HasPrefix(code, prefix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user