func checkAccessRoles()

in lib/dam/dam_integrity.go [397:448]


func checkAccessRoles(roles map[string]*pb.ViewRole, templateName, serviceName string, cfg *pb.DamConfig, vopts ValidateCfgOpts) (string, error) {
	if len(roles) == 0 {
		return "", fmt.Errorf("a view must have at least one role with a selected policy")
	}
	desc := vopts.Services.Descriptors[serviceName]
	for rname, role := range roles {
		if err := checkName(rname); err != nil {
			return httputils.StatusPath(rname), fmt.Errorf("role has invalid name %q: %v", rname, err)
		}
		if len(role.ComputedPolicyBasis) > 0 {
			return httputils.StatusPath(rname, "roleCategories"), fmt.Errorf("role %q roleCategories should be determined at runtime and cannot be stored as part of the config", rname)
		}
		if len(role.ComputedPolicyBasis) > 0 {
			return httputils.StatusPath(rname, "policyBasis"), fmt.Errorf("role %q policyBasis should be determined at runtime and cannot be stored as part of the config", rname)
		}
		if len(role.Policies) > 20 {
			return httputils.StatusPath(rname, "policies"), fmt.Errorf("role exceeeds policy limit")
		}
		hasAllowlist := false
		for i, p := range role.Policies {
			if len(p.Name) == 0 {
				return httputils.StatusPath(rname, "policies", strconv.Itoa(i), "name"), fmt.Errorf("access policy name is not defined")
			}
			if p.Name == allowlistPolicyName {
				hasAllowlist = true
				emails := strings.Split(p.Args["users"], ";")
				if len(emails) > 20 {
					return httputils.StatusPath(rname, "policies", strconv.Itoa(i), "args", "users"), fmt.Errorf("number of emails on allowlist policy exceeeds limit")
				}
				for j, email := range emails {
					if _, err := mail.ParseAddress(email); err != nil {
						return httputils.StatusPath(rname, "policies", strconv.Itoa(i), "args", "users"), fmt.Errorf("email entry %d (%q) is invalid", j, email)
					}
				}
			}
			policy, ok := cfg.Policies[p.Name]
			if !ok {
				return httputils.StatusPath(rname, "policies", strconv.Itoa(i), "name"), fmt.Errorf("policy %q is not defined", p.Name)
			}
			if path, err := validator.ValidatePolicy(policy, cfg.VisaTypes, cfg.TrustedSources, p.Args); err != nil {
				return httputils.StatusPath(rname, "policies", strconv.Itoa(i), path), err
			}
		}
		if len(role.Policies) == 0 && !desc.Properties.IsAggregate {
			return httputils.StatusPath(rname, "policies"), fmt.Errorf("must provide at least one target policy")
		}
		if hasAllowlist && len(role.Policies) > 1 {
			return httputils.StatusPath(rname, "policies"), fmt.Errorf("allowlist policies cannot be used in combination with any other policies")
		}
	}
	return "", nil
}