mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Fixed AR-598: Restore not working for non-admin user
Fixed AR-579: Node ownership not changing for archived and restored nodes git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2964 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -139,6 +139,10 @@
|
|||||||
<type>d:datetime</type>
|
<type>d:datetime</type>
|
||||||
<mandatory>true</mandatory>
|
<mandatory>true</mandatory>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="sys:archivedOriginalOwner">
|
||||||
|
<type>d:text</type>
|
||||||
|
<mandatory>true</mandatory>
|
||||||
|
</property>
|
||||||
</properties>
|
</properties>
|
||||||
</aspect>
|
</aspect>
|
||||||
<aspect name="sys:archived-assocs">
|
<aspect name="sys:archived-assocs">
|
||||||
|
@@ -44,6 +44,7 @@ public interface ContentModel
|
|||||||
static final QName PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "archivedOriginalParentAssoc");
|
static final QName PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "archivedOriginalParentAssoc");
|
||||||
static final QName PROP_ARCHIVED_BY = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "archivedBy");
|
static final QName PROP_ARCHIVED_BY = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "archivedBy");
|
||||||
static final QName PROP_ARCHIVED_DATE = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "archivedDate");
|
static final QName PROP_ARCHIVED_DATE = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "archivedDate");
|
||||||
|
static final QName PROP_ARCHIVED_ORIGINAL_OWNER = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "archivedOriginalOwner");
|
||||||
static final QName ASPECT_ARCHIVED_ASSOCS = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "archived-assocs");
|
static final QName ASPECT_ARCHIVED_ASSOCS = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "archived-assocs");
|
||||||
static final QName PROP_ARCHIVED_PARENT_ASSOCS = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "archivedParentAssocs");
|
static final QName PROP_ARCHIVED_PARENT_ASSOCS = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "archivedParentAssocs");
|
||||||
static final QName PROP_ARCHIVED_CHILD_ASSOCS = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "archivedChildAssocs");
|
static final QName PROP_ARCHIVED_CHILD_ASSOCS = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "archivedChildAssocs");
|
||||||
|
@@ -37,7 +37,9 @@ import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
|||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.service.cmr.security.AccessStatus;
|
||||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||||
|
import org.alfresco.service.cmr.security.OwnableService;
|
||||||
import org.alfresco.service.cmr.security.PermissionService;
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
@@ -70,6 +72,7 @@ public class ArchiveAndRestoreTest extends TestCase
|
|||||||
private PermissionService permissionService;
|
private PermissionService permissionService;
|
||||||
private AuthenticationComponent authenticationComponent;
|
private AuthenticationComponent authenticationComponent;
|
||||||
private AuthenticationService authenticationService;
|
private AuthenticationService authenticationService;
|
||||||
|
private OwnableService ownableService;
|
||||||
private TransactionService transactionService;
|
private TransactionService transactionService;
|
||||||
|
|
||||||
private UserTransaction txn;
|
private UserTransaction txn;
|
||||||
@@ -104,6 +107,7 @@ public class ArchiveAndRestoreTest extends TestCase
|
|||||||
permissionService = serviceRegistry.getPermissionService();
|
permissionService = serviceRegistry.getPermissionService();
|
||||||
authenticationService = serviceRegistry.getAuthenticationService();
|
authenticationService = serviceRegistry.getAuthenticationService();
|
||||||
authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent");
|
authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent");
|
||||||
|
ownableService = (OwnableService) ctx.getBean("ownableService");
|
||||||
transactionService = serviceRegistry.getTransactionService();
|
transactionService = serviceRegistry.getTransactionService();
|
||||||
|
|
||||||
// Start a transaction
|
// Start a transaction
|
||||||
@@ -138,12 +142,6 @@ public class ArchiveAndRestoreTest extends TestCase
|
|||||||
PermissionService.ALL_PERMISSIONS,
|
PermissionService.ALL_PERMISSIONS,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
// grant everyone rights to the archive store
|
|
||||||
permissionService.setPermission(
|
|
||||||
archiveStoreRootNodeRef,
|
|
||||||
PermissionService.ALL_AUTHORITIES,
|
|
||||||
PermissionService.ALL_PERMISSIONS,
|
|
||||||
true);
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -322,6 +320,17 @@ public class ArchiveAndRestoreTest extends TestCase
|
|||||||
assertEquals("Mapping of archived store is not correct", archiveStoreRootNodeRef, archiveNodeRef);
|
assertEquals("Mapping of archived store is not correct", archiveStoreRootNodeRef, archiveNodeRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testArchivedAspect() throws Exception
|
||||||
|
{
|
||||||
|
// delete 'a'
|
||||||
|
nodeService.deleteNode(a);
|
||||||
|
// check that it has the aspect and that the properties are correct
|
||||||
|
assertTrue("Archived aspect not present", nodeService.hasAspect(a_, ContentModel.ASPECT_ARCHIVED));
|
||||||
|
Map<QName, Serializable> properties = nodeService.getProperties(a_);
|
||||||
|
assertNotNull("Original owner property not present", properties.get(ContentModel.PROP_ARCHIVED_ORIGINAL_OWNER));
|
||||||
|
assertEquals("Original owner property is incorrect", USER_A, properties.get(ContentModel.PROP_ARCHIVED_ORIGINAL_OWNER));
|
||||||
|
}
|
||||||
|
|
||||||
public void testArchiveAndRestoreNodeBB() throws Exception
|
public void testArchiveAndRestoreNodeBB() throws Exception
|
||||||
{
|
{
|
||||||
// delete a child
|
// delete a child
|
||||||
@@ -568,6 +577,10 @@ public class ArchiveAndRestoreTest extends TestCase
|
|||||||
nodeService.deleteNode(b);
|
nodeService.deleteNode(b);
|
||||||
commitAndBeginNewTransaction();
|
commitAndBeginNewTransaction();
|
||||||
|
|
||||||
|
// check that archived nodes are visible
|
||||||
|
verifyNodeExistence(a_, true);
|
||||||
|
verifyNodeExistence(b_, true);
|
||||||
|
|
||||||
nodeArchiveService.purgeAllArchivedNodes(workStoreRef);
|
nodeArchiveService.purgeAllArchivedNodes(workStoreRef);
|
||||||
|
|
||||||
commitAndBeginNewTransaction();
|
commitAndBeginNewTransaction();
|
||||||
@@ -581,35 +594,51 @@ public class ArchiveAndRestoreTest extends TestCase
|
|||||||
verifyNodeExistence(aa_, false);
|
verifyNodeExistence(aa_, false);
|
||||||
verifyNodeExistence(bb_, false);
|
verifyNodeExistence(bb_, false);
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// public void testPermissionsForRestore() throws Exception
|
public void testDeletedOwnership() throws Exception
|
||||||
// {
|
{
|
||||||
// // user A deletes 'a'
|
// check that A is the current owner of 'b'
|
||||||
// authenticationService.authenticate(USER_A, USER_A.toCharArray());
|
String bOwner = ownableService.getOwner(b);
|
||||||
// nodeService.deleteNode(a);
|
assertEquals("User A must own 'b'", USER_A, bOwner);
|
||||||
// // user B deletes 'b'
|
// user B deletes 'b'
|
||||||
// authenticationService.authenticate(USER_B, USER_B.toCharArray());
|
authenticationService.authenticate(USER_B, USER_B.toCharArray());
|
||||||
// nodeService.deleteNode(b);
|
nodeService.deleteNode(b);
|
||||||
//
|
// check that B is the owner of 'b_'
|
||||||
// // user B can't see archived 'a'
|
String b_Owner = ownableService.getOwner(b_);
|
||||||
// List<RestoreNodeReport> restoredByB = nodeArchiveService.restoreAllArchivedNodes(workStoreRef);
|
assertEquals("User B must own 'b_'", USER_B, b_Owner);
|
||||||
// assertEquals("User B should not have seen A's delete", 1, restoredByB.size());
|
}
|
||||||
// }
|
|
||||||
//
|
/**
|
||||||
// /**
|
* Check that node ownership changes correctly
|
||||||
// * Deny the current user the rights to write to the destination location
|
*/
|
||||||
// * and ensure that the use-case is handled properly.
|
public void testPermissionsForRestore() throws Exception
|
||||||
// */
|
{
|
||||||
// public void testPermissionsLackingOnDestination() throws Exception
|
// user A deletes 'a'
|
||||||
// {
|
authenticationService.authenticate(USER_A, USER_A.toCharArray());
|
||||||
// // remove 'b', deny permissions to workspace root and attempt a restore
|
nodeService.deleteNode(a);
|
||||||
// nodeService.deleteNode(b);
|
// user B deletes 'b'
|
||||||
// permissionService.setPermission(workStoreRootNodeRef, USER_B, PermissionService.ADD_CHILDREN, false);
|
authenticationService.authenticate(USER_B, USER_B.toCharArray());
|
||||||
// commitAndBeginNewTransaction();
|
nodeService.deleteNode(b);
|
||||||
//
|
|
||||||
// // the restore of b should fail for user B
|
// user B can't see archived 'a'
|
||||||
// authenticationService.authenticate(USER_B, USER_B.toCharArray());
|
List<RestoreNodeReport> restoredByB = nodeArchiveService.restoreAllArchivedNodes(workStoreRef);
|
||||||
// RestoreNodeReport report = nodeArchiveService.restoreArchivedNode(b_);
|
assertEquals("User B should be able to see only B's delete", 1, restoredByB.size());
|
||||||
// assertEquals("Expected permission denied status", RestoreStatus.FAILURE_PERMISSION, report.getStatus());
|
}
|
||||||
// }
|
|
||||||
|
/**
|
||||||
|
* Deny the current user the rights to write to the destination location
|
||||||
|
* and ensure that the use-case is handled properly.
|
||||||
|
*/
|
||||||
|
public void testPermissionsLackingOnDestination() throws Exception
|
||||||
|
{
|
||||||
|
// remove 'b', deny permissions to workspace root and attempt a restore
|
||||||
|
nodeService.deleteNode(b);
|
||||||
|
permissionService.setPermission(workStoreRootNodeRef, USER_B, PermissionService.ADD_CHILDREN, false);
|
||||||
|
commitAndBeginNewTransaction();
|
||||||
|
|
||||||
|
// the restore of b should fail for user B
|
||||||
|
authenticationService.authenticate(USER_B, USER_B.toCharArray());
|
||||||
|
RestoreNodeReport report = nodeArchiveService.restoreArchivedNode(b_);
|
||||||
|
assertEquals("Expected permission denied status", RestoreStatus.FAILURE_PERMISSION, report.getStatus());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1310,7 +1310,8 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
|||||||
ChildAssoc primaryParentAssoc = nodeDaoService.getPrimaryParentAssoc(node);
|
ChildAssoc primaryParentAssoc = nodeDaoService.getPrimaryParentAssoc(node);
|
||||||
|
|
||||||
// add the aspect
|
// add the aspect
|
||||||
node.getAspects().add(ContentModel.ASPECT_ARCHIVED);
|
Set<QName> aspects = node.getAspects();
|
||||||
|
aspects.add(ContentModel.ASPECT_ARCHIVED);
|
||||||
Map<QName, PropertyValue> properties = node.getProperties();
|
Map<QName, PropertyValue> properties = node.getProperties();
|
||||||
PropertyValue archivedByProperty = makePropertyValue(
|
PropertyValue archivedByProperty = makePropertyValue(
|
||||||
dictionaryService.getProperty(ContentModel.PROP_ARCHIVED_BY),
|
dictionaryService.getProperty(ContentModel.PROP_ARCHIVED_BY),
|
||||||
@@ -1324,6 +1325,21 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
|||||||
dictionaryService.getProperty(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC),
|
dictionaryService.getProperty(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC),
|
||||||
primaryParentAssoc.getChildAssocRef());
|
primaryParentAssoc.getChildAssocRef());
|
||||||
properties.put(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC, archivedPrimaryParentNodeRefProperty);
|
properties.put(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC, archivedPrimaryParentNodeRefProperty);
|
||||||
|
PropertyValue originalOwnerProperty = properties.get(ContentModel.PROP_OWNER);
|
||||||
|
PropertyValue originalCreatorProperty = properties.get(ContentModel.PROP_CREATOR);
|
||||||
|
if (originalOwnerProperty != null || originalCreatorProperty != null)
|
||||||
|
{
|
||||||
|
properties.put(
|
||||||
|
ContentModel.PROP_ARCHIVED_ORIGINAL_OWNER,
|
||||||
|
originalOwnerProperty != null ? originalOwnerProperty : originalCreatorProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
// change the node ownership
|
||||||
|
aspects.add(ContentModel.ASPECT_OWNABLE);
|
||||||
|
PropertyValue newOwnerProperty = makePropertyValue(
|
||||||
|
dictionaryService.getProperty(ContentModel.PROP_ARCHIVED_ORIGINAL_OWNER),
|
||||||
|
AuthenticationUtil.getCurrentUserName());
|
||||||
|
properties.put(ContentModel.PROP_OWNER, newOwnerProperty);
|
||||||
|
|
||||||
// move the node
|
// move the node
|
||||||
NodeRef archiveStoreRootNodeRef = getRootNode(archiveStoreRef);
|
NodeRef archiveStoreRootNodeRef = getRootNode(archiveStoreRef);
|
||||||
@@ -1557,11 +1573,20 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
|||||||
ChildAssociationRef originalPrimaryParentAssocRef = (ChildAssociationRef) makeSerializableValue(
|
ChildAssociationRef originalPrimaryParentAssocRef = (ChildAssociationRef) makeSerializableValue(
|
||||||
dictionaryService.getProperty(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC),
|
dictionaryService.getProperty(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC),
|
||||||
properties.get(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC));
|
properties.get(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC));
|
||||||
|
PropertyValue originalOwnerProperty = properties.get(ContentModel.PROP_ARCHIVED_ORIGINAL_OWNER);
|
||||||
// remove the aspect archived aspect
|
// remove the aspect archived aspect
|
||||||
aspects.remove(ContentModel.ASPECT_ARCHIVED);
|
aspects.remove(ContentModel.ASPECT_ARCHIVED);
|
||||||
properties.remove(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC);
|
properties.remove(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC);
|
||||||
properties.remove(ContentModel.PROP_ARCHIVED_BY);
|
properties.remove(ContentModel.PROP_ARCHIVED_BY);
|
||||||
properties.remove(ContentModel.PROP_ARCHIVED_DATE);
|
properties.remove(ContentModel.PROP_ARCHIVED_DATE);
|
||||||
|
properties.remove(ContentModel.PROP_ARCHIVED_ORIGINAL_OWNER);
|
||||||
|
|
||||||
|
// restore the original ownership
|
||||||
|
if (originalOwnerProperty != null)
|
||||||
|
{
|
||||||
|
aspects.add(ContentModel.ASPECT_OWNABLE);
|
||||||
|
properties.put(ContentModel.PROP_OWNER, originalOwnerProperty);
|
||||||
|
}
|
||||||
|
|
||||||
if (destinationParentNodeRef == null)
|
if (destinationParentNodeRef == null)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user