http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/NotificationLogic.java ---------------------------------------------------------------------- diff --git a/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/NotificationLogic.java b/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/NotificationLogic.java new file mode 100644 index 0000000..0c7a8e2 --- /dev/null +++ b/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/NotificationLogic.java @@ -0,0 +1,127 @@ +/* + * 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.logic; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.syncope.common.lib.to.NotificationTO; +import org.apache.syncope.core.persistence.api.dao.NotFoundException; +import org.apache.syncope.core.persistence.api.dao.NotificationDAO; +import org.apache.syncope.core.persistence.api.entity.Notification; +import org.apache.syncope.core.provisioning.api.data.NotificationDataBinder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; + +@Component +public class NotificationLogic extends AbstractTransactionalLogic<NotificationTO> { + + @Autowired + private NotificationDAO notificationDAO; + + @Autowired + private NotificationDataBinder binder; + + @PreAuthorize("hasRole('NOTIFICATION_READ')") + public NotificationTO read(final Long notificationId) { + Notification notification = notificationDAO.find(notificationId); + if (notification == null) { + LOG.error("Could not find notification '" + notificationId + "'"); + + throw new NotFoundException(String.valueOf(notificationId)); + } + + return binder.getNotificationTO(notification); + } + + @PreAuthorize("hasRole('NOTIFICATION_LIST')") + public List<NotificationTO> list() { + List<Notification> notifications = notificationDAO.findAll(); + + List<NotificationTO> notificationTOs = new ArrayList<NotificationTO>(); + for (Notification notification : notifications) { + notificationTOs.add(binder.getNotificationTO(notification)); + } + + return notificationTOs; + } + + @PreAuthorize("hasRole('NOTIFICATION_CREATE')") + public NotificationTO create(final NotificationTO notificationTO) { + return binder.getNotificationTO(notificationDAO.save(binder.create(notificationTO))); + } + + @PreAuthorize("hasRole('NOTIFICATION_UPDATE')") + public NotificationTO update(final NotificationTO notificationTO) { + Notification notification = notificationDAO.find(notificationTO.getKey()); + if (notification == null) { + LOG.error("Could not find notification '" + notificationTO.getKey() + "'"); + throw new NotFoundException(String.valueOf(notificationTO.getKey())); + } + + binder.update(notification, notificationTO); + notification = notificationDAO.save(notification); + + return binder.getNotificationTO(notification); + } + + @PreAuthorize("hasRole('CONNECTOR_DELETE')") + public NotificationTO delete(final Long notificationId) { + Notification notification = notificationDAO.find(notificationId); + if (notification == null) { + LOG.error("Could not find notification '" + notificationId + "'"); + + throw new NotFoundException(String.valueOf(notificationId)); + } + + NotificationTO deleted = binder.getNotificationTO(notification); + notificationDAO.delete(notificationId); + return deleted; + } + + @Override + protected NotificationTO resolveReference(final Method method, final Object... args) + throws UnresolvedReferenceException { + + Long key = null; + + if (ArrayUtils.isNotEmpty(args)) { + for (int i = 0; key == null && i < args.length; i++) { + if (args[i] instanceof Long) { + key = (Long) args[i]; + } else if (args[i] instanceof NotificationTO) { + key = ((NotificationTO) args[i]).getKey(); + } + } + } + + if ((key != null) && !key.equals(0l)) { + try { + return binder.getNotificationTO(notificationDAO.find(key)); + } catch (Throwable ignore) { + LOG.debug("Unresolved reference", ignore); + throw new UnresolvedReferenceException(ignore); + } + } + + throw new UnresolvedReferenceException(); + } +}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/PolicyLogic.java ---------------------------------------------------------------------- diff --git a/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/PolicyLogic.java b/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/PolicyLogic.java new file mode 100644 index 0000000..c01131c --- /dev/null +++ b/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/PolicyLogic.java @@ -0,0 +1,187 @@ +/* + * 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.logic; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.syncope.common.lib.to.AbstractPolicyTO; +import org.apache.syncope.common.lib.to.AccountPolicyTO; +import org.apache.syncope.common.lib.to.PasswordPolicyTO; +import org.apache.syncope.common.lib.to.SyncPolicyTO; +import org.apache.syncope.common.lib.types.PolicyType; +import org.apache.syncope.core.persistence.api.dao.NotFoundException; +import org.apache.syncope.core.persistence.api.dao.PolicyDAO; +import org.apache.syncope.core.persistence.api.entity.AccountPolicy; +import org.apache.syncope.core.persistence.api.entity.PasswordPolicy; +import org.apache.syncope.core.persistence.api.entity.Policy; +import org.apache.syncope.core.persistence.api.entity.SyncPolicy; +import org.apache.syncope.core.provisioning.api.data.PolicyDataBinder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; + +@Component +public class PolicyLogic extends AbstractTransactionalLogic<AbstractPolicyTO> { + + @Autowired + private PolicyDAO policyDAO; + + @Autowired + private PolicyDataBinder binder; + + @PreAuthorize("hasRole('POLICY_CREATE')") + public <T extends AbstractPolicyTO> T create(final T policyTO) { + return binder.getPolicyTO(policyDAO.save(binder.getPolicy(null, policyTO))); + } + + private <T extends AbstractPolicyTO, K extends Policy> T update(final T policyTO, final K policy) { + binder.getPolicy(policy, policyTO); + K savedPolicy = policyDAO.save(policy); + return binder.getPolicyTO(savedPolicy); + } + + @PreAuthorize("hasRole('POLICY_UPDATE')") + public PasswordPolicyTO update(final PasswordPolicyTO policyTO) { + Policy policy = policyDAO.find(policyTO.getKey()); + if (!(policy instanceof PasswordPolicy)) { + throw new NotFoundException("PasswordPolicy with id " + policyTO.getKey()); + } + + return update(policyTO, policy); + } + + @PreAuthorize("hasRole('POLICY_UPDATE')") + public AccountPolicyTO update(final AccountPolicyTO policyTO) { + Policy policy = policyDAO.find(policyTO.getKey()); + if (!(policy instanceof AccountPolicy)) { + throw new NotFoundException("AccountPolicy with id " + policyTO.getKey()); + } + + return update(policyTO, policy); + } + + @PreAuthorize("hasRole('POLICY_UPDATE')") + public SyncPolicyTO update(final SyncPolicyTO policyTO) { + Policy policy = policyDAO.find(policyTO.getKey()); + if (!(policy instanceof SyncPolicy)) { + throw new NotFoundException("SyncPolicy with id " + policyTO.getKey()); + } + + return update(policyTO, policy); + } + + @PreAuthorize("hasRole('POLICY_LIST')") + @SuppressWarnings("unchecked") + public <T extends AbstractPolicyTO> List<T> list(final PolicyType type) { + + List<? extends Policy> policies = policyDAO.find(type); + + final List<T> policyTOs = new ArrayList<T>(); + for (Policy policy : policies) { + policyTOs.add((T) binder.getPolicyTO(policy)); + } + + return policyTOs; + } + + @PreAuthorize("hasRole('POLICY_READ')") + public PasswordPolicyTO getGlobalPasswordPolicy() { + PasswordPolicy policy = policyDAO.getGlobalPasswordPolicy(); + if (policy == null) { + throw new NotFoundException("No password policy found"); + } + + return (PasswordPolicyTO) binder.getPolicyTO(policy); + } + + @PreAuthorize("hasRole('POLICY_READ')") + public AccountPolicyTO getGlobalAccountPolicy() { + AccountPolicy policy = policyDAO.getGlobalAccountPolicy(); + if (policy == null) { + throw new NotFoundException("No account policy found"); + } + + return (AccountPolicyTO) binder.getPolicyTO(policy); + } + + @PreAuthorize("hasRole('POLICY_READ')") + public SyncPolicyTO getGlobalSyncPolicy() { + SyncPolicy policy = policyDAO.getGlobalSyncPolicy(); + if (policy == null) { + throw new NotFoundException("No sync policy found"); + } + + return (SyncPolicyTO) binder.getPolicyTO(policy); + } + + @PreAuthorize("hasRole('POLICY_READ')") + public <T extends AbstractPolicyTO> T read(final Long id) { + Policy policy = policyDAO.find(id); + if (policy == null) { + throw new NotFoundException("Policy " + id + " not found"); + } + + return binder.getPolicyTO(policy); + } + + @PreAuthorize("hasRole('POLICY_DELETE')") + public <T extends AbstractPolicyTO> T delete(final Long id) { + Policy policy = policyDAO.find(id); + if (policy == null) { + throw new NotFoundException("Policy " + id + " not found"); + } + + T policyToDelete = binder.getPolicyTO(policy); + policyDAO.delete(policy); + + return policyToDelete; + } + + /** + * {@inheritDoc} + */ + @Override + protected AbstractPolicyTO resolveReference(final Method method, final Object... args) + throws UnresolvedReferenceException { + Long id = null; + + if (ArrayUtils.isNotEmpty(args)) { + for (int i = 0; id == null && i < args.length; i++) { + if (args[i] instanceof Long) { + id = (Long) args[i]; + } else if (args[i] instanceof AbstractPolicyTO) { + id = ((AbstractPolicyTO) args[i]).getKey(); + } + } + } + + if ((id != null) && !id.equals(0l)) { + try { + return binder.getPolicyTO(policyDAO.find(id)); + } catch (Throwable ignore) { + LOG.debug("Unresolved reference", ignore); + throw new UnresolvedReferenceException(ignore); + } + } + + throw new UnresolvedReferenceException(); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java ---------------------------------------------------------------------- diff --git a/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java b/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java new file mode 100644 index 0000000..a634433 --- /dev/null +++ b/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java @@ -0,0 +1,391 @@ +/* + * 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.logic; + +import java.io.ByteArrayInputStream; +import java.io.OutputStream; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.zip.ZipInputStream; +import org.apache.cocoon.optional.pipeline.components.sax.fop.FopSerializer; +import org.apache.cocoon.pipeline.NonCachingPipeline; +import org.apache.cocoon.pipeline.Pipeline; +import org.apache.cocoon.sax.SAXPipelineComponent; +import org.apache.cocoon.sax.component.XMLGenerator; +import org.apache.cocoon.sax.component.XMLSerializer; +import org.apache.cocoon.sax.component.XSLTTransformer; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.syncope.common.lib.SyncopeClientException; +import org.apache.syncope.common.lib.report.ReportletConf; +import org.apache.syncope.common.lib.to.ReportExecTO; +import org.apache.syncope.common.lib.to.ReportTO; +import org.apache.syncope.common.lib.types.ClientExceptionType; +import org.apache.syncope.common.lib.types.ReportExecExportFormat; +import org.apache.syncope.common.lib.types.ReportExecStatus; +import org.apache.syncope.core.persistence.api.dao.NotFoundException; +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.search.OrderByClause; +import org.apache.syncope.core.persistence.api.entity.EntityFactory; +import org.apache.syncope.core.persistence.api.entity.Report; +import org.apache.syncope.core.persistence.api.entity.ReportExec; +import org.apache.syncope.core.provisioning.api.data.ReportDataBinder; +import org.apache.syncope.core.provisioning.api.job.JobNamer; +import org.apache.syncope.core.logic.init.ImplementationClassNamesLoader; +import org.apache.syncope.core.provisioning.api.job.JobInstanceLoader; +import org.apache.syncope.core.logic.report.Reportlet; +import org.apache.syncope.core.logic.report.ReportletConfClass; +import org.apache.syncope.core.logic.report.TextSerializer; +import org.apache.xmlgraphics.util.MimeConstants; +import org.quartz.JobKey; +import org.quartz.Scheduler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.quartz.SchedulerFactoryBean; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.ClassUtils; + +@Component +public class ReportLogic extends AbstractTransactionalLogic<ReportTO> { + + @Autowired + private ReportDAO reportDAO; + + @Autowired + private ReportExecDAO reportExecDAO; + + @Autowired + private JobInstanceLoader jobInstanceLoader; + + @Autowired + private SchedulerFactoryBean scheduler; + + @Autowired + private ReportDataBinder binder; + + @Autowired + private EntityFactory entityFactory; + + @Autowired + private ImplementationClassNamesLoader classNamesLoader; + + @PreAuthorize("hasRole('REPORT_CREATE')") + public ReportTO create(final ReportTO reportTO) { + Report report = entityFactory.newEntity(Report.class); + binder.getReport(report, reportTO); + report = reportDAO.save(report); + + try { + jobInstanceLoader.registerJob(report); + } catch (Exception e) { + LOG.error("While registering quartz job for report " + report.getKey(), e); + + SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Scheduling); + sce.getElements().add(e.getMessage()); + throw sce; + } + + return binder.getReportTO(report); + } + + @PreAuthorize("hasRole('REPORT_UPDATE')") + public ReportTO update(final ReportTO reportTO) { + Report report = reportDAO.find(reportTO.getKey()); + if (report == null) { + throw new NotFoundException("Report " + reportTO.getKey()); + } + + binder.getReport(report, reportTO); + report = reportDAO.save(report); + + try { + jobInstanceLoader.registerJob(report); + } catch (Exception e) { + LOG.error("While registering quartz job for report " + report.getKey(), e); + + SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Scheduling); + sce.getElements().add(e.getMessage()); + throw sce; + } + + return binder.getReportTO(report); + } + + @PreAuthorize("hasRole('REPORT_LIST')") + public int count() { + return reportDAO.count(); + } + + @PreAuthorize("hasRole('REPORT_LIST')") + public List<ReportTO> list(final int page, final int size, final List<OrderByClause> orderByClauses) { + List<Report> reports = reportDAO.findAll(page, size, orderByClauses); + List<ReportTO> result = new ArrayList<>(reports.size()); + for (Report report : reports) { + result.add(binder.getReportTO(report)); + } + return result; + } + + private Class<? extends ReportletConf> getReportletConfClass(final Class<Reportlet> reportletClass) { + Class<? extends ReportletConf> result = null; + + ReportletConfClass annotation = reportletClass.getAnnotation(ReportletConfClass.class); + if (annotation != null) { + result = annotation.value(); + } + + return result; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + private Set<Class<Reportlet>> getAllReportletClasses() { + Set<Class<Reportlet>> reportletClasses = new HashSet<>(); + + for (String className : classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.REPORTLET)) { + try { + Class reportletClass = ClassUtils.forName(className, ClassUtils.getDefaultClassLoader()); + reportletClasses.add(reportletClass); + } catch (ClassNotFoundException e) { + LOG.warn("Could not load class {}", className); + } catch (LinkageError e) { + LOG.warn("Could not link class {}", className); + } + } + return reportletClasses; + } + + @PreAuthorize("hasRole('REPORT_LIST')") + public Set<String> getReportletConfClasses() { + Set<String> reportletConfClasses = new HashSet<>(); + + for (Class<Reportlet> reportletClass : getAllReportletClasses()) { + Class<? extends ReportletConf> reportletConfClass = getReportletConfClass(reportletClass); + if (reportletConfClass != null) { + reportletConfClasses.add(reportletConfClass.getName()); + } + } + + return reportletConfClasses; + } + + public Class<Reportlet> findReportletClassHavingConfClass(final Class<? extends ReportletConf> reportletConfClass) { + Class<Reportlet> result = null; + for (Class<Reportlet> reportletClass : getAllReportletClasses()) { + Class<? extends ReportletConf> found = getReportletConfClass(reportletClass); + if (found != null && found.equals(reportletConfClass)) { + result = reportletClass; + } + } + + return result; + } + + @PreAuthorize("hasRole('REPORT_READ')") + public ReportTO read(final Long reportKey) { + Report report = reportDAO.find(reportKey); + if (report == null) { + throw new NotFoundException("Report " + reportKey); + } + return binder.getReportTO(report); + } + + @PreAuthorize("hasRole('REPORT_READ')") + @Transactional(readOnly = true) + public ReportExecTO readExecution(final Long executionKey) { + ReportExec reportExec = reportExecDAO.find(executionKey); + if (reportExec == null) { + throw new NotFoundException("Report execution " + executionKey); + } + return binder.getReportExecTO(reportExec); + } + + @PreAuthorize("hasRole('REPORT_READ')") + public void exportExecutionResult(final OutputStream os, final ReportExec reportExec, + final ReportExecExportFormat format) { + + // streaming SAX handler from a compressed byte array stream + ByteArrayInputStream bais = new ByteArrayInputStream(reportExec.getExecResult()); + ZipInputStream zis = new ZipInputStream(bais); + try { + // a single ZipEntry in the ZipInputStream (see ReportJob) + zis.getNextEntry(); + + Pipeline<SAXPipelineComponent> pipeline = new NonCachingPipeline<>(); + pipeline.addComponent(new XMLGenerator(zis)); + + Map<String, Object> parameters = new HashMap<>(); + parameters.put("status", reportExec.getStatus()); + parameters.put("message", reportExec.getMessage()); + parameters.put("startDate", reportExec.getStartDate()); + parameters.put("endDate", reportExec.getEndDate()); + + switch (format) { + case HTML: + XSLTTransformer xsl2html = new XSLTTransformer(getClass().getResource("/report/report2html.xsl")); + xsl2html.setParameters(parameters); + pipeline.addComponent(xsl2html); + pipeline.addComponent(XMLSerializer.createXHTMLSerializer()); + break; + + case PDF: + XSLTTransformer xsl2pdf = new XSLTTransformer(getClass().getResource("/report/report2fo.xsl")); + xsl2pdf.setParameters(parameters); + pipeline.addComponent(xsl2pdf); + pipeline.addComponent(new FopSerializer(MimeConstants.MIME_PDF)); + break; + + case RTF: + XSLTTransformer xsl2rtf = new XSLTTransformer(getClass().getResource("/report/report2fo.xsl")); + xsl2rtf.setParameters(parameters); + pipeline.addComponent(xsl2rtf); + pipeline.addComponent(new FopSerializer(MimeConstants.MIME_RTF)); + break; + + case CSV: + XSLTTransformer xsl2csv = new XSLTTransformer(getClass().getResource("/report/report2csv.xsl")); + xsl2csv.setParameters(parameters); + pipeline.addComponent(xsl2csv); + pipeline.addComponent(new TextSerializer()); + break; + + case XML: + default: + pipeline.addComponent(XMLSerializer.createXMLSerializer()); + } + + pipeline.setup(os); + pipeline.execute(); + + LOG.debug("Result of {} successfully exported as {}", reportExec, format); + } catch (Exception e) { + LOG.error("While exporting content", e); + } finally { + IOUtils.closeQuietly(zis); + IOUtils.closeQuietly(bais); + } + } + + @PreAuthorize("hasRole('REPORT_READ')") + public ReportExec getAndCheckReportExec(final Long executionKey) { + ReportExec reportExec = reportExecDAO.find(executionKey); + if (reportExec == null) { + throw new NotFoundException("Report execution " + executionKey); + } + if (!ReportExecStatus.SUCCESS.name().equals(reportExec.getStatus()) || reportExec.getExecResult() == null) { + SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidReportExec); + sce.getElements().add(reportExec.getExecResult() == null + ? "No report data produced" + : "Report did not run successfully"); + throw sce; + } + return reportExec; + } + + @PreAuthorize("hasRole('REPORT_EXECUTE')") + public ReportExecTO execute(final Long reportKey) { + Report report = reportDAO.find(reportKey); + if (report == null) { + throw new NotFoundException("Report " + reportKey); + } + + try { + jobInstanceLoader.registerJob(report); + + scheduler.getScheduler().triggerJob( + new JobKey(JobNamer.getJobName(report), Scheduler.DEFAULT_GROUP)); + } catch (Exception e) { + LOG.error("While executing report {}", report, e); + + SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Scheduling); + sce.getElements().add(e.getMessage()); + throw sce; + } + + ReportExecTO result = new ReportExecTO(); + result.setReport(reportKey); + result.setStartDate(new Date()); + result.setStatus(ReportExecStatus.STARTED.name()); + result.setMessage("Job fired; waiting for results..."); + + return result; + } + + @PreAuthorize("hasRole('REPORT_DELETE')") + public ReportTO delete(final Long reportKey) { + Report report = reportDAO.find(reportKey); + if (report == null) { + throw new NotFoundException("Report " + reportKey); + } + + ReportTO deletedReport = binder.getReportTO(report); + jobInstanceLoader.unregisterJob(report); + reportDAO.delete(report); + return deletedReport; + } + + @PreAuthorize("hasRole('REPORT_DELETE')") + public ReportExecTO deleteExecution(final Long executionKey) { + ReportExec reportExec = reportExecDAO.find(executionKey); + if (reportExec == null) { + throw new NotFoundException("Report execution " + executionKey); + } + + ReportExecTO reportExecToDelete = binder.getReportExecTO(reportExec); + reportExecDAO.delete(reportExec); + return reportExecToDelete; + } + + @Override + protected ReportTO resolveReference(final Method method, final Object... args) + throws UnresolvedReferenceException { + + Long key = null; + + if (ArrayUtils.isNotEmpty(args) && ("create".equals(method.getName()) + || "update".equals(method.getName()) + || "delete".equals(method.getName()))) { + for (int i = 0; key == null && i < args.length; i++) { + if (args[i] instanceof Long) { + key = (Long) args[i]; + } else if (args[i] instanceof ReportTO) { + key = ((ReportTO) args[i]).getKey(); + } + } + } + + if ((key != null) && !key.equals(0l)) { + try { + return binder.getReportTO(reportDAO.find(key)); + } catch (Throwable ignore) { + LOG.debug("Unresolved reference", ignore); + throw new UnresolvedReferenceException(ignore); + } + } + + throw new UnresolvedReferenceException(); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java ---------------------------------------------------------------------- diff --git a/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java b/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java new file mode 100644 index 0000000..b85b74c --- /dev/null +++ b/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java @@ -0,0 +1,273 @@ +/* + * 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.logic; + +import java.lang.reflect.Method; +import java.util.List; +import java.util.Set; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.syncope.common.lib.SyncopeClientException; +import org.apache.syncope.common.lib.to.BulkAction; +import org.apache.syncope.common.lib.to.BulkActionResult; +import org.apache.syncope.common.lib.to.ConnObjectTO; +import org.apache.syncope.common.lib.to.ResourceTO; +import org.apache.syncope.common.lib.types.ClientExceptionType; +import org.apache.syncope.common.lib.types.MappingPurpose; +import org.apache.syncope.common.lib.types.SubjectType; +import org.apache.syncope.core.persistence.api.dao.DuplicateException; +import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; +import org.apache.syncope.core.persistence.api.dao.NotFoundException; +import org.apache.syncope.core.persistence.api.dao.RoleDAO; +import org.apache.syncope.core.persistence.api.dao.UserDAO; +import org.apache.syncope.core.persistence.api.entity.AttributableUtil; +import org.apache.syncope.core.persistence.api.entity.AttributableUtilFactory; +import org.apache.syncope.core.persistence.api.entity.ConnInstance; +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.Subject; +import org.apache.syncope.core.provisioning.api.Connector; +import org.apache.syncope.core.provisioning.api.ConnectorFactory; +import org.apache.syncope.core.provisioning.api.data.ResourceDataBinder; +import org.apache.syncope.core.misc.ConnObjectUtil; +import org.apache.syncope.core.misc.MappingUtil; +import org.identityconnectors.framework.common.objects.Attribute; +import org.identityconnectors.framework.common.objects.AttributeUtil; +import org.identityconnectors.framework.common.objects.ConnectorObject; +import org.identityconnectors.framework.common.objects.Name; +import org.identityconnectors.framework.common.objects.ObjectClass; +import org.identityconnectors.framework.common.objects.Uid; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +@Component +public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> { + + @Autowired + private ExternalResourceDAO resourceDAO; + + @Autowired + private UserDAO userDAO; + + @Autowired + private RoleDAO roleDAO; + + @Autowired + private ResourceDataBinder binder; + + @Autowired + private ConnObjectUtil connObjectUtil; + + @Autowired + private ConnectorFactory connFactory; + + @Autowired + private AttributableUtilFactory attrUtilFactory; + + @PreAuthorize("hasRole('RESOURCE_CREATE')") + public ResourceTO create(final ResourceTO resourceTO) { + if (StringUtils.isBlank(resourceTO.getKey())) { + SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing); + sce.getElements().add("Resource name"); + throw sce; + } + + if (resourceDAO.find(resourceTO.getKey()) != null) { + throw new DuplicateException("Resource '" + resourceTO.getKey() + "'"); + } + + ExternalResource resource = null; + try { + resource = resourceDAO.save(binder.create(resourceTO)); + } catch (SyncopeClientException e) { + throw e; + } catch (Exception e) { + SyncopeClientException ex = SyncopeClientException.build(ClientExceptionType.InvalidExternalResource); + ex.getElements().add(e.getMessage()); + throw ex; + } + + return binder.getResourceTO(resource); + } + + @PreAuthorize("hasRole('RESOURCE_UPDATE')") + public ResourceTO update(final ResourceTO resourceTO) { + ExternalResource resource = resourceDAO.find(resourceTO.getKey()); + if (resource == null) { + throw new NotFoundException("Resource '" + resourceTO.getKey() + "'"); + } + + resource = binder.update(resource, resourceTO); + try { + resource = resourceDAO.save(resource); + } catch (SyncopeClientException e) { + throw e; + } catch (Exception e) { + SyncopeClientException ex = SyncopeClientException.build(ClientExceptionType.InvalidExternalResource); + ex.getElements().add(e.getMessage()); + throw ex; + } + + return binder.getResourceTO(resource); + } + + @PreAuthorize("hasRole('RESOURCE_DELETE')") + public ResourceTO delete(final String resourceName) { + ExternalResource resource = resourceDAO.find(resourceName); + if (resource == null) { + throw new NotFoundException("Resource '" + resourceName + "'"); + } + + ResourceTO resourceToDelete = binder.getResourceTO(resource); + + resourceDAO.delete(resourceName); + + return resourceToDelete; + } + + @PreAuthorize("hasRole('RESOURCE_READ')") + @Transactional(readOnly = true) + public ResourceTO read(final String resourceName) { + ExternalResource resource = resourceDAO.find(resourceName); + if (resource == null) { + throw new NotFoundException("Resource '" + resourceName + "'"); + } + + return binder.getResourceTO(resource); + } + + @PreAuthorize("isAuthenticated()") + @Transactional(readOnly = true) + public List<ResourceTO> list() { + return binder.getResourceTOs(resourceDAO.findAll()); + } + + @PreAuthorize("hasRole('RESOURCE_GETCONNECTOROBJECT')") + @Transactional(readOnly = true) + public ConnObjectTO getConnectorObject(final String resourceName, final SubjectType type, final Long id) { + ExternalResource resource = resourceDAO.find(resourceName); + if (resource == null) { + throw new NotFoundException("Resource '" + resourceName + "'"); + } + + Subject<?, ?, ?> subject = type == SubjectType.USER + ? userDAO.find(id) + : roleDAO.find(id); + if (subject == null) { + throw new NotFoundException(type + " " + id); + } + + final AttributableUtil attrUtil = attrUtilFactory.getInstance(type.asAttributableType()); + + MappingItem accountIdItem = attrUtil.getAccountIdItem(resource); + if (accountIdItem == null) { + throw new NotFoundException( + "AccountId mapping for " + type + " " + id + " on resource '" + resourceName + "'"); + } + final String accountIdValue = MappingUtil.getAccountIdValue( + subject, resource, attrUtil.getAccountIdItem(resource)); + + final ObjectClass objectClass = SubjectType.USER == type ? ObjectClass.ACCOUNT : ObjectClass.GROUP; + + final Connector connector = connFactory.getConnector(resource); + final ConnectorObject connectorObject = connector.getObject(objectClass, new Uid(accountIdValue), + connector.getOperationOptions(attrUtil.getMappingItems(resource, MappingPurpose.BOTH))); + if (connectorObject == null) { + throw new NotFoundException("Object " + accountIdValue + " with class " + objectClass + + "not found on resource " + resourceName); + } + + final Set<Attribute> attributes = connectorObject.getAttributes(); + if (AttributeUtil.find(Uid.NAME, attributes) == null) { + attributes.add(connectorObject.getUid()); + } + if (AttributeUtil.find(Name.NAME, attributes) == null) { + attributes.add(connectorObject.getName()); + } + + return connObjectUtil.getConnObjectTO(connectorObject); + } + + @PreAuthorize("hasRole('CONNECTOR_READ')") + @Transactional(readOnly = true) + public boolean check(final ResourceTO resourceTO) { + final ConnInstance connInstance = binder.getConnInstance(resourceTO); + + final Connector connector = connFactory.createConnector(connInstance, connInstance.getConfiguration()); + + boolean result; + try { + connector.test(); + result = true; + } catch (Exception e) { + LOG.error("Test connection failure {}", e); + result = false; + } + + return result; + } + + @PreAuthorize("hasRole('RESOURCE_DELETE') and #bulkAction.operation == #bulkAction.operation.DELETE") + public BulkActionResult bulk(final BulkAction bulkAction) { + BulkActionResult res = new BulkActionResult(); + + if (bulkAction.getOperation() == BulkAction.Type.DELETE) { + for (String name : bulkAction.getTargets()) { + try { + res.add(delete(name).getKey(), BulkActionResult.Status.SUCCESS); + } catch (Exception e) { + LOG.error("Error performing delete for resource {}", name, e); + res.add(name, BulkActionResult.Status.FAILURE); + } + } + } + + return res; + } + + @Override + protected ResourceTO resolveReference(final Method method, final Object... args) + throws UnresolvedReferenceException { + + String key = null; + + if (ArrayUtils.isNotEmpty(args)) { + for (int i = 0; key == null && i < args.length; i++) { + if (args[i] instanceof String) { + key = (String) args[i]; + } else if (args[i] instanceof ResourceTO) { + key = ((ResourceTO) args[i]).getKey(); + } + } + } + + if (key != null) { + try { + return binder.getResourceTO(resourceDAO.find(key)); + } catch (Throwable ignore) { + LOG.debug("Unresolved reference", ignore); + throw new UnresolvedReferenceException(ignore); + } + } + + throw new UnresolvedReferenceException(); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/RoleLogic.java ---------------------------------------------------------------------- diff --git a/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/RoleLogic.java b/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/RoleLogic.java new file mode 100644 index 0000000..ebacf04 --- /dev/null +++ b/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/RoleLogic.java @@ -0,0 +1,405 @@ +/* + * 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.logic; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import javax.annotation.Resource; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.syncope.common.lib.SyncopeClientException; +import org.apache.syncope.common.lib.mod.RoleMod; +import org.apache.syncope.common.lib.to.BulkAction; +import org.apache.syncope.common.lib.to.BulkActionResult; +import org.apache.syncope.common.lib.to.PropagationStatus; +import org.apache.syncope.common.lib.to.RoleTO; +import org.apache.syncope.common.lib.types.ClientExceptionType; +import org.apache.syncope.common.lib.types.SubjectType; +import org.apache.syncope.core.persistence.api.RoleEntitlementUtil; +import org.apache.syncope.core.persistence.api.dao.NotFoundException; +import org.apache.syncope.core.persistence.api.dao.RoleDAO; +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; +import org.apache.syncope.core.persistence.api.dao.search.SearchCond; +import org.apache.syncope.core.persistence.api.entity.role.Role; +import org.apache.syncope.core.persistence.api.entity.user.User; +import org.apache.syncope.core.provisioning.api.AttributableTransformer; +import org.apache.syncope.core.provisioning.api.RoleProvisioningManager; +import org.apache.syncope.core.provisioning.api.data.RoleDataBinder; +import org.apache.syncope.core.provisioning.api.propagation.PropagationManager; +import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor; +import org.apache.syncope.core.misc.security.AuthContextUtil; +import org.apache.syncope.core.misc.security.UnauthorizedRoleException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.interceptor.TransactionInterceptor; + +/** + * Note that this controller does not extend {@link AbstractTransactionalLogic}, hence does not provide any + * Spring's Transactional logic at class level. + */ +@Component +public class RoleLogic extends AbstractSubjectLogic<RoleTO, RoleMod> { + + @Autowired + protected RoleDAO roleDAO; + + @Autowired + protected UserDAO userDAO; + + @Autowired + protected SubjectSearchDAO searchDAO; + + @Autowired + protected RoleDataBinder binder; + + @Autowired + protected PropagationManager propagationManager; + + @Autowired + protected PropagationTaskExecutor taskExecutor; + + @Autowired + protected AttributableTransformer attrTransformer; + + @Resource(name = "anonymousUser") + protected String anonymousUser; + + @Autowired + protected RoleProvisioningManager provisioningManager; + + @PreAuthorize("hasAnyRole('ROLE_READ', T(org.apache.syncope.common.lib.SyncopeConstants).ANONYMOUS_ENTITLEMENT)") + @Transactional(readOnly = true) + @Override + public RoleTO read(final Long roleKey) { + Role role; + // bypass role entitlements check + if (anonymousUser.equals(AuthContextUtil.getAuthenticatedUsername())) { + role = roleDAO.find(roleKey); + } else { + role = roleDAO.authFetch(roleKey); + } + + if (role == null) { + throw new NotFoundException("Role " + roleKey); + } + + return binder.getRoleTO(role); + } + + @PreAuthorize("isAuthenticated() " + + "and not(hasRole(T(org.apache.syncope.common.lib.SyncopeConstants).ANONYMOUS_ENTITLEMENT))") + @Transactional(readOnly = true) + public RoleTO readSelf(final Long roleKey) { + // Explicit search instead of using binder.getRoleFromId() in order to bypass auth checks - will do here + Role role = roleDAO.find(roleKey); + if (role == null) { + throw new NotFoundException("Role " + roleKey); + } + + Set<Long> ownedRoleIds; + User authUser = userDAO.find(AuthContextUtil.getAuthenticatedUsername()); + if (authUser == null) { + ownedRoleIds = Collections.<Long>emptySet(); + } else { + ownedRoleIds = authUser.getRoleKeys(); + } + + Set<Long> allowedRoleIds = RoleEntitlementUtil.getRoleKeys(AuthContextUtil.getOwnedEntitlementNames()); + allowedRoleIds.addAll(ownedRoleIds); + if (!allowedRoleIds.contains(role.getKey())) { + throw new UnauthorizedRoleException(role.getKey()); + } + + return binder.getRoleTO(role); + } + + @PreAuthorize("hasRole('ROLE_READ')") + @Transactional(readOnly = true) + public RoleTO parent(final Long roleKey) { + Role role = roleDAO.authFetch(roleKey); + + Set<Long> allowedRoleIds = RoleEntitlementUtil.getRoleKeys(AuthContextUtil.getOwnedEntitlementNames()); + if (role.getParent() != null && !allowedRoleIds.contains(role.getParent().getKey())) { + throw new UnauthorizedRoleException(role.getParent().getKey()); + } + + RoleTO result = role.getParent() == null + ? null + : binder.getRoleTO(role.getParent()); + + return result; + } + + @PreAuthorize("hasRole('ROLE_READ')") + @Transactional(readOnly = true) + public List<RoleTO> children(final Long roleKey) { + Role role = roleDAO.authFetch(roleKey); + + Set<Long> allowedRoleIds = RoleEntitlementUtil.getRoleKeys(AuthContextUtil.getOwnedEntitlementNames()); + + List<Role> children = roleDAO.findChildren(role); + List<RoleTO> childrenTOs = new ArrayList<>(children.size()); + for (Role child : children) { + if (allowedRoleIds.contains(child.getKey())) { + childrenTOs.add(binder.getRoleTO(child)); + } + } + + return childrenTOs; + } + + @PreAuthorize("isAuthenticated()") + @Transactional(readOnly = true, rollbackFor = { Throwable.class }) + @Override + public int count() { + return roleDAO.count(); + } + + @PreAuthorize("isAuthenticated()") + @Transactional(readOnly = true) + @Override + public List<RoleTO> list(final int page, final int size, final List<OrderByClause> orderBy) { + List<Role> roles = roleDAO.findAll(page, size, orderBy); + + List<RoleTO> roleTOs = new ArrayList<>(roles.size()); + for (Role role : roles) { + roleTOs.add(binder.getRoleTO(role)); + } + + return roleTOs; + } + + @PreAuthorize("isAuthenticated()") + @Transactional(readOnly = true, rollbackFor = { Throwable.class }) + @Override + public int searchCount(final SearchCond searchCondition) { + final Set<Long> adminRoleIds = RoleEntitlementUtil.getRoleKeys(AuthContextUtil.getOwnedEntitlementNames()); + return searchDAO.count(adminRoleIds, searchCondition, SubjectType.ROLE); + } + + @PreAuthorize("isAuthenticated()") + @Transactional(readOnly = true, rollbackFor = { Throwable.class }) + @Override + public List<RoleTO> search(final SearchCond searchCondition, final int page, final int size, + final List<OrderByClause> orderBy) { + + final List<Role> matchingRoles = searchDAO.search( + RoleEntitlementUtil.getRoleKeys(AuthContextUtil.getOwnedEntitlementNames()), + searchCondition, page, size, orderBy, SubjectType.ROLE); + + final List<RoleTO> result = new ArrayList<>(matchingRoles.size()); + for (Role role : matchingRoles) { + result.add(binder.getRoleTO(role)); + } + + return result; + } + + @PreAuthorize("hasRole('ROLE_CREATE')") + public RoleTO create(final RoleTO roleTO) { + // Check that this operation is allowed to be performed by caller + Set<Long> allowedRoleIds = RoleEntitlementUtil.getRoleKeys(AuthContextUtil.getOwnedEntitlementNames()); + if (roleTO.getParent() != 0 && !allowedRoleIds.contains(roleTO.getParent())) { + throw new UnauthorizedRoleException(roleTO.getParent()); + } + + // Attributable transformation (if configured) + RoleTO actual = attrTransformer.transform(roleTO); + LOG.debug("Transformed: {}", actual); + + /* + * Actual operations: workflow, propagation + */ + Map.Entry<Long, List<PropagationStatus>> created = provisioningManager.create(roleTO); + final RoleTO savedTO = binder.getRoleTO(created.getKey()); + savedTO.getPropagationStatusTOs().addAll(created.getValue()); + return savedTO; + } + + @PreAuthorize("hasRole('ROLE_UPDATE')") + @Override + public RoleTO update(final RoleMod roleMod) { + // Check that this operation is allowed to be performed by caller + roleDAO.authFetch(roleMod.getKey()); + + // Attribute value transformation (if configured) + RoleMod actual = attrTransformer.transform(roleMod); + LOG.debug("Transformed: {}", actual); + + Map.Entry<Long, List<PropagationStatus>> updated = provisioningManager.update(roleMod); + + final RoleTO updatedTO = binder.getRoleTO(updated.getKey()); + updatedTO.getPropagationStatusTOs().addAll(updated.getValue()); + return updatedTO; + } + + @PreAuthorize("hasRole('ROLE_DELETE')") + @Override + public RoleTO delete(final Long roleKey) { + List<Role> ownedRoles = roleDAO.findOwnedByRole(roleKey); + if (!ownedRoles.isEmpty()) { + List<String> owned = new ArrayList<String>(ownedRoles.size()); + for (Role role : ownedRoles) { + owned.add(role.getKey() + " " + role.getName()); + } + + SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.RoleOwnership); + sce.getElements().addAll(owned); + throw sce; + } + + List<PropagationStatus> statuses = provisioningManager.delete(roleKey); + + RoleTO roleTO = new RoleTO(); + roleTO.setKey(roleKey); + + roleTO.getPropagationStatusTOs().addAll(statuses); + + return roleTO; + } + + @PreAuthorize("(hasRole('ROLE_DELETE') and #bulkAction.operation == #bulkAction.operation.DELETE)") + public BulkActionResult bulk(final BulkAction bulkAction) { + BulkActionResult res = new BulkActionResult(); + + if (bulkAction.getOperation() == BulkAction.Type.DELETE) { + for (String roleKey : bulkAction.getTargets()) { + try { + res.add(delete(Long.valueOf(roleKey)).getKey(), BulkActionResult.Status.SUCCESS); + } catch (Exception e) { + LOG.error("Error performing delete for role {}", roleKey, e); + res.add(roleKey, BulkActionResult.Status.FAILURE); + } + } + } else { + LOG.warn("Unsupported bulk action: {}", bulkAction.getOperation()); + } + + return res; + } + + @PreAuthorize("hasRole('ROLE_UPDATE')") + @Transactional(rollbackFor = { Throwable.class }) + @Override + public RoleTO unlink(final Long roleKey, final Collection<String> resources) { + final RoleMod roleMod = new RoleMod(); + roleMod.setKey(roleKey); + roleMod.getResourcesToRemove().addAll(resources); + final Long updatedResult = provisioningManager.unlink(roleMod); + + return binder.getRoleTO(updatedResult); + } + + @PreAuthorize("hasRole('ROLE_UPDATE')") + @Transactional(rollbackFor = { Throwable.class }) + @Override + public RoleTO link(final Long roleKey, final Collection<String> resources) { + final RoleMod roleMod = new RoleMod(); + roleMod.setKey(roleKey); + roleMod.getResourcesToAdd().addAll(resources); + return binder.getRoleTO(provisioningManager.link(roleMod)); + } + + @PreAuthorize("hasRole('ROLE_UPDATE')") + @Transactional(rollbackFor = { Throwable.class }) + @Override + public RoleTO unassign(final Long roleKey, final Collection<String> resources) { + final RoleMod roleMod = new RoleMod(); + roleMod.setKey(roleKey); + roleMod.getResourcesToRemove().addAll(resources); + return update(roleMod); + } + + @PreAuthorize("hasRole('ROLE_UPDATE')") + @Transactional(rollbackFor = { Throwable.class }) + @Override + public RoleTO assign( + final Long roleKey, final Collection<String> resources, final boolean changePwd, final String password) { + + final RoleMod userMod = new RoleMod(); + userMod.setKey(roleKey); + userMod.getResourcesToAdd().addAll(resources); + return update(userMod); + } + + @PreAuthorize("hasRole('ROLE_UPDATE')") + @Transactional(rollbackFor = { Throwable.class }) + @Override + public RoleTO deprovision(final Long roleKey, final Collection<String> resources) { + final Role role = roleDAO.authFetch(roleKey); + + List<PropagationStatus> statuses = provisioningManager.deprovision(roleKey, resources); + + final RoleTO updatedTO = binder.getRoleTO(role); + updatedTO.getPropagationStatusTOs().addAll(statuses); + return updatedTO; + } + + @PreAuthorize("hasRole('ROLE_UPDATE')") + @Transactional(rollbackFor = { Throwable.class }) + @Override + public RoleTO provision( + final Long roleKey, final Collection<String> resources, final boolean changePwd, final String password) { + final RoleTO original = binder.getRoleTO(roleKey); + + //trick: assign and retrieve propagation statuses ... + original.getPropagationStatusTOs().addAll( + assign(roleKey, resources, changePwd, password).getPropagationStatusTOs()); + + // .... rollback. + TransactionInterceptor.currentTransactionStatus().setRollbackOnly(); + return original; + } + + @Override + protected RoleTO resolveReference(final Method method, final Object... args) throws UnresolvedReferenceException { + Long key = null; + + if (ArrayUtils.isNotEmpty(args)) { + for (int i = 0; key == null && i < args.length; i++) { + if (args[i] instanceof Long) { + key = (Long) args[i]; + } else if (args[i] instanceof RoleTO) { + key = ((RoleTO) args[i]).getKey(); + } else if (args[i] instanceof RoleMod) { + key = ((RoleMod) args[i]).getKey(); + } + } + } + + if ((key != null) && !key.equals(0l)) { + try { + return binder.getRoleTO(key); + } catch (Throwable ignore) { + LOG.debug("Unresolved reference", ignore); + throw new UnresolvedReferenceException(ignore); + } + } + + throw new UnresolvedReferenceException(); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java ---------------------------------------------------------------------- diff --git a/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java b/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java new file mode 100644 index 0000000..b6e4748 --- /dev/null +++ b/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java @@ -0,0 +1,325 @@ +/* + * 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.logic; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.syncope.common.lib.SyncopeClientException; +import org.apache.syncope.common.lib.to.AbstractSchemaTO; +import org.apache.syncope.common.lib.to.DerSchemaTO; +import org.apache.syncope.common.lib.to.PlainSchemaTO; +import org.apache.syncope.common.lib.to.VirSchemaTO; +import org.apache.syncope.common.lib.types.AttributableType; +import org.apache.syncope.common.lib.types.ClientExceptionType; +import org.apache.syncope.common.lib.types.SchemaType; +import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO; +import org.apache.syncope.core.persistence.api.dao.DuplicateException; +import org.apache.syncope.core.persistence.api.dao.NotFoundException; +import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; +import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; +import org.apache.syncope.core.persistence.api.entity.AttributableUtil; +import org.apache.syncope.core.persistence.api.entity.AttributableUtilFactory; +import org.apache.syncope.core.persistence.api.entity.DerSchema; +import org.apache.syncope.core.persistence.api.entity.PlainSchema; +import org.apache.syncope.core.persistence.api.entity.VirSchema; +import org.apache.syncope.core.provisioning.api.data.SchemaDataBinder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; + +@Component +public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> { + + @Autowired + private PlainSchemaDAO plainSchemaDAO; + + @Autowired + private DerSchemaDAO derSchemaDAO; + + @Autowired + private VirSchemaDAO virSchemaDAO; + + @Autowired + private SchemaDataBinder binder; + + @Autowired + private AttributableUtilFactory attrUtilFactory; + + private boolean doesSchemaExist(final SchemaType schemaType, final String name, final AttributableUtil attrUtil) { + boolean found; + + switch (schemaType) { + case VIRTUAL: + found = virSchemaDAO.find(name, attrUtil.virSchemaClass()) != null; + break; + + case DERIVED: + found = derSchemaDAO.find(name, attrUtil.derSchemaClass()) != null; + break; + + case PLAIN: + found = plainSchemaDAO.find(name, attrUtil.plainSchemaClass()) != null; + break; + + default: + found = false; + } + + return found; + } + + @PreAuthorize("hasRole('SCHEMA_CREATE')") + @SuppressWarnings("unchecked") + public <T extends AbstractSchemaTO> T create( + final AttributableType attrType, final SchemaType schemaType, final T schemaTO) { + + if (StringUtils.isBlank(schemaTO.getKey())) { + SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing); + sce.getElements().add("Schema name"); + throw sce; + } + + final AttributableUtil attrUtil = attrUtilFactory.getInstance(attrType); + + if (doesSchemaExist(schemaType, schemaTO.getKey(), attrUtil)) { + throw new DuplicateException(schemaType + "/" + attrType + "/" + schemaTO.getKey()); + } + + T created; + switch (schemaType) { + case VIRTUAL: + VirSchema virSchema = attrUtil.newVirSchema(); + binder.create((VirSchemaTO) schemaTO, virSchema); + virSchema = virSchemaDAO.save(virSchema); + created = (T) binder.getVirSchemaTO(virSchema); + break; + case DERIVED: + DerSchema derSchema = attrUtil.newDerSchema(); + binder.create((DerSchemaTO) schemaTO, derSchema); + derSchema = derSchemaDAO.save(derSchema); + + created = (T) binder.getDerSchemaTO(derSchema); + break; + + case PLAIN: + default: + PlainSchema normalSchema = attrUtil.newPlainSchema(); + binder.create((PlainSchemaTO) schemaTO, normalSchema); + normalSchema = plainSchemaDAO.save(normalSchema); + + created = (T) binder.getSchemaTO(normalSchema, attrUtil); + } + return created; + } + + @PreAuthorize("hasRole('SCHEMA_DELETE')") + public void delete(final AttributableType attrType, final SchemaType schemaType, final String schemaName) { + final AttributableUtil attrUtil = attrUtilFactory.getInstance(attrType); + + if (!doesSchemaExist(schemaType, schemaName, attrUtil)) { + throw new NotFoundException(schemaType + "/" + attrType + "/" + schemaName); + } + + switch (schemaType) { + case VIRTUAL: + virSchemaDAO.delete(schemaName, attrUtil); + break; + + case DERIVED: + derSchemaDAO.delete(schemaName, attrUtil); + break; + + case PLAIN: + default: + plainSchemaDAO.delete(schemaName, attrUtil); + } + } + + @PreAuthorize("isAuthenticated()") + @SuppressWarnings("unchecked") + public <T extends AbstractSchemaTO> List<T> list(final AttributableType attrType, final SchemaType schemaType) { + final AttributableUtil attrUtil = attrUtilFactory.getInstance(attrType); + + List<T> result; + switch (schemaType) { + case VIRTUAL: + List<VirSchema> virSchemas = virSchemaDAO.findAll(attrUtil.virSchemaClass()); + result = new ArrayList<>(virSchemas.size()); + for (VirSchema derSchema : virSchemas) { + result.add((T) binder.getVirSchemaTO(derSchema)); + } + break; + + case DERIVED: + List<DerSchema> derSchemas = derSchemaDAO.findAll(attrUtil.derSchemaClass()); + result = new ArrayList<>(derSchemas.size()); + for (DerSchema derSchema : derSchemas) { + result.add((T) binder.getDerSchemaTO(derSchema)); + } + break; + + case PLAIN: + default: + List<PlainSchema> schemas = plainSchemaDAO.findAll(attrUtil.plainSchemaClass()); + result = new ArrayList<>(schemas.size()); + for (PlainSchema schema : schemas) { + result.add((T) binder.getSchemaTO(schema, attrUtil)); + } + } + + return result; + } + + @PreAuthorize("hasRole('SCHEMA_READ')") + @SuppressWarnings("unchecked") + public <T extends AbstractSchemaTO> T read( + final AttributableType attrType, final SchemaType schemaType, final String schemaName) { + + final AttributableUtil attrUtil = attrUtilFactory.getInstance(attrType); + + T read; + switch (schemaType) { + case VIRTUAL: + VirSchema virSchema = virSchemaDAO.find(schemaName, attrUtil.virSchemaClass()); + if (virSchema == null) { + throw new NotFoundException("Virtual Schema '" + schemaName + "'"); + } + + read = (T) binder.getVirSchemaTO(virSchema); + break; + + case DERIVED: + DerSchema derSchema = derSchemaDAO.find(schemaName, attrUtil.derSchemaClass()); + if (derSchema == null) { + throw new NotFoundException("Derived schema '" + schemaName + "'"); + } + + read = (T) binder.getDerSchemaTO(derSchema); + break; + + case PLAIN: + default: + PlainSchema schema = plainSchemaDAO.find(schemaName, attrUtil.plainSchemaClass()); + if (schema == null) { + throw new NotFoundException("Schema '" + schemaName + "'"); + } + + read = (T) binder.getSchemaTO(schema, attrUtil); + } + + return read; + } + + @PreAuthorize("hasRole('SCHEMA_UPDATE')") + public <T extends AbstractSchemaTO> void update( + final AttributableType attrType, final SchemaType schemaType, final T schemaTO) { + + final AttributableUtil attrUtil = attrUtilFactory.getInstance(attrType); + + if (!doesSchemaExist(schemaType, schemaTO.getKey(), attrUtil)) { + throw new NotFoundException(schemaType + "/" + attrType + "/" + schemaTO.getKey()); + } + + switch (schemaType) { + case VIRTUAL: + VirSchema virSchema = virSchemaDAO.find(schemaTO.getKey(), attrUtil.virSchemaClass()); + if (virSchema == null) { + throw new NotFoundException("Virtual Schema '" + schemaTO.getKey() + "'"); + } + + binder.update((VirSchemaTO) schemaTO, virSchema); + virSchemaDAO.save(virSchema); + break; + + case DERIVED: + DerSchema derSchema = derSchemaDAO.find(schemaTO.getKey(), attrUtil.derSchemaClass()); + if (derSchema == null) { + throw new NotFoundException("Derived schema '" + schemaTO.getKey() + "'"); + } + + binder.update((DerSchemaTO) schemaTO, derSchema); + derSchemaDAO.save(derSchema); + break; + + case PLAIN: + default: + PlainSchema schema = plainSchemaDAO.find(schemaTO.getKey(), attrUtil.plainSchemaClass()); + if (schema == null) { + throw new NotFoundException("Schema '" + schemaTO.getKey() + "'"); + } + + binder.update((PlainSchemaTO) schemaTO, schema, attrUtil); + plainSchemaDAO.save(schema); + } + } + + @Override + protected AbstractSchemaTO resolveReference(final Method method, final Object... args) + throws UnresolvedReferenceException { + + String kind = null; + String key = null; + if (ArrayUtils.isNotEmpty(args)) { + for (int i = 0; (key == null || kind == null) && i < args.length; i++) { + if (args[i] instanceof String) { + if (kind == null) { + kind = (String) args[i]; + } else { + key = (String) args[i]; + } + } else if (args[i] instanceof AbstractSchemaTO) { + key = ((AbstractSchemaTO) args[i]).getKey(); + } + } + } + + if (key != null) { + try { + final AttributableUtil attrUtil = attrUtilFactory.getInstance(kind); + + AbstractSchemaTO result = null; + + PlainSchema plainSchema = plainSchemaDAO.find(key, attrUtil.plainSchemaClass()); + if (plainSchema == null) { + DerSchema derSchema = derSchemaDAO.find(key, attrUtil.derSchemaClass()); + if (derSchema == null) { + VirSchema virSchema = virSchemaDAO.find(key, attrUtil.virSchemaClass()); + if (virSchema != null) { + result = binder.getVirSchemaTO(virSchema); + } + } else { + result = binder.getDerSchemaTO(derSchema); + } + } else { + result = binder.getSchemaTO(plainSchema, attrUtil); + } + + return result; + } catch (Throwable ignore) { + LOG.debug("Unresolved reference", ignore); + throw new UnresolvedReferenceException(ignore); + } + } + + throw new UnresolvedReferenceException(); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/SecurityQuestionLogic.java ---------------------------------------------------------------------- diff --git a/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/SecurityQuestionLogic.java b/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/SecurityQuestionLogic.java new file mode 100644 index 0000000..102891f --- /dev/null +++ b/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/SecurityQuestionLogic.java @@ -0,0 +1,150 @@ +/* + * 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.logic; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.syncope.common.lib.to.SecurityQuestionTO; +import org.apache.syncope.core.persistence.api.dao.NotFoundException; +import org.apache.syncope.core.persistence.api.dao.SecurityQuestionDAO; +import org.apache.syncope.core.persistence.api.dao.UserDAO; +import org.apache.syncope.core.persistence.api.entity.user.SecurityQuestion; +import org.apache.syncope.core.persistence.api.entity.user.User; +import org.apache.syncope.core.provisioning.api.data.SecurityQuestionDataBinder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; + +@Component +public class SecurityQuestionLogic extends AbstractTransactionalLogic<SecurityQuestionTO> { + + @Autowired + private SecurityQuestionDAO securityQuestionDAO; + + @Autowired + private UserDAO userDAO; + + @Autowired + private SecurityQuestionDataBinder binder; + + @PreAuthorize("isAuthenticated()") + public List<SecurityQuestionTO> list() { + List<SecurityQuestionTO> result = new ArrayList<>(); + for (SecurityQuestion securityQuestion : securityQuestionDAO.findAll()) { + result.add(binder.getSecurityQuestionTO(securityQuestion)); + } + + return result; + } + + @PreAuthorize("isAuthenticated()") + public SecurityQuestionTO read(final Long securityQuestionId) { + SecurityQuestion securityQuestion = securityQuestionDAO.find(securityQuestionId); + if (securityQuestion == null) { + LOG.error("Could not find security question '" + securityQuestionId + "'"); + + throw new NotFoundException(String.valueOf(securityQuestionId)); + } + + return binder.getSecurityQuestionTO(securityQuestion); + } + + @PreAuthorize("hasRole('SECURITY_QUESTION_CREATE')") + public SecurityQuestionTO create(final SecurityQuestionTO securityQuestionTO) { + return binder.getSecurityQuestionTO(securityQuestionDAO.save(binder.create(securityQuestionTO))); + } + + @PreAuthorize("hasRole('SECURITY_QUESTION_UPDATE')") + public SecurityQuestionTO update(final SecurityQuestionTO securityQuestionTO) { + SecurityQuestion securityQuestion = securityQuestionDAO.find(securityQuestionTO.getKey()); + if (securityQuestion == null) { + LOG.error("Could not find security question '" + securityQuestionTO.getKey() + "'"); + + throw new NotFoundException(String.valueOf(securityQuestionTO.getKey())); + } + + binder.update(securityQuestion, securityQuestionTO); + securityQuestion = securityQuestionDAO.save(securityQuestion); + + return binder.getSecurityQuestionTO(securityQuestion); + } + + @PreAuthorize("hasRole('SECURITY_QUESTION_DELETE')") + public SecurityQuestionTO delete(final Long securityQuestionId) { + SecurityQuestion securityQuestion = securityQuestionDAO.find(securityQuestionId); + if (securityQuestion == null) { + LOG.error("Could not find security question '" + securityQuestionId + "'"); + + throw new NotFoundException(String.valueOf(securityQuestionId)); + } + + SecurityQuestionTO deleted = binder.getSecurityQuestionTO(securityQuestion); + securityQuestionDAO.delete(securityQuestionId); + return deleted; + } + + @PreAuthorize("isAnonymous() or hasRole(T(org.apache.syncope.common.lib.SyncopeConstants).ANONYMOUS_ENTITLEMENT)") + public SecurityQuestionTO read(final String username) { + if (username == null) { + throw new NotFoundException("Null username"); + } + User user = userDAO.find(username); + if (user == null) { + throw new NotFoundException("User " + username); + } + + if (user.getSecurityQuestion() == null) { + LOG.error("Could not find security question for user '" + username + "'"); + + throw new NotFoundException("Security question for user " + username); + } + + return binder.getSecurityQuestionTO(user.getSecurityQuestion()); + } + + @Override + protected SecurityQuestionTO resolveReference(final Method method, final Object... args) + throws UnresolvedReferenceException { + + Long key = null; + + if (ArrayUtils.isNotEmpty(args)) { + for (int i = 0; key == null && i < args.length; i++) { + if (args[i] instanceof Long) { + key = (Long) args[i]; + } else if (args[i] instanceof SecurityQuestionTO) { + key = ((SecurityQuestionTO) args[i]).getKey(); + } + } + } + + if ((key != null) && !key.equals(0l)) { + try { + return binder.getSecurityQuestionTO(securityQuestionDAO.find(key)); + } catch (Throwable ignore) { + LOG.debug("Unresolved reference", ignore); + throw new UnresolvedReferenceException(ignore); + } + } + + throw new UnresolvedReferenceException(); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java ---------------------------------------------------------------------- diff --git a/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java b/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java new file mode 100644 index 0000000..153b45a --- /dev/null +++ b/syncope620/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java @@ -0,0 +1,168 @@ +/* + * 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.logic; + +import static org.apache.syncope.core.logic.AbstractLogic.LOG; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.net.URI; +import java.util.HashSet; +import java.util.Set; +import javax.annotation.Resource; +import org.apache.syncope.common.lib.to.SyncopeTO; +import org.apache.syncope.core.logic.init.ImplementationClassNamesLoader; +import org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader; +import org.apache.syncope.core.persistence.api.dao.ConfDAO; +import org.apache.syncope.core.provisioning.api.AttributableTransformer; +import org.apache.syncope.core.provisioning.api.ConnIdBundleManager; +import org.apache.syncope.core.provisioning.api.RoleProvisioningManager; +import org.apache.syncope.core.provisioning.api.UserProvisioningManager; +import org.apache.syncope.core.provisioning.java.notification.NotificationManagerImpl; +import org.apache.syncope.core.workflow.api.RoleWorkflowAdapter; +import org.apache.syncope.core.workflow.api.UserWorkflowAdapter; +import org.springframework.aop.support.AopUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +@Component +public class SyncopeLogic extends AbstractLogic<SyncopeTO> { + + @Autowired + private ConfDAO confDAO; + + @Resource(name = "version") + private String version; + + @Autowired + private ConnIdBundleManager bundleManager; + + @Autowired + private AttributableTransformer attrTransformer; + + @Autowired + private UserWorkflowAdapter uwfAdapter; + + @Autowired + private RoleWorkflowAdapter rwfAdapter; + + @Autowired + private UserProvisioningManager uProvisioningManager; + + @Autowired + private RoleProvisioningManager rProvisioningManager; + + @Autowired + private ImplementationClassNamesLoader classNamesLoader; + + @Resource(name = "velocityResourceLoader") + private ResourceWithFallbackLoader resourceLoader; + + @Transactional(readOnly = true) + public boolean isSelfRegAllowed() { + return confDAO.find("selfRegistration.allowed", "false").getValues().get(0).getBooleanValue(); + } + + @Transactional(readOnly = true) + public boolean isPwdResetAllowed() { + return confDAO.find("passwordReset.allowed", "false").getValues().get(0).getBooleanValue(); + } + + @Transactional(readOnly = true) + public boolean isPwdResetRequiringSecurityQuestions() { + return confDAO.find("passwordReset.securityQuestion", "true").getValues().get(0).getBooleanValue(); + } + + @PreAuthorize("isAuthenticated()") + @Transactional(readOnly = true) + public SyncopeTO info() { + SyncopeTO syncopeTO = new SyncopeTO(); + syncopeTO.setVersion(version); + + syncopeTO.setSelfRegAllowed(isSelfRegAllowed()); + syncopeTO.setPwdResetAllowed(isPwdResetAllowed()); + syncopeTO.setPwdResetRequiringSecurityQuestions(isPwdResetRequiringSecurityQuestions()); + + if (bundleManager.getLocations() != null) { + for (URI location : bundleManager.getLocations()) { + syncopeTO.getConnIdLocations().add(location.toASCIIString()); + } + } + + syncopeTO.setAttributableTransformer(attrTransformer.getClass().getName()); + + syncopeTO.setUserWorkflowAdapter(AopUtils.getTargetClass(uwfAdapter).getName()); + syncopeTO.setRoleWorkflowAdapter(AopUtils.getTargetClass(rwfAdapter).getName()); + + syncopeTO.setUserProvisioningManager(uProvisioningManager.getClass().getName()); + syncopeTO.setRoleProvisioningManager(rProvisioningManager.getClass().getName()); + + syncopeTO.getReportlets().addAll( + classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.REPORTLET)); + syncopeTO.getTaskJobs().addAll( + classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.TASKJOB)); + syncopeTO.getPropagationActions().addAll( + classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.PROPAGATION_ACTIONS)); + syncopeTO.getSyncActions().addAll( + classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.SYNC_ACTIONS)); + syncopeTO.getPushActions().addAll( + classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.PUSH_ACTIONS)); + syncopeTO.getSyncCorrelationRules().addAll( + classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.SYNC_CORRELATION_RULE)); + syncopeTO.getPushCorrelationRules().addAll( + classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.PUSH_CORRELATION_RULE)); + syncopeTO.getValidators().addAll( + classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.VALIDATOR)); + + Set<String> htmlTemplates = new HashSet<>(); + Set<String> textTemplates = new HashSet<>(); + try { + for (org.springframework.core.io.Resource resource : resourceLoader.getResources( + NotificationManagerImpl.MAIL_TEMPLATES + "*.vm")) { + + String template = resource.getURL().toExternalForm(); + if (template.endsWith(NotificationManagerImpl.MAIL_TEMPLATE_HTML_SUFFIX)) { + htmlTemplates.add(template.substring(template.indexOf(NotificationManagerImpl.MAIL_TEMPLATES) + 14, + template.indexOf(NotificationManagerImpl.MAIL_TEMPLATE_HTML_SUFFIX))); + } else if (template.endsWith(NotificationManagerImpl.MAIL_TEMPLATE_TEXT_SUFFIX)) { + textTemplates.add(template.substring(template.indexOf(NotificationManagerImpl.MAIL_TEMPLATES) + 14, + template.indexOf(NotificationManagerImpl.MAIL_TEMPLATE_TEXT_SUFFIX))); + } else { + LOG.warn("Unexpected template found: {}, ignoring...", template); + } + } + } catch (IOException e) { + LOG.error("While searching for mail templates", e); + } + // Only templates available both as HTML and TEXT are considered + htmlTemplates.retainAll(textTemplates); + syncopeTO.getMailTemplates().addAll(htmlTemplates); + + return syncopeTO; + } + + @Override + protected SyncopeTO resolveReference(final Method method, final Object... args) + throws UnresolvedReferenceException { + + throw new UnresolvedReferenceException(); + } +}
