func()

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
}