mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
RM-3074: Integration tests
* including fix for ghosted records being visible in collab sites
This commit is contained in:
@@ -260,7 +260,8 @@
|
||||
depends-on="rmDestroyRecordsScheduledForDestructionCapability">
|
||||
<property name="capabilityService" ref="CapabilityService" />
|
||||
<property name="recordableVersionService" ref="RecordableVersionService" />
|
||||
<property name="contentDestructionComponent" ref="contentDestructionComponent"/>
|
||||
<property name="contentDestructionComponent" ref="contentDestructionComponent"/>
|
||||
<property name="inplaceRecordService" ref="InplaceRecordService"/>
|
||||
<property name="ghostingEnabled">
|
||||
<value>${rm.ghosting.enabled}</value>
|
||||
</property>
|
||||
|
@@ -36,6 +36,7 @@ import org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.content.ContentDestructionComponent;
|
||||
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinition;
|
||||
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule;
|
||||
import org.alfresco.module.org_alfresco_module_rm.record.InplaceRecordService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionService;
|
||||
import org.alfresco.service.cmr.action.Action;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
@@ -62,6 +63,9 @@ public class DestroyAction extends RMDispositionActionExecuterAbstractBase
|
||||
|
||||
/** Recordable version service */
|
||||
private RecordableVersionService recordableVersionService;
|
||||
|
||||
/** Inplace record service */
|
||||
private InplaceRecordService inplaceRecordService;
|
||||
|
||||
/** Indicates if ghosting is enabled or not */
|
||||
private boolean ghostingEnabled = true;
|
||||
@@ -89,6 +93,14 @@ public class DestroyAction extends RMDispositionActionExecuterAbstractBase
|
||||
{
|
||||
this.recordableVersionService = recordableVersionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param inplaceRecordService inplace record service
|
||||
*/
|
||||
public void setInplaceRecordService(InplaceRecordService inplaceRecordService)
|
||||
{
|
||||
this.inplaceRecordService = inplaceRecordService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ghostingEnabled true if ghosting is enabled, false otherwise
|
||||
@@ -171,6 +183,9 @@ public class DestroyAction extends RMDispositionActionExecuterAbstractBase
|
||||
|
||||
// Add the ghosted aspect
|
||||
getNodeService().addAspect(record, ASPECT_GHOSTED, null);
|
||||
|
||||
// Hide from inplace users to give the impression of destruction
|
||||
inplaceRecordService.hideRecord(record);
|
||||
|
||||
// destroy content
|
||||
contentDestructionComponent.destroyContent(record);
|
||||
|
@@ -103,22 +103,26 @@ public class InplaceRecordServiceImpl extends ServiceBaseImpl implements Inplace
|
||||
{
|
||||
// remove the child association
|
||||
NodeRef originatingLocation = (NodeRef) nodeService.getProperty(nodeRef, PROP_RECORD_ORIGINATING_LOCATION);
|
||||
List<ChildAssociationRef> parentAssocs = nodeService.getParentAssocs(nodeRef);
|
||||
for (ChildAssociationRef childAssociationRef : parentAssocs)
|
||||
|
||||
if (originatingLocation != null)
|
||||
{
|
||||
if (!childAssociationRef.isPrimary() &&
|
||||
childAssociationRef.getParentRef().equals(originatingLocation) &&
|
||||
!nodeService.hasAspect(childAssociationRef.getChildRef(), ASPECT_PENDING_DELETE))
|
||||
List<ChildAssociationRef> parentAssocs = nodeService.getParentAssocs(nodeRef);
|
||||
for (ChildAssociationRef childAssociationRef : parentAssocs)
|
||||
{
|
||||
nodeService.removeChildAssociation(childAssociationRef);
|
||||
break;
|
||||
if (!childAssociationRef.isPrimary() &&
|
||||
childAssociationRef.getParentRef().equals(originatingLocation) &&
|
||||
!nodeService.hasAspect(childAssociationRef.getChildRef(), ASPECT_PENDING_DELETE))
|
||||
{
|
||||
nodeService.removeChildAssociation(childAssociationRef);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// remove the extended security from the node
|
||||
// this prevents the users from continuing to see the record in searchs and other linked locations
|
||||
extendedSecurityService.remove(nodeRef);
|
||||
}
|
||||
|
||||
// remove the extended security from the node
|
||||
// this prevents the users from continuing to see the record in searchs and other linked locations
|
||||
extendedSecurityService.remove(nodeRef);
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
@@ -34,15 +34,20 @@ import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.action.impl.CutOffAction;
|
||||
import org.alfresco.module.org_alfresco_module_rm.action.impl.DeclareRecordAction;
|
||||
import org.alfresco.module.org_alfresco_module_rm.action.impl.DestroyAction;
|
||||
import org.alfresco.module.org_alfresco_module_rm.capability.Capability;
|
||||
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
|
||||
import org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils;
|
||||
import org.alfresco.module.org_alfresco_module_rm.test.util.bdt.BehaviourTest;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.util.GUID;
|
||||
|
||||
/**
|
||||
* In-place record permission integration test.
|
||||
@@ -322,26 +327,253 @@ public class InplaceRecordPermissionTest extends BaseRMTestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a record
|
||||
* Given an inplace record ready for destruction
|
||||
* When it is destroyed
|
||||
* And it's metadata is maintained
|
||||
* Then the inplace users still have access to the meta-data stub
|
||||
* Then the inplace users will no longer see the record
|
||||
*/
|
||||
// TODO
|
||||
public void testDestroyedRecordInplacePermissions()
|
||||
{
|
||||
test()
|
||||
.given()
|
||||
|
||||
// Given that a record is declared by a collaborator
|
||||
.as(dmCollaborator)
|
||||
.perform(() -> recordService.createRecord(filePlan, dmDocument))
|
||||
.expect(true)
|
||||
.from(() -> recordService.isRecord(dmDocument))
|
||||
.because("Document is a record.")
|
||||
|
||||
// And it is filed into the file plan
|
||||
// And eligible for destruction
|
||||
.asAdmin()
|
||||
.perform(() ->
|
||||
{
|
||||
// create record category and disposition schedule
|
||||
NodeRef recordCategory = filePlanService.createRecordCategory(filePlan, GUID.generate());
|
||||
utils.createBasicDispositionSchedule(recordCategory, GUID.generate(), GUID.generate(), true, true);
|
||||
|
||||
// create record folder and file record
|
||||
NodeRef recordFolder = recordFolderService.createRecordFolder(recordCategory, GUID.generate());
|
||||
fileFolderService.move(dmDocument, recordFolder, null);
|
||||
|
||||
// cut off record
|
||||
rmActionService.executeRecordsManagementAction(dmDocument, DeclareRecordAction.NAME);
|
||||
utils.completeEvent(dmDocument, CommonRMTestUtils.DEFAULT_EVENT_NAME);
|
||||
rmActionService.executeRecordsManagementAction(dmDocument, CutOffAction.NAME);
|
||||
})
|
||||
.expect("destroy")
|
||||
.from(() -> dispositionService.getNextDispositionAction(dmDocument).getName())
|
||||
.because("The next action is destroy.")
|
||||
.expect(true)
|
||||
.from(() -> dispositionService.isNextDispositionActionEligible(dmDocument))
|
||||
.because("The next action is eligible.")
|
||||
|
||||
// When the record is destroyed
|
||||
.when(() -> rmActionService.executeRecordsManagementAction(dmDocument, DestroyAction.NAME))
|
||||
|
||||
.then()
|
||||
.expect(true)
|
||||
.from(() -> recordService.isMetadataStub(dmDocument))
|
||||
.because("The record has been destroyed and the meta-stub remains.")
|
||||
|
||||
// Then the collaborator has no permissions or capabilities
|
||||
.as(dmCollaborator)
|
||||
.perform(() ->
|
||||
checkInPlaceAccess(dmDocument,
|
||||
AccessStatus.DENIED, // read record permission
|
||||
AccessStatus.DENIED, // filing permission
|
||||
AccessStatus.DENIED, // view record capability
|
||||
AccessStatus.DENIED, // edit non record metadata capability
|
||||
AccessStatus.DENIED)) // edit record metadata capability
|
||||
|
||||
// And the consumer has no permissions or capabilities
|
||||
.as(dmConsumer)
|
||||
.perform(() ->
|
||||
checkInPlaceAccess(dmDocument,
|
||||
AccessStatus.DENIED, // read record permission
|
||||
AccessStatus.DENIED, // filing permission
|
||||
AccessStatus.DENIED, // view record capability
|
||||
AccessStatus.DENIED, // edit non record metadata capability
|
||||
AccessStatus.DENIED)) // edit record metadata capability
|
||||
|
||||
// And a user that is not in the site has no permissions or capabilities
|
||||
.as(userName)
|
||||
.perform(() ->
|
||||
checkInPlaceAccess(dmDocument,
|
||||
AccessStatus.DENIED, // read record permission
|
||||
AccessStatus.DENIED, // filing permission
|
||||
AccessStatus.DENIED, // view record capability
|
||||
AccessStatus.DENIED, // edit non record metadata capability
|
||||
AccessStatus.DENIED)); // edit record metadata capability
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an inplace user with write access
|
||||
* When a role is added to the inplace writers role
|
||||
* Then then they receive that additional capability on the inplace record
|
||||
* Given an inplace record
|
||||
* And the collaborator has view and edit non-record capability
|
||||
* And doesn't have edit record capability
|
||||
* When we add edit record metadata capability to the extended writer role
|
||||
* Then the collaborator now has edit record metadata capability
|
||||
*/
|
||||
// TODO
|
||||
public void testAddUserToRole()
|
||||
{
|
||||
test()
|
||||
.given()
|
||||
.as(dmCollaborator)
|
||||
|
||||
// Given an inplace record
|
||||
.perform(() -> recordService.createRecord(filePlan, dmDocument))
|
||||
.expect(true)
|
||||
.from(() -> recordService.isRecord(dmDocument))
|
||||
.because("Document is a record.")
|
||||
|
||||
// And the collaborator has view and edit non-record capability
|
||||
// And doesn't have edit record capability
|
||||
.perform(() ->
|
||||
checkInPlaceAccess(dmDocument,
|
||||
AccessStatus.ALLOWED, // read record permission
|
||||
AccessStatus.ALLOWED, // filing permission
|
||||
AccessStatus.ALLOWED, // view record capability
|
||||
AccessStatus.ALLOWED, // edit non record metadata capability
|
||||
AccessStatus.DENIED)) // edit record metadata capability
|
||||
.when()
|
||||
.asAdmin()
|
||||
|
||||
// When we add edit record metadata capability to the extended writer role
|
||||
.perform(() -> filePlanRoleService.updateRole(filePlan,
|
||||
FilePlanRoleService.ROLE_EXTENDED_WRITERS,
|
||||
"",
|
||||
Stream
|
||||
.of(viewRecordsCapability, editNonRecordMetadataCapability, editRecordMetadataCapability)
|
||||
.collect(Collectors.toSet())))
|
||||
|
||||
.then()
|
||||
.as(dmCollaborator)
|
||||
|
||||
// Then the collaborator now has edit record metadata capability
|
||||
.perform(() ->
|
||||
checkInPlaceAccess(dmDocument,
|
||||
AccessStatus.ALLOWED, // read record permission
|
||||
AccessStatus.ALLOWED, // filing permission
|
||||
AccessStatus.ALLOWED, // view record capability
|
||||
AccessStatus.ALLOWED, // edit non record metadata capability
|
||||
AccessStatus.ALLOWED)) // edit record metadata capability
|
||||
;
|
||||
}
|
||||
|
||||
// hide?
|
||||
// TODO
|
||||
/**
|
||||
* Given an inplace record
|
||||
* When the record is hidden
|
||||
* Then the collaborator has no access to the record
|
||||
* And the consumer has no access to the record
|
||||
* And a user that is not in the site has no permissions or capabilities
|
||||
*/
|
||||
public void testNoPermissionsAfterHide()
|
||||
{
|
||||
test()
|
||||
.given()
|
||||
.as(dmCollaborator)
|
||||
|
||||
// Given an inplace record
|
||||
.perform(() -> recordService.createRecord(filePlan, dmDocument))
|
||||
.expect(true)
|
||||
.from(() -> recordService.isRecord(dmDocument))
|
||||
.because("Document is a record.")
|
||||
.when()
|
||||
.asAdmin()
|
||||
|
||||
// When the record is hidden
|
||||
.perform(() -> inplaceRecordService.hideRecord(dmDocument))
|
||||
|
||||
.then()
|
||||
|
||||
// Then the collaborator has no access to the record
|
||||
.as(dmCollaborator)
|
||||
.perform(() ->
|
||||
checkInPlaceAccess(dmDocument,
|
||||
AccessStatus.DENIED, // read record permission
|
||||
AccessStatus.DENIED, // filing permission
|
||||
AccessStatus.DENIED, // view record capability
|
||||
AccessStatus.DENIED, // edit non record metadata capability
|
||||
AccessStatus.DENIED)) // edit record metadata capability
|
||||
|
||||
// And the consumer has no access to the record
|
||||
.as(dmConsumer)
|
||||
.perform(() ->
|
||||
checkInPlaceAccess(dmDocument,
|
||||
AccessStatus.DENIED, // read record permission
|
||||
AccessStatus.DENIED, // filing permission
|
||||
AccessStatus.DENIED, // view record capability
|
||||
AccessStatus.DENIED, // edit non record metadata capability
|
||||
AccessStatus.DENIED)) // edit record metadata capability
|
||||
|
||||
// And a user that is not in the site has no permissions or capabilities
|
||||
.as(userName)
|
||||
.perform(() ->
|
||||
checkInPlaceAccess(dmDocument,
|
||||
AccessStatus.DENIED, // read record permission
|
||||
AccessStatus.DENIED, // filing permission
|
||||
AccessStatus.DENIED, // view record capability
|
||||
AccessStatus.DENIED, // edit non record metadata capability
|
||||
AccessStatus.DENIED)); // edit record metadata capability
|
||||
;
|
||||
}
|
||||
|
||||
// reject?
|
||||
// TODO
|
||||
|
||||
// user added to group ?
|
||||
// TODO
|
||||
/**
|
||||
* Given an inplace record
|
||||
* When the record is rejected
|
||||
* Then the collaborator has no access to the record
|
||||
* And the consumer has no access to the record
|
||||
* And a user that is not in the site has no permissions or capabilities
|
||||
*/
|
||||
public void testNoPermissionsAfterReject()
|
||||
{
|
||||
test()
|
||||
.given()
|
||||
.as(dmCollaborator)
|
||||
|
||||
// Given an inplace record
|
||||
.perform(() -> recordService.createRecord(filePlan, dmDocument))
|
||||
.expect(true)
|
||||
.from(() -> recordService.isRecord(dmDocument))
|
||||
.because("Document is a record.")
|
||||
.when()
|
||||
.asAdmin()
|
||||
|
||||
// When the record is rejected
|
||||
.perform(() -> recordService.rejectRecord(dmDocument, GUID.generate()))
|
||||
|
||||
.then()
|
||||
|
||||
// Then the collaborator has no access to the record
|
||||
.as(dmCollaborator)
|
||||
.perform(() ->
|
||||
checkInPlaceAccess(dmDocument,
|
||||
AccessStatus.DENIED, // read record permission
|
||||
AccessStatus.DENIED, // filing permission
|
||||
AccessStatus.DENIED, // view record capability
|
||||
AccessStatus.DENIED, // edit non record metadata capability
|
||||
AccessStatus.DENIED)) // edit record metadata capability
|
||||
|
||||
// And the consumer has no access to the record
|
||||
.as(dmConsumer)
|
||||
.perform(() ->
|
||||
checkInPlaceAccess(dmDocument,
|
||||
AccessStatus.DENIED, // read record permission
|
||||
AccessStatus.DENIED, // filing permission
|
||||
AccessStatus.DENIED, // view record capability
|
||||
AccessStatus.DENIED, // edit non record metadata capability
|
||||
AccessStatus.DENIED)) // edit record metadata capability
|
||||
|
||||
// And a user that is not in the site has no permissions or capabilities
|
||||
.as(userName)
|
||||
.perform(() ->
|
||||
checkInPlaceAccess(dmDocument,
|
||||
AccessStatus.DENIED, // read record permission
|
||||
AccessStatus.DENIED, // filing permission
|
||||
AccessStatus.DENIED, // view record capability
|
||||
AccessStatus.DENIED, // edit non record metadata capability
|
||||
AccessStatus.DENIED)); // edit record metadata capability
|
||||
;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user