Repository: istio/istio
File: pilot/pkg/model/authorization.go (Go)

Code before:
	Allow  []AuthorizationPolicy
	Audit  []AuthorizationPolicy
}

// ListAuthorizationPolicies returns authorization policies applied to the workload in the given namespace.
func (policy *AuthorizationPolicies) ListAuthorizationPolicies(namespace string, workload labels.Instance) AuthorizationPoliciesResult {
	ret := AuthorizationPoliciesResult{}
	if policy == nil {
		return ret
	}

	var namespaces []string
	if policy.RootNamespace != "" {
		namespaces = append(namespaces, policy.RootNamespace)
	}
	// To prevent duplicate policies in case root namespace equals proxy's namespace.
	if namespace != policy.RootNamespace {
		namespaces = append(namespaces, namespace)
	}

	for _, ns := range namespaces {
		for _, config := range policy.NamespaceToPolicies[ns] {
			spec := config.Spec
			selector := labels.Instance(spec.GetSelector().GetMatchLabels())
			if selector.SubsetOf(workload) {
				switch config.Spec.GetAction() {
				case authpb.AuthorizationPolicy_ALLOW:
					ret.Allow = append(ret.Allow, config)
				case authpb.AuthorizationPolicy_DENY:
					ret.Deny = append(ret.Deny, config)
				case authpb.AuthorizationPolicy_AUDIT:
					ret.Audit = append(ret.Audit, config)
				case authpb.AuthorizationPolicy_CUSTOM:
					ret.Custom = append(ret.Custom, config)
				default:
					log.Errorf("ignored authorization policy %s.%s with unsupported action: %s",
						config.Namespace, config.Name, config.Spec.GetAction())
				}
			}
		}
	}

	return ret
}


Review comment (refactor):
I am concerned that the current logic of looping through root ns and workload ns may end up applying a policy in the root ns for a waypoint that isn't in the root ns. 

Do I need to prevent this here? _By refactoring waypoint logic out of the ns loop or adding a check for if the root ns is not equal to the waypoint ns._ @keithmattix 

Code after:
	Allow  []AuthorizationPolicy
	Audit  []AuthorizationPolicy
}

// ListAuthorizationPolicies returns authorization policies applied to the workload in the given namespace.
func (policy *AuthorizationPolicies) ListAuthorizationPolicies(selectionOpts WorkloadSelectionOpts) AuthorizationPoliciesResult {
	configs := AuthorizationPoliciesResult{}
	if policy == nil {
		return configs
	}
	rootNamespace := policy.RootNamespace
	namespace := selectionOpts.Namespace
	workloadLabels := selectionOpts.WorkloadLabels
	var lookupInNamespaces []string

	if namespace != rootNamespace {
		// Only check the root namespace if the (workload) namespace is not already the root namespace
		// to avoid double inclusion.
		lookupInNamespaces = []string{rootNamespace, namespace}
	} else {
		lookupInNamespaces = []string{namespace}
	}

	for _, ns := range lookupInNamespaces {
		for _, config := range policy.NamespaceToPolicies[ns] {
			spec := config.Spec
			switch getPolicyMatcher(gvk.AuthorizationPolicy, config.Name, selectionOpts, spec) {
			case policyMatchSelector:
				selector := labels.Instance(spec.GetSelector().GetMatchLabels())
				if selector.SubsetOf(workloadLabels) {
					configs = updateAuthorizationPoliciesResult(configs, config)
				}
			case policyMatchDirect:
				configs = updateAuthorizationPoliciesResult(configs, config)
			}
		}
	}

	return configs
}

func updateAuthorizationPoliciesResult(configs AuthorizationPoliciesResult, config AuthorizationPolicy) AuthorizationPoliciesResult {
	log.Infof("applying authorization policy %s.%s",
		config.Namespace, config.Name)
	switch config.Spec.GetAction() {
	case authpb.AuthorizationPolicy_ALLOW:
		configs.Allow = append(configs.Allow, config)
	case authpb.AuthorizationPolicy_DENY:
		configs.Deny = append(configs.Deny, config)
	case authpb.AuthorizationPolicy_AUDIT:
		configs.Audit = append(configs.Audit, config)