Return-Path: X-Original-To: apmail-incubator-syncope-commits-archive@minotaur.apache.org Delivered-To: apmail-incubator-syncope-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id B4A419F98 for ; Fri, 16 Mar 2012 17:55:58 +0000 (UTC) Received: (qmail 74130 invoked by uid 500); 16 Mar 2012 17:55:58 -0000 Delivered-To: apmail-incubator-syncope-commits-archive@incubator.apache.org Received: (qmail 74103 invoked by uid 500); 16 Mar 2012 17:55:58 -0000 Mailing-List: contact syncope-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: syncope-dev@incubator.apache.org Delivered-To: mailing list syncope-commits@incubator.apache.org Received: (qmail 74095 invoked by uid 99); 16 Mar 2012 17:55:58 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 16 Mar 2012 17:55:58 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 16 Mar 2012 17:55:46 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 64E392388993; Fri, 16 Mar 2012 17:55:23 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1301670 [1/2] - in /incubator/syncope/trunk: client/src/main/java/org/syncope/types/ core/src/main/java/org/syncope/core/audit/ core/src/main/java/org/syncope/core/rest/controller/ core/src/main/java/org/syncope/core/rest/data/ core/src/ma... Date: Fri, 16 Mar 2012 17:55:22 -0000 To: syncope-commits@incubator.apache.org From: ilgrosso@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120316175523.64E392388993@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: ilgrosso Date: Fri Mar 16 17:55:21 2012 New Revision: 1301670 URL: http://svn.apache.org/viewvc?rev=1301670&view=rev Log: [SYNCOPE-20] Audit statements have been spread in all REST controllers: this aspect will need to be refined as soon as there is need of audit features in a real deployment; still missing console interface Modified: incubator/syncope/trunk/client/src/main/java/org/syncope/types/AuditElements.java incubator/syncope/trunk/core/src/main/java/org/syncope/core/audit/AuditManager.java incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ConfigurationController.java incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ConnInstanceController.java incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/DerivedSchemaController.java incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/LoggerController.java incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/NotificationController.java incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/PolicyController.java incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ReportController.java incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ResourceController.java incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/RoleController.java incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/SchemaController.java incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/TaskController.java incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/UserController.java incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/UserRequestController.java incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/VirtualSchemaController.java incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/WorkflowController.java incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/data/ResourceDataBinder.java incubator/syncope/trunk/core/src/main/java/org/syncope/core/scheduling/NotificationJob.java incubator/syncope/trunk/core/src/main/java/org/syncope/core/security/SyncopeAuthenticationProvider.java Modified: incubator/syncope/trunk/client/src/main/java/org/syncope/types/AuditElements.java URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/client/src/main/java/org/syncope/types/AuditElements.java?rev=1301670&r1=1301669&r2=1301670&view=diff ============================================================================== --- incubator/syncope/trunk/client/src/main/java/org/syncope/types/AuditElements.java (original) +++ incubator/syncope/trunk/client/src/main/java/org/syncope/types/AuditElements.java Fri Mar 16 17:55:21 2012 @@ -20,58 +20,48 @@ package org.syncope.types; import java.util.EnumSet; -public class AuditElements { +public final class AuditElements { + + private AuditElements() { + } public enum Category { - authentication, - configuration, - connector, - logger, - notification, - policy, - report, - resource, - role, - schema, - task, - user, - userRequest, - workflow + authentication(AuthenticationSubCategory.class), + configuration(ConfigurationSubCategory.class), + connector(ConnectorSubCategory.class), + logger(LoggerSubCategory.class), + notification(NotificationSubCategory.class), + policy(PolicySubCategory.class), + report(ReportSubCategory.class), + resource(ResourceSubCategory.class), + role(RoleSubCategory.class), + schema(SchemaSubCategory.class), + task(TaskSubCategory.class), + user(UserSubCategory.class), + userRequest(UserRequestSubCategory.class), + workflow(WorkflowSubCategory.class); - } + private Class> subCategory; - public enum Result { + Category(final Class> subCategory) { + this.subCategory = subCategory; + } - success, - failure + public Class getSubCategory() { + return subCategory; + } + public EnumSet> getSubCategoryElements() { + return EnumSet.allOf(getSubCategory()); + } } - public static EnumSet getSubCategories(final Category category) { - EnumSet result; - switch (category) { - case authentication: - result = EnumSet.allOf(AuthenticationSubCategory.class); - break; - - case configuration: - result = EnumSet.allOf(ConfigurationSubCategory.class); - break; - - case connector: - result = EnumSet.allOf(ConnectorSubCategory.class); - break; - - case logger: - result = EnumSet.allOf(LoggerSubCategory.class); - break; + public enum Result { - default: - result = null; - } + success, + failure - return result; } public enum AuthenticationSubCategory { @@ -116,4 +106,137 @@ public class AuditElements { delete } + + public enum NotificationSubCategory { + + list, + create, + read, + update, + delete, + sent + + } + + public enum PolicySubCategory { + + list, + create, + read, + update, + delete + + } + + public enum ReportSubCategory { + + list, + listExecutions, + create, + read, + readExecution, + update, + delete, + deleteExecution, + getReportletConfClasses, + execute, + exportExecutionResult + + } + + public enum ResourceSubCategory { + + list, + create, + read, + update, + delete, + getObject, + getRoleResourcesMapping + + } + + public enum RoleSubCategory { + + list, + create, + read, + update, + delete, + parent, + children + + } + + public enum SchemaSubCategory { + + list, + create, + read, + update, + delete, + listDerived, + createDerived, + readDerived, + updateDerived, + deleteDerived, + listVirtual, + createVirtual, + readVirtual, + updateVirtual, + deleteVirtual + + } + + public enum TaskSubCategory { + + list, + create, + read, + update, + delete, + listExecutions, + getJobClasses, + getJobActionClasses, + readExecution, + execute, + report, + deleteExecution + + } + + public enum UserSubCategory { + + list, + create, + read, + update, + delete, + verifyPassword, + search, + setStatus, + executeWorkflow, + getForms, + getFormForUser, + claimForm, + submitForm + + } + + public enum UserRequestSubCategory { + + list, + create, + read, + update, + delete, + isCreateAllowed,} + + public enum WorkflowSubCategory { + + getDefinition, + updateDefinition, + getDefinedTasks + + } } Modified: incubator/syncope/trunk/core/src/main/java/org/syncope/core/audit/AuditManager.java URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/java/org/syncope/core/audit/AuditManager.java?rev=1301670&r1=1301669&r2=1301670&view=diff ============================================================================== --- incubator/syncope/trunk/core/src/main/java/org/syncope/core/audit/AuditManager.java (original) +++ incubator/syncope/trunk/core/src/main/java/org/syncope/core/audit/AuditManager.java Fri Mar 16 17:55:21 2012 @@ -22,7 +22,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; -import org.syncope.types.AuditElements; +import org.syncope.types.AuditElements.Category; +import org.syncope.types.AuditElements.Result; import org.syncope.types.SyncopeLoggerType; public class AuditManager { @@ -32,29 +33,24 @@ public class AuditManager { */ private static final Logger LOG = LoggerFactory.getLogger(AuditManager.class); - private String getLoggerName(final AuditElements.Category category, final Enum subcategory, - final AuditElements.Result result) { + public String getLoggerName(final Category category, final Enum subcategory, final Result result) { - StringBuilder loggerName = new StringBuilder(); - loggerName.append(SyncopeLoggerType.AUDIT.getPrefix()).append('.').append(category.name()).append('.').append( - subcategory.name()).append('.').append(result.name()); - return loggerName.toString(); + return new StringBuilder().append(SyncopeLoggerType.AUDIT.getPrefix()).append('.'). + append(category.name()).append('.'). + append(subcategory.name()).append('.'). + append(result.name()).toString(); } - public void audit(final AuditElements.Category category, final Enum subcategory, - final AuditElements.Result result, final String message) { - + public void audit(final Category category, final Enum subcategory, final Result result, final String message) { audit(category, subcategory, result, message, null); } - public void audit(final AuditElements.Category category, final Enum subcategory, - final AuditElements.Result result, final String message, final Throwable t) { + public void audit(final Category category, final Enum subcategory, final Result result, final String message, + final Throwable throwable) { if (category == null || subcategory == null || result == null) { - LOG.error("Invalid request: some null items {} {} {}", new Object[] { category, subcategory, result }); - } else if (!AuditElements.getSubCategories(category).contains(subcategory)) { - LOG.error("Invalid request: {} does not belong to {}", new Object[] { subcategory, category }); - } else { + LOG.error("Invalid request: some null items {} {} {}", new Object[]{category, subcategory, result}); + } else if (category.getSubCategoryElements().contains(subcategory)) { StringBuilder auditMessage = new StringBuilder(); final SecurityContext ctx = SecurityContextHolder.getContext(); @@ -64,11 +60,14 @@ public class AuditManager { auditMessage.append(message); Logger logger = LoggerFactory.getLogger(getLoggerName(category, subcategory, result)); - if (t == null) { + if (throwable == null) { logger.debug(auditMessage.toString()); } else { - logger.debug(auditMessage.toString(), t); + logger.debug(auditMessage.toString(), throwable); } + } else { + LOG.error("Invalid request: {} does not belong to {}", new Object[]{subcategory, category}); } + } } Modified: incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ConfigurationController.java URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ConfigurationController.java?rev=1301670&r1=1301669&r2=1301670&view=diff ============================================================================== --- incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ConfigurationController.java (original) +++ incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ConfigurationController.java Fri Mar 16 17:55:21 2012 @@ -134,7 +134,7 @@ public class ConfigurationController ext result.setKey(key); auditManager.audit(Category.configuration, ConfigurationSubCategory.read, Result.failure, - "Could not read conf: " + key); + "Could not find conf: " + key); } return result; @@ -235,7 +235,7 @@ public class ConfigurationController ext LOG.debug("Database content successfully exported"); } catch (Throwable t) { auditManager.audit(Category.configuration, ConfigurationSubCategory.dbExport, Result.failure, - "Could not export database content"); + "Could not export database content", t); LOG.error("While exporting database content", t); } } Modified: incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ConnInstanceController.java URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ConnInstanceController.java?rev=1301670&r1=1301669&r2=1301670&view=diff ============================================================================== --- incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ConnInstanceController.java (original) +++ incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ConnInstanceController.java Fri Mar 16 17:55:21 2012 @@ -102,7 +102,7 @@ public class ConnInstanceController exte "Successfully created connector instance: " + connInstance.getDisplayName()); } catch (Throwable t) { auditManager.audit(Category.connector, ConnectorSubCategory.create, Result.failure, - "Could not create connector instance: " + connectorTO.getDisplayName()); + "Could not create connector instance: " + connectorTO.getDisplayName(), t); SyncopeClientCompositeErrorException scce = new SyncopeClientCompositeErrorException(HttpStatus.BAD_REQUEST); @@ -133,7 +133,7 @@ public class ConnInstanceController exte "Successfully update connector instance: " + connInstance.getDisplayName()); } catch (Throwable t) { auditManager.audit(Category.connector, ConnectorSubCategory.create, Result.failure, - "Could not update connector instance: " + connectorTO.getDisplayName()); + "Could not update connector instance: " + connectorTO.getDisplayName(), t); SyncopeClientCompositeErrorException scce = new SyncopeClientCompositeErrorException(HttpStatus.BAD_REQUEST); @@ -371,7 +371,7 @@ public class ConnInstanceController exte "Successfully checked connector: " + connectorTO); } catch (Exception ex) { auditManager.audit(Category.connector, ConnectorSubCategory.check, Result.failure, - "Unsuccessful check for connector: " + connectorTO); + "Unsuccessful check for connector: " + connectorTO, ex); LOG.error("Test connection failure {}", ex); result = false; Modified: incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/DerivedSchemaController.java URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/DerivedSchemaController.java?rev=1301670&r1=1301669&r2=1301670&view=diff ============================================================================== --- incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/DerivedSchemaController.java (original) +++ incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/DerivedSchemaController.java Fri Mar 16 17:55:21 2012 @@ -31,15 +31,22 @@ import org.springframework.web.bind.anno import org.springframework.web.bind.annotation.RequestMethod; import org.syncope.client.to.DerivedSchemaTO; import org.syncope.client.validation.SyncopeClientCompositeErrorException; +import org.syncope.core.audit.AuditManager; import org.syncope.core.persistence.beans.AbstractDerSchema; import org.syncope.core.persistence.dao.DerSchemaDAO; import org.syncope.core.rest.data.DerivedSchemaDataBinder; +import org.syncope.types.AuditElements.Category; +import org.syncope.types.AuditElements.Result; +import org.syncope.types.AuditElements.SchemaSubCategory; @Controller @RequestMapping("/derivedSchema") public class DerivedSchemaController extends AbstractController { @Autowired + private AuditManager auditManager; + + @Autowired private DerSchemaDAO derivedSchemaDAO; @Autowired @@ -51,10 +58,11 @@ public class DerivedSchemaController ext @RequestBody final DerivedSchemaTO derivedSchemaTO, @PathVariable("kind") final String kind) throws SyncopeClientCompositeErrorException { - AbstractDerSchema derivedSchema = derivedSchemaDataBinder.create(derivedSchemaTO, getAttributableUtil(kind) - .newDerivedSchema()); + AbstractDerSchema derivedSchema = derivedSchemaDAO.save( + derivedSchemaDataBinder.create(derivedSchemaTO, getAttributableUtil(kind).newDerivedSchema())); - derivedSchema = derivedSchemaDAO.save(derivedSchema); + auditManager.audit(Category.schema, SchemaSubCategory.createDerived, Result.success, + "Successfully created derived schema: " + kind + "/" + derivedSchema.getName()); response.setStatus(HttpServletResponse.SC_CREATED); return derivedSchemaDataBinder.getDerivedSchemaTO(derivedSchema); @@ -62,18 +70,19 @@ public class DerivedSchemaController ext @PreAuthorize("hasRole('SCHEMA_DELETE')") @RequestMapping(method = RequestMethod.DELETE, value = "/{kind}/delete/{schema}") - public void delete(HttpServletResponse response, @PathVariable("kind") final String kind, + public void delete(@PathVariable("kind") final String kind, @PathVariable("schema") final String derivedSchemaName) throws NotFoundException { Class reference = getAttributableUtil(kind).derivedSchemaClass(); AbstractDerSchema derivedSchema = derivedSchemaDAO.find(derivedSchemaName, reference); if (derivedSchema == null) { - LOG.error("Could not find derived schema '" + derivedSchemaName + "'"); - - throw new NotFoundException(derivedSchemaName); - } else { - derivedSchemaDAO.delete(derivedSchemaName, getAttributableUtil(kind)); + throw new NotFoundException("Derived schema '" + derivedSchemaName + "'"); } + + derivedSchemaDAO.delete(derivedSchemaName, getAttributableUtil(kind)); + + auditManager.audit(Category.schema, SchemaSubCategory.deleteDerived, Result.success, + "Successfully deleted derived schema: " + kind + "/" + derivedSchema.getName()); } @RequestMapping(method = RequestMethod.GET, value = "/{kind}/list") @@ -83,10 +92,12 @@ public class DerivedSchemaController ext List derivedSchemaTOs = new ArrayList(derivedAttributeSchemas.size()); for (AbstractDerSchema derivedSchema : derivedAttributeSchemas) { - derivedSchemaTOs.add(derivedSchemaDataBinder.getDerivedSchemaTO(derivedSchema)); } + auditManager.audit(Category.schema, SchemaSubCategory.listDerived, Result.success, + "Successfully listed all derived schemas: " + kind + "/" + derivedSchemaTOs.size()); + return derivedSchemaTOs; } @@ -98,28 +109,32 @@ public class DerivedSchemaController ext Class reference = getAttributableUtil(kind).derivedSchemaClass(); AbstractDerSchema derivedSchema = derivedSchemaDAO.find(derivedSchemaName, reference); if (derivedSchema == null) { - LOG.error("Could not find derived schema '" + derivedSchemaName + "'"); - throw new NotFoundException(derivedSchemaName); + throw new NotFoundException("Derived schema '" + derivedSchemaName + "'"); } + auditManager.audit(Category.schema, SchemaSubCategory.readDerived, Result.success, + "Successfully read derived schema: " + kind + "/" + derivedSchema.getName()); + return derivedSchemaDataBinder.getDerivedSchemaTO(derivedSchema); } @PreAuthorize("hasRole('SCHEMA_UPDATE')") @RequestMapping(method = RequestMethod.POST, value = "/{kind}/update") public DerivedSchemaTO update(@RequestBody final DerivedSchemaTO derivedSchemaTO, - @PathVariable("kind") final String kind) throws SyncopeClientCompositeErrorException, NotFoundException { + @PathVariable("kind") final String kind) throws NotFoundException { Class reference = getAttributableUtil(kind).derivedSchemaClass(); AbstractDerSchema derivedSchema = derivedSchemaDAO.find(derivedSchemaTO.getName(), reference); if (derivedSchema == null) { - LOG.error("Could not find derived schema '" + derivedSchemaTO.getName() + "'"); - throw new NotFoundException(derivedSchemaTO.getName()); + throw new NotFoundException("Derived schema '" + derivedSchemaTO.getName() + "'"); } derivedSchema = derivedSchemaDataBinder.update(derivedSchemaTO, derivedSchema); - derivedSchema = derivedSchemaDAO.save(derivedSchema); + + auditManager.audit(Category.schema, SchemaSubCategory.updateDerived, Result.success, + "Successfully updated derived schema: " + kind + "/" + derivedSchema.getName()); + return derivedSchemaDataBinder.getDerivedSchemaTO(derivedSchema); } } Modified: incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/LoggerController.java URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/LoggerController.java?rev=1301670&r1=1301669&r2=1301670&view=diff ============================================================================== --- incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/LoggerController.java (original) +++ incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/LoggerController.java Fri Mar 16 17:55:21 2012 @@ -133,9 +133,12 @@ public class LoggerController extends Ab } @PreAuthorize("hasRole('AUDIT_SET_LEVEL')") - @RequestMapping(method = RequestMethod.POST, value = "/audit/{name}/{level}") - public LoggerTO setAuditLevel(@PathVariable("name") final String name, @PathVariable("level") final Level level) { - return setLevel(name, level, SyncopeLoggerType.AUDIT); + @RequestMapping(method = RequestMethod.POST, value = "/audit/{category}/{subcategory}/{result}/{level}") + public LoggerTO setAuditLevel(@PathVariable("category") final Category category, + @PathVariable("subcategory") final Enum subcategory, @PathVariable("result") final Result result, + @PathVariable("level") final Level level) { + + return setLevel(auditManager.getLoggerName(category, subcategory, result), level, SyncopeLoggerType.AUDIT); } private void delete(final String name, final SyncopeLoggerType expectedType) throws NotFoundException { @@ -167,9 +170,11 @@ public class LoggerController extends Ab } @PreAuthorize("hasRole('AUDIT_DELETE')") - @RequestMapping(method = RequestMethod.DELETE, value = "/audit/delete/{name}") - public void deleteAudit(@PathVariable("name") final String name) throws NotFoundException { + @RequestMapping(method = RequestMethod.DELETE, value = "/audit/delete/{category}/{subcategory}/{result}") + public void deleteAudit(@PathVariable("category") final Category category, + @PathVariable("subcategory") final Enum subcategory, @PathVariable("result") final Result result) throws + NotFoundException { - delete(name, SyncopeLoggerType.AUDIT); + delete(auditManager.getLoggerName(category, subcategory, result), SyncopeLoggerType.AUDIT); } } Modified: incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/NotificationController.java URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/NotificationController.java?rev=1301670&r1=1301669&r2=1301670&view=diff ============================================================================== --- incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/NotificationController.java (original) +++ incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/NotificationController.java Fri Mar 16 17:55:21 2012 @@ -30,15 +30,22 @@ import org.springframework.web.bind.anno import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.syncope.client.to.NotificationTO; +import org.syncope.core.audit.AuditManager; import org.syncope.core.persistence.beans.Notification; import org.syncope.core.persistence.dao.NotificationDAO; import org.syncope.core.rest.data.NotificationDataBinder; +import org.syncope.types.AuditElements.Category; +import org.syncope.types.AuditElements.NotificationSubCategory; +import org.syncope.types.AuditElements.Result; @Controller @RequestMapping("/notification") public class NotificationController extends AbstractController { @Autowired + private AuditManager auditManager; + + @Autowired private NotificationDAO notificationDAO; @Autowired @@ -46,7 +53,7 @@ public class NotificationController exte @PreAuthorize("hasRole('NOTIFICATION_READ')") @RequestMapping(method = RequestMethod.GET, value = "/read/{notificationId}") - public NotificationTO read(@PathVariable("notificationId") Long notificationId) throws NotFoundException { + public NotificationTO read(@PathVariable("notificationId") final Long notificationId) throws NotFoundException { Notification notification = notificationDAO.find(notificationId); if (notification == null) { @@ -69,6 +76,9 @@ public class NotificationController exte notificationTOs.add(binder.getNotificationTO(notification)); } + auditManager.audit(Category.notification, NotificationSubCategory.list, Result.success, + "Successfully listed all notifications: " + notificationTOs.size()); + return notificationTOs; } @@ -79,8 +89,10 @@ public class NotificationController exte LOG.debug("Notification create called with parameter {}", notificationTO); - Notification notification = binder.createNotification(notificationTO); - notification = notificationDAO.save(notification); + Notification notification = notificationDAO.save(binder.createNotification(notificationTO)); + + auditManager.audit(Category.notification, NotificationSubCategory.create, Result.success, + "Successfully created notification: " + notification.getId()); response.setStatus(HttpServletResponse.SC_CREATED); return binder.getNotificationTO(notification); @@ -102,6 +114,9 @@ public class NotificationController exte binder.updateNotification(notification, notificationTO); notification = notificationDAO.save(notification); + auditManager.audit(Category.notification, NotificationSubCategory.update, Result.success, + "Successfully updated notification: " + notification.getId()); + return binder.getNotificationTO(notification); } @@ -116,6 +131,9 @@ public class NotificationController exte throw new NotFoundException(String.valueOf(notificationId)); } + auditManager.audit(Category.notification, NotificationSubCategory.delete, Result.success, + "Successfully deleted notification: " + notification.getId()); + notificationDAO.delete(notificationId); } } Modified: incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/PolicyController.java URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/PolicyController.java?rev=1301670&r1=1301669&r2=1301670&view=diff ============================================================================== --- incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/PolicyController.java (original) +++ incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/PolicyController.java Fri Mar 16 17:55:21 2012 @@ -20,26 +20,31 @@ package org.syncope.core.rest.controller import java.util.ArrayList; import java.util.List; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; +import java.util.Locale; import javassist.NotFoundException; import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; import org.syncope.client.to.AccountPolicyTO; import org.syncope.client.to.PasswordPolicyTO; import org.syncope.client.to.PolicyTO; import org.syncope.client.to.SyncPolicyTO; import org.syncope.client.validation.SyncopeClientCompositeErrorException; +import org.syncope.core.audit.AuditManager; import org.syncope.core.persistence.beans.AccountPolicy; import org.syncope.core.persistence.beans.PasswordPolicy; import org.syncope.core.persistence.beans.Policy; import org.syncope.core.persistence.beans.SyncPolicy; import org.syncope.core.persistence.dao.PolicyDAO; import org.syncope.core.rest.data.PolicyDataBinder; +import org.syncope.types.AuditElements.Category; +import org.syncope.types.AuditElements.PolicySubCategory; +import org.syncope.types.AuditElements.Result; import org.syncope.types.PolicyType; @Controller @@ -47,6 +52,9 @@ import org.syncope.types.PolicyType; public class PolicyController extends AbstractController { @Autowired + private AuditManager auditManager; + + @Autowired private PolicyDAO policyDAO; @Autowired @@ -54,57 +62,69 @@ public class PolicyController extends Ab @PreAuthorize("hasRole('POLICY_CREATE')") @RequestMapping(method = RequestMethod.POST, value = "/password/create") - public PasswordPolicyTO create(final HttpServletResponse response, final @RequestBody PasswordPolicyTO policyTO) + public PasswordPolicyTO create(final HttpServletResponse response, @RequestBody final PasswordPolicyTO policyTO) throws SyncopeClientCompositeErrorException { LOG.debug("Creating policy " + policyTO); final PasswordPolicy policy = binder.getPolicy(null, policyTO); + auditManager.audit(Category.policy, PolicySubCategory.create, Result.success, + "Successfully created password policy: " + policy.getId()); + return binder.getPolicyTO(policyDAO.save(policy)); } @PreAuthorize("hasRole('POLICY_CREATE')") @RequestMapping(method = RequestMethod.POST, value = "/account/create") - public AccountPolicyTO create(final HttpServletResponse response, final @RequestBody AccountPolicyTO policyTO) + public AccountPolicyTO create(final HttpServletResponse response, @RequestBody final AccountPolicyTO policyTO) throws SyncopeClientCompositeErrorException { LOG.debug("Creating policy " + policyTO); final AccountPolicy policy = binder.getPolicy(null, policyTO); + auditManager.audit(Category.policy, PolicySubCategory.create, Result.success, + "Successfully created account policy: " + policy.getId()); + return binder.getPolicyTO(policyDAO.save(policy)); } @PreAuthorize("hasRole('POLICY_CREATE')") @RequestMapping(method = RequestMethod.POST, value = "/sync/create") - public SyncPolicyTO create(final HttpServletResponse response, final @RequestBody SyncPolicyTO policyTO) + public SyncPolicyTO create(final HttpServletResponse response, @RequestBody final SyncPolicyTO policyTO) throws SyncopeClientCompositeErrorException { LOG.debug("Creating policy " + policyTO); final SyncPolicy policy = binder.getPolicy(null, policyTO); + auditManager.audit(Category.policy, PolicySubCategory.create, Result.success, + "Successfully created sync policy: " + policy.getId()); + return binder.getPolicyTO(policyDAO.save(policy)); } - private T update(T policyTO, K policy) { + private T update(final T policyTO, final K policy) { LOG.debug("Updating policy " + policyTO); binder.getPolicy(policy, policyTO); - policy = policyDAO.save(policy); + K savedPolicy = policyDAO.save(policy); - return binder.getPolicyTO(policy); + auditManager.audit(Category.policy, PolicySubCategory.update, Result.success, + "Successfully updated policy (" + savedPolicy.getType() + "): " + savedPolicy.getId()); + + return binder.getPolicyTO(savedPolicy); } @PreAuthorize("hasRole('POLICY_UPDATE')") @RequestMapping(method = RequestMethod.POST, value = "/password/update") - public PasswordPolicyTO update(final HttpServletResponse response, final @RequestBody PasswordPolicyTO policyTO) + public PasswordPolicyTO update(@RequestBody final PasswordPolicyTO policyTO) throws NotFoundException { Policy policy = policyDAO.find(policyTO.getId()); - if (policy == null || !(policy instanceof PasswordPolicy)) { + if (!(policy instanceof PasswordPolicy)) { throw new NotFoundException("PasswordPolicy with id " + policyTO.getId()); } @@ -113,11 +133,11 @@ public class PolicyController extends Ab @PreAuthorize("hasRole('POLICY_UPDATE')") @RequestMapping(method = RequestMethod.POST, value = "/account/update") - public AccountPolicyTO update(final HttpServletResponse response, final @RequestBody AccountPolicyTO policyTO) + public AccountPolicyTO update(@RequestBody final AccountPolicyTO policyTO) throws NotFoundException, SyncopeClientCompositeErrorException { Policy policy = policyDAO.find(policyTO.getId()); - if (policy == null || !(policy instanceof AccountPolicy)) { + if (!(policy instanceof AccountPolicy)) { throw new NotFoundException("AccountPolicy with id " + policyTO.getId()); } @@ -126,11 +146,11 @@ public class PolicyController extends Ab @PreAuthorize("hasRole('POLICY_UPDATE')") @RequestMapping(method = RequestMethod.POST, value = "/sync/update") - public SyncPolicyTO update(final HttpServletResponse response, final @RequestBody SyncPolicyTO policyTO) + public SyncPolicyTO update(@RequestBody final SyncPolicyTO policyTO) throws NotFoundException, SyncopeClientCompositeErrorException { Policy policy = policyDAO.find(policyTO.getId()); - if (policy == null || !(policy instanceof SyncPolicy)) { + if (!(policy instanceof SyncPolicy)) { throw new NotFoundException("SyncPolicy with id " + policyTO.getId()); } @@ -139,22 +159,25 @@ public class PolicyController extends Ab @PreAuthorize("hasRole('POLICY_LIST')") @RequestMapping(method = RequestMethod.GET, value = "/{kind}/list") - public List listByType(final HttpServletResponse response, @PathVariable("kind") final String kind) { + public List listByType(@PathVariable("kind") final String kind) { LOG.debug("Listing policies"); - List policies = policyDAO.find(PolicyType.valueOf(kind.toUpperCase())); + List policies = policyDAO.find(PolicyType.valueOf(kind.toUpperCase(Locale.ENGLISH))); final List policyTOs = new ArrayList(); for (Policy policy : policies) { policyTOs.add(binder.getPolicyTO(policy)); } + auditManager.audit(Category.policy, PolicySubCategory.list, Result.success, + "Successfully listed all policies (" + kind + "): " + policyTOs.size()); + return policyTOs; } @PreAuthorize("hasRole('POLICY_READ')") @RequestMapping(method = RequestMethod.GET, value = "/password/global/read") - public PasswordPolicyTO getGlobalPasswordPolicy(final HttpServletResponse response) throws NotFoundException { + public PasswordPolicyTO getGlobalPasswordPolicy() throws NotFoundException { LOG.debug("Reading global password policy"); @@ -163,12 +186,15 @@ public class PolicyController extends Ab throw new NotFoundException("No password policy found"); } + auditManager.audit(Category.policy, PolicySubCategory.read, Result.success, + "Successfully read global password policy: " + policy.getId()); + return (PasswordPolicyTO) binder.getPolicyTO(policy); } @PreAuthorize("hasRole('POLICY_READ')") @RequestMapping(method = RequestMethod.GET, value = "/account/global/read") - public AccountPolicyTO getGlobalAccountPolicy(final HttpServletResponse response) throws NotFoundException { + public AccountPolicyTO getGlobalAccountPolicy() throws NotFoundException { LOG.debug("Reading global account policy"); @@ -177,12 +203,15 @@ public class PolicyController extends Ab throw new NotFoundException("No account policy found"); } + auditManager.audit(Category.policy, PolicySubCategory.read, Result.success, + "Successfully read global account policy: " + policy.getId()); + return (AccountPolicyTO) binder.getPolicyTO(policy); } @PreAuthorize("hasRole('POLICY_READ')") @RequestMapping(method = RequestMethod.GET, value = "/sync/global/read") - public SyncPolicyTO getGlobalSyncPolicy(final HttpServletResponse response) throws NotFoundException { + public SyncPolicyTO getGlobalSyncPolicy() throws NotFoundException { LOG.debug("Reading global sync policy"); @@ -191,12 +220,15 @@ public class PolicyController extends Ab throw new NotFoundException("No sync policy found"); } + auditManager.audit(Category.policy, PolicySubCategory.read, Result.success, + "Successfully read global sync policy: " + policy.getId()); + return (SyncPolicyTO) binder.getPolicyTO(policy); } @PreAuthorize("hasRole('POLICY_READ')") @RequestMapping(method = RequestMethod.GET, value = "/read/{id}") - public PolicyTO read(final HttpServletResponse response, @PathVariable("id") final Long id) + public PolicyTO read(@PathVariable("id") final Long id) throws NotFoundException { LOG.debug("Reading policy with id {}", id); @@ -206,14 +238,20 @@ public class PolicyController extends Ab throw new NotFoundException("Policy " + id + " not found"); } + auditManager.audit(Category.policy, PolicySubCategory.read, Result.success, + "Successfully read policy (" + policy.getType() + "): " + policy.getId()); + return binder.getPolicyTO(policy); } @PreAuthorize("hasRole('POLICY_DELETE')") @RequestMapping(method = RequestMethod.DELETE, value = "/delete/{id}") - public void delete(final HttpServletResponse response, @PathVariable("id") final Long id) throws NotFoundException { + public void delete(@PathVariable("id") final Long id) throws NotFoundException { LOG.debug("Delete policy"); policyDAO.delete(id); + + auditManager.audit(Category.policy, PolicySubCategory.delete, Result.success, + "Successfully deleted policy: " + id); } } Modified: incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ReportController.java URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ReportController.java?rev=1301670&r1=1301669&r2=1301670&view=diff ============================================================================== --- incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ReportController.java (original) +++ incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ReportController.java Fri Mar 16 17:55:21 2012 @@ -59,6 +59,7 @@ import org.syncope.client.to.ReportExecT import org.syncope.client.to.ReportTO; import org.syncope.client.validation.SyncopeClientCompositeErrorException; import org.syncope.client.validation.SyncopeClientException; +import org.syncope.core.audit.AuditManager; import org.syncope.core.init.JobInstanceLoader; import org.syncope.core.persistence.beans.Report; import org.syncope.core.persistence.beans.ReportExec; @@ -66,6 +67,9 @@ import org.syncope.core.persistence.dao. import org.syncope.core.persistence.dao.ReportExecDAO; import org.syncope.core.report.Reportlet; import org.syncope.core.rest.data.ReportDataBinder; +import org.syncope.types.AuditElements.Category; +import org.syncope.types.AuditElements.ReportSubCategory; +import org.syncope.types.AuditElements.Result; import org.syncope.types.ReportExecExportFormat; import org.syncope.types.ReportExecStatus; import org.syncope.types.SyncopeClientExceptionType; @@ -75,6 +79,9 @@ import org.syncope.types.SyncopeClientEx public class ReportController extends AbstractController { @Autowired + private AuditManager auditManager; + + @Autowired private ReportDAO reportDAO; @Autowired @@ -106,13 +113,17 @@ public class ReportController extends Ab } catch (Exception e) { LOG.error("While registering quartz job for report " + report.getId(), e); - SyncopeClientCompositeErrorException scce = new SyncopeClientCompositeErrorException(HttpStatus.BAD_REQUEST); + SyncopeClientCompositeErrorException scce = + new SyncopeClientCompositeErrorException(HttpStatus.BAD_REQUEST); SyncopeClientException sce = new SyncopeClientException(SyncopeClientExceptionType.Scheduling); sce.addElement(e.getMessage()); scce.addException(sce); throw scce; } + auditManager.audit(Category.report, ReportSubCategory.create, Result.success, + "Successfully created report: " + report.getId()); + response.setStatus(HttpServletResponse.SC_CREATED); return binder.getReportTO(report); } @@ -143,6 +154,9 @@ public class ReportController extends Ab throw scce; } + auditManager.audit(Category.report, ReportSubCategory.update, Result.success, + "Successfully updated report: " + report.getId()); + return binder.getReportTO(report); } @@ -161,6 +175,9 @@ public class ReportController extends Ab result.add(binder.getReportTO(report)); } + auditManager.audit(Category.report, ReportSubCategory.list, Result.success, + "Successfully listed all reports: " + result.size()); + return result; } @@ -173,6 +190,9 @@ public class ReportController extends Ab result.add(binder.getReportTO(report)); } + auditManager.audit(Category.report, ReportSubCategory.list, Result.success, + "Successfully listed reports (page=" + page + ", size=" + size + "): " + result.size()); + return result; } @@ -185,6 +205,9 @@ public class ReportController extends Ab executionTOs.add(binder.getReportExecTO(execution)); } + auditManager.audit(Category.report, ReportSubCategory.listExecutions, Result.success, + "Successfully listed all report executions: " + executionTOs.size()); + return executionTOs; } @@ -200,9 +223,10 @@ public class ReportController extends Ab } } - ModelAndView result = new ModelAndView(); - result.addObject(reportletConfClasses); - return result; + auditManager.audit(Category.report, ReportSubCategory.getReportletConfClasses, Result.success, + "Successfully listed all ReportletConf classes: " + reportletConfClasses.size()); + + return new ModelAndView().addObject(reportletConfClasses); } @PreAuthorize("hasRole('REPORT_READ')") @@ -214,6 +238,9 @@ public class ReportController extends Ab throw new NotFoundException("Report " + reportId); } + auditManager.audit(Category.report, ReportSubCategory.read, Result.success, + "Successfully read report: " + report.getId()); + return binder.getReportTO(report); } @@ -222,12 +249,15 @@ public class ReportController extends Ab @Transactional(readOnly = true) public ReportExecTO readExecution(@PathVariable("executionId") final Long executionId) throws NotFoundException { - ReportExec execution = reportExecDAO.find(executionId); - if (execution == null) { + ReportExec reportExec = reportExecDAO.find(executionId); + if (reportExec == null) { throw new NotFoundException("Report execution " + executionId); } - return binder.getReportExecTO(execution); + auditManager.audit(Category.report, ReportSubCategory.readExecution, Result.success, + "Successfully read report execution: " + reportExec.getId()); + + return binder.getReportExecTO(reportExec); } @PreAuthorize("hasRole('REPORT_READ')") @@ -319,6 +349,9 @@ public class ReportController extends Ab LOG.error("While closing stream for execution result", e); } } + + auditManager.audit(Category.report, ReportSubCategory.exportExecutionResult, Result.success, + "Successfully exported report execution: " + reportExec.getId()); } @PreAuthorize("hasRole('REPORT_EXECUTE')") @@ -335,10 +368,17 @@ public class ReportController extends Ab JobDataMap map = new JobDataMap(); scheduler.getScheduler().triggerJob(JobInstanceLoader.getJobName(report), Scheduler.DEFAULT_GROUP, map); + + auditManager.audit(Category.report, ReportSubCategory.execute, Result.success, + "Successfully started execution for report: " + report.getId()); } catch (Exception e) { LOG.error("While executing report {}", report, e); - SyncopeClientCompositeErrorException scce = new SyncopeClientCompositeErrorException(HttpStatus.BAD_REQUEST); + auditManager.audit(Category.report, ReportSubCategory.execute, Result.failure, + "Could not start execution for report: " + report.getId(), e); + + SyncopeClientCompositeErrorException scce = + new SyncopeClientCompositeErrorException(HttpStatus.BAD_REQUEST); SyncopeClientException sce = new SyncopeClientException(SyncopeClientExceptionType.Scheduling); sce.addElement(e.getMessage()); scce.addException(sce); @@ -356,7 +396,7 @@ public class ReportController extends Ab @PreAuthorize("hasRole('REPORT_DELETE')") @RequestMapping(method = RequestMethod.DELETE, value = "/delete/{reportId}") - public void delete(@PathVariable("reportId") Long reportId) + public void delete(@PathVariable("reportId") final Long reportId) throws NotFoundException, SyncopeClientCompositeErrorException { Report report = reportDAO.find(reportId); @@ -367,18 +407,24 @@ public class ReportController extends Ab jobInstanceLoader.unregisterJob(report); reportDAO.delete(report); + + auditManager.audit(Category.report, ReportSubCategory.delete, Result.success, + "Successfully deleted report: " + report.getId()); } @PreAuthorize("hasRole('REPORT_DELETE')") @RequestMapping(method = RequestMethod.DELETE, value = "/execution/delete/{executionId}") - public void deleteExecution(@PathVariable("executionId") Long executionId) + public void deleteExecution(@PathVariable("executionId") final Long executionId) throws NotFoundException, SyncopeClientCompositeErrorException { - ReportExec execution = reportExecDAO.find(executionId); - if (execution == null) { + ReportExec reportExec = reportExecDAO.find(executionId); + if (reportExec == null) { throw new NotFoundException("Report execution " + executionId); } - reportExecDAO.delete(execution); + reportExecDAO.delete(reportExec); + + auditManager.audit(Category.report, ReportSubCategory.deleteExecution, Result.success, + "Successfully deleted report execution: " + reportExec.getId()); } } Modified: incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ResourceController.java URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ResourceController.java?rev=1301670&r1=1301669&r2=1301670&view=diff ============================================================================== --- incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ResourceController.java (original) +++ incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/ResourceController.java Fri Mar 16 17:55:21 2012 @@ -30,7 +30,6 @@ import org.identityconnectors.framework. import org.identityconnectors.framework.common.objects.ObjectClass; import org.identityconnectors.framework.common.objects.Uid; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; import org.springframework.transaction.annotation.Transactional; @@ -43,7 +42,7 @@ import org.syncope.client.to.ConnObjectT import org.syncope.client.to.ResourceTO; import org.syncope.client.to.SchemaMappingTO; import org.syncope.client.validation.SyncopeClientCompositeErrorException; -import org.syncope.client.validation.SyncopeClientException; +import org.syncope.core.audit.AuditManager; import org.syncope.core.init.ConnInstanceLoader; import org.syncope.core.persistence.beans.ConnInstance; import org.syncope.core.persistence.beans.ExternalResource; @@ -54,13 +53,18 @@ import org.syncope.core.persistence.dao. import org.syncope.core.propagation.ConnectorFacadeProxy; import org.syncope.core.rest.data.ResourceDataBinder; import org.syncope.core.util.ConnObjectUtil; -import org.syncope.types.SyncopeClientExceptionType; +import org.syncope.types.AuditElements.Category; +import org.syncope.types.AuditElements.ResourceSubCategory; +import org.syncope.types.AuditElements.Result; @Controller @RequestMapping("/resource") public class ResourceController extends AbstractController { @Autowired + private AuditManager auditManager; + + @Autowired private ResourceDAO resourceDAO; @Autowired @@ -83,41 +87,15 @@ public class ResourceController extends @PreAuthorize("hasRole('RESOURCE_CREATE')") @RequestMapping(method = RequestMethod.POST, value = "/create") - public ResourceTO create(final HttpServletResponse response, final @RequestBody ResourceTO resourceTO) + public ResourceTO create(final HttpServletResponse response, @RequestBody final ResourceTO resourceTO) throws SyncopeClientCompositeErrorException, NotFoundException { LOG.debug("Resource creation: {}", resourceTO); - if (resourceTO == null) { - LOG.error("Missing resource"); - - throw new NotFoundException("Missing resource"); - } - - SyncopeClientCompositeErrorException scce = new SyncopeClientCompositeErrorException(HttpStatus.BAD_REQUEST); - - LOG.debug("Verify that resource doesn't exist yet"); - if (resourceTO.getName() != null && resourceDAO.find(resourceTO.getName()) != null) { - SyncopeClientException ex = new SyncopeClientException(SyncopeClientExceptionType.DataIntegrityViolation); - - ex.addElement("Existing " + resourceTO.getName()); - scce.addException(ex); - - throw scce; - } - - ExternalResource resource = binder.create(resourceTO); - if (resource == null) { - LOG.error("Resource creation failed"); - - SyncopeClientException ex = new SyncopeClientException(SyncopeClientExceptionType.Unknown); + ExternalResource resource = resourceDAO.save(binder.create(resourceTO)); - scce.addException(ex); - - throw scce; - } - - resource = resourceDAO.save(resource); + auditManager.audit(Category.resource, ResourceSubCategory.create, Result.success, + "Successfully created resource: " + resource.getName()); response.setStatus(HttpServletResponse.SC_CREATED); return binder.getResourceTO(resource); @@ -125,62 +103,55 @@ public class ResourceController extends @PreAuthorize("hasRole('RESOURCE_UPDATE')") @RequestMapping(method = RequestMethod.POST, value = "/update") - public ResourceTO update(final HttpServletResponse response, final @RequestBody ResourceTO resourceTO) + public ResourceTO update(@RequestBody final ResourceTO resourceTO) throws SyncopeClientCompositeErrorException, NotFoundException { LOG.debug("Role update request: {}", resourceTO); - ExternalResource resource = null; - if (resourceTO != null && resourceTO.getName() != null) { - resource = resourceDAO.find(resourceTO.getName()); - } + ExternalResource resource = resourceDAO.find(resourceTO.getName()); if (resource == null) { - LOG.error("Missing resource: {}", resourceTO.getName()); throw new NotFoundException("Resource '" + resourceTO.getName() + "'"); } resource = binder.update(resource, resourceTO); - if (resource == null) { - LOG.error("Resource update failed"); - - SyncopeClientCompositeErrorException scce = new SyncopeClientCompositeErrorException(HttpStatus.BAD_REQUEST); - SyncopeClientException ex = new SyncopeClientException(SyncopeClientExceptionType.Unknown); - scce.addException(ex); - throw scce; - } - resource = resourceDAO.save(resource); + auditManager.audit(Category.resource, ResourceSubCategory.update, Result.success, + "Successfully updated resource: " + resource.getName()); + return binder.getResourceTO(resource); } @PreAuthorize("hasRole('RESOURCE_DELETE')") @RequestMapping(method = RequestMethod.DELETE, value = "/delete/{resourceName}") - public void delete(final HttpServletResponse response, final @PathVariable("resourceName") String resourceName) + public void delete(@PathVariable("resourceName") final String resourceName) throws NotFoundException { ExternalResource resource = resourceDAO.find(resourceName); - if (resource == null) { - LOG.error("Could not find resource '" + resourceName + "'"); throw new NotFoundException("Resource '" + resourceName + "'"); } + auditManager.audit(Category.resource, ResourceSubCategory.delete, Result.success, + "Successfully deleted resource: " + resource.getName()); + resourceDAO.delete(resourceName); } @PreAuthorize("hasRole('RESOURCE_READ')") @Transactional(readOnly = true) @RequestMapping(method = RequestMethod.GET, value = "/read/{resourceName}") - public ResourceTO read(final HttpServletResponse response, final @PathVariable("resourceName") String resourceName) + public ResourceTO read(@PathVariable("resourceName") final String resourceName) throws NotFoundException { ExternalResource resource = resourceDAO.find(resourceName); if (resource == null) { - LOG.error("Could not find resource '" + resourceName + "'"); throw new NotFoundException("Resource '" + resourceName + "'"); } + auditManager.audit(Category.resource, ResourceSubCategory.read, Result.success, + "Successfully read resource: " + resource.getName()); + return binder.getResourceTO(resource); } @@ -189,7 +160,7 @@ public class ResourceController extends public List list(@RequestParam(required = false, value = "connInstanceId") final Long connInstanceId) throws NotFoundException { - final List resources; + List resources; if (connInstanceId == null) { resources = resourceDAO.findAll(); @@ -198,37 +169,24 @@ public class ResourceController extends resources = connInstance.getResources(); } - if (resources == null) { - LOG.error("No resources found"); - throw new NotFoundException("No resources found"); - } + List result = binder.getResourceTOs(resources); + + auditManager.audit(Category.resource, ResourceSubCategory.list, Result.success, + connInstanceId == null + ? "Successfully listed all resources: " + result.size() + : "Successfully listed resources for connector " + connInstanceId + ": " + result.size()); - return binder.getResourceTOs(resources); + return result; } @PreAuthorize("hasRole('RESOURCE_READ')") - @RequestMapping(method = RequestMethod.GET, value = "/{roleName}/mappings") - public List getRoleResourcesMapping(final HttpServletResponse response, - @PathVariable("roleName") final Long roleId) throws SyncopeClientCompositeErrorException { - - SyncopeRole role = null; - if (roleId != null) { - role = roleDAO.find(roleId); - } + @RequestMapping(method = RequestMethod.GET, value = "/{roleId}/mappings") + public List getRoleResourcesMapping(@PathVariable("roleId") final Long roleId) + throws NotFoundException { + SyncopeRole role = roleDAO.find(roleId); if (role == null) { - LOG.error("Role " + roleId + " not found."); - - SyncopeClientCompositeErrorException compositeErrorException = new SyncopeClientCompositeErrorException( - HttpStatus.BAD_REQUEST); - - SyncopeClientException ex = new SyncopeClientException(SyncopeClientExceptionType.RequiredValuesMissing); - - ex.addElement("resource"); - - compositeErrorException.addException(ex); - - throw compositeErrorException; + throw new NotFoundException("Role '" + roleId + "'"); } List roleMappings = new ArrayList(); @@ -237,7 +195,8 @@ public class ResourceController extends roleMappings.addAll(binder.getSchemaMappingTOs(resource.getMappings())); } - LOG.debug("Mappings found: {} ", roleMappings); + auditManager.audit(Category.resource, ResourceSubCategory.getRoleResourcesMapping, Result.success, + "Found " + roleMappings.size() + " mappings for role " + roleId); return roleMappings; } @@ -245,20 +204,19 @@ public class ResourceController extends @PreAuthorize("hasRole('RESOURCE_GETOBJECT')") @Transactional(readOnly = true) @RequestMapping(method = RequestMethod.GET, value = "/{resourceName}/read/{objectId}") - public ConnObjectTO getObject(final HttpServletResponse response, - @PathVariable("resourceName") String resourceName, @PathVariable("objectId") final String objectId) + public ConnObjectTO getObject(@PathVariable("resourceName") final String resourceName, + @PathVariable("objectId") final String objectId) throws NotFoundException { ExternalResource resource = resourceDAO.find(resourceName); if (resource == null) { - LOG.error("Could not find resource '" + resourceName + "'"); throw new NotFoundException("Resource '" + resourceName + "'"); } final ConnectorFacadeProxy connector = connLoader.getConnector(resource); - final ConnectorObject connectorObject = connector.getObject(ObjectClass.ACCOUNT, new Uid(objectId), connector - .getOperationOptions(resource)); + final ConnectorObject connectorObject = connector.getObject(ObjectClass.ACCOUNT, new Uid(objectId), connector. + getOperationOptions(resource)); if (connectorObject == null) { throw new NotFoundException("Object " + objectId + " not found on resource " + resourceName); @@ -274,6 +232,9 @@ public class ResourceController extends attributes.add(connectorObject.getName()); } + auditManager.audit(Category.resource, ResourceSubCategory.getObject, Result.success, + "Successfully read object " + objectId + " from resource " + resourceName); + return connObjectUtil.getConnObjectTO(connectorObject); } } Modified: incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/RoleController.java URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/RoleController.java?rev=1301670&r1=1301669&r2=1301670&view=diff ============================================================================== --- incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/RoleController.java (original) +++ incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/RoleController.java Fri Mar 16 17:55:21 2012 @@ -33,16 +33,23 @@ import org.springframework.web.bind.anno import org.syncope.client.mod.RoleMod; import org.syncope.client.to.RoleTO; import org.syncope.client.validation.SyncopeClientCompositeErrorException; +import org.syncope.core.audit.AuditManager; import org.syncope.core.persistence.beans.role.SyncopeRole; import org.syncope.core.persistence.dao.RoleDAO; import org.syncope.core.rest.data.RoleDataBinder; import org.syncope.core.util.EntitlementUtil; +import org.syncope.types.AuditElements.Category; +import org.syncope.types.AuditElements.Result; +import org.syncope.types.AuditElements.RoleSubCategory; @Controller @RequestMapping("/role") public class RoleController extends AbstractController { @Autowired + private AuditManager auditManager; + + @Autowired private RoleDAO roleDAO; @Autowired @@ -50,26 +57,20 @@ public class RoleController extends Abst @PreAuthorize("hasRole('ROLE_CREATE')") @RequestMapping(method = RequestMethod.POST, value = "/create") - public RoleTO create(final HttpServletResponse response, final @RequestBody RoleTO roleTO) + public RoleTO create(final HttpServletResponse response, @RequestBody final RoleTO roleTO) throws SyncopeClientCompositeErrorException, UnauthorizedRoleException { LOG.debug("Role create called with parameters {}", roleTO); Set allowedRoleIds = EntitlementUtil.getRoleIds(EntitlementUtil.getOwnedEntitlementNames()); if (roleTO.getParent() != 0 && !allowedRoleIds.contains(roleTO.getParent())) { - throw new UnauthorizedRoleException(roleTO.getParent()); } - SyncopeRole role; - try { - role = roleDataBinder.create(roleTO); - } catch (SyncopeClientCompositeErrorException e) { - LOG.error("Could not create for " + roleTO, e); + SyncopeRole role = roleDAO.save(roleDataBinder.create(roleTO)); - throw e; - } - role = roleDAO.save(role); + auditManager.audit(Category.role, RoleSubCategory.create, Result.success, + "Successfully created role: " + role.getId()); response.setStatus(HttpServletResponse.SC_CREATED); return roleDataBinder.getRoleTO(role); @@ -77,7 +78,7 @@ public class RoleController extends Abst @PreAuthorize("hasRole('ROLE_DELETE')") @RequestMapping(method = RequestMethod.DELETE, value = "/delete/{roleId}") - public void delete(@PathVariable("roleId") Long roleId) throws NotFoundException, UnauthorizedRoleException { + public void delete(@PathVariable("roleId") final Long roleId) throws NotFoundException, UnauthorizedRoleException { SyncopeRole role = roleDAO.find(roleId); if (role == null) { @@ -89,6 +90,9 @@ public class RoleController extends Abst throw new UnauthorizedRoleException(role.getId()); } + auditManager.audit(Category.role, RoleSubCategory.delete, Result.success, + "Successfully deleted role: " + role.getId()); + roleDAO.delete(roleId); } @@ -100,32 +104,42 @@ public class RoleController extends Abst roleTOs.add(roleDataBinder.getRoleTO(role)); } + auditManager.audit(Category.role, RoleSubCategory.list, Result.success, + "Successfully listed all roles: " + roleTOs.size()); + return roleTOs; } @PreAuthorize("hasRole('ROLE_READ')") @RequestMapping(method = RequestMethod.GET, value = "/parent/{roleId}") - public RoleTO parent(@PathVariable("roleId") Long roleId) throws NotFoundException, UnauthorizedRoleException { + public RoleTO parent(@PathVariable("roleId") final Long roleId) + throws NotFoundException, UnauthorizedRoleException { SyncopeRole role = roleDAO.find(roleId); if (role == null) { - throw new NotFoundException("Role " + String.valueOf(roleId)); + throw new NotFoundException("Role " + roleId); } Set allowedRoleIds = EntitlementUtil.getRoleIds(EntitlementUtil.getOwnedEntitlementNames()); if (role.getParent() != null && !allowedRoleIds.contains(role.getParent().getId())) { - throw new UnauthorizedRoleException(role.getParent().getId()); } - return role.getParent() == null + RoleTO result = role.getParent() == null ? null : roleDataBinder.getRoleTO(role.getParent()); + + auditManager.audit(Category.role, RoleSubCategory.parent, Result.success, + result == null + ? "Role " + role.getId() + " is a root role" + : "Found parent for role " + role.getId() + ": " + result.getId()); + + return result; } @PreAuthorize("hasRole('ROLE_READ')") @RequestMapping(method = RequestMethod.GET, value = "/children/{roleId}") - public List children(@PathVariable("roleId") Long roleId) { + public List children(@PathVariable("roleId") final Long roleId) { Set allowedRoleIds = EntitlementUtil.getRoleIds(EntitlementUtil.getOwnedEntitlementNames()); List roles = roleDAO.findChildren(roleId); @@ -136,12 +150,16 @@ public class RoleController extends Abst } } + auditManager.audit(Category.role, RoleSubCategory.children, Result.success, + "Found " + roleTOs.size() + " children of role " + roleId); + return roleTOs; } @PreAuthorize("hasRole('ROLE_READ')") @RequestMapping(method = RequestMethod.GET, value = "/read/{roleId}") - public RoleTO read(@PathVariable("roleId") Long roleId) throws NotFoundException, UnauthorizedRoleException { + public RoleTO read(@PathVariable("roleId") final Long roleId) + throws NotFoundException, UnauthorizedRoleException { SyncopeRole role = roleDAO.find(roleId); if (role == null) { @@ -153,12 +171,15 @@ public class RoleController extends Abst throw new UnauthorizedRoleException(role.getId()); } + auditManager.audit(Category.role, RoleSubCategory.read, Result.success, + "Successfully read role: " + role.getId()); + return roleDataBinder.getRoleTO(role); } @PreAuthorize("hasRole('ROLE_UPDATE')") @RequestMapping(method = RequestMethod.POST, value = "/update") - public RoleTO update(@RequestBody RoleMod roleMod) throws NotFoundException, UnauthorizedRoleException { + public RoleTO update(@RequestBody final RoleMod roleMod) throws NotFoundException, UnauthorizedRoleException { LOG.debug("Role update called with parameter {}", roleMod); @@ -175,6 +196,9 @@ public class RoleController extends Abst roleDataBinder.update(role, roleMod); role = roleDAO.save(role); + auditManager.audit(Category.role, RoleSubCategory.update, Result.success, + "Successfully updated role: " + role.getId()); + return roleDataBinder.getRoleTO(role); } } Modified: incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/SchemaController.java URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/SchemaController.java?rev=1301670&r1=1301669&r2=1301670&view=diff ============================================================================== --- incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/SchemaController.java (original) +++ incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/SchemaController.java Fri Mar 16 17:55:21 2012 @@ -30,16 +30,23 @@ import org.springframework.web.bind.anno import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.syncope.client.to.SchemaTO; -import org.syncope.core.rest.data.SchemaDataBinder; +import org.syncope.core.audit.AuditManager; import org.syncope.core.persistence.beans.AbstractSchema; import org.syncope.core.persistence.dao.SchemaDAO; +import org.syncope.core.rest.data.SchemaDataBinder; import org.syncope.core.util.AttributableUtil; +import org.syncope.types.AuditElements.Category; +import org.syncope.types.AuditElements.SchemaSubCategory; +import org.syncope.types.AuditElements.Result; @Controller @RequestMapping("/schema") public class SchemaController extends AbstractController { @Autowired + private AuditManager auditManager; + + @Autowired private SchemaDAO schemaDAO; @Autowired @@ -54,6 +61,9 @@ public class SchemaController extends Ab schemaDataBinder.create(schemaTO, schema); schema = schemaDAO.save(schema); + auditManager.audit(Category.schema, SchemaSubCategory.create, Result.success, + "Successfully created schema: " + kind + "/" + schema.getName()); + response.setStatus(HttpServletResponse.SC_CREATED); return schemaDataBinder.getSchemaTO(schema, getAttributableUtil(kind)); } @@ -66,12 +76,13 @@ public class SchemaController extends Ab Class reference = getAttributableUtil(kind).schemaClass(); AbstractSchema schema = schemaDAO.find(schemaName, reference); if (schema == null) { - LOG.error("Could not find schema '" + schemaName + "'"); - - throw new NotFoundException(schemaName); + throw new NotFoundException("Schema '" + schemaName + "'"); } schemaDAO.delete(schemaName, getAttributableUtil(kind)); + + auditManager.audit(Category.schema, SchemaSubCategory.delete, Result.success, + "Successfully deleted schema: " + kind + "/" + schema.getName()); } @RequestMapping(method = RequestMethod.GET, value = "/{kind}/list") @@ -84,6 +95,9 @@ public class SchemaController extends Ab schemaTOs.add(schemaDataBinder.getSchemaTO(schema, attributableUtil)); } + auditManager.audit(Category.schema, SchemaSubCategory.list, Result.success, + "Successfully listed all schemas: " + kind + "/" + schemaTOs.size()); + return schemaTOs; } @@ -95,10 +109,12 @@ public class SchemaController extends Ab AttributableUtil attributableUtil = getAttributableUtil(kind); AbstractSchema schema = schemaDAO.find(schemaName, attributableUtil.schemaClass()); if (schema == null) { - LOG.error("Could not find schema '" + schemaName + "'"); throw new NotFoundException("Schema '" + schemaName + "'"); } + auditManager.audit(Category.schema, SchemaSubCategory.read, Result.success, + "Successfully read schema: " + kind + "/" + schema.getName()); + return schemaDataBinder.getSchemaTO(schema, attributableUtil); } @@ -110,13 +126,15 @@ public class SchemaController extends Ab AttributableUtil attributableUtil = getAttributableUtil(kind); AbstractSchema schema = schemaDAO.find(schemaTO.getName(), attributableUtil.schemaClass()); if (schema == null) { - LOG.error("Could not find schema '" + schemaTO.getName() + "'"); throw new NotFoundException("Schema '" + schemaTO.getName() + "'"); } schemaDataBinder.update(schemaTO, schema, attributableUtil); schema = schemaDAO.save(schema); + auditManager.audit(Category.schema, SchemaSubCategory.update, Result.success, + "Successfully updated schema: " + kind + "/" + schema.getName()); + return schemaDataBinder.getSchemaTO(schema, attributableUtil); } } Modified: incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/TaskController.java URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/TaskController.java?rev=1301670&r1=1301669&r2=1301670&view=diff ============================================================================== --- incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/TaskController.java (original) +++ incubator/syncope/trunk/core/src/main/java/org/syncope/core/rest/controller/TaskController.java Fri Mar 16 17:55:21 2012 @@ -52,6 +52,7 @@ import org.syncope.client.to.TaskExecTO; import org.syncope.client.to.TaskTO; import org.syncope.client.validation.SyncopeClientCompositeErrorException; import org.syncope.client.validation.SyncopeClientException; +import org.syncope.core.audit.AuditManager; import org.syncope.core.init.JobInstanceLoader; import org.syncope.core.notification.NotificationManager; import org.syncope.core.persistence.beans.NotificationTask; @@ -69,6 +70,9 @@ import org.syncope.core.scheduling.Repor import org.syncope.core.scheduling.SyncJob; import org.syncope.core.scheduling.SyncJobActions; import org.syncope.core.util.TaskUtil; +import org.syncope.types.AuditElements.Category; +import org.syncope.types.AuditElements.Result; +import org.syncope.types.AuditElements.TaskSubCategory; import org.syncope.types.PropagationMode; import org.syncope.types.PropagationTaskExecStatus; import org.syncope.types.SyncopeClientExceptionType; @@ -78,6 +82,9 @@ import org.syncope.types.SyncopeClientEx public class TaskController extends AbstractController { @Autowired + private AuditManager auditManager; + + @Autowired private TaskDAO taskDAO; @Autowired @@ -126,13 +133,17 @@ public class TaskController extends Abst } catch (Exception e) { LOG.error("While registering quartz job for task " + task.getId(), e); - SyncopeClientCompositeErrorException scce = new SyncopeClientCompositeErrorException(HttpStatus.BAD_REQUEST); + SyncopeClientCompositeErrorException scce = + new SyncopeClientCompositeErrorException(HttpStatus.BAD_REQUEST); SyncopeClientException sce = new SyncopeClientException(SyncopeClientExceptionType.Scheduling); sce.addElement(e.getMessage()); scce.addException(sce); throw scce; } + auditManager.audit(Category.task, TaskSubCategory.create, Result.success, + "Successfully created task: " + task.getId() + "/" + taskUtil); + response.setStatus(HttpServletResponse.SC_CREATED); return binder.getTaskTO(task, taskUtil); } @@ -173,6 +184,9 @@ public class TaskController extends Abst throw scce; } + auditManager.audit(Category.task, TaskSubCategory.update, Result.success, + "Successfully udpated task: " + task.getId() + "/" + taskUtil); + return binder.getTaskTO(task, taskUtil); } @@ -193,6 +207,9 @@ public class TaskController extends Abst taskTOs.add(binder.getTaskTO(task, taskUtil)); } + auditManager.audit(Category.task, TaskSubCategory.list, Result.success, + "Successfully listed all tasks: " + taskTOs.size() + "/" + taskUtil); + return taskTOs; } @@ -209,6 +226,10 @@ public class TaskController extends Abst taskTOs.add(binder.getTaskTO(task, taskUtil)); } + auditManager.audit(Category.task, TaskSubCategory.list, Result.success, + "Successfully listed all tasks (page=" + page + ", size=" + size + "): " + + taskTOs.size() + "/" + taskUtil); + return taskTOs; } @@ -222,6 +243,9 @@ public class TaskController extends Abst executionTOs.add(binder.getTaskExecTO(execution)); } + auditManager.audit(Category.task, TaskSubCategory.listExecutions, Result.success, + "Successfully listed all task executions: " + executionTOs.size() + "/" + kind); + return executionTOs; } @@ -237,8 +261,8 @@ public class TaskController extends Abst ClassMetadata metadata = cachingMetadataReaderFactory.getMetadataReader(resource).getClassMetadata(); try { - Set interfaces = ClassUtils.getAllInterfacesForClassAsSet(ClassUtils.forName(metadata - .getClassName(), ClassUtils.getDefaultClassLoader())); + Set interfaces = ClassUtils.getAllInterfacesForClassAsSet(ClassUtils.forName(metadata. + getClassName(), ClassUtils.getDefaultClassLoader())); if ((interfaces.contains(Job.class) || interfaces.contains(StatefulJob.class)) && !metadata.isAbstract() && !SyncJob.class.getName().equals(metadata.getClassName()) @@ -255,9 +279,10 @@ public class TaskController extends Abst LOG.error("While searching for class implementing {}", Job.class.getName(), e); } - ModelAndView result = new ModelAndView(); - result.addObject(jobClasses); - return result; + auditManager.audit(Category.task, TaskSubCategory.getJobClasses, Result.success, + "Successfully listed all Job classes: " + jobClasses.size()); + + return new ModelAndView().addObject(jobClasses); } @PreAuthorize("hasRole('TASK_LIST')") @@ -271,8 +296,8 @@ public class TaskController extends Abst ClassMetadata metadata = cachingMetadataReaderFactory.getMetadataReader(resource).getClassMetadata(); try { - Set interfaces = ClassUtils.getAllInterfacesForClassAsSet(ClassUtils.forName(metadata - .getClassName(), ClassUtils.getDefaultClassLoader())); + Set interfaces = ClassUtils.getAllInterfacesForClassAsSet(ClassUtils.forName(metadata. + getClassName(), ClassUtils.getDefaultClassLoader())); if (interfaces.contains(SyncJobActions.class) && !metadata.isAbstract()) { jobActionsClasses.add(metadata.getClassName()); @@ -285,9 +310,10 @@ public class TaskController extends Abst LOG.error("While searching for class implementing {}", SyncJobActions.class.getName(), e); } - ModelAndView result = new ModelAndView(); - result.addObject(jobActionsClasses); - return result; + auditManager.audit(Category.task, TaskSubCategory.getJobActionClasses, Result.success, + "Successfully listed all SyncJobActions classes: " + jobActionsClasses.size()); + + return new ModelAndView().addObject(jobActionsClasses); } @PreAuthorize("hasRole('TASK_READ')") @@ -298,20 +324,27 @@ public class TaskController extends Abst if (task == null) { throw new NotFoundException("Task " + taskId); } + TaskUtil taskUtil = getTaskUtil(task); + + auditManager.audit(Category.task, TaskSubCategory.read, Result.success, + "Successfully read task: " + task.getId() + "/" + taskUtil); - return binder.getTaskTO(task, getTaskUtil(task)); + return binder.getTaskTO(task, taskUtil); } @PreAuthorize("hasRole('TASK_READ')") @RequestMapping(method = RequestMethod.GET, value = "/execution/read/{executionId}") public TaskExecTO readExecution(@PathVariable("executionId") final Long executionId) throws NotFoundException { - TaskExec execution = taskExecDAO.find(executionId); - if (execution == null) { + TaskExec taskExec = taskExecDAO.find(executionId); + if (taskExec == null) { throw new NotFoundException("Task execution " + executionId); } - return binder.getTaskExecTO(execution); + auditManager.audit(Category.task, TaskSubCategory.readExecution, Result.success, + "Successfully read task execution: " + taskExec.getId()); + + return binder.getTaskExecTO(taskExec); } @PreAuthorize("hasRole('TASK_EXECUTE')") @@ -323,10 +356,11 @@ public class TaskController extends Abst if (task == null) { throw new NotFoundException("Task " + taskId); } + TaskUtil taskUtil = getTaskUtil(task); TaskExecTO result = null; LOG.debug("Execution started for {}", task); - switch (getTaskUtil(task)) { + switch (taskUtil) { case PROPAGATION: final TaskExec propExec = propagationManager.execute((PropagationTask) task); result = binder.getTaskExecTO(propExec); @@ -340,8 +374,8 @@ public class TaskController extends Abst case SCHED: case SYNC: try { - jobInstanceLoader.registerJob(task, ((SchedTask) task).getJobClassName(), ((SchedTask) task) - .getCronExpression()); + jobInstanceLoader.registerJob(task, ((SchedTask) task).getJobClassName(), ((SchedTask) task). + getCronExpression()); JobDataMap map = new JobDataMap(); map.put(AbstractTaskJob.DRY_RUN_JOBDETAIL_KEY, dryRun); @@ -350,6 +384,9 @@ public class TaskController extends Abst } catch (Exception e) { LOG.error("While executing task {}", task, e); + auditManager.audit(Category.task, TaskSubCategory.execute, Result.failure, + "Could not start execution for task: " + task.getId() + "/" + taskUtil, e); + SyncopeClientCompositeErrorException scce = new SyncopeClientCompositeErrorException( HttpStatus.BAD_REQUEST); SyncopeClientException sce = new SyncopeClientException(SyncopeClientExceptionType.Scheduling); @@ -369,6 +406,9 @@ public class TaskController extends Abst } LOG.debug("Execution finished for {}, {}", task, result); + auditManager.audit(Category.task, TaskSubCategory.execute, Result.success, + "Successfully started execution for task: " + task.getId() + "/" + taskUtil); + return result; } @@ -384,17 +424,17 @@ public class TaskController extends Abst throw new NotFoundException("Task execution " + executionId); } - SyncopeClientException invalidReportException = new SyncopeClientException( + SyncopeClientException sce = new SyncopeClientException( SyncopeClientExceptionType.InvalidPropagationTaskExecReport); TaskUtil taskUtil = getTaskUtil(exec.getTask()); - if (taskUtil != TaskUtil.PROPAGATION) { - invalidReportException.addElement("Task type: " + taskUtil); - } else { + if (TaskUtil.PROPAGATION == taskUtil) { PropagationTask task = (PropagationTask) exec.getTask(); if (task.getPropagationMode() != PropagationMode.TWO_PHASES) { - invalidReportException.addElement("Propagation mode: " + task.getPropagationMode()); + sce.addElement("Propagation mode: " + task.getPropagationMode()); } + } else { + sce.addElement("Task type: " + taskUtil); } switch (status) { @@ -405,15 +445,20 @@ public class TaskController extends Abst case CREATED: case SUBMITTED: case UNSUBMITTED: - invalidReportException.addElement("Execution status to be set: " + status); + sce.addElement("Execution status to be set: " + status); break; default: } - if (!invalidReportException.isEmpty()) { - SyncopeClientCompositeErrorException scce = new SyncopeClientCompositeErrorException(HttpStatus.BAD_REQUEST); - scce.addException(invalidReportException); + if (!sce.isEmpty()) { + SyncopeClientCompositeErrorException scce = + new SyncopeClientCompositeErrorException(HttpStatus.BAD_REQUEST); + scce.addException(sce); + + auditManager.audit(Category.task, TaskSubCategory.report, Result.failure, + "Could not reported execution status: " + exec.getId() + "/" + taskUtil, scce); + throw scce; } @@ -421,36 +466,46 @@ public class TaskController extends Abst exec.setMessage(message); exec = taskExecDAO.save(exec); + auditManager.audit(Category.task, TaskSubCategory.report, Result.success, + "Successfully reported execution status: " + exec.getId() + "/" + taskUtil); + return binder.getTaskExecTO(exec); } @PreAuthorize("hasRole('TASK_DELETE')") @RequestMapping(method = RequestMethod.DELETE, value = "/delete/{taskId}") - public void delete(@PathVariable("taskId") Long taskId) + public void delete(@PathVariable("taskId") final Long taskId) throws NotFoundException, SyncopeClientCompositeErrorException { Task task = taskDAO.find(taskId); if (task == null) { throw new NotFoundException("Task " + taskId); } + TaskUtil taskUtil = getTaskUtil(task); - if (TaskUtil.SCHED == getTaskUtil(task) || TaskUtil.SYNC == getTaskUtil(task)) { + if (TaskUtil.SCHED == taskUtil || TaskUtil.SYNC == taskUtil) { jobInstanceLoader.unregisterJob(task); } taskDAO.delete(task); + + auditManager.audit(Category.task, TaskSubCategory.delete, Result.success, + "Successfully deleted task: " + task.getId() + "/" + taskUtil); } @PreAuthorize("hasRole('TASK_DELETE')") @RequestMapping(method = RequestMethod.DELETE, value = "/execution/delete/{executionId}") - public void deleteExecution(@PathVariable("executionId") Long executionId) + public void deleteExecution(@PathVariable("executionId") final Long executionId) throws NotFoundException, SyncopeClientCompositeErrorException { - TaskExec execution = taskExecDAO.find(executionId); - if (execution == null) { + TaskExec taskExec = taskExecDAO.find(executionId); + if (taskExec == null) { throw new NotFoundException("Task execution " + executionId); } - taskExecDAO.delete(execution); + taskExecDAO.delete(taskExec); + + auditManager.audit(Category.task, TaskSubCategory.deleteExecution, Result.success, + "Successfully deleted task execution: " + taskExec.getId()); } }