You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2019/11/22 12:15:35 UTC

[syncope] branch master updated: [SYNCOPE-1499] Support was missing for SAML2 IdP and OIDC extensions

This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/master by this push:
     new 80cbe28  [SYNCOPE-1499] Support was missing for SAML2 IdP and OIDC extensions
80cbe28 is described below

commit 80cbe283ebd5858a00a6d50ddd035f2ada72d415
Author: Francesco Chicchiriccò <il...@apache.org>
AuthorDate: Fri Nov 22 13:05:45 2019 +0100

    [SYNCOPE-1499] Support was missing for SAML2 IdP and OIDC extensions
---
 .../provisioning/java/pushpull/InboundMatcher.java | 51 ++++++++----
 .../syncope/core/logic/oidc/OIDCUserManager.java   | 96 +++-------------------
 .../syncope/core/logic/saml2/SAML2UserManager.java | 96 +++-------------------
 3 files changed, 55 insertions(+), 188 deletions(-)

diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/InboundMatcher.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/InboundMatcher.java
index 33a9764..870f47d 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/InboundMatcher.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/InboundMatcher.java
@@ -37,9 +37,7 @@ import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.policy.PullCorrelationRuleEntity;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
-import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.IntAttrName;
@@ -58,6 +56,7 @@ import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
+import org.apache.syncope.core.persistence.api.entity.resource.Item;
 import org.apache.syncope.core.provisioning.api.VirAttrHandler;
 import org.apache.syncope.core.provisioning.java.IntAttrNameParser;
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
@@ -125,7 +124,7 @@ public class InboundMatcher {
             return Optional.empty();
         }
 
-        Stream<MappingItem> mapItems = Stream.concat(
+        Stream<Item> mapItems = Stream.concat(
                 provision.get().getMapping().getItems().stream(),
                 virSchemaDAO.findByProvision(provision.get()).stream().map(VirSchema::asLinkingMappingItem));
 
@@ -189,10 +188,25 @@ public class InboundMatcher {
     }
 
     public List<PullMatch> matchByConnObjectKeyValue(
-            final MappingItem connObjectKeyItem,
+            final Item connObjectKeyItem,
             final String connObjectKeyValue,
             final Provision provision) {
 
+        return matchByConnObjectKeyValue(
+                connObjectKeyItem,
+                connObjectKeyValue,
+                provision.getAnyType().getKind(),
+                provision.isIgnoreCaseMatch(),
+                provision.getResource());
+    }
+
+    public List<PullMatch> matchByConnObjectKeyValue(
+            final Item connObjectKeyItem,
+            final String connObjectKeyValue,
+            final AnyTypeKind anyTypeKind,
+            final boolean ignoreCaseMatch,
+            final ExternalResource resource) {
+
         String finalConnObjectKeyValue = connObjectKeyValue;
         for (ItemTransformer transformer : MappingUtils.getItemTransformers(connObjectKeyItem)) {
             List<Object> output = transformer.beforePull(
@@ -208,14 +222,13 @@ public class InboundMatcher {
 
         IntAttrName intAttrName;
         try {
-            intAttrName = intAttrNameParser.parse(
-                    connObjectKeyItem.getIntAttrName(), provision.getAnyType().getKind());
+            intAttrName = intAttrNameParser.parse(connObjectKeyItem.getIntAttrName(), anyTypeKind);
         } catch (ParseException e) {
             LOG.error("Invalid intAttrName '{}' specified, ignoring", connObjectKeyItem.getIntAttrName(), e);
             return noMatchResult;
         }
 
-        AnyUtils anyUtils = anyUtilsFactory.getInstance(provision.getAnyType().getKind());
+        AnyUtils anyUtils = anyUtilsFactory.getInstance(anyTypeKind);
 
         List<Any<?>> anys = new ArrayList<>();
 
@@ -226,7 +239,7 @@ public class InboundMatcher {
                     break;
 
                 case "username":
-                    if (provision.getAnyType().getKind() == AnyTypeKind.USER && provision.isIgnoreCaseMatch()) {
+                    if (anyTypeKind == AnyTypeKind.USER && ignoreCaseMatch) {
                         AnyCond cond = new AnyCond(AttributeCond.Type.IEQ);
                         cond.setSchema("username");
                         cond.setExpression(connObjectKeyValue);
@@ -237,7 +250,7 @@ public class InboundMatcher {
                     break;
 
                 case "name":
-                    if (provision.getAnyType().getKind() == AnyTypeKind.GROUP && provision.isIgnoreCaseMatch()) {
+                    if (anyTypeKind == AnyTypeKind.GROUP && ignoreCaseMatch) {
                         AnyCond cond = new AnyCond(AttributeCond.Type.IEQ);
                         cond.setSchema("name");
                         cond.setExpression(connObjectKeyValue);
@@ -246,7 +259,7 @@ public class InboundMatcher {
                         Optional.ofNullable(groupDAO.findByName(connObjectKeyValue)).ifPresent(anys::add);
                     }
 
-                    if (provision.getAnyType().getKind() == AnyTypeKind.ANY_OBJECT && provision.isIgnoreCaseMatch()) {
+                    if (anyTypeKind == AnyTypeKind.ANY_OBJECT && ignoreCaseMatch) {
                         AnyCond cond = new AnyCond(AttributeCond.Type.IEQ);
                         cond.setSchema("name");
                         cond.setExpression(connObjectKeyValue);
@@ -273,17 +286,17 @@ public class InboundMatcher {
 
                     if (intAttrName.getSchema().isUniqueConstraint()) {
                         anyUtils.dao().findByPlainAttrUniqueValue((PlainSchema) intAttrName.getSchema(),
-                                (PlainAttrUniqueValue) value, provision.isIgnoreCaseMatch()).
+                                (PlainAttrUniqueValue) value, ignoreCaseMatch).
                                 ifPresent(anys::add);
                     } else {
                         anys.addAll(anyUtils.dao().findByPlainAttrValue((PlainSchema) intAttrName.getSchema(),
-                                value, provision.isIgnoreCaseMatch()));
+                                value, ignoreCaseMatch));
                     }
                     break;
 
                 case DERIVED:
                     anys.addAll(anyUtils.dao().findByDerAttrValue((DerSchema) intAttrName.getSchema(),
-                            connObjectKeyValue, provision.isIgnoreCaseMatch()));
+                            connObjectKeyValue, ignoreCaseMatch));
                     break;
 
                 default:
@@ -294,9 +307,11 @@ public class InboundMatcher {
                 map(any -> new PullMatch(MatchType.ANY, any)).
                 collect(Collectors.toList());
 
-        userDAO.findLinkedAccount(provision.getResource(), finalConnObjectKeyValue).
-                map(account -> new PullMatch(MatchType.LINKED_ACCOUNT, account)).
-                ifPresent(result::add);
+        if (resource != null) {
+            userDAO.findLinkedAccount(resource, finalConnObjectKeyValue).
+                    map(account -> new PullMatch(MatchType.LINKED_ACCOUNT, account)).
+                    ifPresent(result::add);
+        }
 
         return result.isEmpty() ? noMatchResult : result;
     }
@@ -348,7 +363,7 @@ public class InboundMatcher {
             } else {
                 String connObjectKeyValue = null;
 
-                Optional<? extends MappingItem> connObjectKeyItem = MappingUtils.getConnObjectKeyItem(provision);
+                Optional<? extends Item> connObjectKeyItem = MappingUtils.getConnObjectKeyItem(provision);
                 if (connObjectKeyItem.isPresent()) {
                     Attribute connObjectKeyAttr = syncDelta.getObject().
                             getAttributeByName(connObjectKeyItem.get().getExtAttrName());
@@ -388,7 +403,7 @@ public class InboundMatcher {
     public List<Realm> match(final SyncDelta syncDelta, final OrgUnit orgUnit) {
         String connObjectKey = null;
 
-        Optional<? extends OrgUnitItem> connObjectKeyItem = orgUnit.getConnObjectKeyItem();
+        Optional<? extends Item> connObjectKeyItem = orgUnit.getConnObjectKeyItem();
         if (connObjectKeyItem.isPresent()) {
             Attribute connObjectKeyAttr = syncDelta.getObject().
                     getAttributeByName(connObjectKeyItem.get().getExtAttrName());
diff --git a/ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/oidc/OIDCUserManager.java b/ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/oidc/OIDCUserManager.java
index dd9c0f0..0b88dac 100644
--- a/ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/oidc/OIDCUserManager.java
+++ b/ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/oidc/OIDCUserManager.java
@@ -20,7 +20,6 @@ package org.apache.syncope.core.logic.oidc;
 
 import java.text.ParseException;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
 import java.util.stream.Collectors;
@@ -36,23 +35,16 @@ import org.apache.syncope.common.lib.to.OIDCLoginResponseTO;
 import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.DerSchema;
-import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.OIDCProvider;
 import org.apache.syncope.core.persistence.api.entity.OIDCProviderItem;
-import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.IntAttrName;
 import org.apache.syncope.core.provisioning.api.OIDCProviderActions;
 import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
 import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
 import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
 import org.apache.syncope.core.provisioning.java.IntAttrNameParser;
+import org.apache.syncope.core.provisioning.java.pushpull.InboundMatcher;
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
 import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
 import org.apache.syncope.core.spring.ImplementationManager;
@@ -69,13 +61,13 @@ public class OIDCUserManager {
     private static final Logger LOG = LoggerFactory.getLogger(OIDCUserManager.class);
 
     @Autowired
-    private UserDAO userDAO;
+    private InboundMatcher inboundMatcher;
 
     @Autowired
-    private IntAttrNameParser intAttrNameParser;
+    private UserDAO userDAO;
 
     @Autowired
-    private EntityFactory entityFactory;
+    private IntAttrNameParser intAttrNameParser;
 
     @Autowired
     private TemplateUtils templateUtils;
@@ -87,81 +79,15 @@ public class OIDCUserManager {
     private UserDataBinder binder;
 
     @Transactional(readOnly = true)
-    public List<String> findMatchingUser(final String keyValue, final OIDCProviderItem connObjectKeyItem) {
-        List<String> result = new ArrayList<>();
-
-        String transformed = keyValue;
-        for (ItemTransformer transformer : MappingUtils.getItemTransformers(connObjectKeyItem)) {
-            List<Object> output = transformer.beforePull(
-                    null,
-                    null,
-                    Collections.<Object>singletonList(transformed));
-            if (output != null && !output.isEmpty()) {
-                transformed = output.get(0).toString();
-            }
-        }
-
-        IntAttrName intAttrName;
-        try {
-            intAttrName = intAttrNameParser.parse(connObjectKeyItem.getIntAttrName(), AnyTypeKind.USER);
-        } catch (ParseException e) {
-            LOG.error("Invalid intAttrName '{}' specified, ignoring", connObjectKeyItem.getIntAttrName(), e);
-            return result;
-        }
-
-        if (intAttrName.getField() != null) {
-            switch (intAttrName.getField()) {
-                case "key":
-                    User byKey = userDAO.find(transformed);
-                    if (byKey != null) {
-                        result.add(byKey.getUsername());
-                    }
-                    break;
-
-                case "username":
-                    User byUsername = userDAO.findByUsername(transformed);
-                    if (byUsername != null) {
-                        result.add(byUsername.getUsername());
-                    }
-                    break;
-
-                default:
-            }
-        } else if (intAttrName.getSchemaType() != null) {
-            switch (intAttrName.getSchemaType()) {
-                case PLAIN:
-                    PlainAttrValue value = entityFactory.newEntity(UPlainAttrValue.class);
-
-                    if (intAttrName.getSchemaType() == SchemaType.PLAIN) {
-                        value.setStringValue(transformed);
-                    } else {
-                        try {
-                            value.parseValue((PlainSchema) intAttrName.getSchema(), transformed);
-                        } catch (ParsingValidationException e) {
-                            LOG.error("While parsing provided key value {}", transformed, e);
-                            value.setStringValue(transformed);
-                        }
-                    }
-
-                    result.addAll(userDAO.findByPlainAttrValue(
-                            (PlainSchema) intAttrName.getSchema(), value, false).stream().
-                            map(User::getUsername).collect(Collectors.toList()));
-                    break;
-
-                case DERIVED:
-                    result.addAll(userDAO.findByDerAttrValue(
-                            (DerSchema) intAttrName.getSchema(), transformed, false).stream().
-                            map(User::getUsername).collect(Collectors.toList()));
-                    break;
-
-                default:
-            }
-        }
-
-        return result;
+    public List<String> findMatchingUser(final String connObjectKeyValue, final OIDCProviderItem connObjectKeyItem) {
+        return inboundMatcher.matchByConnObjectKeyValue(
+                connObjectKeyItem, connObjectKeyValue, AnyTypeKind.USER, false, null).stream().
+                filter(match -> match.getAny() != null).
+                map(match -> match.getAny().getKey()).
+                collect(Collectors.toList());
     }
 
-    private static List<OIDCProviderActions> getActions(final OIDCProvider op) {
+    private List<OIDCProviderActions> getActions(final OIDCProvider op) {
         List<OIDCProviderActions> actions = new ArrayList<>();
         op.getActions().forEach(impl -> {
             try {
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2UserManager.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2UserManager.java
index 0a6b857..8fe49c0 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2UserManager.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2UserManager.java
@@ -36,24 +36,17 @@ import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.SAML2LoginResponseTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
 import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
 import org.apache.syncope.core.persistence.api.dao.SAML2IdPDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.DerSchema;
-import org.apache.syncope.core.persistence.api.entity.EntityFactory;
-import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.SAML2IdP;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.IntAttrName;
 import org.apache.syncope.core.provisioning.api.SAML2IdPActions;
 import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
 import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
 import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
 import org.apache.syncope.core.provisioning.java.IntAttrNameParser;
+import org.apache.syncope.core.provisioning.java.pushpull.InboundMatcher;
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
 import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
 import org.apache.syncope.core.spring.ImplementationManager;
@@ -73,6 +66,9 @@ public class SAML2UserManager {
     private SAML2IdPDAO idpDAO;
 
     @Autowired
+    private InboundMatcher inboundMatcher;
+
+    @Autowired
     private UserDAO userDAO;
 
     @Autowired
@@ -82,9 +78,6 @@ public class SAML2UserManager {
     private IntAttrNameParser intAttrNameParser;
 
     @Autowired
-    private EntityFactory entityFactory;
-
-    @Autowired
     private TemplateUtils templateUtils;
 
     @Autowired
@@ -94,85 +87,18 @@ public class SAML2UserManager {
     private UserDataBinder binder;
 
     @Transactional(readOnly = true)
-    public List<String> findMatchingUser(final String keyValue, final String idpKey) {
-        List<String> result = new ArrayList<>();
-
+    public List<String> findMatchingUser(final String connObjectKeyValue, final String idpKey) {
         SAML2IdP idp = idpDAO.find(idpKey);
         if (idp == null) {
             LOG.warn("Invalid IdP: {}", idpKey);
-            return result;
-        }
-
-        String transformed = keyValue;
-        for (ItemTransformer transformer : MappingUtils.getItemTransformers(idp.getConnObjectKeyItem().get())) {
-            List<Object> output = transformer.beforePull(
-                    null,
-                    null,
-                    Collections.<Object>singletonList(transformed));
-            if (output != null && !output.isEmpty()) {
-                transformed = output.get(0).toString();
-            }
-        }
-
-        IntAttrName intAttrName;
-        try {
-            intAttrName = intAttrNameParser.parse(idp.getConnObjectKeyItem().get().getIntAttrName(), AnyTypeKind.USER);
-        } catch (ParseException e) {
-            LOG.error("Invalid intAttrName '{}' specified, ignoring",
-                    idp.getConnObjectKeyItem().get().getIntAttrName(), e);
-            return result;
-        }
-
-        if (intAttrName.getField() != null) {
-            switch (intAttrName.getField()) {
-                case "key":
-                    User byKey = userDAO.find(transformed);
-                    if (byKey != null) {
-                        result.add(byKey.getUsername());
-                    }
-                    break;
-
-                case "username":
-                    User byUsername = userDAO.findByUsername(transformed);
-                    if (byUsername != null) {
-                        result.add(byUsername.getUsername());
-                    }
-                    break;
-
-                default:
-            }
-        } else if (intAttrName.getSchemaType() != null) {
-            switch (intAttrName.getSchemaType()) {
-                case PLAIN:
-                    PlainAttrValue value = entityFactory.newEntity(UPlainAttrValue.class);
-
-                    if (intAttrName.getSchemaType() == SchemaType.PLAIN) {
-                        value.setStringValue(transformed);
-                    } else {
-                        try {
-                            value.parseValue((PlainSchema) intAttrName.getSchema(), transformed);
-                        } catch (ParsingValidationException e) {
-                            LOG.error("While parsing provided key value {}", transformed, e);
-                            value.setStringValue(transformed);
-                        }
-                    }
-
-                    result.addAll(userDAO.findByPlainAttrValue(
-                            (PlainSchema) intAttrName.getSchema(), value, false).stream().
-                            map(User::getUsername).collect(Collectors.toList()));
-                    break;
-
-                case DERIVED:
-                    result.addAll(userDAO.findByDerAttrValue(
-                            (DerSchema) intAttrName.getSchema(), transformed, false).stream().
-                            map(User::getUsername).collect(Collectors.toList()));
-                    break;
-
-                default:
-            }
+            return Collections.emptyList();
         }
 
-        return result;
+        return inboundMatcher.matchByConnObjectKeyValue(
+                idp.getConnObjectKeyItem().get(), connObjectKeyValue, AnyTypeKind.USER, false, null).stream().
+                filter(match -> match.getAny() != null).
+                map(match -> match.getAny().getKey()).
+                collect(Collectors.toList());
     }
 
     private List<SAML2IdPActions> getActions(final SAML2IdPEntity idp) {