diff --git a/source/java/org/alfresco/repo/site/SiteServiceImpl.java b/source/java/org/alfresco/repo/site/SiteServiceImpl.java index 56fabc19d6..215e5532ca 100644 --- a/source/java/org/alfresco/repo/site/SiteServiceImpl.java +++ b/source/java/org/alfresco/repo/site/SiteServiceImpl.java @@ -50,6 +50,8 @@ import org.alfresco.repo.admin.SysAdminParams; import org.alfresco.repo.cache.SimpleCache; import org.alfresco.repo.node.NodeArchiveServicePolicies; import org.alfresco.repo.node.NodeArchiveServicePolicies.BeforePurgeNodePolicy; +import org.alfresco.repo.node.NodeServicePolicies; +import org.alfresco.repo.node.NodeServicePolicies.OnRestoreNodePolicy; import org.alfresco.repo.node.getchildren.FilterProp; import org.alfresco.repo.node.getchildren.FilterPropString; import org.alfresco.repo.node.getchildren.FilterPropString.FilterTypeString; @@ -118,7 +120,7 @@ import org.springframework.extensions.surf.util.ParameterCheck; * * @author Roy Wetherall */ -public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServiceInternal, SiteModel, NodeArchiveServicePolicies.BeforePurgeNodePolicy +public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServiceInternal, SiteModel, NodeArchiveServicePolicies.BeforePurgeNodePolicy, NodeServicePolicies.OnRestoreNodePolicy { /** Logger */ protected static Log logger = LogFactory.getLog(SiteServiceImpl.class); @@ -402,6 +404,10 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic BeforePurgeNodePolicy.QNAME, SiteModel.TYPE_SITE, new JavaBehaviour(this, "beforePurgeNode")); + this.policyComponent.bindClassBehaviour( + OnRestoreNodePolicy.QNAME, + SiteModel.TYPE_SITE, + new JavaBehaviour(this, "onRestoreNode")); } /* (non-Javadoc) @@ -563,6 +569,12 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic */ private void setupSitePermissions( final NodeRef siteNodeRef, final String shortName, final SiteVisibility visibility, final Map> memberships) + { + setupSitePermissions(siteNodeRef, shortName, visibility, memberships, false); + } + + private void setupSitePermissions( + final NodeRef siteNodeRef, final String shortName, final SiteVisibility visibility, final Map> memberships, final boolean ignoreExistingGroups) { // Get the current user final String currentUser = authenticationContext.getCurrentUserName(); @@ -593,14 +605,26 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic // Create the site's groups String siteGroupShortName = getSiteGroup(shortName, false); - String siteGroup = authorityService.createAuthority(AuthorityType.GROUP, siteGroupShortName, + /* MNT-11289 fix - group is probably already exists. we should check it for existence */ + String siteGroup = authorityService.getName(AuthorityType.GROUP, siteGroupShortName); + if (!ignoreExistingGroups || !authorityService.authorityExists(siteGroup)) + { + siteGroup = authorityService.createAuthority(AuthorityType.GROUP, siteGroupShortName, siteGroupShortName, shareZones); + } QName siteType = directNodeService.getType(siteNodeRef); Set permissions = permissionService.getSettablePermissions(siteType); for (String permission : permissions) { // Create a group for the permission String permissionGroupShortName = getSiteRoleGroup(shortName, permission, false); + /* MNT-11289 fix - group is probably already exists. we should check it for existence */ + String authorityName = authorityService.getName(AuthorityType.GROUP, permissionGroupShortName); + if (ignoreExistingGroups && authorityService.authorityExists(authorityName)) + { + continue; + } + String permissionGroup = authorityService.createAuthority(AuthorityType.GROUP, permissionGroupShortName, permissionGroupShortName, shareZones); authorityService.addAuthority(siteGroup, permissionGroup); @@ -646,9 +670,12 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic permissionService.setPermission(siteNodeRef, PermissionService.ALL_AUTHORITIES, PermissionService.READ_PERMISSIONS, true); - if (memberships == null) + + // add the default site manager authority + Set currentManagers = + authorityService.getContainedAuthorities(AuthorityType.USER, getSiteRoleGroup(shortName, SiteModel.SITE_MANAGER, true), false); + if (currentManagers.isEmpty()) { - // add the default site manager authority authorityService.addAuthority(getSiteRoleGroup(shortName, SiteModel.SITE_MANAGER, true), currentUser); } @@ -1820,6 +1847,22 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic return getPagingResults(pagingRequest, results); } + /** + * @see org.alfresco.repo.node.NodeServicePolicies.OnRestoreNodePolicy#onRestoreNode(org.alfresco.service.cmr.repository.ChildAssociationRef) + */ + @SuppressWarnings("unchecked") + @Override + public void onRestoreNode(ChildAssociationRef childAssocRef) + { + // regenerate the groups for the site when it is restored from the Archive store + NodeRef siteRef = childAssocRef.getChildRef(); + setupSitePermissions( + siteRef, + (String)directNodeService.getProperty(siteRef, ContentModel.PROP_NAME), + getSiteVisibility(siteRef), + (Map>)directNodeService.getProperty(siteRef, QName.createQName(null, "memberships")), true); + } + /** * @see org.alfresco.service.cmr.site.SiteService#listMembers(java.lang.String, java.lang.String, java.lang.String, int) */ diff --git a/source/test-java/org/alfresco/repo/site/SiteServiceImplMoreTest.java b/source/test-java/org/alfresco/repo/site/SiteServiceImplMoreTest.java index 24177fd7f3..dde02b3f4f 100644 --- a/source/test-java/org/alfresco/repo/site/SiteServiceImplMoreTest.java +++ b/source/test-java/org/alfresco/repo/site/SiteServiceImplMoreTest.java @@ -194,6 +194,138 @@ public class SiteServiceImplMoreTest } }); } + /** + * This test ensures that site deleted before MNT-10109 fix (i.e. deleted with their associated authorities) could be restored + * with site-groups recreation + * + * @throws Exception + */ + @Test public void deleteSiteDeleteAuthoritiesAndRestoreEnsuringSiteGroupsWasRecreated() throws Exception + { + final String siteShortName = "testsite-" + System.currentTimeMillis(); + final SiteServiceImpl siteServiceImpl = (SiteServiceImpl)SITE_SERVICE; + log.debug("Creating test site called: " + siteShortName); + + // Create site + final TestSiteAndMemberInfo testSiteAndMemberInfo = + perMethodTestSites.createTestSiteWithUserPerRole(siteShortName, "sitePreset", SiteVisibility.PUBLIC, AuthenticationUtil.getAdminUserName()); + + // Delete permissions and site + final Map membersBefore = TRANSACTION_HELPER.doInTransaction(new RetryingTransactionCallback>() + { + public Map execute() throws Throwable + { + NodeRef siteNodeRef = testSiteAndMemberInfo.siteInfo.getNodeRef(); + + Map membersBefore = SITE_SERVICE.listMembers(siteShortName, null, null, 0, true); + log.debug(membersBefore.size() + " members..."); + for (Map.Entry entry : membersBefore.entrySet()) { log.debug(entry); } + + Map> groupsMemberships = new HashMap>(); + + log.debug("About to delete site-related groups."); + // delete authorities + Set permissions = PERMISSION_SERVICE.getSettablePermissions(SiteModel.TYPE_SITE); + for (String permission : permissions) + { + String prefixSiteRoleGroup = siteServiceImpl.getSiteRoleGroup(siteShortName, permission, true); + + Set groupUsers = AUTHORITY_SERVICE.getContainedAuthorities(null, prefixSiteRoleGroup, true); + groupsMemberships.put(prefixSiteRoleGroup, groupUsers); + + AUTHORITY_SERVICE.deleteAuthority(prefixSiteRoleGroup); + } + //emulate onDelete site behavior before MNT-10109 fix + NODE_SERVICE.setProperty(siteNodeRef, QName.createQName(null, "memberships"), (Serializable)groupsMemberships); + log.debug("Site-related groups deleted."); + + log.debug("About to delete site."); + SITE_SERVICE.deleteSite(siteShortName); + log.debug("Site deleted."); + + return membersBefore; + } + }); + + // restore the site + TRANSACTION_HELPER.doInTransaction(new RetryingTransactionCallback() + { + public Void execute() throws Throwable + { + assertThatArchivedNodeExists(testSiteAndMemberInfo.siteInfo.getNodeRef(), "Site node not found in archive."); + + // ensure there are no authorities + Set permissions = PERMISSION_SERVICE.getSettablePermissions(SiteModel.TYPE_SITE); + for (String permission : permissions) + { + String permissionGroupShortName = siteServiceImpl.getSiteRoleGroup(siteShortName, permission, false); + String authorityName = AUTHORITY_SERVICE.getName(AuthorityType.GROUP, permissionGroupShortName); + + assertTrue("Authotiry should not exist : " + authorityName, !AUTHORITY_SERVICE.authorityExists(authorityName)); + } + + log.debug("About to restore site node from archive"); + + final NodeRef archivedSiteNode = NODE_ARCHIVE_SERVICE.getArchivedNode(testSiteAndMemberInfo.siteInfo.getNodeRef()); + RestoreNodeReport report = NODE_ARCHIVE_SERVICE.restoreArchivedNode(archivedSiteNode); + // ...which should work + assertEquals("Failed to restore site from archive", RestoreStatus.SUCCESS, report.getStatus()); + + log.debug("Successfully restored site from arhive."); + + return null; + } + }); + + TRANSACTION_HELPER.doInTransaction(new RetryingTransactionCallback>() + { + public Map execute() throws Throwable + { + // The site itself should have been restored, of course... + assertTrue("The site noderef was not restored as expected", NODE_SERVICE.exists(testSiteAndMemberInfo.siteInfo.getNodeRef())); + + Map members = SITE_SERVICE.listMembers(siteShortName, null, null, 0, true); + assertEquals("Not all member have been restored", membersBefore.size(), members.size()); + log.debug(members.size() + " members..."); + for (Map.Entry entry : SITE_SERVICE.listMembers(siteShortName, null, null, 0, true).entrySet()) { log.debug(entry); } + + // Group authority nodes should be restored or recreated + for (String role : SITE_SERVICE.getSiteRoles()) + { + final String siteGroup = SITE_SERVICE.getSiteRoleGroup(siteShortName, role); + assertTrue("Site group for role " + role + " did not exist after site restoration", + AUTHORITY_SERVICE.authorityExists(siteGroup)); + } + + Set currentManagers = + AUTHORITY_SERVICE.getContainedAuthorities(AuthorityType.USER, siteServiceImpl.getSiteRoleGroup(siteShortName, SiteModel.SITE_MANAGER, true), false); + // ensure that there is at least one site manager + log.debug("Current Managers " + currentManagers); + assertTrue("There should be at least one site manager", !currentManagers.isEmpty()); + + return null; + } + }); + + // remove site completely + TRANSACTION_HELPER.doInTransaction(new RetryingTransactionCallback() + { + public Void execute() throws Throwable + { + log.debug("About to delete site completely."); + SITE_SERVICE.deleteSite(siteShortName); + log.debug("About to purge site from trashcan."); + + // get archive node reference + String storePath = "archive://SpacesStore"; + StoreRef storeRef = new StoreRef(storePath); + NodeRef archivedNodeRef = new NodeRef(storeRef, testSiteAndMemberInfo.siteInfo.getNodeRef().getId()); + NODE_ARCHIVE_SERVICE.purgeArchivedNode(archivedNodeRef); + + return null; + } + }); + } /** * This test ensures that when sites are deleted (moved to the trashcan) and then restored, that the 4 role-based groups are