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
}