Skip to content

Commit 2152acf

Browse files
Avoid allocations while checking role bindings
1 parent 9ff9b92 commit 2152acf

File tree

3 files changed

+80
-1
lines changed

3 files changed

+80
-1
lines changed

pkg/authorization/api/helpers.go

+53
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,59 @@ func SubjectsStrings(currentNamespace string, subjects []kapi.ObjectReference) (
244244
return users, groups, sas, others
245245
}
246246

247+
// SubjectsContainUser returns true if the provided subjects contain the named user. currentNamespace
248+
// is used to identify service accounts that are defined in a relative fashion.
249+
func SubjectsContainUser(subjects []kapi.ObjectReference, currentNamespace string, user string) bool {
250+
if !strings.HasPrefix(user, serviceaccount.ServiceAccountUsernamePrefix) {
251+
for _, subject := range subjects {
252+
switch subject.Kind {
253+
case UserKind, SystemUserKind:
254+
if user == subject.Name {
255+
return true
256+
}
257+
}
258+
}
259+
return false
260+
}
261+
262+
for _, subject := range subjects {
263+
switch subject.Kind {
264+
case ServiceAccountKind:
265+
namespace := currentNamespace
266+
if len(subject.Namespace) > 0 {
267+
namespace = subject.Namespace
268+
}
269+
if len(namespace) == 0 {
270+
continue
271+
}
272+
if user == serviceaccount.MakeUsername(namespace, subject.Name) {
273+
return true
274+
}
275+
276+
case UserKind, SystemUserKind:
277+
if user == subject.Name {
278+
return true
279+
}
280+
}
281+
}
282+
return false
283+
}
284+
285+
// SubjectsContainGroups returns true if the provided subjects any of the named groups.
286+
func SubjectsContainGroups(subjects []kapi.ObjectReference, groups []string) bool {
287+
for _, subject := range subjects {
288+
switch subject.Kind {
289+
case GroupKind, SystemGroupKind:
290+
for _, group := range groups {
291+
if group == subject.Name {
292+
return true
293+
}
294+
}
295+
}
296+
}
297+
return false
298+
}
299+
247300
func AddUserToSAR(user user.Info, sar *SubjectAccessReview) *SubjectAccessReview {
248301
origScopes := user.GetExtra()[ScopesKey]
249302
scopes := make([]string, len(origScopes), len(origScopes))

pkg/authorization/interfaces/interfaces.go

+26
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package interfaces
22

33
import (
44
kapi "k8s.io/kubernetes/pkg/api"
5+
"k8s.io/kubernetes/pkg/auth/user"
56
"k8s.io/kubernetes/pkg/util/sets"
67

78
authorizationapi "github.com/openshift/origin/pkg/authorization/api"
@@ -36,6 +37,9 @@ type RoleBinding interface {
3637
RoleRef() kapi.ObjectReference
3738
Users() sets.String
3839
Groups() sets.String
40+
41+
// AppliesToUser returns true if the provided user matches this role binding
42+
AppliesToUser(user.Info) bool
3943
}
4044

4145
func NewClusterPolicyAdapter(policy *authorizationapi.ClusterPolicy) Policy {
@@ -219,6 +223,17 @@ func (a RoleBindingAdapter) Groups() sets.String {
219223
return sets.NewString(groups...)
220224
}
221225

226+
// AppliesToUser returns true if this binding applies to the provided user.
227+
func (a RoleBindingAdapter) AppliesToUser(user user.Info) bool {
228+
if authorizationapi.SubjectsContainUser(a.roleBinding.Subjects, a.roleBinding.Namespace, user.GetName()) {
229+
return true
230+
}
231+
if authorizationapi.SubjectsContainGroups(a.roleBinding.Subjects, user.GetGroups()) {
232+
return true
233+
}
234+
return false
235+
}
236+
222237
type ClusterPolicyBindingAdapter struct {
223238
policyBinding *authorizationapi.ClusterPolicyBinding
224239

@@ -274,3 +289,14 @@ func (a ClusterRoleBindingAdapter) Groups() sets.String {
274289

275290
return sets.NewString(groups...)
276291
}
292+
293+
// AppliesToUser returns true if this binding applies to the provided user.
294+
func (a ClusterRoleBindingAdapter) AppliesToUser(user user.Info) bool {
295+
if authorizationapi.SubjectsContainUser(a.roleBinding.Subjects, a.roleBinding.Namespace, user.GetName()) {
296+
return true
297+
}
298+
if authorizationapi.SubjectsContainGroups(a.roleBinding.Subjects, user.GetGroups()) {
299+
return true
300+
}
301+
return false
302+
}

pkg/authorization/rulevalidation/find_rules.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ func (a *DefaultRuleResolver) GetEffectivePolicyRules(ctx kapi.Context) ([]autho
129129
errs := []error{}
130130
rules := make([]authorizationapi.PolicyRule, 0, len(roleBindings))
131131
for _, roleBinding := range roleBindings {
132-
if !appliesToUser(roleBinding.Users(), roleBinding.Groups(), user) {
132+
if !roleBinding.AppliesToUser(user) {
133133
continue
134134
}
135135

0 commit comments

Comments
 (0)