| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.syncope.core.persistence.jpa.dao; |
| |
| import java.util.ArrayList; |
| import java.util.Base64; |
| import java.util.List; |
| import java.util.Objects; |
| import java.util.Optional; |
| import org.apache.commons.lang3.tuple.Pair; |
| import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition; |
| import org.apache.syncope.common.lib.policy.DefaultPushCorrelationRuleConf; |
| import org.apache.syncope.common.lib.policy.PushCorrelationRuleConf; |
| import org.apache.syncope.common.lib.search.ConnObjectTOFiqlSearchConditionBuilder; |
| import org.apache.syncope.common.lib.types.MappingPurpose; |
| import org.apache.syncope.core.persistence.api.dao.PushCorrelationRule; |
| import org.apache.syncope.core.persistence.api.dao.PushCorrelationRuleConfClass; |
| import org.apache.syncope.core.persistence.api.entity.Any; |
| import org.apache.syncope.core.persistence.api.entity.resource.Provision; |
| import org.apache.syncope.core.provisioning.api.AccountGetter; |
| import org.apache.syncope.core.provisioning.api.MappingManager; |
| import org.apache.syncope.core.provisioning.api.PlainAttrGetter; |
| import org.identityconnectors.common.security.GuardedByteArray; |
| import org.identityconnectors.common.security.GuardedString; |
| import org.identityconnectors.common.security.SecurityUtil; |
| import org.identityconnectors.framework.common.objects.Attribute; |
| import org.identityconnectors.framework.common.objects.AttributeBuilder; |
| import org.identityconnectors.framework.common.objects.ConnectorObject; |
| import org.identityconnectors.framework.common.objects.filter.Filter; |
| import org.identityconnectors.framework.common.objects.filter.FilterBuilder; |
| import org.springframework.beans.factory.annotation.Autowired; |
| import org.springframework.util.CollectionUtils; |
| |
| @PushCorrelationRuleConfClass(DefaultPushCorrelationRuleConf.class) |
| public class DefaultPushCorrelationRule implements PushCorrelationRule { |
| |
| protected static final ConnObjectTOFiqlSearchConditionBuilder FIQL_BUILDER = |
| new ConnObjectTOFiqlSearchConditionBuilder(); |
| |
| @Autowired |
| protected MappingManager mappingManager; |
| |
| protected DefaultPushCorrelationRuleConf conf; |
| |
| @Override |
| public void setConf(final PushCorrelationRuleConf conf) { |
| if (conf instanceof DefaultPushCorrelationRuleConf) { |
| this.conf = DefaultPushCorrelationRuleConf.class.cast(conf); |
| } else { |
| throw new IllegalArgumentException( |
| DefaultPushCorrelationRuleConf.class.getName() + " expected, got " + conf.getClass().getName()); |
| } |
| } |
| |
| @Override |
| public Filter getFilter(final Any<?> any, final Provision provision) { |
| List<Filter> filters = new ArrayList<>(); |
| |
| provision.getMapping().getItems().stream().filter( |
| item -> conf.getSchemas().contains(item.getIntAttrName()) && item.getPurpose() != MappingPurpose.NONE). |
| forEach(item -> { |
| Pair<String, Attribute> attr = mappingManager.prepareAttr( |
| provision, |
| item, |
| any, |
| null, |
| AccountGetter.DEFAULT, |
| AccountGetter.DEFAULT, |
| PlainAttrGetter.DEFAULT); |
| if (attr != null) { |
| Attribute toFilter = null; |
| if (attr.getLeft() != null) { |
| toFilter = AttributeBuilder.build(item.getExtAttrName(), attr.getLeft()); |
| } else if (attr.getRight() != null) { |
| toFilter = attr.getRight(); |
| } |
| if (toFilter != null) { |
| filters.add(provision.isIgnoreCaseMatch() |
| ? FilterBuilder.equalsIgnoreCase(toFilter) |
| : FilterBuilder.equalTo(toFilter)); |
| } |
| } |
| }); |
| |
| return conf.isOrSchemas() |
| ? FilterBuilder.or(filters) |
| : FilterBuilder.and(filters); |
| } |
| |
| @Override |
| public String getFiql(final ConnectorObject connectorObject, final Provision provision) { |
| List<CompleteCondition> conditions = new ArrayList<>(); |
| |
| provision.getMapping().getItems().stream().filter( |
| item -> conf.getSchemas().contains(item.getIntAttrName()) && item.getPurpose() != MappingPurpose.NONE). |
| forEach(item -> Optional.ofNullable(connectorObject.getAttributeByName(item.getExtAttrName())). |
| ifPresent(attr -> { |
| if (CollectionUtils.isEmpty(attr.getValue())) { |
| conditions.add(FIQL_BUILDER.isNull(attr.getName())); |
| } else { |
| List<CompleteCondition> valueConditions = new ArrayList<>(); |
| |
| attr.getValue().stream().filter(Objects::nonNull).forEach(value -> { |
| if (value instanceof GuardedString) { |
| valueConditions.add(FIQL_BUILDER.is(attr.getName()). |
| equalTo(SecurityUtil.decrypt((GuardedString) value))); |
| } else if (value instanceof GuardedByteArray) { |
| valueConditions.add(FIQL_BUILDER.is(attr.getName()). |
| equalTo(new String(SecurityUtil.decrypt((GuardedByteArray) value)))); |
| } else if (value instanceof byte[]) { |
| valueConditions.add(FIQL_BUILDER.is(attr.getName()). |
| equalTo(Base64.getEncoder().encodeToString((byte[]) value))); |
| } else { |
| valueConditions.add(FIQL_BUILDER.is(attr.getName()).equalTo(value.toString())); |
| } |
| }); |
| |
| if (!valueConditions.isEmpty()) { |
| conditions.add(valueConditions.size() == 1 |
| ? valueConditions.get(0) |
| : FIQL_BUILDER.and(valueConditions)); |
| } |
| } |
| })); |
| |
| return conf.isOrSchemas() |
| ? FIQL_BUILDER.or(conditions).query() |
| : FIQL_BUILDER.and(conditions).query(); |
| } |
| } |