in pkg/identity/keystone/authorizer.go [314:398]
func (a *Authorizer) Authorize(attributes authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
a.mu.Lock()
defer a.mu.Unlock()
// Get roles and projects from the request.
user := attributes.GetUser()
userRoles := sets.NewString()
if val, ok := user.GetExtra()[Roles]; ok {
for _, role := range val {
userRoles.Insert(role)
}
}
// When the user.Extra does not exist, it means that the keytone user authentication has failed, and the authorization verification should not pass.
if user.GetExtra() == nil {
return authorizer.DecisionDeny, "No auth info found.", nil
}
// We support both project name and project ID.
userProjects := sets.NewString()
if val, ok := user.GetExtra()[ProjectName]; ok {
for _, project := range val {
userProjects.Insert(project)
}
}
if val, ok := user.GetExtra()[ProjectID]; ok {
for _, project := range val {
userProjects.Insert(project)
}
}
klog.V(4).Infof("Request userRoles: %s, userProjects: %s", userRoles.List(), userProjects.List())
// The permission is whitelist. Make sure we go through all the policies that match the user roles and projects. If
// the operation is allowed explicitly, stop the loop and return "allowed".
for _, p := range a.pl {
policyRoles := sets.NewString()
policyProjects := sets.NewString()
if p.Users != nil {
if val, ok := p.Users["roles"]; ok {
for _, role := range val {
policyRoles.Insert(role)
}
}
if val, ok := p.Users["projects"]; ok {
for _, project := range val {
policyProjects.Insert(project)
}
}
klog.V(4).Infof("policyRoles: %s, policyProjects: %s", policyRoles.List(), policyProjects.List())
if !userRoles.IsSuperset(policyRoles) || !policyProjects.HasAny(userProjects.List()...) {
continue
}
}
// ResourcePermissionsSpec and NonResourcePermissionsSpec take precedence over ResourceSpec and NonResourceSpec
if attributes.IsResourceRequest() {
if p.ResourcePermissionsSpec != nil {
if resourcePermissionAllowed(p.ResourcePermissionsSpec, attributes) {
return authorizer.DecisionAllow, "", nil
}
} else if p.ResourceSpec != nil {
if resourceMatches(*p, attributes) {
return authorizer.DecisionAllow, "", nil
}
}
} else {
if p.NonResourcePermissionsSpec != nil {
if nonResourcePermissionAllowed(p.NonResourcePermissionsSpec, attributes) {
return authorizer.DecisionAllow, "", nil
}
} else if p.NonResourceSpec != nil {
if nonResourceMatches(*p, attributes) {
return authorizer.DecisionAllow, "", nil
}
}
}
}
klog.V(4).Infof("Authorization failed, user: %#v, attributes: %#v\n", attributes.GetUser(), attributes)
return authorizer.DecisionDeny, "No policy matched.", nil
}