diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml
index 978d73d381..4057ea3e2d 100644
--- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml
+++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml
@@ -921,6 +921,7 @@
+
cm:lastThumbnailModification
diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-webscript-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-webscript-context.xml
index c815e3e411..637551ea30 100644
--- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-webscript-context.xml
+++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-webscript-context.xml
@@ -536,6 +536,8 @@
+
+
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/audit/RecordsManagementAuditServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/audit/RecordsManagementAuditServiceImpl.java
index b0b406217c..9e804bc72e 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/audit/RecordsManagementAuditServiceImpl.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/audit/RecordsManagementAuditServiceImpl.java
@@ -40,6 +40,7 @@ import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction;
import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementActionService;
import org.alfresco.module.org_alfresco_module_rm.audit.event.AuditEvent;
+import org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService;
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
import org.alfresco.repo.audit.AuditComponent;
import org.alfresco.repo.audit.model.AuditApplication;
@@ -62,6 +63,7 @@ import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.MLText;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
@@ -98,6 +100,8 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
/** Logger */
private static Log logger = LogFactory.getLog(RecordsManagementAuditServiceImpl.class);
+ private static final String ACCESS_AUDIT_CAPABILITY = "AccessAudit";
+
private static final String KEY_RM_AUDIT_NODE_RECORDS = "RMAUditNodeRecords";
protected static final String RM_AUDIT_EVENT_LOGIN_SUCCESS = "Login.Success";
@@ -179,6 +183,7 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
private RecordsManagementActionService rmActionService;
private FilePlanService filePlanService;
private NamespaceService namespaceService;
+ protected CapabilityService capabilityService;
private boolean shutdown = false;
@@ -270,6 +275,17 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
{
this.namespaceService = namespaceService;
}
+
+ /**
+ * @param capabilityService capability service
+ */
+ public void setCapabilityService(CapabilityService capabilityService)
+ {
+ this.capabilityService = capabilityService;
+ }
+
+
+
/**
* @param ignoredAuditProperties
@@ -904,6 +920,13 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
// Skip it
return true;
}
+
+ if(nodeRef != null && nodeService.exists(nodeRef) &&
+ !AccessStatus.ALLOWED.equals(
+ capabilityService.getCapabilityAccessState(nodeRef, ACCESS_AUDIT_CAPABILITY)))
+ {
+ return true;
+ }
// TODO: Refactor this to use the builder pattern
RecordsManagementAuditEntry entry = new RecordsManagementAuditEntry(
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/AuditLogGet.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/AuditLogGet.java
index 6cf968f99c..3acdbd1197 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/AuditLogGet.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/AuditLogGet.java
@@ -21,9 +21,17 @@ package org.alfresco.module.org_alfresco_module_rm.script;
import java.io.File;
import java.io.IOException;
+import org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditQueryParameters;
+import org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService.ReportFormat;
+import org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService;
+import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
import org.alfresco.repo.web.scripts.content.ContentStreamer;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.security.AccessStatus;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.springframework.extensions.webscripts.Status;
+import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
@@ -39,9 +47,16 @@ public class AuditLogGet extends BaseAuditRetrievalWebScript
private static Log logger = LogFactory.getLog(AuditLogGet.class);
private static final String PARAM_EXPORT = "export";
+ private static final String ACCESS_AUDIT_CAPABILITY = "AccessAudit";
/** Content Streamer */
protected ContentStreamer contentStreamer;
+
+ /** Capability service */
+ protected CapabilityService capabilityService;
+
+ /** File plan service */
+ protected FilePlanService filePlanService;
/**
* @param contentStreamer
@@ -50,6 +65,24 @@ public class AuditLogGet extends BaseAuditRetrievalWebScript
{
this.contentStreamer = contentStreamer;
}
+
+ /**
+ *
+ * @param capabilityService Capability Service
+ */
+ public void setCapabilityService(CapabilityService capabilityService)
+ {
+ this.capabilityService = capabilityService;
+ }
+
+ /**
+ *
+ * @param capabilityService Capability Service
+ */
+ public void setFilePlanService(FilePlanService filePlanService)
+ {
+ this.filePlanService = filePlanService;
+ }
@Override
public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException
@@ -58,8 +91,16 @@ public class AuditLogGet extends BaseAuditRetrievalWebScript
try
{
+
+ RecordsManagementAuditQueryParameters queryParams = parseQueryParameters(req);
+ ReportFormat reportFormat = parseReportFormat(req);
+
+ if( !userCanAccessAudit(queryParams) )
+ {
+ throw new WebScriptException(Status.STATUS_FORBIDDEN, "Access denied because the user does not have the Access Audit capability");
+ }
// parse the parameters and get a file containing the audit trail
- auditTrail = this.rmAuditService.getAuditTrailFile(parseQueryParameters(req), parseReportFormat(req));
+ auditTrail = this.rmAuditService.getAuditTrailFile(queryParams, reportFormat);
if (logger.isDebugEnabled())
{
@@ -101,4 +142,15 @@ public class AuditLogGet extends BaseAuditRetrievalWebScript
}
}
}
+
+ private boolean userCanAccessAudit(RecordsManagementAuditQueryParameters queryParams)
+ {
+ NodeRef targetNode = queryParams.getNodeRef();
+ if( targetNode == null )
+ {
+ targetNode = filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID);
+ }
+ return AccessStatus.ALLOWED.equals(
+ capabilityService.getCapabilityAccessState(targetNode, ACCESS_AUDIT_CAPABILITY));
+ }
}
\ No newline at end of file
diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementAuditServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementAuditServiceImplTest.java
index 65b0cede07..1a9d8f469c 100644
--- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementAuditServiceImplTest.java
+++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementAuditServiceImplTest.java
@@ -141,6 +141,55 @@ public class RecordsManagementAuditServiceImplTest extends BaseRMTestCase
}, ADMIN_USER);
}
+ /**
+ * Test getAuditTrail method to check that deleted items always show in the audit.
+ *
+ * @see RM-2391 (last addressed isue)
+ */
+ public void testGetAuditTrailForDeletedItem()
+ {
+ // We have only one entry for the event "audit.start":
+ List entries = getAuditTrail(1, ADMIN_USER);
+
+ assertEquals(entries.get(0).getEvent(), "audit.start");
+
+ // Event "audit.view" was generated but will be visible on the next call to getAuditTrail().
+
+ // Make a change:
+ updateTitle(filePlan, ADMIN_USER); // event=Update RM Object
+
+ // Show the audit has been updated; at this point we have three entries for the three events up to now:
+ // "audit.start", "audit.view" and "Update RM Object";
+ entries = getAuditTrail(3, ADMIN_USER);
+
+ assertEquals(entries.get(0).getEvent(), "audit.start");
+ assertEquals(entries.get(1).getEvent(), "audit.view");
+ assertEquals(entries.get(2).getEvent(), "Update RM Object");
+
+ // New "audit.view" event was generated - will be visible on next getAuditTrail().
+
+ doTestInTransaction(new Test()
+ {
+ @Override
+ public Void run() throws Exception
+ {
+ nodeService.deleteNode(record);
+ List entries = getAuditTrail(5, ADMIN_USER);
+
+ assertEquals(entries.get(0).getEvent(), "audit.start");
+ assertEquals(entries.get(1).getEvent(), "audit.view");
+ assertEquals(entries.get(2).getEvent(), "Update RM Object");
+ assertEquals(entries.get(3).getEvent(), "audit.view");
+
+ // Show the audit contains a reference to the deleted item:
+ assertEquals(entries.get(4).getEvent(), "Delete RM Object");
+ assertEquals(entries.get(4).getNodeRef(), record);
+
+ return null;
+ }
+ });
+ }
+
/**
* Test getAuditTrail method and parameter filters.
*/
diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/webscript/AuditRestApiTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/webscript/AuditRestApiTest.java
new file mode 100644
index 0000000000..d28c62d790
--- /dev/null
+++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/webscript/AuditRestApiTest.java
@@ -0,0 +1,72 @@
+package org.alfresco.module.org_alfresco_module_rm.test.legacy.webscript;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+
+import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMWebScriptTestCase;
+import org.alfresco.repo.security.authentication.AuthenticationUtil;
+import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.util.GUID;
+import org.springframework.extensions.webscripts.Status;
+import org.springframework.extensions.webscripts.TestWebScriptServer.GetRequest;
+
+
+public class AuditRestApiTest extends BaseRMWebScriptTestCase
+{
+ /** URL for the REST APIs */
+ protected static final String GET_NODE_AUDITLOG_URL_FORMAT = "/api/node/{0}/rmauditlog";
+
+ private static final String USER_WITHOUT_AUDIT_CAPABILITY = GUID.generate();
+
+ private NodeRef record;
+
+ public void testAuditAccessCapability() throws IOException
+ {
+
+ String recordAuditUrl = MessageFormat.format(GET_NODE_AUDITLOG_URL_FORMAT,record.toString().replace("://", "/"));
+
+ sendRequest(new GetRequest(recordAuditUrl), Status.STATUS_OK, AuthenticationUtil.getAdminUserName() );
+
+ sendRequest(new GetRequest(recordAuditUrl), Status.STATUS_FORBIDDEN, USER_WITHOUT_AUDIT_CAPABILITY );
+ }
+
+ @Override
+ protected void setupTestData()
+ {
+ super.setupTestData();
+
+ retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback