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 2012/03/16 18:55:22 UTC

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...

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<? extends Enum<?>> subCategory;
 
-    public enum Result {
+        Category(final Class<? extends Enum<?>> subCategory) {
+            this.subCategory = subCategory;
+        }
 
-        success,
-        failure
+        public Class<? extends Enum> getSubCategory() {
+            return subCategory;
+        }
 
+        public EnumSet<? extends Enum<?>> getSubCategoryElements() {
+            return EnumSet.allOf(getSubCategory());
+        }
     }
 
-    public static EnumSet<? extends Enum> getSubCategories(final Category category) {
-        EnumSet<? extends Enum> 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<DerivedSchemaTO> derivedSchemaTOs = new ArrayList<DerivedSchemaTO>(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 extends PolicyTO, K extends Policy> T update(T policyTO, K policy) {
+    private <T extends PolicyTO, K extends Policy> 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<PolicyTO> listByType(final HttpServletResponse response, @PathVariable("kind") final String kind) {
+    public List<PolicyTO> listByType(@PathVariable("kind") final String kind) {
 
         LOG.debug("Listing policies");
-        List<? extends Policy> policies = policyDAO.find(PolicyType.valueOf(kind.toUpperCase()));
+        List<? extends Policy> policies = policyDAO.find(PolicyType.valueOf(kind.toUpperCase(Locale.ENGLISH)));
 
         final List<PolicyTO> policyTOs = new ArrayList<PolicyTO>();
         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<ResourceTO> list(@RequestParam(required = false, value = "connInstanceId") final Long connInstanceId)
             throws NotFoundException {
 
-        final List<ExternalResource> resources;
+        List<ExternalResource> 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<ResourceTO> 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<SchemaMappingTO> 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<SchemaMappingTO> 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<SchemaMappingTO> roleMappings = new ArrayList<SchemaMappingTO>();
@@ -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<Long> 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<Long> 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<RoleTO> children(@PathVariable("roleId") Long roleId) {
+    public List<RoleTO> children(@PathVariable("roleId") final Long roleId) {
         Set<Long> allowedRoleIds = EntitlementUtil.getRoleIds(EntitlementUtil.getOwnedEntitlementNames());
 
         List<SyncopeRole> 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<Class> interfaces = ClassUtils.getAllInterfacesForClassAsSet(ClassUtils.forName(metadata
-                            .getClassName(), ClassUtils.getDefaultClassLoader()));
+                    Set<Class> 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<Class> interfaces = ClassUtils.getAllInterfacesForClassAsSet(ClassUtils.forName(metadata
-                            .getClassName(), ClassUtils.getDefaultClassLoader()));
+                    Set<Class> 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());
     }
 }