You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by sk...@apache.org on 2018/03/19 15:20:20 UTC
syncope git commit: [SYNCOPE-1283] Added support for Azure AD
Repository: syncope
Updated Branches:
refs/heads/2_0_X 98af7118e -> e901ce365
[SYNCOPE-1283] Added support for Azure AD
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/e901ce36
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/e901ce36
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/e901ce36
Branch: refs/heads/2_0_X
Commit: e901ce365a4cbd5ab67dbccd6c0693b0717ef667
Parents: 98af711
Author: skylark17 <ma...@tirasa.net>
Authored: Mon Mar 19 16:20:03 2018 +0100
Committer: skylark17 <ma...@tirasa.net>
Committed: Mon Mar 19 16:20:03 2018 +0100
----------------------------------------------------------------------
.../propagation/AzurePropagationActions.java | 201 +++++++++++++++++++
.../core/reference/ITImplementationLookup.java | 4 +
pom.xml | 6 +
3 files changed, 211 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/e901ce36/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AzurePropagationActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AzurePropagationActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AzurePropagationActions.java
new file mode 100644
index 0000000..6a35493
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AzurePropagationActions.java
@@ -0,0 +1,201 @@
+package org.apache.syncope.core.provisioning.java.propagation;
+
+import java.util.HashSet;
+import java.util.Set;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidPlainAttrValueException;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.AttributeUtil;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.identityconnectors.framework.common.objects.Name;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * This class is required during setup of an External Resource based on the ConnId
+ * <a href="https://github.com/Tirasa/ConnIdAzureBundle">Azure connector</a>.
+ *
+ * It manages:
+ * <ol>
+ * <li>the User id provided by Azure, which will need to be used for all subsequent operations</li>
+ * <li>the Group id provided by Azure, which will need to be used for all subsequent operations</li>
+ * </ol>
+ */
+public class AzurePropagationActions extends DefaultPropagationActions {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AzurePropagationActions.class);
+
+ @Autowired
+ private PlainSchemaDAO plainSchemaDAO;
+
+ @Autowired
+ private UserDAO userDAO;
+
+ @Autowired
+ private GroupDAO groupDAO;
+
+ @Autowired
+ private EntityFactory entityFactory;
+
+ @Autowired
+ private AnyUtilsFactory anyUtilsFactory;
+
+ private final static String USER_MAIL_NICKNAME = "mailNickname";
+
+ private final static String GROUP_MAIL_NICKNAME = "mailNickname";
+
+ protected String getAzureIdSchema() {
+ return "AzureUserId";
+ }
+
+ protected String getAzureGroupIdSchema() {
+ return "AzureGroupId";
+ }
+
+ @Transactional
+ @Override
+ public void before(final PropagationTask task, final ConnectorObject beforeObj) {
+ super.before(task, beforeObj);
+
+ switch (task.getAnyTypeKind()) {
+ case USER:
+ User user = userDAO.find(task.getEntityKey());
+ if (user != null) {
+ Set<Attribute> attributes = new HashSet<>(task.getAttributes());
+
+ // Ensure to set __NAME__ value to user's "mailNickname"
+ Name name = AttributeUtil.getNameFromAttributes(attributes);
+ if (name != null) {
+ attributes.remove(name);
+ }
+ attributes.add(
+ new Name(AttributeUtil.find(USER_MAIL_NICKNAME, attributes).getValue().get(0).toString()));
+
+ task.setAttributes(attributes);
+ }
+
+ break;
+ case GROUP:
+ Set<Attribute> attributes = new HashSet<>(task.getAttributes());
+
+ // Ensure to set __NAME__ value to user's "mailNickname"
+ Name name = AttributeUtil.getNameFromAttributes(attributes);
+ if (name != null) {
+ attributes.remove(name);
+ }
+ attributes.add(
+ new Name(AttributeUtil.find(GROUP_MAIL_NICKNAME, attributes).getValue().get(0).toString()));
+
+ task.setAttributes(attributes);
+ break;
+ default:
+ LOG.debug("Not about user, or group, not doing anything");
+ break;
+ }
+ }
+
+ @Transactional
+ @Override
+ public void after(final PropagationTask task, final TaskExec execution, final ConnectorObject afterObj) {
+ if (task.getOperation() == ResourceOperation.DELETE || task.getOperation() == ResourceOperation.NONE) {
+ return;
+ }
+
+ if (AnyTypeKind.USER.equals(task.getAnyTypeKind())) {
+
+ User user = userDAO.find(task.getEntityKey());
+ if (user == null) {
+ LOG.error("Could not find user {}, skipping", task.getEntityKey());
+ } else {
+ boolean modified = false;
+ AnyUtils anyUtils = anyUtilsFactory.getInstance(user);
+
+ // Azure User ID
+ PlainSchema azureId = plainSchemaDAO.find(getAzureIdSchema());
+ if (azureId == null) {
+ LOG.error("Could not find schema {}, skipping", getAzureIdSchema());
+ } else {
+ // set back the __UID__ received by Azure
+ UPlainAttr attr = user.getPlainAttr(getAzureIdSchema());
+ if (attr == null) {
+ attr = entityFactory.newEntity(UPlainAttr.class);
+ attr.setSchema(azureId);
+ attr.setOwner(user);
+ user.add(attr);
+
+ try {
+ attr.add(afterObj.getUid().getUidValue(), anyUtils);
+ modified = true;
+ } catch (InvalidPlainAttrValueException e) {
+ LOG.error("Invalid value for attribute {}: {}",
+ azureId.getKey(), afterObj.getUid().getUidValue(), e);
+ }
+ } else {
+ LOG.debug("User {} has already {} assigned: {}",
+ user, azureId.getKey(), attr.getValuesAsStrings());
+ }
+ }
+
+ if (modified) {
+ userDAO.save(user);
+ }
+ }
+ } else if (AnyTypeKind.GROUP.equals(task.getAnyTypeKind())) {
+
+ Group group = groupDAO.find(task.getEntityKey());
+ if (group == null) {
+ LOG.error("Could not find group {}, skipping", task.getEntityKey());
+ } else {
+ boolean modified = false;
+ AnyUtils anyUtils = anyUtilsFactory.getInstance(group);
+
+ // Azure Group ID
+ PlainSchema azureId = plainSchemaDAO.find(getAzureGroupIdSchema());
+ if (azureId == null) {
+ LOG.error("Could not find schema {}, skipping", getAzureGroupIdSchema());
+ } else {
+ // set back the __UID__ received by Azure
+ GPlainAttr attr = group.getPlainAttr(getAzureGroupIdSchema());
+ if (attr == null) {
+ attr = entityFactory.newEntity(GPlainAttr.class);
+ attr.setSchema(azureId);
+ attr.setOwner(group);
+ group.add(attr);
+
+ try {
+ attr.add(afterObj.getUid().getUidValue(), anyUtils);
+ modified = true;
+ } catch (InvalidPlainAttrValueException e) {
+ LOG.error("Invalid value for attribute {}: {}",
+ azureId.getKey(), afterObj.getUid().getUidValue(), e);
+ }
+ } else {
+ LOG.debug("Group {} has already {} assigned: {}",
+ group, azureId.getKey(), attr.getValuesAsStrings());
+ }
+ }
+
+ if (modified) {
+ groupDAO.save(group);
+ }
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/e901ce36/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java
index b5aa249..61c6ed3 100644
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java
@@ -56,7 +56,9 @@ import org.apache.syncope.core.persistence.jpa.dao.DefaultAccountRule;
import org.apache.syncope.core.persistence.jpa.dao.DefaultPasswordRule;
import org.apache.syncope.core.provisioning.java.DefaultLogicActions;
import org.apache.syncope.core.provisioning.java.data.DefaultItemTransformer;
+import org.apache.syncope.core.provisioning.java.propagation.AzurePropagationActions;
import org.apache.syncope.core.provisioning.java.propagation.DBPasswordPropagationActions;
+import org.apache.syncope.core.provisioning.java.propagation.GoogleAppsPropagationActions;
import org.apache.syncope.core.provisioning.java.propagation.LDAPMembershipPropagationActions;
import org.apache.syncope.core.provisioning.java.propagation.LDAPPasswordPropagationActions;
import org.apache.syncope.core.provisioning.java.pushpull.DBPasswordPullActions;
@@ -122,6 +124,8 @@ public class ITImplementationLookup implements ImplementationLookup {
classNames.add(LDAPMembershipPropagationActions.class.getName());
classNames.add(LDAPPasswordPropagationActions.class.getName());
classNames.add(DBPasswordPropagationActions.class.getName());
+ classNames.add(AzurePropagationActions.class.getName());
+ classNames.add(GoogleAppsPropagationActions.class.getName());
put(Type.PROPAGATION_ACTIONS, classNames);
classNames = new HashSet<>();
http://git-wip-us.apache.org/repos/asf/syncope/blob/e901ce36/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 66a83a5..954032d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -364,6 +364,7 @@ under the License.
<connid.ldap.version>1.5.2</connid.ldap.version>
<connid.ad.version>1.3.4</connid.ad.version>
<connid.googleapps.version>1.4.1</connid.googleapps.version>
+ <connid.azure.version>1.0.0-SNAPSHOT</connid.azure.version>
<cxf.version>3.1.15</cxf.version>
@@ -1837,6 +1838,11 @@ under the License.
<artifactId>net.tirasa.connid.bundles.googleapps</artifactId>
<version>${connid.googleapps.version}</version>
</artifactItem>
+ <artifactItem>
+ <groupId>net.tirasa.connid.bundles</groupId>
+ <artifactId>net.tirasa.connid.bundles.azure</artifactId>
+ <version>${connid.azure.version}</version>
+ </artifactItem>
</artifactItems>
</configuration>
</plugin>