Repository: syncope Updated Branches: refs/heads/master 410972518 -> a413dbca5
[SYNCOPE-1283] Fix checkstyle Project: http://git-wip-us.apache.org/repos/asf/syncope/repo Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/a413dbca Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/a413dbca Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/a413dbca Branch: refs/heads/master Commit: a413dbca5d69a18a76ba8fc2380fcbe40d4cfd02 Parents: 4109725 Author: skylark17 <matteo.alessandr...@tirasa.net> Authored: Mon Mar 19 17:02:16 2018 +0100 Committer: skylark17 <matteo.alessandr...@tirasa.net> Committed: Mon Mar 19 17:16:03 2018 +0100 ---------------------------------------------------------------------- .../propagation/AzurePropagationActions.java | 218 +++++++++++++++++++ .../core/reference/ITImplementationLookup.java | 4 + 2 files changed, 222 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/a413dbca/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..1a3ee96 --- /dev/null +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AzurePropagationActions.java @@ -0,0 +1,218 @@ +/* + * 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.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.apache.syncope.core.provisioning.api.propagation.PropagationActions; +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 implements PropagationActions { + + 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 static final String USER_MAIL_NICKNAME = "mailNickname"; + + private static final 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) { + 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()).orElse(null); + 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()).orElse(null); + 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/a413dbca/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 8466864..352692e 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 @@ -65,7 +65,9 @@ import org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddress import org.apache.syncope.core.persistence.jpa.dao.DefaultAccountRule; import org.apache.syncope.core.persistence.jpa.dao.DefaultPasswordRule; import org.apache.syncope.core.persistence.jpa.dao.DefaultPullCorrelationRule; +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; @@ -180,6 +182,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(ImplementationType.PROPAGATION_ACTIONS, classNames); classNames = new HashSet<>();