mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
Merged BRANCHES/V2.2 to BRANCHES/V2.3:
109406: RM-2271 - added the job lock refresh mechanism so that for long running jobs that exceed the locks TTL the lock will be refreshed. 109401: RM-2391 - Added capability checking to the AuditLog Get REST API. Added a unit test. Minor changes on the Share side to forward the forbidden status. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.3@110464 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -535,6 +535,8 @@
|
|||||||
<property name="recordsManagementAuditService" ref="RecordsManagementAuditService"/>
|
<property name="recordsManagementAuditService" ref="RecordsManagementAuditService"/>
|
||||||
<property name="contentStreamer" ref="webscript.content.streamer" />
|
<property name="contentStreamer" ref="webscript.content.streamer" />
|
||||||
<property name="namespaceService" ref="namespaceService" />
|
<property name="namespaceService" ref="namespaceService" />
|
||||||
|
<property name="capabilityService" ref="CapabilityService" />
|
||||||
|
<property name="filePlanService" ref="FilePlanService" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- REST impl for GET Class Definitions for RM/DM -->
|
<!-- REST impl for GET Class Definitions for RM/DM -->
|
||||||
|
@@ -18,8 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.module.org_alfresco_module_rm.job;
|
package org.alfresco.module.org_alfresco_module_rm.job;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
import org.alfresco.repo.lock.JobLockService;
|
import org.alfresco.repo.lock.JobLockService;
|
||||||
|
import org.alfresco.repo.lock.JobLockService.JobLockRefreshCallback;
|
||||||
import org.alfresco.repo.lock.LockAcquisitionException;
|
import org.alfresco.repo.lock.LockAcquisitionException;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||||
@@ -56,6 +59,24 @@ public class RecordsManagementJob implements Job
|
|||||||
return QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, jobName);
|
return QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, jobName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class LockCallback implements JobLockRefreshCallback
|
||||||
|
{
|
||||||
|
final AtomicBoolean running = new AtomicBoolean(true);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isActive()
|
||||||
|
{
|
||||||
|
return running.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void lockReleased()
|
||||||
|
{
|
||||||
|
running.set(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to get the lock. If the lock couldn't be taken, then <tt>null</tt> is returned.
|
* Attempts to get the lock. If the lock couldn't be taken, then <tt>null</tt> is returned.
|
||||||
*
|
*
|
||||||
@@ -97,6 +118,7 @@ public class RecordsManagementJob implements Job
|
|||||||
throw new AlfrescoRuntimeException("Job name has not been specified.");
|
throw new AlfrescoRuntimeException("Job name has not been specified.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final LockCallback lockCallback = new LockCallback();
|
||||||
AuthenticationUtil.runAs(new RunAsWork<Void>()
|
AuthenticationUtil.runAs(new RunAsWork<Void>()
|
||||||
{
|
{
|
||||||
public Void doWork()
|
public Void doWork()
|
||||||
@@ -107,6 +129,7 @@ public class RecordsManagementJob implements Job
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
jobLockService.refreshLock(lockToken, getLockQName(), DEFAULT_TIME, lockCallback);
|
||||||
// do work
|
// do work
|
||||||
jobExecuter.execute();
|
jobExecuter.execute();
|
||||||
}
|
}
|
||||||
@@ -114,6 +137,7 @@ public class RecordsManagementJob implements Job
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
lockCallback.running.set(false);
|
||||||
jobLockService.releaseLock(lockToken, getLockQName());
|
jobLockService.releaseLock(lockToken, getLockQName());
|
||||||
}
|
}
|
||||||
catch (LockAcquisitionException e)
|
catch (LockAcquisitionException e)
|
||||||
|
@@ -21,9 +21,17 @@ package org.alfresco.module.org_alfresco_module_rm.script;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
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.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.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
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.WebScriptRequest;
|
||||||
import org.springframework.extensions.webscripts.WebScriptResponse;
|
import org.springframework.extensions.webscripts.WebScriptResponse;
|
||||||
|
|
||||||
@@ -39,10 +47,17 @@ public class AuditLogGet extends BaseAuditRetrievalWebScript
|
|||||||
private static Log logger = LogFactory.getLog(AuditLogGet.class);
|
private static Log logger = LogFactory.getLog(AuditLogGet.class);
|
||||||
|
|
||||||
private static final String PARAM_EXPORT = "export";
|
private static final String PARAM_EXPORT = "export";
|
||||||
|
private static final String ACCESS_AUDIT_CAPABILITY = "AccessAudit";
|
||||||
|
|
||||||
/** Content Streamer */
|
/** Content Streamer */
|
||||||
protected ContentStreamer contentStreamer;
|
protected ContentStreamer contentStreamer;
|
||||||
|
|
||||||
|
/** Capability service */
|
||||||
|
protected CapabilityService capabilityService;
|
||||||
|
|
||||||
|
/** File plan service */
|
||||||
|
protected FilePlanService filePlanService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param contentStreamer
|
* @param contentStreamer
|
||||||
*/
|
*/
|
||||||
@@ -51,6 +66,24 @@ public class AuditLogGet extends BaseAuditRetrievalWebScript
|
|||||||
this.contentStreamer = contentStreamer;
|
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
|
@Override
|
||||||
public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException
|
public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException
|
||||||
{
|
{
|
||||||
@@ -58,8 +91,16 @@ public class AuditLogGet extends BaseAuditRetrievalWebScript
|
|||||||
|
|
||||||
try
|
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
|
// 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())
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
@@ -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<Object>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public Object execute() throws Throwable
|
||||||
|
{
|
||||||
|
|
||||||
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil
|
||||||
|
.getSystemUserName());
|
||||||
|
|
||||||
|
createUser(USER_WITHOUT_AUDIT_CAPABILITY);
|
||||||
|
|
||||||
|
record = utils.createRecord(recordFolder, GUID.generate());
|
||||||
|
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void tearDownImpl()
|
||||||
|
{
|
||||||
|
super.tearDownImpl();
|
||||||
|
|
||||||
|
deleteUser(USER_WITHOUT_AUDIT_CAPABILITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getRMSiteId()
|
||||||
|
{
|
||||||
|
return filePlanService.DEFAULT_RM_SITE_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -279,7 +279,7 @@ public class BaseRMWebScriptTestCase extends BaseWebScriptTest
|
|||||||
assertNotNull("Could not create base folder", folder);
|
assertNotNull("Could not create base folder", folder);
|
||||||
|
|
||||||
// Create the site
|
// Create the site
|
||||||
siteId = GUID.generate();
|
siteId = getRMSiteId();
|
||||||
siteInfo = siteService.createSite("rm-site-dashboard", siteId, "title", "descrition", SiteVisibility.PUBLIC, RecordsManagementModel.TYPE_RM_SITE);
|
siteInfo = siteService.createSite("rm-site-dashboard", siteId, "title", "descrition", SiteVisibility.PUBLIC, RecordsManagementModel.TYPE_RM_SITE);
|
||||||
filePlan = siteService.getContainer(siteId, RmSiteType.COMPONENT_DOCUMENT_LIBRARY);
|
filePlan = siteService.getContainer(siteId, RmSiteType.COMPONENT_DOCUMENT_LIBRARY);
|
||||||
assertNotNull("Site document library container was not created successfully.", filePlan);
|
assertNotNull("Site document library container was not created successfully.", filePlan);
|
||||||
@@ -383,4 +383,9 @@ public class BaseRMWebScriptTestCase extends BaseWebScriptTest
|
|||||||
authorityService.deleteAuthority(groupName, true);
|
authorityService.deleteAuthority(groupName, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String getRMSiteId()
|
||||||
|
{
|
||||||
|
return GUID.generate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user