http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java index 1b320b7..6f926cf 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java @@ -18,14 +18,15 @@ */ package org.apache.syncope.core.provisioning.java.job; -import org.apache.commons.lang3.ClassUtils; +import org.apache.syncope.core.persistence.api.dao.ImplementationDAO; +import org.apache.syncope.core.persistence.api.entity.Implementation; import org.apache.syncope.core.spring.security.AuthContextUtils; import org.apache.syncope.core.spring.ApplicationContextProvider; import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; -import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.apache.syncope.core.provisioning.api.job.JobManager; +import org.apache.syncope.core.spring.ImplementationManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,7 +36,7 @@ public class TaskJob extends AbstractInterruptableJob { public static final String DRY_RUN_JOBDETAIL_KEY = "dryRun"; - public static final String DELEGATE_CLASS_KEY = "delegateClass"; + public static final String DELEGATE_IMPLEMENTATION = "delegateImpl"; /** * Task execution status. @@ -69,14 +70,19 @@ public class TaskJob extends AbstractInterruptableJob { AuthContextUtils.execWithAuthContext(context.getMergedJobDataMap().getString(JobManager.DOMAIN_KEY), () -> { try { - Class<?> delegateClass = - ClassUtils.getClass(context.getMergedJobDataMap().getString(DELEGATE_CLASS_KEY)); - - ((SchedTaskJobDelegate) ApplicationContextProvider.getBeanFactory(). - createBean(delegateClass, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false)). - execute(taskKey, - context.getMergedJobDataMap().getBoolean(DRY_RUN_JOBDETAIL_KEY), - context); + ImplementationDAO implementationDAO = + ApplicationContextProvider.getApplicationContext().getBean(ImplementationDAO.class); + Implementation taskJobDelegate = implementationDAO.find( + context.getMergedJobDataMap().getString(DELEGATE_IMPLEMENTATION)); + if (taskJobDelegate == null) { + LOG.error("Could not find Implementation '{}', aborting", + context.getMergedJobDataMap().getString(DELEGATE_IMPLEMENTATION)); + } else { + ImplementationManager.<SchedTaskJobDelegate>build(taskJobDelegate). + execute(taskKey, + context.getMergedJobDataMap().getBoolean(DRY_RUN_JOBDETAIL_KEY), + context); + } } catch (Exception e) { LOG.error("While executing task {}", taskKey, e); throw new RuntimeException(e);
http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/AbstractReportlet.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/AbstractReportlet.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/AbstractReportlet.java index 2c85b20..ede3535 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/AbstractReportlet.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/AbstractReportlet.java @@ -31,15 +31,18 @@ public abstract class AbstractReportlet implements Reportlet { protected static final Logger LOG = LoggerFactory.getLogger(AbstractReportlet.class); + protected ReportletConf conf; + + @Override + public void setConf(final ReportletConf conf) { + this.conf = conf; + } + protected abstract void doExtract(ReportletConf conf, ContentHandler handler) throws SAXException; @Override @Transactional(readOnly = true) - public void extract(final ReportletConf conf, final ContentHandler handler) throws SAXException { - if (conf == null) { - throw new ReportException(new IllegalArgumentException("No configuration provided")); - } - + public void extract(final ContentHandler handler) throws SAXException { AttributesImpl atts = new AttributesImpl(); atts.addAttribute("", "", ReportXMLConst.ATTR_NAME, ReportXMLConst.XSD_STRING, conf.getName()); atts.addAttribute("", "", ReportXMLConst.ATTR_CLASS, ReportXMLConst.XSD_STRING, getClass().getName()); http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReportJobDelegate.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReportJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReportJobDelegate.java index 28f4894..10a529f 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReportJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReportJobDelegate.java @@ -22,6 +22,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Date; +import java.util.Optional; import java.util.zip.Deflater; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; @@ -31,22 +32,20 @@ import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamResult; import org.apache.commons.io.IOUtils; -import org.apache.syncope.common.lib.report.ReportletConf; import org.apache.syncope.common.lib.types.ReportExecStatus; import org.apache.syncope.core.provisioning.api.utils.ExceptionUtils2; -import org.apache.syncope.core.spring.ApplicationContextProvider; -import org.apache.syncope.core.persistence.api.ImplementationLookup; import org.apache.syncope.core.persistence.api.dao.ReportDAO; import org.apache.syncope.core.persistence.api.dao.ReportExecDAO; import org.apache.syncope.core.persistence.api.dao.Reportlet; import org.apache.syncope.core.persistence.api.entity.EntityFactory; +import org.apache.syncope.core.persistence.api.entity.Implementation; import org.apache.syncope.core.persistence.api.entity.Report; import org.apache.syncope.core.persistence.api.entity.ReportExec; +import org.apache.syncope.core.spring.ImplementationManager; import org.quartz.JobExecutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import org.xml.sax.helpers.AttributesImpl; @@ -71,9 +70,6 @@ public class ReportJobDelegate { @Autowired private EntityFactory entityFactory; - @Autowired - private ImplementationLookup implementationLookup; - @Transactional public void execute(final String reportKey) throws JobExecutionException { Report report = reportDAO.find(reportKey); @@ -132,27 +128,11 @@ public class ReportJobDelegate { handler.startElement("", "", ReportXMLConst.ELEMENT_REPORT, atts); // iterate over reportlet instances defined for this report - for (ReportletConf reportletConf : report.getReportletConfs()) { - Class<? extends Reportlet> reportletClass = - implementationLookup.getReportletClass(reportletConf.getClass()); - if (reportletClass == null) { - LOG.warn("Could not find matching reportlet for {}", reportletConf.getClass()); - } else { - // fetch (or create) reportlet - Reportlet reportlet; - if (ApplicationContextProvider.getBeanFactory().containsSingleton(reportletClass.getName())) { - reportlet = (Reportlet) ApplicationContextProvider.getBeanFactory(). - getSingleton(reportletClass.getName()); - } else { - reportlet = (Reportlet) ApplicationContextProvider.getBeanFactory(). - createBean(reportletClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false); - ApplicationContextProvider.getBeanFactory(). - registerSingleton(reportletClass.getName(), reportlet); - } - - // invoke reportlet + for (Implementation impl : report.getReportlets()) { + Optional<Reportlet> reportlet = ImplementationManager.buildReportlet(impl); + if (reportlet.isPresent()) { try { - reportlet.extract(reportletConf, handler); + reportlet.get().extract(handler); } catch (Throwable t) { LOG.error("While executing reportlet {} for report {}", reportlet, reportKey, t); http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java index f2eeaf4..75b028f 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java @@ -27,6 +27,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; import org.apache.commons.jexl3.MapContext; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; @@ -47,7 +48,6 @@ import org.apache.syncope.core.persistence.api.dao.UserDAO; import org.apache.syncope.core.persistence.api.dao.search.OrderByClause; 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.PlainAttr; import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.api.entity.task.NotificationTask; import org.apache.syncope.core.persistence.api.entity.task.TaskExec; @@ -56,7 +56,6 @@ import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.provisioning.api.data.GroupDataBinder; import org.apache.syncope.core.provisioning.api.data.UserDataBinder; import org.apache.syncope.core.persistence.api.search.SearchCondConverter; -import org.apache.syncope.core.spring.ApplicationContextProvider; import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; import org.apache.syncope.core.persistence.api.dao.AnySearchDAO; import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO; @@ -73,14 +72,14 @@ import org.apache.syncope.core.provisioning.api.IntAttrName; import org.apache.syncope.core.provisioning.api.VirAttrHandler; import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder; import org.apache.syncope.core.provisioning.api.notification.NotificationManager; -import org.apache.syncope.core.provisioning.api.notification.NotificationRecipientsProvider; import org.apache.syncope.core.provisioning.api.event.AfterHandlingEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; +import org.apache.syncope.core.provisioning.api.notification.RecipientsProvider; +import org.apache.syncope.core.spring.ImplementationManager; @Component @Transactional(rollbackFor = { Throwable.class }) @@ -210,15 +209,13 @@ public class NotificationManagerImpl implements NotificationManager { recipientEmails.addAll(notification.getStaticRecipients()); } - if (notification.getRecipientsProviderClassName() != null) { + if (notification.getRecipientsProvider() != null) { try { - NotificationRecipientsProvider recipientsProvider = - (NotificationRecipientsProvider) ApplicationContextProvider.getBeanFactory(). - createBean(Class.forName(notification.getRecipientsProviderClassName()), - AbstractBeanDefinition.AUTOWIRE_BY_NAME, false); + RecipientsProvider recipientsProvider = + ImplementationManager.build(notification.getRecipientsProvider()); recipientEmails.addAll(recipientsProvider.provideRecipients(notification)); } catch (Exception e) { - LOG.error("Could not fetch recipients from {}", notification.getRecipientsProviderClassName(), e); + LOG.error("While building {}", notification.getRecipientsProvider(), e); } } @@ -470,10 +467,7 @@ public class NotificationManagerImpl implements NotificationManager { } protected Map<String, String> findAllSyncopeConfs() { - Map<String, String> syncopeConfMap = new HashMap<>(); - for (PlainAttr<?> attr : confDAO.get().getPlainAttrs()) { - syncopeConfMap.put(attr.getSchema().getKey(), attr.getValuesAsStrings().get(0)); - } - return syncopeConfMap; + return confDAO.get().getPlainAttrs().stream().collect( + Collectors.toMap(attr -> attr.getSchema().getKey(), attr -> attr.getValuesAsStrings().get(0))); } } http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java index a36489d..e4f443f 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java @@ -47,7 +47,6 @@ import org.apache.syncope.core.provisioning.api.TimeoutException; import org.apache.syncope.core.provisioning.api.propagation.PropagationActions; import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter; import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor; -import org.apache.syncope.core.spring.ApplicationContextProvider; import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils; import org.apache.syncope.core.provisioning.api.utils.ExceptionUtils2; import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; @@ -65,6 +64,7 @@ import org.apache.syncope.core.provisioning.api.data.TaskDataBinder; import org.apache.syncope.core.provisioning.api.notification.NotificationManager; import org.apache.syncope.core.provisioning.api.propagation.PropagationException; import org.apache.syncope.core.provisioning.java.utils.MappingUtils; +import org.apache.syncope.core.spring.ImplementationManager; import org.identityconnectors.framework.common.exceptions.ConnectorException; import org.identityconnectors.framework.common.objects.Attribute; import org.identityconnectors.framework.common.objects.AttributeBuilder; @@ -77,7 +77,6 @@ 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.beans.factory.support.AbstractBeanDefinition; import org.springframework.transaction.annotation.Transactional; @Transactional(rollbackFor = { Throwable.class }) @@ -162,17 +161,13 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask protected List<PropagationActions> getPropagationActions(final ExternalResource resource) { List<PropagationActions> result = new ArrayList<>(); - if (!resource.getPropagationActionsClassNames().isEmpty()) { - resource.getPropagationActionsClassNames().forEach(className -> { - try { - Class<?> actionsClass = Class.forName(className); - result.add((PropagationActions) ApplicationContextProvider.getBeanFactory(). - createBean(actionsClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true)); - } catch (ClassNotFoundException e) { - LOG.error("Invalid PropagationAction class name '{}' for resource {}", resource, className, e); - } - }); - } + resource.getPropagationActions().forEach(impl -> { + try { + result.add(ImplementationManager.build(impl)); + } catch (Exception e) { + LOG.error("While building {}", impl, e); + } + }); return result; } http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java index 8bfe089..8f3ee71 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java @@ -44,7 +44,6 @@ import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile; import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.apache.syncope.core.provisioning.api.pushpull.ReconciliationFilterBuilder; import org.apache.syncope.core.persistence.api.entity.task.PullTask; import org.apache.syncope.core.provisioning.api.pushpull.AnyObjectPullResultHandler; import org.apache.syncope.core.provisioning.api.pushpull.PullActions; @@ -57,6 +56,8 @@ import org.apache.syncope.core.provisioning.java.utils.MappingUtils; import org.identityconnectors.framework.common.objects.ObjectClass; import org.identityconnectors.framework.common.objects.OperationOptions; import org.identityconnectors.framework.common.objects.SyncToken; +import org.apache.syncope.core.provisioning.api.pushpull.ReconFilterBuilder; +import org.apache.syncope.core.spring.ImplementationManager; public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> implements SyncopePullExecutor { @@ -170,15 +171,11 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i LOG.debug("Executing pull on {}", pullTask.getResource()); List<PullActions> actions = new ArrayList<>(); - pullTask.getActionsClassNames().forEach(className -> { + pullTask.getActions().forEach(impl -> { try { - Class<?> actionsClass = Class.forName(className); - PullActions pullActions = (PullActions) ApplicationContextProvider.getBeanFactory(). - createBean(actionsClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true); - - actions.add(pullActions); + actions.add(ImplementationManager.build(impl)); } catch (Exception e) { - LOG.warn("Class '{}' not found", className, e); + LOG.warn("While building {}", impl, e); } }); @@ -223,10 +220,8 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i break; case FILTERED_RECONCILIATION: - ReconciliationFilterBuilder filterBuilder = - (ReconciliationFilterBuilder) ApplicationContextProvider.getBeanFactory(). - createBean(Class.forName(pullTask.getReconciliationFilterBuilderClassName()), - AbstractBeanDefinition.AUTOWIRE_BY_NAME, false); + ReconFilterBuilder filterBuilder = + ImplementationManager.build(pullTask.getReconFilterBuilder()); connector.filteredReconciliation(orgUnit.getObjectClass(), filterBuilder, rhandler, @@ -296,11 +291,8 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i break; case FILTERED_RECONCILIATION: - ReconciliationFilterBuilder filterBuilder = - (ReconciliationFilterBuilder) ApplicationContextProvider.getBeanFactory(). - createBean( - Class.forName(pullTask.getReconciliationFilterBuilderClassName()), - AbstractBeanDefinition.AUTOWIRE_BY_NAME, false); + ReconFilterBuilder filterBuilder = + ImplementationManager.build(pullTask.getReconFilterBuilder()); connector.filteredReconciliation(provision.getObjectClass(), filterBuilder, handler, http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java index 15976b4..44c80bd 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java @@ -23,7 +23,6 @@ import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; -import org.apache.commons.lang3.StringUtils; import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.policy.PullPolicySpec; import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; @@ -33,12 +32,15 @@ import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; import org.apache.syncope.core.persistence.api.dao.AnySearchDAO; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.dao.GroupDAO; +import org.apache.syncope.core.persistence.api.dao.ImplementationDAO; import org.apache.syncope.core.persistence.api.dao.RealmDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.AnyType; 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.Entity; +import org.apache.syncope.core.persistence.api.entity.Implementation; 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.Realm; @@ -68,6 +70,7 @@ import org.springframework.transaction.annotation.Transactional; import org.apache.syncope.core.provisioning.api.pushpull.PullCorrelationRule; import org.apache.syncope.core.provisioning.java.utils.MappingUtils; import org.apache.syncope.core.provisioning.api.data.ItemTransformer; +import org.apache.syncope.core.spring.ImplementationManager; @Transactional(readOnly = true) @Component @@ -109,6 +112,9 @@ public class PullUtils { private RealmDAO realmDAO; @Autowired + private ImplementationDAO implementationDAO; + + @Autowired private AnyUtilsFactory anyUtilsFactory; @Autowired @@ -264,32 +270,33 @@ public class PullUtils { private List<String> findByCorrelationRule( final ConnectorObject connObj, final PullCorrelationRule rule, final AnyTypeKind type) { - List<String> result = new ArrayList<>(); - searchDAO.search(rule.getSearchCond(connObj), type).forEach(any -> { - result.add(any.getKey()); - }); - - return result; + return searchDAO.search(rule.getSearchCond(connObj), type).stream(). + map(Entity::getKey).collect(Collectors.toList()); } private PullCorrelationRule getCorrelationRule(final Provision provision, final PullPolicySpec policySpec) { - PullCorrelationRule result = null; + PullCorrelationRule rule = null; String pullCorrelationRule = policySpec.getCorrelationRules().get(provision.getAnyType().getKey()); - if (StringUtils.isNotBlank(pullCorrelationRule)) { + if (pullCorrelationRule != null) { if (pullCorrelationRule.charAt(0) == '[') { - result = new PlainAttrsPullCorrelationRule( + rule = new PlainAttrsPullCorrelationRule( POJOHelper.deserialize(pullCorrelationRule, String[].class), provision); } else { - try { - result = (PullCorrelationRule) Class.forName(pullCorrelationRule).newInstance(); - } catch (Exception e) { - LOG.error("Failure instantiating correlation rule class '{}'", pullCorrelationRule, e); + Implementation impl = implementationDAO.find(pullCorrelationRule); + if (impl == null) { + LOG.error("Could not find any Implementation matching '{}'", pullCorrelationRule); + } else { + try { + rule = ImplementationManager.build(impl); + } catch (Exception e) { + LOG.error("While building {}", impl, e); + } } } } - return result; + return rule; } /** http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java index ad3ccfd..b1a8b07 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java @@ -48,6 +48,7 @@ import org.apache.syncope.core.provisioning.api.pushpull.PushActions; import org.apache.syncope.core.provisioning.api.pushpull.RealmPushResultHandler; import org.apache.syncope.core.provisioning.api.pushpull.SyncopePushResultHandler; import org.apache.syncope.core.provisioning.api.pushpull.UserPushResultHandler; +import org.apache.syncope.core.spring.ImplementationManager; import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.support.AbstractBeanDefinition; @@ -164,15 +165,11 @@ public class PushJobDelegate extends AbstractProvisioningJobDelegate<PushTask> { LOG.debug("Executing push on {}", pushTask.getResource()); List<PushActions> actions = new ArrayList<>(); - pushTask.getActionsClassNames().forEach(className -> { + pushTask.getActions().forEach(impl -> { try { - Class<?> actionsClass = Class.forName(className); - - PushActions pushActions = (PushActions) ApplicationContextProvider.getBeanFactory(). - createBean(actionsClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true); - actions.add(pushActions); + actions.add(ImplementationManager.build(impl)); } catch (Exception e) { - LOG.info("Class '{}' not found", className, e); + LOG.warn("While building {}", impl, e); } }); http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java index c49c84a..6aa8e88 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java @@ -24,7 +24,6 @@ import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.common.lib.AnyOperations; import org.apache.syncope.common.lib.patch.AnyPatch; -import org.apache.syncope.common.lib.policy.PasswordRuleConf; import org.apache.syncope.common.lib.to.AnyObjectTO; import org.apache.syncope.common.lib.to.AnyTO; import org.apache.syncope.common.lib.to.AttrTO; @@ -41,6 +40,7 @@ import org.apache.syncope.core.spring.security.PasswordGenerator; import org.apache.syncope.core.spring.security.SecureRandomUtils; import org.apache.syncope.core.persistence.api.dao.RealmDAO; import org.apache.syncope.core.persistence.api.entity.Realm; +import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy; import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit; import org.apache.syncope.core.persistence.api.entity.resource.Provision; import org.apache.syncope.core.persistence.api.entity.task.PullTask; @@ -171,26 +171,27 @@ public class ConnObjectUtils { if (anyTO instanceof UserTO && StringUtils.isBlank(((UserTO) anyTO).getPassword())) { UserTO userTO = (UserTO) anyTO; - List<PasswordRuleConf> ruleConfs = new ArrayList<>(); + List<PasswordPolicy> passwordPolicies = new ArrayList<>(); Realm realm = realmDAO.findByFullPath(userTO.getRealm()); if (realm != null) { realmDAO.findAncestors(realm).stream(). - filter(ancestor -> (ancestor.getPasswordPolicy() != null)). - forEachOrdered(ancestor -> { - ruleConfs.addAll(ancestor.getPasswordPolicy().getRuleConfs()); + filter(ancestor -> ancestor.getPasswordPolicy() != null). + forEach(ancestor -> { + passwordPolicies.add(ancestor.getPasswordPolicy()); }); } - userTO.getResources().stream().map(resName -> resourceDAO.find(resName)). - filter(resource -> (resource != null && resource.getPasswordPolicy() != null)). - forEachOrdered(resource -> { - ruleConfs.addAll(resource.getPasswordPolicy().getRuleConfs()); + userTO.getResources().stream(). + map(resource -> resourceDAO.find(resource)). + filter(resource -> resource != null && resource.getPasswordPolicy() != null). + forEach(resource -> { + passwordPolicies.add(resource.getPasswordPolicy()); }); String password; try { - password = passwordGenerator.generate(ruleConfs); + password = passwordGenerator.generate(passwordPolicies); } catch (InvalidPasswordRuleConf e) { LOG.error("Could not generate policy-compliant random password for {}", userTO, e); http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java index eee6d9a..9041b10 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java @@ -27,9 +27,7 @@ import java.util.Set; import java.util.stream.Collectors; import org.apache.commons.jexl3.JexlContext; import org.apache.commons.jexl3.MapContext; -import org.apache.commons.lang3.ClassUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.syncope.common.lib.to.ItemTO; import org.apache.syncope.common.lib.types.MappingPurpose; import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.Realm; @@ -51,6 +49,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.apache.syncope.core.provisioning.api.data.ItemTransformer; import org.apache.syncope.core.provisioning.api.data.JEXLItemTransformer; +import org.apache.syncope.core.spring.ImplementationManager; public final class MappingUtils { @@ -69,14 +68,14 @@ public final class MappingUtils { public static List<? extends Item> getPropagationItems(final List<? extends Item> items) { return items.stream(). - filter(item -> item.getPurpose() == MappingPurpose.PROPAGATION - || item.getPurpose() == MappingPurpose.BOTH).collect(Collectors.toList()); + filter(item -> item.getPurpose() == MappingPurpose.PROPAGATION + || item.getPurpose() == MappingPurpose.BOTH).collect(Collectors.toList()); } public static List<? extends Item> getPullItems(final List<? extends Item> items) { return items.stream(). - filter(item -> item.getPurpose() == MappingPurpose.PULL - || item.getPurpose() == MappingPurpose.BOTH).collect(Collectors.toList()); + filter(item -> item.getPurpose() == MappingPurpose.PULL + || item.getPurpose() == MappingPurpose.BOTH).collect(Collectors.toList()); } private static Name evaluateNAME(final String evalConnObjectLink, final String connObjectKey) { @@ -160,54 +159,33 @@ public final class MappingUtils { return evaluateNAME(evalConnObjectLink, connObjectKey); } - private static List<ItemTransformer> getItemTransformers( - final String propagationJEXLTransformer, - final String pullJEXLTransformer, - final List<String> mappingItemTransformerClassNames) { - + public static List<ItemTransformer> getItemTransformers(final Item item) { List<ItemTransformer> result = new ArrayList<>(); // First consider the JEXL transformation expressions - if (StringUtils.isNotBlank(propagationJEXLTransformer) || StringUtils.isNotBlank(pullJEXLTransformer)) { - JEXLItemTransformer jexlTransformer = - (JEXLItemTransformer) ApplicationContextProvider.getBeanFactory(). - createBean(JEXLItemTransformerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, - false); - - jexlTransformer.setPropagationJEXL(propagationJEXLTransformer); - jexlTransformer.setPullJEXL(pullJEXLTransformer); + if (StringUtils.isNotBlank(item.getPropagationJEXLTransformer()) + || StringUtils.isNotBlank(item.getPullJEXLTransformer())) { + + JEXLItemTransformer jexlTransformer = (JEXLItemTransformer) ApplicationContextProvider.getBeanFactory(). + createBean(JEXLItemTransformerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false); + + jexlTransformer.setPropagationJEXL(item.getPropagationJEXLTransformer()); + jexlTransformer.setPullJEXL(item.getPullJEXLTransformer()); result.add(jexlTransformer); } - // Then other custom tranaformers - mappingItemTransformerClassNames.forEach(className -> { + // Then other custom transformers + item.getTransformers().forEach(impl -> { try { - Class<?> transformerClass = ClassUtils.getClass(className); - - result.add((ItemTransformer) ApplicationContextProvider.getBeanFactory(). - createBean(transformerClass, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false)); + result.add(ImplementationManager.build(impl)); } catch (Exception e) { - LOG.error("Could not instantiate {}, ignoring...", className, e); + LOG.error("While building {}", impl, e); } }); return result; } - public static List<ItemTransformer> getItemTransformers(final ItemTO item) { - return getItemTransformers( - item.getPropagationJEXLTransformer(), - item.getPullJEXLTransformer(), - item.getTransformerClassNames()); - } - - public static List<ItemTransformer> getItemTransformers(final Item item) { - return getItemTransformers( - item.getPropagationJEXLTransformer(), - item.getPullJEXLTransformer(), - item.getTransformerClassNames()); - } - /** * Build options for requesting all mapped connector attributes. * http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/DummyImplementationLookup.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/DummyImplementationLookup.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/DummyImplementationLookup.java index cac936d..55e2a26 100644 --- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/DummyImplementationLookup.java +++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/DummyImplementationLookup.java @@ -23,6 +23,7 @@ import java.util.Set; import org.apache.syncope.common.lib.policy.AccountRuleConf; import org.apache.syncope.common.lib.policy.PasswordRuleConf; import org.apache.syncope.common.lib.report.ReportletConf; +import org.apache.syncope.common.lib.types.ImplementationType; import org.apache.syncope.core.persistence.api.ImplementationLookup; import org.apache.syncope.core.persistence.api.dao.AccountRule; import org.apache.syncope.core.persistence.api.dao.PasswordRule; @@ -45,7 +46,7 @@ public class DummyImplementationLookup implements ImplementationLookup { } @Override - public Set<String> getClassNames(final Type type) { + public Set<String> getClassNames(final ImplementationType type) { return Collections.emptySet(); } http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ImplementationServiceImpl.java ---------------------------------------------------------------------- diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ImplementationServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ImplementationServiceImpl.java new file mode 100644 index 0000000..c3190af --- /dev/null +++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ImplementationServiceImpl.java @@ -0,0 +1,67 @@ +/* + * 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.rest.cxf.service; + +import java.net.URI; +import java.util.List; +import javax.ws.rs.core.Response; +import org.apache.syncope.common.lib.to.ImplementationTO; +import org.apache.syncope.common.lib.types.ImplementationType; +import org.apache.syncope.common.rest.api.RESTHeaders; +import org.apache.syncope.common.rest.api.service.ImplementationService; +import org.apache.syncope.core.logic.ImplementationLogic; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class ImplementationServiceImpl extends AbstractServiceImpl implements ImplementationService { + + @Autowired + private ImplementationLogic logic; + + @Override + public List<ImplementationTO> list(final ImplementationType type) { + return logic.list(type); + } + + @Override + public ImplementationTO read(final String key) { + return logic.read(key); + } + + @Override + public Response create(final ImplementationTO implementationTO) { + ImplementationTO created = logic.create(implementationTO); + URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(created.getKey())).build(); + return Response.created(location). + header(RESTHeaders.RESOURCE_KEY, created.getKey()). + build(); + } + + @Override + public void update(final ImplementationTO implementationTO) { + logic.update(implementationTO); + } + + @Override + public void delete(final String key) { + logic.delete(key); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/spring/pom.xml ---------------------------------------------------------------------- diff --git a/core/spring/pom.xml b/core/spring/pom.xml index addb5d3..22ba98b 100644 --- a/core/spring/pom.xml +++ b/core/spring/pom.xml @@ -73,6 +73,11 @@ under the License. </dependency> <dependency> + <groupId>org.codehaus.groovy</groupId> + <artifactId>groovy-all</artifactId> + </dependency> + + <dependency> <groupId>org.apache.syncope.core</groupId> <artifactId>syncope-core-provisioning-api</artifactId> <version>${project.version}</version> @@ -91,6 +96,11 @@ under the License. <scope>test</scope> </dependency> <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-test</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <scope>test</scope> http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/spring/src/main/java/org/apache/syncope/core/spring/ImplementationManager.java ---------------------------------------------------------------------- diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/ImplementationManager.java b/core/spring/src/main/java/org/apache/syncope/core/spring/ImplementationManager.java new file mode 100644 index 0000000..af1b2f7 --- /dev/null +++ b/core/spring/src/main/java/org/apache/syncope/core/spring/ImplementationManager.java @@ -0,0 +1,174 @@ +/* + * 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.spring; + +import groovy.lang.GroovyClassLoader; +import java.util.Optional; +import org.apache.syncope.common.lib.policy.AccountRuleConf; +import org.apache.syncope.common.lib.policy.PasswordRuleConf; +import org.apache.syncope.common.lib.report.ReportletConf; +import org.apache.syncope.core.persistence.api.ImplementationLookup; +import org.apache.syncope.core.persistence.api.dao.AccountRule; +import org.apache.syncope.core.persistence.api.dao.PasswordRule; +import org.apache.syncope.core.persistence.api.dao.Reportlet; +import org.apache.syncope.core.persistence.api.entity.Implementation; +import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.support.AbstractBeanDefinition; + +public final class ImplementationManager { + + private static final Logger LOG = LoggerFactory.getLogger(ImplementationManager.class); + + private static final GroovyClassLoader GROOVY_CLASSLOADER = new GroovyClassLoader(); + + public static Optional<Reportlet> buildReportlet(final Implementation impl) + throws InstantiationException, IllegalAccessException { + + switch (impl.getEngine()) { + case GROOVY: + return Optional.of(ImplementationManager.<Reportlet>buildGroovy(impl.getBody())); + + case JAVA: + default: + Reportlet reportlet = null; + + ReportletConf reportletConf = POJOHelper.deserialize(impl.getBody(), ReportletConf.class); + Class<? extends Reportlet> reportletClass = ApplicationContextProvider.getApplicationContext(). + getBean(ImplementationLookup.class).getReportletClass(reportletConf.getClass()); + if (reportletClass == null) { + LOG.warn("Could not find matching reportlet for {}", reportletConf.getClass()); + } else { + // fetch (or create) reportlet + if (ApplicationContextProvider.getBeanFactory().containsSingleton(reportletClass.getName())) { + reportlet = (Reportlet) ApplicationContextProvider.getBeanFactory(). + getSingleton(reportletClass.getName()); + } else { + reportlet = (Reportlet) ApplicationContextProvider.getBeanFactory(). + createBean(reportletClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false); + ApplicationContextProvider.getBeanFactory(). + registerSingleton(reportletClass.getName(), reportlet); + } + reportlet.setConf(reportletConf); + } + + return Optional.ofNullable(reportlet); + } + } + + public static Optional<AccountRule> buildAccountRule(final Implementation impl) + throws InstantiationException, IllegalAccessException { + + switch (impl.getEngine()) { + case GROOVY: + return Optional.of(ImplementationManager.<AccountRule>buildGroovy(impl.getBody())); + + case JAVA: + default: + AccountRule rule = null; + + AccountRuleConf ruleConf = POJOHelper.deserialize(impl.getBody(), AccountRuleConf.class); + Class<? extends AccountRule> ruleClass = ApplicationContextProvider.getApplicationContext(). + getBean(ImplementationLookup.class).getAccountRuleClass(ruleConf.getClass()); + if (ruleClass == null) { + LOG.warn("Could not find matching password rule for {}", impl.getClass()); + } else { + // fetch (or create) rule + if (ApplicationContextProvider.getBeanFactory().containsSingleton(ruleClass.getName())) { + rule = (AccountRule) ApplicationContextProvider.getBeanFactory(). + getSingleton(ruleClass.getName()); + } else { + rule = (AccountRule) ApplicationContextProvider.getBeanFactory(). + createBean(ruleClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false); + ApplicationContextProvider.getBeanFactory(). + registerSingleton(ruleClass.getName(), rule); + } + rule.setConf(ruleConf); + } + + return Optional.ofNullable(rule); + } + } + + public static Optional<PasswordRule> buildPasswordRule(final Implementation impl) + throws InstantiationException, IllegalAccessException { + + switch (impl.getEngine()) { + case GROOVY: + return Optional.of(ImplementationManager.<PasswordRule>buildGroovy(impl.getBody())); + + case JAVA: + default: + PasswordRule rule = null; + + PasswordRuleConf ruleConf = POJOHelper.deserialize(impl.getBody(), PasswordRuleConf.class); + Class<? extends PasswordRule> ruleClass = ApplicationContextProvider.getApplicationContext(). + getBean(ImplementationLookup.class).getPasswordRuleClass(ruleConf.getClass()); + if (ruleClass == null) { + LOG.warn("Could not find matching password rule for {}", impl.getClass()); + } else { + // fetch (or create) rule + if (ApplicationContextProvider.getBeanFactory().containsSingleton(ruleClass.getName())) { + rule = (PasswordRule) ApplicationContextProvider.getBeanFactory(). + getSingleton(ruleClass.getName()); + } else { + rule = (PasswordRule) ApplicationContextProvider.getBeanFactory(). + createBean(ruleClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false); + ApplicationContextProvider.getBeanFactory(). + registerSingleton(ruleClass.getName(), rule); + } + rule.setConf(ruleConf); + } + + return Optional.ofNullable(rule); + } + } + + public static <T> T build(final Implementation impl) + throws InstantiationException, IllegalAccessException, ClassNotFoundException { + + switch (impl.getEngine()) { + case GROOVY: + return ImplementationManager.<T>buildGroovy(impl.getBody()); + + case JAVA: + default: + return ImplementationManager.<T>buildJava(impl.getBody()); + } + } + + @SuppressWarnings("unchecked") + private static <T> T buildGroovy(final String classBody) throws InstantiationException, IllegalAccessException { + Class<?> clazz = GROOVY_CLASSLOADER.parseClass(classBody); + return (T) ApplicationContextProvider.getBeanFactory(). + createBean(clazz, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false); + } + + @SuppressWarnings("unchecked") + private static <T> T buildJava(final String className) throws ClassNotFoundException { + Class<?> clazz = Class.forName(className); + return (T) ApplicationContextProvider.getBeanFactory(). + createBean(clazz, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false); + } + + private ImplementationManager() { + // private constructor for static utility class + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java ---------------------------------------------------------------------- diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java index 3a5ee7b..691ff36 100644 --- a/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java +++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java @@ -141,7 +141,7 @@ public class AuthDataAccessor { jwtSSOProviders = new HashMap<>(); implementationLookup.getJWTSSOProviderClasses().stream(). - map((clazz) -> (JWTSSOProvider) ApplicationContextProvider.getBeanFactory(). + map(clazz -> (JWTSSOProvider) ApplicationContextProvider.getBeanFactory(). createBean(clazz, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true)). forEachOrdered(jwtSSOProvider -> { jwtSSOProviders.put(jwtSSOProvider.getIssuer(), jwtSSOProvider); http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/spring/src/main/java/org/apache/syncope/core/spring/security/DefaultPasswordGenerator.java ---------------------------------------------------------------------- diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/DefaultPasswordGenerator.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/DefaultPasswordGenerator.java index 93c750c..b0a4d95 100644 --- a/core/spring/src/main/java/org/apache/syncope/core/spring/security/DefaultPasswordGenerator.java +++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/DefaultPasswordGenerator.java @@ -20,12 +20,17 @@ package org.apache.syncope.core.spring.security; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf; -import org.apache.syncope.common.lib.policy.PasswordRuleConf; -import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource; +import org.apache.syncope.core.persistence.api.dao.PasswordRule; +import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy; import org.apache.syncope.core.provisioning.api.utils.policy.InvalidPasswordRuleConf; import org.apache.syncope.core.provisioning.api.utils.policy.PolicyPattern; +import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource; +import org.apache.syncope.core.spring.ImplementationManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.transaction.annotation.Transactional; /** @@ -36,6 +41,8 @@ import org.springframework.transaction.annotation.Transactional; */ public class DefaultPasswordGenerator implements PasswordGenerator { + private static final Logger LOG = LoggerFactory.getLogger(PasswordGenerator.class); + private static final char[] SPECIAL_CHARS = { '!', '£', '%', '&', '(', ')', '?', '#', '$' }; private static final int VERY_MIN_LENGTH = 0; @@ -47,23 +54,29 @@ public class DefaultPasswordGenerator implements PasswordGenerator { @Transactional(readOnly = true) @Override public String generate(final ExternalResource resource) throws InvalidPasswordRuleConf { - List<PasswordRuleConf> ruleConfs = new ArrayList<>(); + List<PasswordPolicy> policies = new ArrayList<>(); if (resource.getPasswordPolicy() != null) { - ruleConfs.addAll(resource.getPasswordPolicy().getRuleConfs()); + policies.add(resource.getPasswordPolicy()); } - return generate(ruleConfs); + return generate(policies); } @Override - public String generate(final List<PasswordRuleConf> ruleConfs) throws InvalidPasswordRuleConf { + public String generate(final List<PasswordPolicy> policies) throws InvalidPasswordRuleConf { List<DefaultPasswordRuleConf> defaultRuleConfs = new ArrayList<>(); - ruleConfs.stream(). - filter(ruleConf -> (ruleConf instanceof DefaultPasswordRuleConf)). - forEachOrdered(ruleConf -> { - defaultRuleConfs.add((DefaultPasswordRuleConf) ruleConf); - }); + + policies.stream().forEach(policy -> policy.getRules().forEach(impl -> { + try { + Optional<PasswordRule> rule = ImplementationManager.buildPasswordRule(impl); + if (rule.isPresent() && rule.get().getConf() instanceof DefaultPasswordRuleConf) { + defaultRuleConfs.add((DefaultPasswordRuleConf) rule.get().getConf()); + } + } catch (Exception e) { + LOG.error("Invalid {}, ignoring...", impl, e); + } + })); DefaultPasswordRuleConf ruleConf = merge(defaultRuleConfs); check(ruleConf); @@ -301,17 +314,17 @@ public class DefaultPasswordGenerator implements PasswordGenerator { } private void checkPrefixAndSuffix(final String[] generatedPassword, final DefaultPasswordRuleConf ruleConf) { - for (String prefix : ruleConf.getPrefixesNotPermitted()) { + ruleConf.getPrefixesNotPermitted().forEach(prefix -> { if (StringUtils.join(generatedPassword).startsWith(prefix)) { checkStartChar(generatedPassword, ruleConf); } - } + }); - for (String suffix : ruleConf.getSuffixesNotPermitted()) { + ruleConf.getSuffixesNotPermitted().forEach(suffix -> { if (StringUtils.join(generatedPassword).endsWith(suffix)) { checkEndChar(generatedPassword, ruleConf); } - } + }); } } http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/spring/src/main/java/org/apache/syncope/core/spring/security/PasswordGenerator.java ---------------------------------------------------------------------- diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/PasswordGenerator.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/PasswordGenerator.java index 06b73e4..cf40d5f 100644 --- a/core/spring/src/main/java/org/apache/syncope/core/spring/security/PasswordGenerator.java +++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/PasswordGenerator.java @@ -19,7 +19,7 @@ package org.apache.syncope.core.spring.security; import java.util.List; -import org.apache.syncope.common.lib.policy.PasswordRuleConf; +import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy; import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource; import org.apache.syncope.core.provisioning.api.utils.policy.InvalidPasswordRuleConf; @@ -27,6 +27,6 @@ public interface PasswordGenerator { String generate(ExternalResource resource) throws InvalidPasswordRuleConf; - String generate(List<PasswordRuleConf> ruleConfs) throws InvalidPasswordRuleConf; + String generate(List<PasswordPolicy> policies) throws InvalidPasswordRuleConf; } http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/spring/src/test/java/org/apache/syncope/core/spring/security/DummyImplementationLookup.java ---------------------------------------------------------------------- diff --git a/core/spring/src/test/java/org/apache/syncope/core/spring/security/DummyImplementationLookup.java b/core/spring/src/test/java/org/apache/syncope/core/spring/security/DummyImplementationLookup.java new file mode 100644 index 0000000..e644645 --- /dev/null +++ b/core/spring/src/test/java/org/apache/syncope/core/spring/security/DummyImplementationLookup.java @@ -0,0 +1,80 @@ +/* + * 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.spring.security; + +import java.util.Collections; +import java.util.Set; +import org.apache.syncope.common.lib.policy.AccountRuleConf; +import org.apache.syncope.common.lib.policy.PasswordRuleConf; +import org.apache.syncope.common.lib.report.ReportletConf; +import org.apache.syncope.common.lib.types.ImplementationType; +import org.apache.syncope.core.persistence.api.ImplementationLookup; +import org.apache.syncope.core.persistence.api.dao.AccountRule; +import org.apache.syncope.core.persistence.api.dao.PasswordRule; +import org.apache.syncope.core.persistence.api.dao.Reportlet; + +public class DummyImplementationLookup implements ImplementationLookup { + + @Override + public Integer getPriority() { + return -1; + } + + @Override + public void load() { + // do nothing + } + + @Override + public Set<String> getClassNames(final ImplementationType type) { + return Collections.emptySet(); + } + + @Override + public Set<Class<?>> getJWTSSOProviderClasses() { + return Collections.emptySet(); + } + + @Override + public Class<Reportlet> getReportletClass( + final Class<? extends ReportletConf> reportletConfClass) { + + return null; + } + + @Override + public Class<? extends AccountRule> getAccountRuleClass( + final Class<? extends AccountRuleConf> accountRuleConfClass) { + + return null; + } + + @Override + public Class<? extends PasswordRule> getPasswordRuleClass( + final Class<? extends PasswordRuleConf> passwordRuleConfClass) { + + return TestPasswordRule.class; + } + + @Override + public Set<Class<?>> getAuditAppenderClasses() { + return Collections.emptySet(); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/spring/src/test/java/org/apache/syncope/core/spring/security/EncryptorTest.java ---------------------------------------------------------------------- diff --git a/core/spring/src/test/java/org/apache/syncope/core/spring/security/EncryptorTest.java b/core/spring/src/test/java/org/apache/syncope/core/spring/security/EncryptorTest.java index 0d1b801..4ec78b9 100644 --- a/core/spring/src/test/java/org/apache/syncope/core/spring/security/EncryptorTest.java +++ b/core/spring/src/test/java/org/apache/syncope/core/spring/security/EncryptorTest.java @@ -18,8 +18,6 @@ */ package org.apache.syncope.core.spring.security; -import org.apache.syncope.core.spring.security.Encryptor; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/spring/src/test/java/org/apache/syncope/core/spring/security/PasswordGeneratorTest.java ---------------------------------------------------------------------- diff --git a/core/spring/src/test/java/org/apache/syncope/core/spring/security/PasswordGeneratorTest.java b/core/spring/src/test/java/org/apache/syncope/core/spring/security/PasswordGeneratorTest.java index 2edab6d..8378a57 100644 --- a/core/spring/src/test/java/org/apache/syncope/core/spring/security/PasswordGeneratorTest.java +++ b/core/spring/src/test/java/org/apache/syncope/core/spring/security/PasswordGeneratorTest.java @@ -27,11 +27,14 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf; -import org.apache.syncope.common.lib.policy.PasswordRuleConf; +import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy; +import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; import org.apache.syncope.core.provisioning.api.utils.policy.InvalidPasswordRuleConf; import org.apache.syncope.core.provisioning.api.utils.policy.PolicyPattern; import org.junit.jupiter.api.Test; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; +@SpringJUnitConfig(locations = { "classpath:springTest.xml" }) public class PasswordGeneratorTest { private final DefaultPasswordGenerator passwordGenerator = new DefaultPasswordGenerator(); @@ -62,48 +65,72 @@ public class PasswordGeneratorTest { @Test public void startEndWithDigit() throws InvalidPasswordRuleConf { - DefaultPasswordRuleConf pwdRuleConf = createBaseDefaultPasswordRuleConf(); - pwdRuleConf.setMustStartWithDigit(true); + DefaultPasswordRuleConf pwdRuleConf1 = createBaseDefaultPasswordRuleConf(); + pwdRuleConf1.setMustStartWithDigit(true); + TestImplementation passwordRule1 = new TestImplementation(); + passwordRule1.setBody(POJOHelper.serialize(pwdRuleConf1)); + TestPasswordPolicy policy1 = new TestPasswordPolicy(); + policy1.add(passwordRule1); DefaultPasswordRuleConf pwdRuleConf2 = createBaseDefaultPasswordRuleConf(); pwdRuleConf2.setMustEndWithDigit(true); - - List<PasswordRuleConf> ruleConfs = new ArrayList<>(); - ruleConfs.add(pwdRuleConf); - ruleConfs.add(pwdRuleConf2); - String generatedPassword = passwordGenerator.generate(ruleConfs); + TestImplementation passwordRule2 = new TestImplementation(); + passwordRule2.setBody(POJOHelper.serialize(pwdRuleConf2)); + TestPasswordPolicy policy2 = new TestPasswordPolicy(); + policy2.add(passwordRule2); + + List<PasswordPolicy> policies = new ArrayList<>(); + policies.add(policy1); + policies.add(policy2); + String generatedPassword = passwordGenerator.generate(policies); assertTrue(Character.isDigit(generatedPassword.charAt(0))); assertTrue(Character.isDigit(generatedPassword.charAt(generatedPassword.length() - 1))); } @Test public void startWithDigitAndWithAlpha() throws InvalidPasswordRuleConf { - DefaultPasswordRuleConf pwdRuleConf = createBaseDefaultPasswordRuleConf(); - pwdRuleConf.setMustStartWithDigit(true); + DefaultPasswordRuleConf pwdRuleConf1 = createBaseDefaultPasswordRuleConf(); + pwdRuleConf1.setMustStartWithDigit(true); + TestImplementation passwordRule1 = new TestImplementation(); + passwordRule1.setBody(POJOHelper.serialize(pwdRuleConf1)); + TestPasswordPolicy policy1 = new TestPasswordPolicy(); + policy1.add(passwordRule1); DefaultPasswordRuleConf pwdRuleConf2 = createBaseDefaultPasswordRuleConf(); pwdRuleConf2.setMustEndWithAlpha(true); - - List<PasswordRuleConf> pwdRuleConfs = new ArrayList<>(); - pwdRuleConfs.add(pwdRuleConf); - pwdRuleConfs.add(pwdRuleConf2); - String generatedPassword = passwordGenerator.generate(pwdRuleConfs); + TestImplementation passwordRule2 = new TestImplementation(); + passwordRule2.setBody(POJOHelper.serialize(pwdRuleConf2)); + TestPasswordPolicy policy2 = new TestPasswordPolicy(); + policy2.add(passwordRule2); + + List<PasswordPolicy> policies = new ArrayList<>(); + policies.add(policy1); + policies.add(policy2); + String generatedPassword = passwordGenerator.generate(policies); assertTrue(Character.isDigit(generatedPassword.charAt(0))); assertTrue(Character.isLetter(generatedPassword.charAt(generatedPassword.length() - 1))); } @Test public void passwordWithNonAlpha() throws InvalidPasswordRuleConf { - DefaultPasswordRuleConf pwdRuleConf = createBaseDefaultPasswordRuleConf(); - pwdRuleConf.setNonAlphanumericRequired(true); + DefaultPasswordRuleConf pwdRuleConf1 = createBaseDefaultPasswordRuleConf(); + pwdRuleConf1.setNonAlphanumericRequired(true); + TestImplementation passwordRule1 = new TestImplementation(); + passwordRule1.setBody(POJOHelper.serialize(pwdRuleConf1)); + TestPasswordPolicy policy1 = new TestPasswordPolicy(); + policy1.add(passwordRule1); DefaultPasswordRuleConf pwdRuleConf2 = createBaseDefaultPasswordRuleConf(); pwdRuleConf2.setMustEndWithAlpha(true); - - List<PasswordRuleConf> pwdRuleConfs = new ArrayList<>(); - pwdRuleConfs.add(pwdRuleConf); - pwdRuleConfs.add(pwdRuleConf2); - String generatedPassword = passwordGenerator.generate(pwdRuleConfs); + TestImplementation passwordRule2 = new TestImplementation(); + passwordRule2.setBody(POJOHelper.serialize(pwdRuleConf2)); + TestPasswordPolicy policy2 = new TestPasswordPolicy(); + policy2.add(passwordRule2); + + List<PasswordPolicy> policies = new ArrayList<>(); + policies.add(policy1); + policies.add(policy2); + String generatedPassword = passwordGenerator.generate(policies); assertTrue(PolicyPattern.NON_ALPHANUMERIC.matcher(generatedPassword).matches()); assertTrue(Character.isLetter(generatedPassword.charAt(generatedPassword.length() - 1))); } @@ -111,16 +138,24 @@ public class PasswordGeneratorTest { @Test public void incopatiblePolicies() { assertThrows(InvalidPasswordRuleConf.class, () -> { - DefaultPasswordRuleConf pwdRuleConf = createBaseDefaultPasswordRuleConf(); - pwdRuleConf.setMinLength(12); + DefaultPasswordRuleConf pwdRuleConf1 = createBaseDefaultPasswordRuleConf(); + pwdRuleConf1.setMinLength(12); + TestImplementation passwordRule1 = new TestImplementation(); + passwordRule1.setBody(POJOHelper.serialize(pwdRuleConf1)); + TestPasswordPolicy policy1 = new TestPasswordPolicy(); + policy1.add(passwordRule1); DefaultPasswordRuleConf pwdRuleConf2 = createBaseDefaultPasswordRuleConf(); - pwdRuleConf.setMaxLength(10); - - List<PasswordRuleConf> pwdRuleConfs = new ArrayList<>(); - pwdRuleConfs.add(pwdRuleConf); - pwdRuleConfs.add(pwdRuleConf2); - passwordGenerator.generate(pwdRuleConfs); + pwdRuleConf2.setMaxLength(10); + TestImplementation passwordRule2 = new TestImplementation(); + passwordRule2.setBody(POJOHelper.serialize(pwdRuleConf2)); + TestPasswordPolicy policy2 = new TestPasswordPolicy(); + policy2.add(passwordRule2); + + List<PasswordPolicy> policies = new ArrayList<>(); + policies.add(policy1); + policies.add(policy2); + passwordGenerator.generate(policies); }); } @@ -128,17 +163,21 @@ public class PasswordGeneratorTest { public void issueSYNCOPE678() { String password = null; try { - password = passwordGenerator.generate(Collections.<PasswordRuleConf>emptyList()); + password = passwordGenerator.generate(Collections.<PasswordPolicy>emptyList()); } catch (InvalidPasswordRuleConf e) { fail(e.getMessage()); } assertNotNull(password); - DefaultPasswordRuleConf ppSpec = createBaseDefaultPasswordRuleConf(); - ppSpec.setMinLength(0); + DefaultPasswordRuleConf pwdRuleConf1 = createBaseDefaultPasswordRuleConf(); + pwdRuleConf1.setMinLength(0); + TestImplementation passwordRule1 = new TestImplementation(); + passwordRule1.setBody(POJOHelper.serialize(pwdRuleConf1)); + TestPasswordPolicy policy1 = new TestPasswordPolicy(); + password = null; try { - password = passwordGenerator.generate(Collections.<PasswordRuleConf>singletonList(ppSpec)); + password = passwordGenerator.generate(Collections.<PasswordPolicy>singletonList(policy1)); } catch (InvalidPasswordRuleConf e) { fail(e.getMessage()); } http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/spring/src/test/java/org/apache/syncope/core/spring/security/TestImplementation.java ---------------------------------------------------------------------- diff --git a/core/spring/src/test/java/org/apache/syncope/core/spring/security/TestImplementation.java b/core/spring/src/test/java/org/apache/syncope/core/spring/security/TestImplementation.java new file mode 100644 index 0000000..96479ce --- /dev/null +++ b/core/spring/src/test/java/org/apache/syncope/core/spring/security/TestImplementation.java @@ -0,0 +1,71 @@ +/* + * 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.spring.security; + +import org.apache.syncope.common.lib.types.ImplementationEngine; +import org.apache.syncope.common.lib.types.ImplementationType; +import org.apache.syncope.core.persistence.api.entity.Implementation; + +public class TestImplementation implements Implementation { + + private static final long serialVersionUID = -2362660463135828190L; + + private String body; + + @Override + public void setKey(final String key) { + // nothing to do + } + + @Override + public String getKey() { + return ""; + } + + @Override + public ImplementationEngine getEngine() { + return ImplementationEngine.JAVA; + } + + @Override + public void setEngine(ImplementationEngine engine) { + // nothing to do + } + + @Override + public ImplementationType getType() { + return ImplementationType.PASSWORD_RULE; + } + + @Override + public void setType(ImplementationType type) { + // nothing to do + } + + @Override + public String getBody() { + return body; + } + + @Override + public void setBody(final String body) { + this.body = body; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/spring/src/test/java/org/apache/syncope/core/spring/security/TestPasswordPolicy.java ---------------------------------------------------------------------- diff --git a/core/spring/src/test/java/org/apache/syncope/core/spring/security/TestPasswordPolicy.java b/core/spring/src/test/java/org/apache/syncope/core/spring/security/TestPasswordPolicy.java new file mode 100644 index 0000000..bf2255d --- /dev/null +++ b/core/spring/src/test/java/org/apache/syncope/core/spring/security/TestPasswordPolicy.java @@ -0,0 +1,77 @@ +/* + * 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.spring.security; + +import java.util.ArrayList; +import java.util.List; +import org.apache.syncope.core.persistence.api.entity.Implementation; +import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy; + +public class TestPasswordPolicy implements PasswordPolicy { + + private static final long serialVersionUID = 4978614846223679095L; + + private final List<Implementation> rules = new ArrayList<>(); + + @Override + public String getKey() { + return ""; + } + + @Override + public String getDescription() { + return ""; + } + + @Override + public void setDescription(String description) { + // nothing to do + } + + @Override + public boolean isAllowNullPassword() { + return false; + } + + @Override + public void setAllowNullPassword(final boolean allowNullPassword) { + // nothing to do + } + + @Override + public int getHistoryLength() { + return 0; + } + + @Override + public void setHistoryLength(final int historyLength) { + // nothing to do + } + + @Override + public boolean add(final Implementation rule) { + return this.rules.add(rule); + } + + @Override + public List<? extends Implementation> getRules() { + return this.rules; + + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/spring/src/test/java/org/apache/syncope/core/spring/security/TestPasswordRule.java ---------------------------------------------------------------------- diff --git a/core/spring/src/test/java/org/apache/syncope/core/spring/security/TestPasswordRule.java b/core/spring/src/test/java/org/apache/syncope/core/spring/security/TestPasswordRule.java new file mode 100644 index 0000000..549549a --- /dev/null +++ b/core/spring/src/test/java/org/apache/syncope/core/spring/security/TestPasswordRule.java @@ -0,0 +1,52 @@ +/* + * 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.spring.security; + +import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf; +import org.apache.syncope.common.lib.policy.PasswordRuleConf; +import org.apache.syncope.core.persistence.api.dao.PasswordRule; +import org.apache.syncope.core.persistence.api.dao.PasswordRuleConfClass; +import org.apache.syncope.core.persistence.api.entity.user.User; + +@PasswordRuleConfClass(DefaultPasswordRuleConf.class) +public class TestPasswordRule implements PasswordRule { + + private DefaultPasswordRuleConf conf; + + @Override + public PasswordRuleConf getConf() { + return conf; + } + + @Override + public void setConf(final PasswordRuleConf conf) { + if (conf instanceof DefaultPasswordRuleConf) { + this.conf = (DefaultPasswordRuleConf) conf; + } else { + throw new IllegalArgumentException( + DefaultPasswordRuleConf.class.getName() + " expected, got " + conf.getClass().getName()); + } + } + + @Override + public void enforce(final User user) { + // nothing to do + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/core/spring/src/test/resources/springTest.xml ---------------------------------------------------------------------- diff --git a/core/spring/src/test/resources/springTest.xml b/core/spring/src/test/resources/springTest.xml new file mode 100644 index 0000000..76ae511 --- /dev/null +++ b/core/spring/src/test/resources/springTest.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +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. +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:context="http://www.springframework.org/schema/context" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/context + http://www.springframework.org/schema/context/spring-context.xsd"> + + <bean class="org.apache.syncope.core.spring.ApplicationContextProvider"/> + <bean class="org.apache.syncope.core.spring.security.DummyImplementationLookup"/> + +</beans> http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java ---------------------------------------------------------------------- diff --git a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java index b11a530..9c78366 100644 --- a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java +++ b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java @@ -20,9 +20,7 @@ package org.apache.syncope.common.lib.to; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; import javax.ws.rs.PathParam; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; @@ -61,7 +59,7 @@ public class SAML2IdPTO extends AbstractBaseBean implements EntityTO, ItemContai private final List<ItemTO> items = new ArrayList<>(); - private final Set<String> actionsClassNames = new HashSet<>(); + private final List<String> actions = new ArrayList<>(); @Override public String getKey() { @@ -182,11 +180,11 @@ public class SAML2IdPTO extends AbstractBaseBean implements EntityTO, ItemContai return this.items.remove(item); } - @XmlElementWrapper(name = "actionsClassNames") - @XmlElement(name = "actionsClassName") - @JsonProperty("actionsClassNames") - public Set<String> getActionsClassNames() { - return actionsClassNames; + @XmlElementWrapper(name = "actions") + @XmlElement(name = "action") + @JsonProperty("actions") + public List<String> getActions() { + return actions; } public boolean isSupportUnsolicited() {
