Switch to pointer to policy rule, visit and short circuit during authorization
This commit is contained in:
@@ -39,6 +39,10 @@ type AuthorizationRuleResolver interface {
|
||||
// PolicyRules may not be complete, but it contains all retrievable rules. This is done because policy rules are purely additive and policy determinations
|
||||
// can be made on the basis of those rules that are found.
|
||||
RulesFor(user user.Info, namespace string) ([]rbac.PolicyRule, error)
|
||||
|
||||
// VisitRulesFor invokes visitor() with each rule that applies to a given user in a given namespace, and each error encountered resolving those rules.
|
||||
// If visitor() returns false, visiting is short-circuited.
|
||||
VisitRulesFor(user user.Info, namespace string, visitor func(rule *rbac.PolicyRule, err error) bool)
|
||||
}
|
||||
|
||||
// ConfirmNoEscalation determines if the roles for a given user in a given namespace encompass the provided role.
|
||||
@@ -93,12 +97,31 @@ type ClusterRoleBindingLister interface {
|
||||
}
|
||||
|
||||
func (r *DefaultRuleResolver) RulesFor(user user.Info, namespace string) ([]rbac.PolicyRule, error) {
|
||||
policyRules := []rbac.PolicyRule{}
|
||||
errorlist := []error{}
|
||||
visitor := &ruleAccumulator{}
|
||||
r.VisitRulesFor(user, namespace, visitor.visit)
|
||||
return visitor.rules, utilerrors.NewAggregate(visitor.errors)
|
||||
}
|
||||
|
||||
type ruleAccumulator struct {
|
||||
rules []rbac.PolicyRule
|
||||
errors []error
|
||||
}
|
||||
|
||||
func (r *ruleAccumulator) visit(rule *rbac.PolicyRule, err error) bool {
|
||||
if rule != nil {
|
||||
r.rules = append(r.rules, *rule)
|
||||
}
|
||||
if err != nil {
|
||||
r.errors = append(r.errors, err)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (r *DefaultRuleResolver) VisitRulesFor(user user.Info, namespace string, visitor func(rule *rbac.PolicyRule, err error) bool) {
|
||||
if clusterRoleBindings, err := r.clusterRoleBindingLister.ListClusterRoleBindings(); err != nil {
|
||||
errorlist = append(errorlist, err)
|
||||
|
||||
if !visitor(nil, err) {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
for _, clusterRoleBinding := range clusterRoleBindings {
|
||||
if !appliesTo(user, clusterRoleBinding.Subjects, "") {
|
||||
@@ -106,17 +129,24 @@ func (r *DefaultRuleResolver) RulesFor(user user.Info, namespace string) ([]rbac
|
||||
}
|
||||
rules, err := r.GetRoleReferenceRules(clusterRoleBinding.RoleRef, "")
|
||||
if err != nil {
|
||||
errorlist = append(errorlist, err)
|
||||
if !visitor(nil, err) {
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
policyRules = append(policyRules, rules...)
|
||||
for i := range rules {
|
||||
if !visitor(&rules[i], nil) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(namespace) > 0 {
|
||||
if roleBindings, err := r.roleBindingLister.ListRoleBindings(namespace); err != nil {
|
||||
errorlist = append(errorlist, err)
|
||||
|
||||
if !visitor(nil, err) {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
for _, roleBinding := range roleBindings {
|
||||
if !appliesTo(user, roleBinding.Subjects, namespace) {
|
||||
@@ -124,15 +154,19 @@ func (r *DefaultRuleResolver) RulesFor(user user.Info, namespace string) ([]rbac
|
||||
}
|
||||
rules, err := r.GetRoleReferenceRules(roleBinding.RoleRef, namespace)
|
||||
if err != nil {
|
||||
errorlist = append(errorlist, err)
|
||||
if !visitor(nil, err) {
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
policyRules = append(policyRules, rules...)
|
||||
for i := range rules {
|
||||
if !visitor(&rules[i], nil) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return policyRules, utilerrors.NewAggregate(errorlist)
|
||||
}
|
||||
|
||||
// GetRoleReferenceRules attempts to resolve the RoleBinding or ClusterRoleBinding.
|
||||
|
@@ -128,7 +128,7 @@ func TestDefaultRuleResolver(t *testing.T) {
|
||||
StaticRoles: staticRoles1,
|
||||
user: &user.DefaultInfo{Name: "foobar"},
|
||||
namespace: "namespace2",
|
||||
effectiveRules: []rbac.PolicyRule{},
|
||||
effectiveRules: nil,
|
||||
},
|
||||
{
|
||||
StaticRoles: staticRoles1,
|
||||
@@ -139,7 +139,7 @@ func TestDefaultRuleResolver(t *testing.T) {
|
||||
{
|
||||
StaticRoles: staticRoles1,
|
||||
user: &user.DefaultInfo{},
|
||||
effectiveRules: []rbac.PolicyRule{},
|
||||
effectiveRules: nil,
|
||||
},
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user