github.com/cozy/cozy-stack@v0.0.0-20240327093429-939e4a21320e/model/permission/match.go (about) 1 package permission 2 3 import "strings" 4 5 // Fetcher is an interface for an object to see if it matches a rule. 6 type Fetcher interface { 7 ID() string 8 DocType() string 9 Fetch(field string) []string 10 } 11 12 func matchValues(r Rule, o Fetcher) bool { 13 // empty r.Values = any value 14 if len(r.Values) == 0 { 15 return true 16 } 17 if r.Selector == "" { 18 return r.ValuesContain(o.ID()) 19 } 20 return r.ValuesMatch(o) 21 } 22 23 func matchOnFields(r Rule, o Fetcher, fields ...string) bool { 24 // in this case, if r.Values is empty the selector is considered too wide and 25 // is forbidden 26 if len(r.Values) == 0 || r.Selector == "" { 27 return false 28 } 29 var matchSelector bool 30 for _, f := range fields { 31 if r.Selector == f { 32 matchSelector = true 33 break 34 } 35 } 36 if !matchSelector { 37 return false 38 } 39 return r.ValuesMatch(o) 40 } 41 42 func matchVerb(r Rule, v Verb) bool { 43 return r.Verbs.Contains(v) 44 } 45 46 // MatchType returns true if the rule type matches the given doctype 47 func MatchType(r Rule, doctype string) bool { 48 if r.Type == doctype || isMaximal(r.Type) { 49 return true 50 } 51 if !isWildcard(r.Type) { 52 return false 53 } 54 typ := TrimWildcard(r.Type) 55 return typ == doctype || strings.HasPrefix(doctype, typ+".") 56 } 57 58 func matchWholeType(r Rule) bool { 59 return len(r.Values) == 0 60 } 61 62 func matchID(r Rule, id string) bool { 63 return r.Selector == "" && r.ValuesContain(id) 64 } 65 66 // AllowWholeType returns true if the set allows to apply verb to every 67 // document from the given doctypes (ie. r.values == 0) 68 func (s Set) AllowWholeType(v Verb, doctype string) bool { 69 return s.Some(func(r Rule) bool { 70 return matchVerb(r, v) && 71 MatchType(r, doctype) && 72 matchWholeType(r) 73 }) 74 } 75 76 // AllowID returns true if the set allows to apply verb to given type & id 77 func (s Set) AllowID(v Verb, doctype, id string) bool { 78 return s.Some(func(r Rule) bool { 79 return matchVerb(r, v) && 80 MatchType(r, doctype) && 81 (matchWholeType(r) || matchID(r, id)) 82 }) 83 } 84 85 // Allow returns true if the set allows to apply verb to given doc 86 func (s Set) Allow(v Verb, o Fetcher) bool { 87 return s.Some(func(r Rule) bool { 88 return matchVerb(r, v) && 89 MatchType(r, o.DocType()) && 90 matchValues(r, o) 91 }) 92 } 93 94 // AllowOnFields returns true if the set allows to apply verb to given doc on 95 // the specified fields. 96 func (s Set) AllowOnFields(v Verb, o Fetcher, fields ...string) bool { 97 return s.Some(func(r Rule) bool { 98 return matchVerb(r, v) && 99 MatchType(r, o.DocType()) && 100 matchOnFields(r, o, fields...) 101 }) 102 }