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:
Derek Hulley
2006-05-24 07:13:56 +00:00
parent 47949f8155
commit 8c870f8c34
4 changed files with 97 additions and 38 deletions

View File

@@ -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">

View File

@@ -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");

View File

@@ -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());
}
} }

View File

@@ -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)
{ {