1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.core.persistence.jpa.validation.entity;
20
21 import java.util.HashSet;
22 import java.util.Set;
23 import javax.validation.ConstraintValidatorContext;
24 import org.apache.syncope.common.lib.to.Item;
25 import org.apache.syncope.common.lib.to.ItemContainer;
26 import org.apache.syncope.common.lib.to.Mapping;
27 import org.apache.syncope.common.lib.to.OrgUnit;
28 import org.apache.syncope.common.lib.types.EntityViolationType;
29 import org.apache.syncope.core.persistence.api.entity.AnyType;
30 import org.apache.syncope.core.persistence.api.entity.Entity;
31 import org.apache.syncope.core.persistence.api.entity.ExternalResource;
32 import org.identityconnectors.framework.common.objects.ObjectClass;
33
34 public class ExternalResourceValidator extends AbstractValidator<ExternalResourceCheck, ExternalResource> {
35
36 private static boolean areItemsValid(
37 final ItemContainer itemContainer,
38 final ConstraintValidatorContext context) {
39
40 if (itemContainer.getItems().stream().
41 anyMatch(item -> item.getIntAttrName() == null
42 || item.getExtAttrName() == null
43 || item.getPurpose() == null)) {
44
45 context.buildConstraintViolationWithTemplate(
46 getTemplate(EntityViolationType.InvalidMapping,
47 "intAttrName, extAttrName and purpose must be specified for each item")).
48 addPropertyNode("items").addConstraintViolation();
49 return false;
50 }
51
52 if (itemContainer.getConnObjectKeyItem().isEmpty()) {
53 context.buildConstraintViolationWithTemplate(
54 getTemplate(EntityViolationType.InvalidMapping, "Single ConnObjectKey mapping is required")).
55 addPropertyNode("connObjectKey.size").addConstraintViolation();
56 return false;
57 }
58
59 return true;
60 }
61
62 private static boolean isValid(final OrgUnit orgUnit, final ConstraintValidatorContext context) {
63 if (orgUnit == null) {
64 return true;
65 }
66
67 return areItemsValid(orgUnit, context);
68 }
69
70 private static boolean isValid(final Mapping mapping, final ConstraintValidatorContext context) {
71 if (mapping == null) {
72 return true;
73 }
74
75 boolean isValid = true;
76
77 long passwords = mapping.getItems().stream().filter(Item::isPassword).count();
78 if (passwords > 1) {
79 context.buildConstraintViolationWithTemplate(
80 getTemplate(EntityViolationType.InvalidMapping, "One password mapping is allowed at most")).
81 addPropertyNode("password.size").addConstraintViolation();
82 isValid = false;
83 }
84
85 return isValid && areItemsValid(mapping, context);
86 }
87
88 @Override
89 public boolean isValid(final ExternalResource resource, final ConstraintValidatorContext context) {
90 context.disableDefaultConstraintViolation();
91
92 if (resource.getKey() == null || !Entity.ID_PATTERN.matcher(resource.getKey()).matches()) {
93 context.buildConstraintViolationWithTemplate(
94 getTemplate(EntityViolationType.InvalidKey, resource.getKey())).
95 addPropertyNode("key").addConstraintViolation();
96 return false;
97 }
98
99 Set<String> anyTypes = new HashSet<>();
100 Set<String> objectClasses = new HashSet<>();
101 boolean validMappings = resource.getProvisions().stream().allMatch(provision -> {
102 anyTypes.add(provision.getAnyType());
103 if (provision.getObjectClass() != null) {
104 objectClasses.add(provision.getObjectClass());
105 }
106 return isValid(provision.getMapping(), context);
107 });
108 validMappings &= isValid(resource.getOrgUnit(), context);
109
110 if (anyTypes.size() < resource.getProvisions().size()) {
111 context.buildConstraintViolationWithTemplate(getTemplate(EntityViolationType.InvalidResource,
112 "Each provision requires a different " + AnyType.class.getSimpleName())).
113 addPropertyNode("provisions").addConstraintViolation();
114 return false;
115 }
116 if (objectClasses.size() < resource.getProvisions().size()) {
117 context.buildConstraintViolationWithTemplate(getTemplate(EntityViolationType.InvalidResource,
118 "Each provision requires a different" + ObjectClass.class.getSimpleName())).
119 addPropertyNode("provisions").addConstraintViolation();
120 return false;
121 }
122
123 return validMappings;
124 }
125 }