MCPcopy Index your code
hub / github.com/coder/coder / IntersectAllowLists

Function IntersectAllowLists

coderd/rbac/allowlist.go:174–228  ·  view source on GitHub ↗

IntersectAllowLists combines the allow list produced by RBAC expansion with the API key's stored allow list. The result enforces both constraints: any resource must be allowed by the scope *and* the database filter. Wildcards in either list are respected and short-circuit appropriately. Intuition:

(scopeList []AllowListElement, dbList []AllowListElement)

Source from the content-addressed store, hash-verified

172// stored. Only scopes that intentionally embed resource filters would trim the
173// DB entries.
174func IntersectAllowLists(scopeList []AllowListElement, dbList []AllowListElement) []AllowListElement {
175 // Empty DB list means no additional restriction.
176 if len(dbList) == 0 {
177 // Defensive: API keys should always persist a non-empty allow list, but
178 // we cannot have an empty allow list, thus we fail close.
179 return nil
180 }
181
182 // If scope already allows everything, the db list is authoritative.
183 scopeAll := allowListContainsAll(scopeList)
184 dbAll := allowListContainsAll(dbList)
185
186 switch {
187 case scopeAll && dbAll:
188 return []AllowListElement{AllowListAll()}
189 case scopeAll:
190 return dbList
191 case dbAll:
192 return scopeList
193 }
194
195 // Otherwise compute intersection.
196 resultSet := make(map[string]AllowListElement)
197 for _, scopeElem := range scopeList {
198 matching := intersectAllow(scopeElem, dbList)
199 for _, elem := range matching {
200 resultSet[elem.String()] = elem
201 }
202 }
203
204 if len(resultSet) == 0 {
205 return []AllowListElement{}
206 }
207
208 result := make([]AllowListElement, 0, len(resultSet))
209 for _, elem := range resultSet {
210 result = append(result, elem)
211 }
212
213 slices.SortFunc(result, func(a, b AllowListElement) int {
214 if a.Type == b.Type {
215 return strings.Compare(a.ID, b.ID)
216 }
217 return strings.Compare(a.Type, b.Type)
218 })
219
220 normalized, err := NormalizeAllowList(result)
221 if err != nil {
222 return result
223 }
224 if normalized == nil {
225 return []AllowListElement{}
226 }
227 return normalized
228}
229
230func allowListContainsAll(elements []AllowListElement) bool {
231 if len(elements) == 0 {

Callers 2

TestIntersectAllowListsFunction · 0.92
ExpandMethod · 0.92

Calls 6

allowListContainsAllFunction · 0.85
AllowListAllFunction · 0.85
intersectAllowFunction · 0.85
NormalizeAllowListFunction · 0.85
CompareMethod · 0.80
StringMethod · 0.45

Tested by 1

TestIntersectAllowListsFunction · 0.74