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 2015/04/21 11:34:20 UTC
[51/57] syncope git commit: [SYNCOPE-119] New security model
implemented
http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
index b67f543..4929d62 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
@@ -18,7 +18,6 @@
*/
package org.apache.syncope.core.logic;
-import org.apache.syncope.core.misc.security.UnauthorizedGroupException;
import java.lang.reflect.Method;
import java.security.AccessControlException;
import java.util.ArrayList;
@@ -30,19 +29,17 @@ import java.util.Set;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.mod.AttrMod;
import org.apache.syncope.common.lib.mod.StatusMod;
import org.apache.syncope.common.lib.mod.UserMod;
-import org.apache.syncope.common.lib.to.BulkAction;
-import org.apache.syncope.common.lib.to.BulkActionResult;
-import org.apache.syncope.common.lib.to.BulkActionResult.Status;
-import org.apache.syncope.common.lib.to.MembershipTO;
import org.apache.syncope.common.lib.to.PropagationStatus;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.Entitlement;
import org.apache.syncope.common.lib.types.SubjectType;
-import org.apache.syncope.core.persistence.api.GroupEntitlementUtil;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
import org.apache.syncope.core.persistence.api.dao.GroupDAO;
import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO;
@@ -57,7 +54,9 @@ import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
import org.apache.syncope.core.provisioning.java.VirAttrHandler;
-import org.apache.syncope.core.misc.security.AuthContextUtil;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.misc.security.UnauthorizedException;
+import org.apache.syncope.core.misc.serialization.POJOHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
@@ -114,25 +113,20 @@ public class UserLogic extends AbstractSubjectLogic<UserTO, UserMod> {
@PreAuthorize("hasRole('USER_LIST')")
@Transactional(readOnly = true, rollbackFor = { Throwable.class })
@Override
- public int count() {
- return userDAO.count(GroupEntitlementUtil.getGroupKeys(AuthContextUtil.getOwnedEntitlementNames()));
+ public int count(final List<String> realms) {
+ return userDAO.count(
+ getEffectiveRealms(AuthContextUtils.getAuthorizations().get(Entitlement.USER_LIST), realms));
}
@PreAuthorize("hasRole('USER_LIST')")
@Transactional(readOnly = true, rollbackFor = { Throwable.class })
@Override
- public int searchCount(final SearchCond searchCondition) {
- return searchDAO.count(GroupEntitlementUtil.getGroupKeys(AuthContextUtil.getOwnedEntitlementNames()),
- searchCondition, SubjectType.USER);
- }
-
- @PreAuthorize("hasRole('USER_LIST')")
- @Transactional(readOnly = true, rollbackFor = { Throwable.class })
- @Override
- public List<UserTO> list(final int page, final int size, final List<OrderByClause> orderBy) {
- final Set<Long> adminGroupKeys = GroupEntitlementUtil.getGroupKeys(AuthContextUtil.getOwnedEntitlementNames());
+ public List<UserTO> list(
+ final int page, final int size, final List<OrderByClause> orderBy, final List<String> realms) {
- return CollectionUtils.collect(userDAO.findAll(adminGroupKeys, page, size, orderBy),
+ return CollectionUtils.collect(userDAO.findAll(
+ getEffectiveRealms(AuthContextUtils.getAuthorizations().get(Entitlement.USER_LIST), realms),
+ page, size, orderBy),
new Transformer<User, UserTO>() {
@Override
@@ -142,11 +136,12 @@ public class UserLogic extends AbstractSubjectLogic<UserTO, UserMod> {
}, new ArrayList<UserTO>());
}
- @PreAuthorize("isAuthenticated() "
- + "and not(hasRole(T(org.apache.syncope.common.lib.SyncopeConstants).ANONYMOUS_ENTITLEMENT))")
+ @PreAuthorize("isAuthenticated()")
@Transactional(readOnly = true)
- public UserTO readSelf() {
- return binder.getAuthenticatedUserTO();
+ public Pair<String, UserTO> readSelf() {
+ return ImmutablePair.of(
+ POJOHelper.serialize(AuthContextUtils.getAuthorizations()),
+ binder.getAuthenticatedUserTO());
}
@PreAuthorize("hasRole('USER_READ')")
@@ -156,14 +151,23 @@ public class UserLogic extends AbstractSubjectLogic<UserTO, UserMod> {
return binder.getUserTO(key);
}
- @PreAuthorize("hasRole('USER_LIST')")
- @Transactional(readOnly = true)
+ @PreAuthorize("hasRole('USER_SEARCH')")
+ @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+ @Override
+ public int searchCount(final SearchCond searchCondition, final List<String> realms) {
+ return searchDAO.count(
+ getEffectiveRealms(AuthContextUtils.getAuthorizations().get(Entitlement.USER_SEARCH), realms),
+ searchCondition, SubjectType.USER);
+ }
+
+ @PreAuthorize("hasRole('USER_SEARCH')")
+ @Transactional(readOnly = true, rollbackFor = { Throwable.class })
@Override
public List<UserTO> search(final SearchCond searchCondition, final int page, final int size,
- final List<OrderByClause> orderBy) {
+ final List<OrderByClause> orderBy, final List<String> realms) {
- final List<User> matchingUsers = searchDAO.search(GroupEntitlementUtil.getGroupKeys(AuthContextUtil.
- getOwnedEntitlementNames()),
+ final List<User> matchingUsers = searchDAO.search(
+ getEffectiveRealms(AuthContextUtils.getAuthorizations().get(Entitlement.USER_SEARCH), realms),
searchCondition, page, size, orderBy, SubjectType.USER);
return CollectionUtils.collect(matchingUsers, new Transformer<User, UserTO>() {
@@ -174,24 +178,22 @@ public class UserLogic extends AbstractSubjectLogic<UserTO, UserMod> {
}, new ArrayList<UserTO>());
}
- @PreAuthorize("isAnonymous() or hasRole(T(org.apache.syncope.common.lib.SyncopeConstants).ANONYMOUS_ENTITLEMENT)")
+ @PreAuthorize("isAnonymous() or hasRole('ANONYMOUS')")
public UserTO createSelf(final UserTO userTO, final boolean storePassword) {
return doCreate(userTO, storePassword);
}
@PreAuthorize("hasRole('USER_CREATE')")
public UserTO create(final UserTO userTO, final boolean storePassword) {
- Collection<Long> requestGroupIds = CollectionUtils.removeAll(
- CollectionUtils.collect(userTO.getMemberships(), new Transformer<MembershipTO, Long>() {
-
- @Override
- public Long transform(final MembershipTO membership) {
- return membership.getGroupId();
- }
- }, new ArrayList<Long>()),
- GroupEntitlementUtil.getGroupKeys(AuthContextUtil.getOwnedEntitlementNames()));
- if (!requestGroupIds.isEmpty()) {
- throw new UnauthorizedGroupException(requestGroupIds);
+ if (userTO.getRealm() == null) {
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
+ throw sce;
+ }
+ Set<String> effectiveRealms = getEffectiveRealms(
+ AuthContextUtils.getAuthorizations().get(Entitlement.USER_CREATE),
+ Collections.singleton(userTO.getRealm()));
+ if (effectiveRealms.isEmpty()) {
+ throw new UnauthorizedException(SubjectType.USER, null);
}
return doCreate(userTO, storePassword);
@@ -209,8 +211,7 @@ public class UserLogic extends AbstractSubjectLogic<UserTO, UserMod> {
return savedTO;
}
- @PreAuthorize("isAuthenticated() "
- + "and not(hasRole(T(org.apache.syncope.common.lib.SyncopeConstants).ANONYMOUS_ENTITLEMENT))")
+ @PreAuthorize("isAuthenticated() and not(hasRole('ANONYMOUS'))")
public UserTO updateSelf(final UserMod userMod) {
UserTO userTO = binder.getAuthenticatedUserTO();
@@ -284,7 +285,7 @@ public class UserLogic extends AbstractSubjectLogic<UserTO, UserMod> {
return savedTO;
}
- @PreAuthorize("isAnonymous() or hasRole(T(org.apache.syncope.common.lib.SyncopeConstants).ANONYMOUS_ENTITLEMENT)")
+ @PreAuthorize("isAnonymous() or hasRole('ANONYMOUS')")
@Transactional
public void requestPasswordReset(final String username, final String securityAnswer) {
if (username == null) {
@@ -305,7 +306,7 @@ public class UserLogic extends AbstractSubjectLogic<UserTO, UserMod> {
provisioningManager.requestPasswordReset(user.getKey());
}
- @PreAuthorize("isAnonymous() or hasRole(T(org.apache.syncope.common.lib.SyncopeConstants).ANONYMOUS_ENTITLEMENT)")
+ @PreAuthorize("isAnonymous() or hasRole('ANONYMOUS')")
@Transactional
public void confirmPasswordReset(final String token, final String password) {
User user = userDAO.findByToken(token);
@@ -315,8 +316,7 @@ public class UserLogic extends AbstractSubjectLogic<UserTO, UserMod> {
provisioningManager.confirmPasswordReset(user, token, password);
}
- @PreAuthorize("isAuthenticated() "
- + "and not(hasRole(T(org.apache.syncope.common.lib.SyncopeConstants).ANONYMOUS_ENTITLEMENT))")
+ @PreAuthorize("isAuthenticated() and not(hasRole('ANONYMOUS'))")
public UserTO deleteSelf() {
UserTO userTO = binder.getAuthenticatedUserTO();
@@ -354,59 +354,6 @@ public class UserLogic extends AbstractSubjectLogic<UserTO, UserMod> {
return deletedTO;
}
- @PreAuthorize("(hasRole('USER_DELETE') and #bulkAction.operation == #bulkAction.operation.DELETE) or "
- + "(hasRole('USER_UPDATE') and "
- + "(#bulkAction.operation == #bulkAction.operation.REACTIVATE or "
- + "#bulkAction.operation == #bulkAction.operation.SUSPEND))")
- public BulkActionResult bulk(final BulkAction bulkAction) {
- BulkActionResult res = new BulkActionResult();
-
- switch (bulkAction.getOperation()) {
- case DELETE:
- for (String key : bulkAction.getTargets()) {
- try {
- res.add(delete(Long.valueOf(key)).getKey(), Status.SUCCESS);
- } catch (Exception e) {
- LOG.error("Error performing delete for user {}", key, e);
- res.add(key, Status.FAILURE);
- }
- }
- break;
-
- case SUSPEND:
- for (String key : bulkAction.getTargets()) {
- StatusMod statusMod = new StatusMod();
- statusMod.setKey(Long.valueOf(key));
- statusMod.setType(StatusMod.ModType.SUSPEND);
- try {
- res.add(status(statusMod).getKey(), Status.SUCCESS);
- } catch (Exception e) {
- LOG.error("Error performing suspend for user {}", key, e);
- res.add(key, Status.FAILURE);
- }
- }
- break;
-
- case REACTIVATE:
- for (String key : bulkAction.getTargets()) {
- StatusMod statusMod = new StatusMod();
- statusMod.setKey(Long.valueOf(key));
- statusMod.setType(StatusMod.ModType.REACTIVATE);
- try {
- res.add(status(statusMod).getKey(), Status.SUCCESS);
- } catch (Exception e) {
- LOG.error("Error performing reactivate for user {}", key, e);
- res.add(key, Status.FAILURE);
- }
- }
- break;
-
- default:
- }
-
- return res;
- }
-
@PreAuthorize("hasRole('USER_UPDATE')")
@Transactional(rollbackFor = { Throwable.class })
@Override
http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java
index d15eef9..69c95f0 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java
@@ -19,9 +19,9 @@
package org.apache.syncope.core.logic;
import java.lang.reflect.Method;
-import java.util.AbstractMap;
import java.util.List;
-import java.util.Map;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.mod.AbstractAttributableMod;
import org.apache.syncope.common.lib.mod.UserMod;
import org.apache.syncope.common.lib.to.UserTO;
@@ -70,9 +70,9 @@ public class UserWorkflowLogic extends AbstractTransactionalLogic<WorkflowFormTO
UserMod userMod = new UserMod();
userMod.setKey(userTO.getKey());
- List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(
- new WorkflowResult<Map.Entry<UserMod, Boolean>>(
- new AbstractMap.SimpleEntry<UserMod, Boolean>(userMod, null),
+ List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
+ new WorkflowResult<Pair<UserMod, Boolean>>(
+ new ImmutablePair<UserMod, Boolean>(userMod, null),
updated.getPropByRes(), updated.getPerformedTasks()));
taskExecutor.execute(tasks);
@@ -110,9 +110,9 @@ public class UserWorkflowLogic extends AbstractTransactionalLogic<WorkflowFormTO
if (updated.getResult() instanceof UserMod
&& updated.getPropByRes() != null && !updated.getPropByRes().isEmpty()) {
- List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(
- new WorkflowResult<Map.Entry<UserMod, Boolean>>(
- new AbstractMap.SimpleEntry<>((UserMod) updated.getResult(), Boolean.TRUE),
+ List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
+ new WorkflowResult<Pair<UserMod, Boolean>>(
+ new ImmutablePair<>((UserMod) updated.getResult(), Boolean.TRUE),
updated.getPropByRes(),
updated.getPerformedTasks()));
http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java b/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
index 88d42fd..9e40ff1 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
@@ -31,7 +31,7 @@ import org.apache.syncope.core.persistence.api.entity.EntityFactory;
import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.ExceptionUtil;
+import org.apache.syncope.core.misc.ExceptionUtils2;
import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
@@ -186,7 +186,7 @@ public class NotificationJob implements Job {
execution.setStatus(Status.NOT_SENT.name());
if (task.getTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal()) {
- execution.setMessage(ExceptionUtil.getFullStackTrace(e));
+ execution.setMessage(ExceptionUtils2.getFullStackTrace(e));
}
auditManager.audit(
http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
index 38c96c6..d564335 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
@@ -22,8 +22,8 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.report.GroupReportletConf;
import org.apache.syncope.common.lib.report.GroupReportletConf.Feature;
import org.apache.syncope.common.lib.to.AbstractAttributableTO;
@@ -31,8 +31,6 @@ import org.apache.syncope.common.lib.to.AbstractSubjectTO;
import org.apache.syncope.common.lib.to.AttrTO;
import org.apache.syncope.common.lib.to.GroupTO;
import org.apache.syncope.common.lib.types.SubjectType;
-import org.apache.syncope.core.persistence.api.GroupEntitlementUtil;
-import org.apache.syncope.core.persistence.api.dao.EntitlementDAO;
import org.apache.syncope.core.persistence.api.dao.GroupDAO;
import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
@@ -51,9 +49,6 @@ public class GroupReportlet extends AbstractReportlet<GroupReportletConf> {
private static final int PAGE_SIZE = 10;
@Autowired
- private EntitlementDAO entitlementDAO;
-
- @Autowired
private GroupDAO groupDAO;
@Autowired
@@ -62,13 +57,14 @@ public class GroupReportlet extends AbstractReportlet<GroupReportletConf> {
@Autowired
private GroupDataBinder groupDataBinder;
- private List<Group> getPagedgroups(final int page) {
- final Set<Long> adminGroupIds = GroupEntitlementUtil.getGroupKeys(entitlementDAO.findAll());
- final List<Group> result;
+ private List<Group> getPagedGroups(final int page) {
+ List<Group> result;
+
if (StringUtils.isBlank(conf.getMatchingCond())) {
- result = groupDAO.findAll();
+ result = groupDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, page, PAGE_SIZE);
} else {
- result = searchDAO.search(adminGroupIds, SearchCondConverter.convert(conf.getMatchingCond()),
+ result = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+ SearchCondConverter.convert(conf.getMatchingCond()),
page, PAGE_SIZE, Collections.<OrderByClause>emptyList(), SubjectType.GROUP);
}
@@ -76,11 +72,9 @@ public class GroupReportlet extends AbstractReportlet<GroupReportletConf> {
}
private int count() {
- Set<Long> adminGroupIds = GroupEntitlementUtil.getGroupKeys(entitlementDAO.findAll());
-
return StringUtils.isBlank(conf.getMatchingCond())
- ? groupDAO.findAll().size()
- : searchDAO.count(adminGroupIds,
+ ? groupDAO.count(SyncopeConstants.FULL_ADMIN_REALMS)
+ : searchDAO.count(SyncopeConstants.FULL_ADMIN_REALMS,
SearchCondConverter.convert(conf.getMatchingCond()), SubjectType.GROUP);
}
@@ -236,20 +230,6 @@ public class GroupReportlet extends AbstractReportlet<GroupReportletConf> {
doExtractAttributes(handler, groupTO, conf.getPlainAttrs(), conf.getDerAttrs(), conf.getVirAttrs());
- if (conf.getFeatures().contains(Feature.entitlements)) {
- handler.startElement("", "", "entitlements", null);
-
- for (String ent : groupTO.getEntitlements()) {
- atts.clear();
-
- atts.addAttribute("", "", "id", ReportXMLConst.XSD_STRING, String.valueOf(ent));
-
- handler.startElement("", "", "entitlement", atts);
- handler.endElement("", "", "entitlement");
- }
-
- handler.endElement("", "", "entitlements");
- }
// to get resources associated to a group
if (conf.getFeatures().contains(Feature.resources)) {
doExtractResources(handler, groupTO);
@@ -322,7 +302,7 @@ public class GroupReportlet extends AbstractReportlet<GroupReportletConf> {
protected void doExtract(final ContentHandler handler) throws SAXException, ReportException {
doExtractConf(handler);
for (int i = 1; i <= (count() / PAGE_SIZE) + 1; i++) {
- doExtract(handler, getPagedgroups(i));
+ doExtract(handler, getPagedGroups(i));
}
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
index 7d03b61..e07612a 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
@@ -40,7 +40,7 @@ import org.apache.syncope.core.persistence.api.entity.Report;
import org.apache.syncope.core.persistence.api.entity.ReportExec;
import org.apache.syncope.core.logic.ReportLogic;
import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.apache.syncope.core.misc.ExceptionUtil;
+import org.apache.syncope.core.misc.ExceptionUtils2;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
@@ -167,7 +167,7 @@ public class ReportJob implements Job {
? e.getCause()
: e;
reportExecutionMessage.
- append(ExceptionUtil.getFullStackTrace(t)).
+ append(ExceptionUtils2.getFullStackTrace(t)).
append("\n==================\n");
}
}
@@ -182,7 +182,7 @@ public class ReportJob implements Job {
}
} catch (Exception e) {
execution.setStatus(ReportExecStatus.FAILURE);
- reportExecutionMessage.append(ExceptionUtil.getFullStackTrace(e));
+ reportExecutionMessage.append(ExceptionUtils2.getFullStackTrace(e));
throw new JobExecutionException(e, true);
} finally {
http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
index f0023fc..02976f6 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
@@ -22,8 +22,8 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.report.UserReportletConf;
import org.apache.syncope.common.lib.report.UserReportletConf.Feature;
import org.apache.syncope.common.lib.to.AbstractAttributableTO;
@@ -32,8 +32,6 @@ import org.apache.syncope.common.lib.to.AttrTO;
import org.apache.syncope.common.lib.to.MembershipTO;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.types.SubjectType;
-import org.apache.syncope.core.persistence.api.GroupEntitlementUtil;
-import org.apache.syncope.core.persistence.api.dao.EntitlementDAO;
import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
@@ -54,9 +52,6 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
private static final int PAGE_SIZE = 10;
@Autowired
- private EntitlementDAO entitlementDAO;
-
- @Autowired
private UserDAO userDAO;
@Autowired
@@ -69,13 +64,13 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
private GroupDataBinder groupDataBinder;
private List<User> getPagedUsers(final int page) {
- final Set<Long> adminGroupIds = GroupEntitlementUtil.getGroupKeys(entitlementDAO.findAll());
+ List<User> result;
- final List<User> result;
if (StringUtils.isBlank(conf.getMatchingCond())) {
- result = userDAO.findAll(adminGroupIds, page, PAGE_SIZE);
+ result = userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, page, PAGE_SIZE);
} else {
- result = searchDAO.search(adminGroupIds, SearchCondConverter.convert(conf.getMatchingCond()),
+ result = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+ SearchCondConverter.convert(conf.getMatchingCond()),
page, PAGE_SIZE, Collections.<OrderByClause>emptyList(), SubjectType.USER);
}
@@ -83,11 +78,10 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
}
private int count() {
- Set<Long> adminGroupIds = GroupEntitlementUtil.getGroupKeys(entitlementDAO.findAll());
-
return StringUtils.isBlank(conf.getMatchingCond())
- ? userDAO.count(adminGroupIds)
- : searchDAO.count(adminGroupIds, SearchCondConverter.convert(conf.getMatchingCond()), SubjectType.USER);
+ ? userDAO.count(SyncopeConstants.FULL_ADMIN_REALMS)
+ : searchDAO.count(SyncopeConstants.FULL_ADMIN_REALMS,
+ SearchCondConverter.convert(conf.getMatchingCond()), SubjectType.USER);
}
private void doExtractResources(final ContentHandler handler, final AbstractSubjectTO subjectTO)
@@ -280,17 +274,18 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
atts.clear();
atts.addAttribute("", "", "id", ReportXMLConst.XSD_LONG, String.valueOf(memb.getKey()));
- atts.addAttribute("", "", "groupId", ReportXMLConst.XSD_LONG, String.valueOf(memb.getGroupId()));
- atts.addAttribute("", "", "groupName", ReportXMLConst.XSD_STRING, String.valueOf(memb.getGroupName()));
+ atts.addAttribute("", "", "groupId", ReportXMLConst.XSD_LONG, String.valueOf(memb.getGroupKey()));
+ atts.addAttribute("", "", "groupName", ReportXMLConst.XSD_STRING, String.
+ valueOf(memb.getGroupName()));
handler.startElement("", "", "membership", atts);
doExtractAttributes(handler, memb, memb.getPlainAttrMap().keySet(), memb.getDerAttrMap()
.keySet(), memb.getVirAttrMap().keySet());
if (conf.getFeatures().contains(Feature.resources)) {
- Membership actualMemb = user.getMembership(memb.getGroupId());
+ Membership actualMemb = user.getMembership(memb.getGroupKey());
if (actualMemb == null) {
- LOG.warn("Unexpected: cannot find membership for group {} for user {}", memb.getGroupId(),
+ LOG.warn("Unexpected: cannot find membership for group {} for user {}", memb.getGroupKey(),
user);
} else {
doExtractResources(handler, groupDataBinder.getGroupTO(actualMemb.getGroup()));
http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/logic/src/main/resources/report/groupReportlet2csv.xsl
----------------------------------------------------------------------
diff --git a/core/logic/src/main/resources/report/groupReportlet2csv.xsl b/core/logic/src/main/resources/report/groupReportlet2csv.xsl
index 06730dc..86fe635 100644
--- a/core/logic/src/main/resources/report/groupReportlet2csv.xsl
+++ b/core/logic/src/main/resources/report/groupReportlet2csv.xsl
@@ -62,18 +62,6 @@ under the License.
<xsl:value-of select="$groupAttr/."/>
<xsl:text>"</xsl:text>
</xsl:when>
- <xsl:when test="name($attrs/*[name(.)=$nameAttr]/*[name(.)='entitlement'])
- and count($attrs/*[name(.)=$nameAttr]/node()) > 0">
- <xsl:text>"</xsl:text>
- <xsl:for-each select="$attrs/*/entitlement">
- <xsl:variable name="value" select="@id"/>
- <xsl:value-of select="$value"/>
- <xsl:if test="position() != last()">
- <xsl:value-of select="$delimiter"/>
- </xsl:if>
- </xsl:for-each>
- <xsl:text>"</xsl:text>
- </xsl:when>
<xsl:when test="name($attrs/*[name(.)=$nameAttr]/*[name(.)='resource'])
and count($attrs/*[name(.)=$nameAttr]/node()) > 0">
<xsl:text>"</xsl:text>
http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/logic/src/main/resources/report/groupReportlet2fo.xsl
----------------------------------------------------------------------
diff --git a/core/logic/src/main/resources/report/groupReportlet2fo.xsl b/core/logic/src/main/resources/report/groupReportlet2fo.xsl
index c83eb31..e95d170 100644
--- a/core/logic/src/main/resources/report/groupReportlet2fo.xsl
+++ b/core/logic/src/main/resources/report/groupReportlet2fo.xsl
@@ -102,19 +102,6 @@ under the License.
</xsl:otherwise>
</xsl:choose>
- <!--entitlements-->
- <xsl:choose>
- <xsl:when test="entitlements/entitlement">
- <xsl:call-template name="entitlements">
- <xsl:with-param name="label">Entitlements</xsl:with-param>
- <xsl:with-param name="node" select="entitlements/entitlement"/>
- </xsl:call-template>
- </xsl:when>
- <xsl:otherwise>
- <fo:block color="red" font-size="9pt" space-after="3mm">THIS GROUP HASN'T ANY ENTITLEMENT</fo:block>
- </xsl:otherwise>
- </xsl:choose>
-
<xsl:choose>
<xsl:when test="users/user">
<fo:block font-size="11pt" font-weight="bold">Users</fo:block>
@@ -184,36 +171,6 @@ under the License.
</fo:table-body>
</fo:table>
</xsl:template>
- <!--entitlements template-->
- <xsl:template name="entitlements">
- <xsl:param name="label"/>
- <xsl:param name="node"/>
- <fo:block font-size="11pt" font-weight="bold" space-after="2mm" space-before="5mm">
- <xsl:value-of select="$label"/>
- </fo:block>
- <fo:table table-layout="fixed" space-after="7mm">
- <fo:table-column/>
- <!--<fo:table-column/>-->
- <fo:table-header>
- <fo:table-row height="7mm" background-color="(#ccccba)">
- <fo:table-cell>
- <fo:block font-weight="bold">Name</fo:block>
- </fo:table-cell>
- </fo:table-row>
- </fo:table-header>
- <fo:table-body>
- <xsl:for-each select="$node">
- <fo:table-row height="4mm" background-color="(#ccccff)">
- <fo:table-cell>
- <fo:block>
- <xsl:value-of select="@id"/>
- </fo:block>
- </fo:table-cell>
- </fo:table-row>
- </xsl:for-each>
- </fo:table-body>
- </fo:table>
- </xsl:template>
<xsl:template name="groupResources">
<xsl:param name="node"/>
http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/logic/src/main/resources/report/groupReportlet2html.xsl
----------------------------------------------------------------------
diff --git a/core/logic/src/main/resources/report/groupReportlet2html.xsl b/core/logic/src/main/resources/report/groupReportlet2html.xsl
index ce36c6b..7e2a52f 100644
--- a/core/logic/src/main/resources/report/groupReportlet2html.xsl
+++ b/core/logic/src/main/resources/report/groupReportlet2html.xsl
@@ -88,18 +88,6 @@ under the License.
</xsl:choose>
<xsl:choose>
- <xsl:when test="entitlements/entitlement">
- <xsl:call-template name="entitlements">
- <xsl:with-param name="label">Entitlements: </xsl:with-param>
- <xsl:with-param name="node" select="entitlements/entitlement"/>
- </xsl:call-template>
- </xsl:when>
- <xsl:otherwise>
- <h5>THIS GROUP HASN'T ANY ENTITLEMENT</h5>
- </xsl:otherwise>
- </xsl:choose>
-
- <xsl:choose>
<xsl:when test="users/user">
<h4>Users</h4>
<xsl:for-each select="users/user">
@@ -118,30 +106,6 @@ under the License.
</xsl:for-each>
</xsl:template>
-
- <!--entitlement template-->
- <xsl:template name="entitlements">
- <xsl:param name="label"/>
- <xsl:param name="node"/>
-
- <h4>
- <xsl:value-of select="$label"/>
- </h4>
-
- <table>
-
- <tbody>
- <xsl:for-each select="$node">
- <tr>
- <td>
- <xsl:value-of select="@id"/>
- </td>
- </tr>
- </xsl:for-each>
- </tbody>
- </table>
- </xsl:template>
-
<xsl:template name="attributes">
<xsl:param name="label"/>
http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java
----------------------------------------------------------------------
diff --git a/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java b/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java
index 4555189..47ea2a9 100644
--- a/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java
+++ b/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java
@@ -26,6 +26,7 @@ import com.icegreen.greenmail.util.GreenMail;
import com.icegreen.greenmail.util.ServerSetup;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Random;
@@ -37,6 +38,8 @@ import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Store;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.search.GroupFiqlSearchConditionBuilder;
@@ -47,22 +50,23 @@ import org.apache.syncope.common.lib.to.NotificationTaskTO;
import org.apache.syncope.common.lib.to.GroupTO;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.Entitlement;
import org.apache.syncope.common.lib.types.IntMappingType;
import org.apache.syncope.common.lib.types.TaskType;
import org.apache.syncope.common.lib.types.TraceLevel;
import org.apache.syncope.core.persistence.api.dao.ConfDAO;
-import org.apache.syncope.core.persistence.api.dao.EntitlementDAO;
import org.apache.syncope.core.persistence.api.dao.NotificationDAO;
import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
import org.apache.syncope.core.persistence.api.dao.TaskDAO;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilFactory;
-import org.apache.syncope.core.persistence.api.entity.Entitlement;
+import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
import org.apache.syncope.core.persistence.api.entity.EntityFactory;
import org.apache.syncope.core.persistence.api.entity.Notification;
import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr;
import org.apache.syncope.core.persistence.api.entity.conf.CPlainSchema;
import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
import org.apache.syncope.core.logic.notification.NotificationJob;
+import org.apache.syncope.core.misc.security.SyncopeGrantedAuthority;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
import org.junit.AfterClass;
import org.junit.Before;
@@ -77,7 +81,6 @@ import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
@@ -119,10 +122,10 @@ public class NotificationTest {
private String adminUser;
@Autowired
- private EntitlementDAO entitlementDAO;
+ private NotificationDAO notificationDAO;
@Autowired
- private NotificationDAO notificationDAO;
+ private RealmDAO realmDAO;
@Autowired
private TaskDAO taskDAO;
@@ -155,7 +158,7 @@ public class NotificationTest {
private EntityFactory entityFactory;
@Autowired
- private AttributableUtilFactory attrUtilFactory;
+ private AttributableUtilsFactory attrUtilsFactory;
@BeforeClass
public static void startGreenMail() {
@@ -190,6 +193,7 @@ public class NotificationTest {
UserTO userTO = new UserTO();
userTO.setPassword("password123");
userTO.setUsername(uid);
+ userTO.setRealm("/even/two");
userTO.getPlainAttrs().add(attributeTO("fullname", uid));
userTO.getPlainAttrs().add(attributeTO("firstname", uid));
@@ -205,12 +209,16 @@ public class NotificationTest {
@Before
public void setupSecurity() {
- List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
- for (Entitlement entitlement : entitlementDAO.findAll()) {
- authorities.add(new SimpleGrantedAuthority(entitlement.getKey()));
- }
+ List<GrantedAuthority> authorities = CollectionUtils.collect(Arrays.asList(Entitlement.values()),
+ new Transformer<Entitlement, GrantedAuthority>() {
+
+ @Override
+ public GrantedAuthority transform(final Entitlement entitlement) {
+ return new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM);
+ }
+ }, new ArrayList<GrantedAuthority>());
- UserDetails userDetails = new User(adminUser, "FAKE_PASSWORD", true, true, true, true, authorities);
+ UserDetails userDetails = new User(adminUser, "FAKE_PASSWORD", authorities);
Authentication authentication = new TestingAuthenticationToken(userDetails, "FAKE_PASSWORD", authorities);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
@@ -279,7 +287,7 @@ public class NotificationTest {
// 2. create user
UserTO userTO = getSampleTO(MAIL_ADDRESS);
MembershipTO membershipTO = new MembershipTO();
- membershipTO.setGroupId(7);
+ membershipTO.setGroupKey(7);
userTO.getMemberships().add(membershipTO);
userLogic.create(userTO, true);
@@ -336,7 +344,7 @@ public class NotificationTest {
// 2. create user
UserTO userTO = getSampleTO(MAIL_ADDRESS);
MembershipTO membershipTO = new MembershipTO();
- membershipTO.setGroupId(7);
+ membershipTO.setGroupKey(7);
userTO.getMemberships().add(membershipTO);
userLogic.create(userTO, true);
@@ -389,7 +397,7 @@ public class NotificationTest {
// 2. create user
UserTO userTO = getSampleTO(MAIL_ADDRESS);
MembershipTO membershipTO = new MembershipTO();
- membershipTO.setGroupId(7);
+ membershipTO.setGroupKey(7);
userTO.getMemberships().add(membershipTO);
userLogic.create(userTO, true);
@@ -439,7 +447,7 @@ public class NotificationTest {
// 2. create user
UserTO userTO = getSampleTO(MAIL_ADDRESS);
MembershipTO membershipTO = new MembershipTO();
- membershipTO.setGroupId(7);
+ membershipTO.setGroupKey(7);
userTO.getMemberships().add(membershipTO);
userLogic.create(userTO, true);
@@ -447,7 +455,7 @@ public class NotificationTest {
// 3. Set number of retries
CPlainAttr maxRetries = entityFactory.newEntity(CPlainAttr.class);
maxRetries.setSchema(plainSchemaDAO.find("notification.maxRetries", CPlainSchema.class));
- maxRetries.addValue("5", attrUtilFactory.getInstance(AttributableType.CONFIGURATION));
+ maxRetries.addValue("5", attrUtilsFactory.getInstance(AttributableType.CONFIGURATION));
confDAO.save(maxRetries);
confDAO.flush();
@@ -476,7 +484,7 @@ public class NotificationTest {
// 8. reset number of retries
maxRetries = entityFactory.newEntity(CPlainAttr.class);
maxRetries.setSchema(plainSchemaDAO.find("notification.maxRetries", CPlainSchema.class));
- maxRetries.addValue("0", attrUtilFactory.getInstance(AttributableType.CONFIGURATION));
+ maxRetries.addValue("0", attrUtilsFactory.getInstance(AttributableType.CONFIGURATION));
confDAO.save(maxRetries);
confDAO.flush();
}
@@ -510,7 +518,7 @@ public class NotificationTest {
// 2. create user
UserTO userTO = getSampleTO(MAIL_ADDRESS);
MembershipTO membershipTO = new MembershipTO();
- membershipTO.setGroupId(7);
+ membershipTO.setGroupKey(7);
userTO.getMemberships().add(membershipTO);
userLogic.create(userTO, true);
@@ -571,7 +579,7 @@ public class NotificationTest {
// 2. create user
UserTO userTO = getUniqueSampleTO(MAIL_ADDRESS);
MembershipTO membershipTO = new MembershipTO();
- membershipTO.setGroupId(7);
+ membershipTO.setGroupKey(7);
userTO.getMemberships().add(membershipTO);
userLogic.create(userTO, true);
@@ -612,7 +620,7 @@ public class NotificationTest {
// 2. create group
GroupTO groupTO = new GroupTO();
groupTO.setName("group446");
- groupTO.setParent(1L);
+ groupTO.setRealm("/even/two");
GroupTO createdGroup = groupLogic.create(groupTO);
assertNotNull(createdGroup);
http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/misc/src/main/java/org/apache/syncope/core/misc/ConnObjectUtil.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/ConnObjectUtil.java b/core/misc/src/main/java/org/apache/syncope/core/misc/ConnObjectUtil.java
deleted file mode 100644
index 182e2c7..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/ConnObjectUtil.java
+++ /dev/null
@@ -1,763 +0,0 @@
-/*
- * 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.misc;
-
-import org.apache.syncope.core.misc.policy.InvalidPasswordPolicySpecException;
-import org.apache.syncope.core.misc.security.PasswordGenerator;
-import org.apache.syncope.core.misc.security.SecureRandomUtil;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.AttributableOperations;
-import org.apache.syncope.common.lib.mod.AbstractAttributableMod;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
-import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.AttributableType;
-import org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.common.lib.types.PasswordPolicySpec;
-import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
-import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
-import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtil;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.PasswordPolicy;
-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.Subject;
-import org.apache.syncope.core.persistence.api.entity.VirAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.provisioning.api.ConnectorFactory;
-import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
-import org.apache.syncope.core.provisioning.api.cache.VirAttrCacheValue;
-import org.apache.syncope.core.misc.security.Encryptor;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.apache.syncope.core.misc.jexl.JexlUtil;
-import org.identityconnectors.common.Base64;
-import org.identityconnectors.common.security.GuardedByteArray;
-import org.identityconnectors.common.security.GuardedString;
-import org.identityconnectors.framework.common.objects.Attribute;
-import org.identityconnectors.framework.common.objects.ConnectorObject;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.identityconnectors.framework.common.objects.OperationOptions;
-import org.identityconnectors.framework.common.objects.Uid;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Transactional;
-
-@Component
-public class ConnObjectUtil {
-
- /**
- * Logger.
- */
- private static final Logger LOG = LoggerFactory.getLogger(ConnObjectUtil.class);
-
- @Autowired
- private PolicyDAO policyDAO;
-
- @Autowired
- private UserDAO userDAO;
-
- @Autowired
- private GroupDAO groupDAO;
-
- @Autowired
- private ExternalResourceDAO resourceDAO;
-
- @Autowired
- private PlainSchemaDAO plainSchemaDAO;
-
- @Autowired
- private PasswordGenerator pwdGen;
-
- private final Encryptor encryptor = Encryptor.getInstance();
-
- /**
- * Virtual attribute cache.
- */
- @Autowired
- private VirAttrCache virAttrCache;
-
- public ObjectClass fromSubject(final Subject<?, ?, ?> subject) {
- if (subject == null) {
- throw new IllegalArgumentException("No ObjectClass could be provided for " + subject);
- }
-
- ObjectClass result = null;
- if (subject instanceof User) {
- result = ObjectClass.ACCOUNT;
- }
- if (subject instanceof Group) {
- result = ObjectClass.GROUP;
- }
-
- return result;
- }
-
- /**
- * Build a UserTO / GroupTO out of connector object attributes and schema mapping.
- *
- * @param obj connector object
- * @param syncTask synchronization task
- * @param attrUtil AttributableUtil
- * @param <T> user/group
- * @return UserTO for the user to be created
- */
- @Transactional(readOnly = true)
- public <T extends AbstractSubjectTO> T getSubjectTO(final ConnectorObject obj, final SyncTask syncTask,
- final AttributableUtil attrUtil) {
-
- T subjectTO = getSubjectTOFromConnObject(obj, syncTask, attrUtil);
-
- // (for users) if password was not set above, generate
- if (subjectTO instanceof UserTO && StringUtils.isBlank(((UserTO) subjectTO).getPassword())) {
- final UserTO userTO = (UserTO) subjectTO;
-
- List<PasswordPolicySpec> ppSpecs = new ArrayList<>();
-
- PasswordPolicy globalPP = policyDAO.getGlobalPasswordPolicy();
- if (globalPP != null && globalPP.getSpecification(PasswordPolicySpec.class) != null) {
- ppSpecs.add(globalPP.getSpecification(PasswordPolicySpec.class));
- }
-
- for (MembershipTO memb : userTO.getMemberships()) {
- Group group = groupDAO.find(memb.getGroupId());
- if (group != null && group.getPasswordPolicy() != null
- && group.getPasswordPolicy().getSpecification(PasswordPolicySpec.class) != null) {
-
- ppSpecs.add(group.getPasswordPolicy().getSpecification(PasswordPolicySpec.class));
- }
- }
-
- for (String resName : userTO.getResources()) {
- ExternalResource resource = resourceDAO.find(resName);
- if (resource != null && resource.getPasswordPolicy() != null
- && resource.getPasswordPolicy().getSpecification(PasswordPolicySpec.class) != null) {
-
- ppSpecs.add(resource.getPasswordPolicy().getSpecification(PasswordPolicySpec.class));
- }
- }
-
- String password;
- try {
- password = pwdGen.generate(ppSpecs);
- } catch (InvalidPasswordPolicySpecException e) {
- LOG.error("Could not generate policy-compliant random password for {}", userTO, e);
-
- password = SecureRandomUtil.generateRandomPassword(16);
- }
- userTO.setPassword(password);
- }
-
- return subjectTO;
- }
-
- /**
- * Build an UserMod out of connector object attributes and schema mapping.
- *
- * @param key user to be updated
- * @param obj connector object
- * @param original subject to get diff from
- * @param syncTask synchronization task
- * @param attrUtil AttributableUtil
- * @param <T> user/group
- * @return modifications for the user/group to be updated
- */
- @SuppressWarnings("unchecked")
- @Transactional(readOnly = true)
- public <T extends AbstractAttributableMod> T getAttributableMod(final Long key, final ConnectorObject obj,
- final AbstractAttributableTO original, final SyncTask syncTask, final AttributableUtil attrUtil) {
-
- final AbstractAttributableTO updated = getSubjectTOFromConnObject(obj, syncTask, attrUtil);
- updated.setKey(key);
-
- if (AttributableType.USER == attrUtil.getType()) {
- // update password if and only if password is really changed
- final User user = userDAO.authFetch(key);
- if (StringUtils.isBlank(((UserTO) updated).getPassword())
- || encryptor.verify(((UserTO) updated).getPassword(),
- user.getCipherAlgorithm(), user.getPassword())) {
-
- ((UserTO) updated).setPassword(null);
- }
-
- for (MembershipTO membTO : ((UserTO) updated).getMemberships()) {
- Membership memb = user.getMembership(membTO.getGroupId());
- if (memb != null) {
- membTO.setKey(memb.getKey());
- }
- }
-
- return (T) AttributableOperations.diff(((UserTO) updated), ((UserTO) original), true);
- }
- if (AttributableType.GROUP == attrUtil.getType()) {
- // reading from connector object cannot change entitlements
- ((GroupTO) updated).getEntitlements().addAll(((GroupTO) original).getEntitlements());
- return (T) AttributableOperations.diff(((GroupTO) updated), ((GroupTO) original), true);
- }
-
- return null;
- }
-
- private <T extends AbstractSubjectTO> T getSubjectTOFromConnObject(final ConnectorObject obj,
- final SyncTask syncTask, final AttributableUtil attrUtil) {
-
- final T subjectTO = attrUtil.newSubjectTO();
-
- // 1. fill with data from connector object
- for (MappingItem item : attrUtil.getUidToMappingItems(
- syncTask.getResource(), MappingPurpose.SYNCHRONIZATION)) {
-
- Attribute attribute = obj.getAttributeByName(item.getExtAttrName());
-
- AttrTO attributeTO;
- switch (item.getIntMappingType()) {
- case UserId:
- case GroupId:
- break;
-
- case Password:
- if (subjectTO instanceof UserTO && attribute != null && attribute.getValue() != null
- && !attribute.getValue().isEmpty()) {
-
- ((UserTO) subjectTO).setPassword(getPassword(attribute.getValue().get(0)));
- }
- break;
-
- case Username:
- if (subjectTO instanceof UserTO) {
- ((UserTO) subjectTO).setUsername(attribute == null || attribute.getValue().isEmpty()
- || attribute.getValue().get(0) == null
- ? null
- : attribute.getValue().get(0).toString());
- }
- break;
-
- case GroupName:
- if (subjectTO instanceof GroupTO) {
- ((GroupTO) subjectTO).setName(attribute == null || attribute.getValue().isEmpty()
- || attribute.getValue().get(0) == null
- ? null
- : attribute.getValue().get(0).toString());
- }
- break;
-
- case GroupOwnerSchema:
- if (subjectTO instanceof GroupTO && attribute != null) {
- // using a special attribute (with schema "", that will be ignored) for carrying the
- // GroupOwnerSchema value
- attributeTO = new AttrTO();
- attributeTO.setSchema(StringUtils.EMPTY);
- if (attribute.getValue().isEmpty() || attribute.getValue().get(0) == null) {
- attributeTO.getValues().add(StringUtils.EMPTY);
- } else {
- attributeTO.getValues().add(attribute.getValue().get(0).toString());
- }
-
- ((GroupTO) subjectTO).getPlainAttrs().add(attributeTO);
- }
- break;
-
- case UserPlainSchema:
- case GroupPlainSchema:
- attributeTO = new AttrTO();
- attributeTO.setSchema(item.getIntAttrName());
-
- PlainSchema schema = plainSchemaDAO.find(item.getIntAttrName(), attrUtil.plainSchemaClass());
-
- for (Object value : attribute == null || attribute.getValue() == null
- ? Collections.emptyList()
- : attribute.getValue()) {
-
- AttrSchemaType schemaType = schema == null ? AttrSchemaType.String : schema.getType();
- if (value != null) {
- final PlainAttrValue attrValue = attrUtil.newPlainAttrValue();
- switch (schemaType) {
- case String:
- attrValue.setStringValue(value.toString());
- break;
-
- case Binary:
- attrValue.setBinaryValue((byte[]) value);
- break;
-
- default:
- try {
- attrValue.parseValue(schema, value.toString());
- } catch (ParsingValidationException e) {
- LOG.error("While parsing provided value {}", value, e);
- attrValue.setStringValue(value.toString());
- schemaType = AttrSchemaType.String;
- }
- break;
- }
- attributeTO.getValues().add(attrValue.getValueAsString(schemaType));
- }
- }
-
- subjectTO.getPlainAttrs().add(attributeTO);
- break;
-
- case UserDerivedSchema:
- case GroupDerivedSchema:
- attributeTO = new AttrTO();
- attributeTO.setSchema(item.getIntAttrName());
- subjectTO.getDerAttrs().add(attributeTO);
- break;
-
- case UserVirtualSchema:
- case GroupVirtualSchema:
- attributeTO = new AttrTO();
- attributeTO.setSchema(item.getIntAttrName());
-
- for (Object value : attribute == null || attribute.getValue() == null
- ? Collections.emptyList()
- : attribute.getValue()) {
-
- if (value != null) {
- attributeTO.getValues().add(value.toString());
- }
- }
-
- subjectTO.getVirAttrs().add(attributeTO);
- break;
-
- default:
- }
- }
-
- // 2. add data from defined template (if any)
- AbstractSubjectTO template = AttributableType.USER == attrUtil.getType()
- ? syncTask.getUserTemplate() : syncTask.getGroupTemplate();
-
- if (template != null) {
- if (template instanceof UserTO) {
- if (StringUtils.isNotBlank(((UserTO) template).getUsername())) {
- String evaluated = JexlUtil.evaluate(((UserTO) template).getUsername(), subjectTO);
- if (StringUtils.isNotBlank(evaluated)) {
- ((UserTO) subjectTO).setUsername(evaluated);
- }
- }
-
- if (StringUtils.isNotBlank(((UserTO) template).getPassword())) {
- String evaluated = JexlUtil.evaluate(((UserTO) template).getPassword(), subjectTO);
- if (StringUtils.isNotBlank(evaluated)) {
- ((UserTO) subjectTO).setPassword(evaluated);
- }
- }
-
- Map<Long, MembershipTO> currentMembs = ((UserTO) subjectTO).getMembershipMap();
- for (MembershipTO membTO : ((UserTO) template).getMemberships()) {
- MembershipTO membTBU;
- if (currentMembs.containsKey(membTO.getGroupId())) {
- membTBU = currentMembs.get(membTO.getGroupId());
- } else {
- membTBU = new MembershipTO();
- membTBU.setGroupId(membTO.getGroupId());
- ((UserTO) subjectTO).getMemberships().add(membTBU);
- }
- fillFromTemplate(membTBU, membTO);
- }
- }
- if (template instanceof GroupTO) {
- if (StringUtils.isNotBlank(((GroupTO) template).getName())) {
- String evaluated = JexlUtil.evaluate(((GroupTO) template).getName(), subjectTO);
- if (StringUtils.isNotBlank(evaluated)) {
- ((GroupTO) subjectTO).setName(evaluated);
- }
- }
-
- if (((GroupTO) template).getParent() != 0) {
- final Group parentGroup = groupDAO.find(((GroupTO) template).getParent());
- if (parentGroup != null) {
- ((GroupTO) subjectTO).setParent(parentGroup.getKey());
- }
- }
-
- if (((GroupTO) template).getUserOwner() != null) {
- final User userOwner = userDAO.find(((GroupTO) template).getUserOwner());
- if (userOwner != null) {
- ((GroupTO) subjectTO).setUserOwner(userOwner.getKey());
- }
- }
- if (((GroupTO) template).getGroupOwner() != null) {
- final Group groupOwner = groupDAO.find(((GroupTO) template).getGroupOwner());
- if (groupOwner != null) {
- ((GroupTO) subjectTO).setGroupOwner(groupOwner.getKey());
- }
- }
-
- ((GroupTO) subjectTO).getEntitlements().addAll(((GroupTO) template).getEntitlements());
-
- ((GroupTO) subjectTO).getGPlainAttrTemplates().addAll(((GroupTO) template).getGPlainAttrTemplates());
- ((GroupTO) subjectTO).getGDerAttrTemplates().addAll(((GroupTO) template).getGDerAttrTemplates());
- ((GroupTO) subjectTO).getGVirAttrTemplates().addAll(((GroupTO) template).getGVirAttrTemplates());
- ((GroupTO) subjectTO).getMPlainAttrTemplates().addAll(((GroupTO) template).getMPlainAttrTemplates());
- ((GroupTO) subjectTO).getMDerAttrTemplates().addAll(((GroupTO) template).getMDerAttrTemplates());
- ((GroupTO) subjectTO).getMVirAttrTemplates().addAll(((GroupTO) template).getMVirAttrTemplates());
-
- ((GroupTO) subjectTO).setAccountPolicy(((GroupTO) template).getAccountPolicy());
- ((GroupTO) subjectTO).setPasswordPolicy(((GroupTO) template).getPasswordPolicy());
-
- ((GroupTO) subjectTO).setInheritOwner(((GroupTO) template).isInheritOwner());
- ((GroupTO) subjectTO).setInheritTemplates(((GroupTO) template).isInheritTemplates());
- ((GroupTO) subjectTO).setInheritPlainAttrs(((GroupTO) template).isInheritPlainAttrs());
- ((GroupTO) subjectTO).setInheritDerAttrs(((GroupTO) template).isInheritDerAttrs());
- ((GroupTO) subjectTO).setInheritVirAttrs(((GroupTO) template).isInheritVirAttrs());
- ((GroupTO) subjectTO).setInheritPasswordPolicy(((GroupTO) template).isInheritPasswordPolicy());
- ((GroupTO) subjectTO).setInheritAccountPolicy(((GroupTO) template).isInheritAccountPolicy());
- }
-
- fillFromTemplate(subjectTO, template);
-
- for (String resource : template.getResources()) {
- subjectTO.getResources().add(resource);
- }
- }
-
- return subjectTO;
- }
-
- /**
- * Extract password value from passed value (if instance of GuardedString or GuardedByteArray).
- *
- * @param pwd received from the underlying connector
- * @return password value
- */
- public String getPassword(final Object pwd) {
- final StringBuilder result = new StringBuilder();
-
- if (pwd instanceof GuardedString) {
- ((GuardedString) pwd).access(new GuardedString.Accessor() {
-
- @Override
- public void access(final char[] clearChars) {
- result.append(clearChars);
- }
- });
- } else if (pwd instanceof GuardedByteArray) {
- ((GuardedByteArray) pwd).access(new GuardedByteArray.Accessor() {
-
- @Override
- public void access(final byte[] clearBytes) {
- result.append(new String(clearBytes));
- }
- });
- } else if (pwd instanceof String) {
- result.append((String) pwd);
- } else {
- result.append(pwd.toString());
- }
-
- return result.toString();
- }
-
- /**
- * Get connector object TO from a connector object.
- *
- * @param connObject connector object.
- * @return connector object TO.
- */
- public ConnObjectTO getConnObjectTO(final ConnectorObject connObject) {
- final ConnObjectTO connObjectTO = new ConnObjectTO();
-
- for (Attribute attr : connObject.getAttributes()) {
- AttrTO attrTO = new AttrTO();
- attrTO.setSchema(attr.getName());
-
- if (attr.getValue() != null) {
- for (Object value : attr.getValue()) {
- if (value != null) {
- if (value instanceof GuardedString || value instanceof GuardedByteArray) {
- attrTO.getValues().add(getPassword(value));
- } else if (value instanceof byte[]) {
- attrTO.getValues().add(Base64.encode((byte[]) value));
- } else {
- attrTO.getValues().add(value.toString());
- }
- }
- }
- }
-
- connObjectTO.getPlainAttrs().add(attrTO);
- }
-
- return connObjectTO;
- }
-
- /**
- * Query connected external resources for values to populated virtual attributes associated with the given owner.
- *
- * @param owner user or group
- * @param attrUtil attributable util
- */
- public void retrieveVirAttrValues(final Attributable<?, ?, ?> owner, final AttributableUtil attrUtil) {
- final ConfigurableApplicationContext context = ApplicationContextProvider.getApplicationContext();
- final ConnectorFactory connFactory = context.getBean(ConnectorFactory.class);
-
- final IntMappingType type = attrUtil.getType() == AttributableType.USER
- ? IntMappingType.UserVirtualSchema : attrUtil.getType() == AttributableType.GROUP
- ? IntMappingType.GroupVirtualSchema : IntMappingType.MembershipVirtualSchema;
-
- final Map<String, ConnectorObject> externalResources = new HashMap<>();
-
- // -----------------------
- // Retrieve virtual attribute values if and only if they have not been retrieved yet
- // -----------------------
- for (VirAttr virAttr : owner.getVirAttrs()) {
- // reset value set
- if (virAttr.getValues().isEmpty()) {
- retrieveVirAttrValue(owner, virAttr, attrUtil, type, externalResources, connFactory);
- }
- }
- // -----------------------
- }
-
- private void retrieveVirAttrValue(
- final Attributable<?, ?, ?> owner,
- final VirAttr virAttr,
- final AttributableUtil attrUtil,
- final IntMappingType type,
- final Map<String, ConnectorObject> externalResources,
- final ConnectorFactory connFactory) {
-
- final String schemaName = virAttr.getSchema().getKey();
- final VirAttrCacheValue virAttrCacheValue = virAttrCache.get(attrUtil.getType(), owner.getKey(), schemaName);
-
- LOG.debug("Retrieve values for virtual attribute {} ({})", schemaName, type);
-
- if (virAttrCache.isValidEntry(virAttrCacheValue)) {
- // cached ...
- LOG.debug("Values found in cache {}", virAttrCacheValue);
- virAttr.getValues().clear();
- virAttr.getValues().addAll(new ArrayList<>(virAttrCacheValue.getValues()));
- } else {
- // not cached ...
- LOG.debug("Need one or more remote connections");
-
- final VirAttrCacheValue toBeCached = new VirAttrCacheValue();
-
- // SYNCOPE-458 if virattr owner is a Membership, owner must become user involved in membership because
- // membership mapping is contained in user mapping
- final Subject<?, ?, ?> realOwner = owner instanceof Membership
- ? ((Membership) owner).getUser()
- : (Subject) owner;
-
- final Set<ExternalResource> targetResources = owner instanceof Membership
- ? getTargetResource(virAttr, type, attrUtil, realOwner.getResources())
- : getTargetResource(virAttr, type, attrUtil);
-
- for (ExternalResource resource : targetResources) {
- LOG.debug("Search values into {}", resource.getKey());
- try {
- final List<MappingItem> mappings = attrUtil.getMappingItems(resource, MappingPurpose.BOTH);
-
- final ConnectorObject connectorObject;
-
- if (externalResources.containsKey(resource.getKey())) {
- connectorObject = externalResources.get(resource.getKey());
- } else {
- LOG.debug("Perform connection to {}", resource.getKey());
- final String accountId = attrUtil.getAccountIdItem(resource) == null
- ? null
- : MappingUtil.getAccountIdValue(
- realOwner, resource, attrUtil.getAccountIdItem(resource));
-
- if (StringUtils.isBlank(accountId)) {
- throw new IllegalArgumentException("No AccountId found for " + resource.getKey());
- }
-
- final Connector connector = connFactory.getConnector(resource);
-
- final OperationOptions oo =
- connector.getOperationOptions(MappingUtil.getMatchingMappingItems(mappings, type));
-
- connectorObject = connector.getObject(fromSubject(realOwner), new Uid(accountId), oo);
- externalResources.put(resource.getKey(), connectorObject);
- }
-
- if (connectorObject != null) {
- // ask for searched virtual attribute value
- final List<MappingItem> virAttrMappings =
- MappingUtil.getMatchingMappingItems(mappings, schemaName, type);
-
- // the same virtual attribute could be mapped with one or more external attribute
- for (MappingItem mapping : virAttrMappings) {
- final Attribute attribute = connectorObject.getAttributeByName(mapping.getExtAttrName());
-
- if (attribute != null && attribute.getValue() != null) {
- for (Object obj : attribute.getValue()) {
- if (obj != null) {
- virAttr.getValues().add(obj.toString());
- }
- }
- }
- }
-
- toBeCached.setResourceValues(resource.getKey(), new HashSet<String>(virAttr.getValues()));
-
- LOG.debug("Retrieved values {}", virAttr.getValues());
- }
- } catch (Exception e) {
- LOG.error("Error reading connector object from {}", resource.getKey(), e);
-
- if (virAttrCacheValue != null) {
- toBeCached.forceExpiring();
- LOG.debug("Search for a cached value (even expired!) ...");
- final Set<String> cachedValues = virAttrCacheValue.getValues(resource.getKey());
- if (cachedValues != null) {
- LOG.debug("Use cached value {}", cachedValues);
- virAttr.getValues().addAll(cachedValues);
- toBeCached.setResourceValues(resource.getKey(), new HashSet<>(cachedValues));
- }
- }
- }
- }
-
- virAttrCache.put(attrUtil.getType(), owner.getKey(), schemaName, toBeCached);
- }
- }
-
- private Set<ExternalResource> getTargetResource(
- final VirAttr attr, final IntMappingType type, final AttributableUtil attrUtil) {
-
- final Set<ExternalResource> resources = new HashSet<>();
-
- if (attr.getOwner() instanceof Subject) {
- for (ExternalResource res : ((Subject<?, ?, ?>) attr.getOwner()).getResources()) {
- if (!MappingUtil.getMatchingMappingItems(
- attrUtil.getMappingItems(res, MappingPurpose.BOTH),
- attr.getSchema().getKey(), type).isEmpty()) {
-
- resources.add(res);
- }
- }
- }
-
- return resources;
- }
-
- private Set<ExternalResource> getTargetResource(final VirAttr attr, final IntMappingType type,
- final AttributableUtil attrUtil, final Set<? extends ExternalResource> ownerResources) {
-
- final Set<ExternalResource> resources = new HashSet<>();
-
- for (ExternalResource res : ownerResources) {
- if (!MappingUtil.getMatchingMappingItems(
- attrUtil.getMappingItems(res, MappingPurpose.BOTH),
- attr.getSchema().getKey(), type).isEmpty()) {
-
- resources.add(res);
- }
- }
-
- return resources;
- }
-
- private void fillFromTemplate(final AbstractAttributableTO attributableTO, final AbstractAttributableTO template) {
- Map<String, AttrTO> currentAttrMap = attributableTO.getPlainAttrMap();
- for (AttrTO templateAttr : template.getPlainAttrs()) {
- if (templateAttr.getValues() != null && !templateAttr.getValues().isEmpty()
- && (!currentAttrMap.containsKey(templateAttr.getSchema())
- || currentAttrMap.get(templateAttr.getSchema()).getValues().isEmpty())) {
-
- attributableTO.getPlainAttrs().add(evaluateAttrTemplate(attributableTO, templateAttr));
- }
- }
-
- currentAttrMap = attributableTO.getDerAttrMap();
- for (AttrTO templateDerAttr : template.getDerAttrs()) {
- if (!currentAttrMap.containsKey(templateDerAttr.getSchema())) {
- attributableTO.getDerAttrs().add(templateDerAttr);
- }
- }
-
- currentAttrMap = attributableTO.getVirAttrMap();
- for (AttrTO templateVirAttr : template.getVirAttrs()) {
- if (templateVirAttr.getValues() != null && !templateVirAttr.getValues().isEmpty()
- && (!currentAttrMap.containsKey(templateVirAttr.getSchema())
- || currentAttrMap.get(templateVirAttr.getSchema()).getValues().isEmpty())) {
-
- attributableTO.getVirAttrs().add(evaluateAttrTemplate(attributableTO, templateVirAttr));
- }
- }
- }
-
- private AttrTO evaluateAttrTemplate(final AbstractAttributableTO attributableTO, final AttrTO template) {
- AttrTO result = new AttrTO();
- result.setSchema(template.getSchema());
-
- if (template.getValues() != null && !template.getValues().isEmpty()) {
- for (String value : template.getValues()) {
- String evaluated = JexlUtil.evaluate(value, attributableTO);
- if (StringUtils.isNotBlank(evaluated)) {
- result.getValues().add(evaluated);
- }
- }
- }
-
- return result;
- }
-
- /**
- * Transform a
- * <code>Collection</code> of {@link Attribute} instances into a {@link Map}. The key to each element in the map is
- * the <i>name</i> of an
- * <code>Attribute</code>. The value of each element in the map is the
- * <code>Attribute</code> instance with that name. <br/> Different from the original because: <ul> <li>map keys are
- * transformed toUpperCase()</li> <li>returned map is mutable</li> </ul>
- *
- * @param attributes set of attribute to transform to a map.
- * @return a map of string and attribute.
- *
- * @see org.identityconnectors.framework.common.objects.AttributeUtil#toMap(java.util.Collection)
- */
- public Map<String, Attribute> toMap(final Collection<? extends Attribute> attributes) {
- final Map<String, Attribute> map = new HashMap<>();
- for (Attribute attr : attributes) {
- map.put(attr.getName().toUpperCase(), attr);
- }
- return map;
- }
-}