You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2015/02/12 10:14:54 UTC
[49/54] [abbrv] [partial] syncope git commit: [SYNCOPE-620] Renaming
'server' after 'core',
to provide continuity with older releases (especially for archetype)
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();
+ }
+}