1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.core.provisioning.java.pushpull;
20
21 import java.util.ArrayList;
22 import java.util.Base64;
23 import java.util.List;
24 import java.util.Objects;
25 import java.util.Optional;
26 import org.apache.commons.lang3.tuple.Pair;
27 import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
28 import org.apache.syncope.common.lib.policy.DefaultPushCorrelationRuleConf;
29 import org.apache.syncope.common.lib.policy.PushCorrelationRuleConf;
30 import org.apache.syncope.common.lib.search.ConnObjectTOFiqlSearchConditionBuilder;
31 import org.apache.syncope.common.lib.to.Provision;
32 import org.apache.syncope.common.lib.types.MappingPurpose;
33 import org.apache.syncope.core.persistence.api.entity.Any;
34 import org.apache.syncope.core.persistence.api.entity.ExternalResource;
35 import org.apache.syncope.core.provisioning.api.AccountGetter;
36 import org.apache.syncope.core.provisioning.api.MappingManager;
37 import org.apache.syncope.core.provisioning.api.PlainAttrGetter;
38 import org.apache.syncope.core.provisioning.api.rules.PushCorrelationRule;
39 import org.apache.syncope.core.provisioning.api.rules.PushCorrelationRuleConfClass;
40 import org.identityconnectors.common.security.GuardedByteArray;
41 import org.identityconnectors.common.security.GuardedString;
42 import org.identityconnectors.common.security.SecurityUtil;
43 import org.identityconnectors.framework.common.objects.Attribute;
44 import org.identityconnectors.framework.common.objects.AttributeBuilder;
45 import org.identityconnectors.framework.common.objects.ConnectorObject;
46 import org.identityconnectors.framework.common.objects.filter.Filter;
47 import org.identityconnectors.framework.common.objects.filter.FilterBuilder;
48 import org.springframework.beans.factory.annotation.Autowired;
49 import org.springframework.util.CollectionUtils;
50
51 @PushCorrelationRuleConfClass(DefaultPushCorrelationRuleConf.class)
52 public class DefaultPushCorrelationRule implements PushCorrelationRule {
53
54 protected static final ConnObjectTOFiqlSearchConditionBuilder FIQL_BUILDER =
55 new ConnObjectTOFiqlSearchConditionBuilder();
56
57 @Autowired
58 protected MappingManager mappingManager;
59
60 protected DefaultPushCorrelationRuleConf conf;
61
62 @Override
63 public void setConf(final PushCorrelationRuleConf conf) {
64 if (conf instanceof DefaultPushCorrelationRuleConf) {
65 this.conf = DefaultPushCorrelationRuleConf.class.cast(conf);
66 } else {
67 throw new IllegalArgumentException(
68 DefaultPushCorrelationRuleConf.class.getName() + " expected, got " + conf.getClass().getName());
69 }
70 }
71
72 @Override
73 public Filter getFilter(final Any<?> any, final ExternalResource resource, final Provision provision) {
74 List<Filter> filters = new ArrayList<>();
75
76 provision.getMapping().getItems().stream().filter(
77 item -> conf.getSchemas().contains(item.getIntAttrName()) && item.getPurpose() != MappingPurpose.NONE).
78 forEach(item -> {
79 Pair<String, Attribute> attr = mappingManager.prepareAttr(
80 resource,
81 provision,
82 item,
83 any,
84 null,
85 AccountGetter.DEFAULT,
86 AccountGetter.DEFAULT,
87 PlainAttrGetter.DEFAULT);
88 if (attr != null) {
89 Attribute toFilter = null;
90 if (attr.getLeft() != null) {
91 toFilter = AttributeBuilder.build(item.getExtAttrName(), attr.getLeft());
92 } else if (attr.getRight() != null) {
93 toFilter = attr.getRight();
94 }
95 if (toFilter != null) {
96 filters.add(provision.isIgnoreCaseMatch()
97 ? FilterBuilder.equalsIgnoreCase(toFilter)
98 : FilterBuilder.equalTo(toFilter));
99 }
100 }
101 });
102
103 return conf.isOrSchemas()
104 ? FilterBuilder.or(filters)
105 : FilterBuilder.and(filters);
106 }
107
108 @Override
109 public String getFIQL(final ConnectorObject connectorObject, final Provision provision) {
110 List<CompleteCondition> conditions = new ArrayList<>();
111
112 provision.getMapping().getItems().stream().filter(
113 item -> conf.getSchemas().contains(item.getIntAttrName()) && item.getPurpose() != MappingPurpose.NONE).
114 forEach(item -> Optional.ofNullable(connectorObject.getAttributeByName(item.getExtAttrName())).
115 ifPresent(attr -> {
116 if (CollectionUtils.isEmpty(attr.getValue())) {
117 conditions.add(FIQL_BUILDER.isNull(attr.getName()));
118 } else {
119 List<CompleteCondition> valueConditions = new ArrayList<>();
120
121 attr.getValue().stream().filter(Objects::nonNull).forEach(value -> {
122 if (value instanceof GuardedString) {
123 valueConditions.add(FIQL_BUILDER.is(attr.getName()).
124 equalTo(SecurityUtil.decrypt((GuardedString) value)));
125 } else if (value instanceof GuardedByteArray) {
126 valueConditions.add(FIQL_BUILDER.is(attr.getName()).
127 equalTo(new String(SecurityUtil.decrypt((GuardedByteArray) value))));
128 } else if (value instanceof byte[]) {
129 valueConditions.add(FIQL_BUILDER.is(attr.getName()).
130 equalTo(Base64.getEncoder().encodeToString((byte[]) value)));
131 } else {
132 valueConditions.add(FIQL_BUILDER.is(attr.getName()).equalTo(value.toString()));
133 }
134 });
135
136 if (!valueConditions.isEmpty()) {
137 conditions.add(valueConditions.size() == 1
138 ? valueConditions.get(0)
139 : FIQL_BUILDER.and(valueConditions));
140 }
141 }
142 }));
143
144 return conf.isOrSchemas()
145 ? FIQL_BUILDER.or(conditions).query()
146 : FIQL_BUILDER.and(conditions).query();
147 }
148 }