diff --git a/source/java/org/alfresco/repo/site/SiteServiceImpl.java b/source/java/org/alfresco/repo/site/SiteServiceImpl.java index 22cdd321a5..5688edf7da 100644 --- a/source/java/org/alfresco/repo/site/SiteServiceImpl.java +++ b/source/java/org/alfresco/repo/site/SiteServiceImpl.java @@ -35,6 +35,7 @@ import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.repo.activities.ActivityType; import org.alfresco.repo.security.authentication.AuthenticationComponent; +import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.service.cmr.activities.ActivityService; import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.model.FileInfo; @@ -59,6 +60,8 @@ import org.apache.commons.logging.LogFactory; import org.json.JSONException; import org.json.JSONObject; +import sun.reflect.ReflectionFactory.GetReflectionFactoryAction; + /** * Site Service Implementation. Also bootstraps the site AVM and DM stores. * @@ -476,9 +479,9 @@ public class SiteServiceImpl implements SiteService, SiteModel /** * @see org.alfresco.repo.site.SiteService#removeMembership(java.lang.String, java.lang.String) */ - public void removeMembership(String shortName, String userName) + public void removeMembership(final String shortName, final String userName) { - NodeRef siteNodeRef = getSiteNodeRef(shortName); + final NodeRef siteNodeRef = getSiteNodeRef(shortName); if (siteNodeRef == null) { throw new AlfrescoRuntimeException("Site " + shortName + " does not exist."); @@ -487,8 +490,39 @@ public class SiteServiceImpl implements SiteService, SiteModel // TODO what do we do about the user if they are in a group that has rights to the site? // TODO do not remove the only site manager - // Clear the permissions for the user - this.permissionService.clearPermission(siteNodeRef, userName); + // Determine whether the site is private or not + boolean isPublic = isSitePublic(siteNodeRef); + + // Get the current user + String currentUserName = AuthenticationUtil.getCurrentUserName(); + + // Get the user current role + String role = getMembersRole(shortName, userName); + + // If ... + // -- the site is public and + // -- the user is ourselves and + // -- the users current role is consumer + if (isPublic == true && + currentUserName.equals(userName) == true && + role != null && + role.equals(SiteModel.SITE_CONSUMER) == true) + { + // Run as system user + AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() + { + public Object doWork() throws Exception + { + permissionService.clearPermission(siteNodeRef, userName); + return null; + } + }, AuthenticationUtil.SYSTEM_USER_NAME); + } + else + { + // Clear the permissions for the user + this.permissionService.clearPermission(siteNodeRef, userName); + } if (AuthorityType.getAuthorityType(userName) == AuthorityType.USER) { @@ -504,14 +538,18 @@ public class SiteServiceImpl implements SiteService, SiteModel /** * @see org.alfresco.repo.site.SiteService#setMembership(java.lang.String, java.lang.String, java.lang.String) */ - public void setMembership(String shortName, String userName, String role) + public void setMembership(String shortName, final String userName, final String role) { - NodeRef siteNodeRef = getSiteNodeRef(shortName); + final NodeRef siteNodeRef = getSiteNodeRef(shortName); if (siteNodeRef == null) { throw new AlfrescoRuntimeException("Site " + shortName + " does not exist."); } + // Determine whether the site is private or not + boolean isPublic = isSitePublic(siteNodeRef); + + // Determine whether the user is already a member of the site boolean alreadyMember = false; Set permissions = this.permissionService.getAllSetPermissions(siteNodeRef); for (AccessPermission permission : permissions) @@ -526,11 +564,43 @@ public class SiteServiceImpl implements SiteService, SiteModel // TODO if this is the only site manager do not downgrade their permissions - // Clear any existing permissions - this.permissionService.clearPermission(siteNodeRef, userName); - - // Set the permissions - this.permissionService.setPermission(siteNodeRef, userName, role, true); + // If we are: + // -- refering to a public site and + // -- the role being set is consumer and + // -- the user being added is ourselves and + // -- the member does not already have permissions + // ... then we can set the permissions as system user + String currentUserName = AuthenticationUtil.getCurrentUserName(); + if (isPublic == true && + role.equals(SiteModel.SITE_CONSUMER) == true && + userName.equals(currentUserName) == true && + alreadyMember == false) + { + // Run as system user + AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() + { + public Object doWork() throws Exception + { + // Clear any existing permissions + permissionService.clearPermission(siteNodeRef, userName); + + // Set the permissions + permissionService.setPermission(siteNodeRef, userName, role, true); + + return null; + } + + }, AuthenticationUtil.SYSTEM_USER_NAME); + + } + else + { + // Clear any existing permissions + this.permissionService.clearPermission(siteNodeRef, userName); + + // Set the permissions + this.permissionService.setPermission(siteNodeRef, userName, role, true); + } if (! alreadyMember) { diff --git a/source/java/org/alfresco/repo/site/SiteServiceImplTest.java b/source/java/org/alfresco/repo/site/SiteServiceImplTest.java index 3b1674d7cc..77a3e2bc12 100644 --- a/source/java/org/alfresco/repo/site/SiteServiceImplTest.java +++ b/source/java/org/alfresco/repo/site/SiteServiceImplTest.java @@ -361,6 +361,84 @@ public class SiteServiceImplTest extends BaseAlfrescoSpringTest // TODO .. try and remove the only site manager and should get a failure } + + public void testJoinLeave() + { + // Create a site as user one + this.siteService.createSite(TEST_SITE_PRESET, "testMembership", TEST_TITLE, TEST_DESCRIPTION, true); + this.siteService.createSite(TEST_SITE_PRESET, "testMembershipPrivate", TEST_TITLE, TEST_DESCRIPTION, false); + + // Become user two + TestWithUserUtils.authenticateUser(USER_TWO, "PWD", this.authenticationService, this.authenticationComponent); + + // As user two try and add self as contributor + try + { + this.siteService.setMembership("testMembership", USER_TWO, SiteModel.SITE_COLLABORATOR); + fail("This should have failed because you don't have permissions"); + } + catch (AlfrescoRuntimeException exception) + { + // Ignore because as expected + } + + // As user two try and add self as consumer to public site + this.siteService.setMembership("testMembership", USER_TWO, SiteModel.SITE_CONSUMER); + + // As user two try and add self as consumer to private site + try + { + this.siteService.setMembership("testMembership", USER_TWO, SiteModel.SITE_CONSUMER); + fail("This should have failed because you can't do this to a private site unless you are site manager"); + } + catch (AlfrescoRuntimeException exception) + { + // Ignore because as expected + } + + // As user two try and add user three as a consumer to a public site + try + { + this.siteService.setMembership("testMembership", USER_THREE, SiteModel.SITE_CONSUMER); + fail("This should have failed because you can't add another user as a consumer of a public site"); + } + catch (AlfrescoRuntimeException exception) + { + // Ignore because as expected + } + + + // add some members use in remove tests + TestWithUserUtils.authenticateUser(USER_ONE, "PWD", this.authenticationService, this.authenticationComponent); + this.siteService.setMembership("testMembership", USER_THREE, SiteModel.SITE_COLLABORATOR); + this.siteService.setMembership("testMembershipPrivate", USER_TWO, SiteModel.SITE_CONSUMER); + TestWithUserUtils.authenticateUser(USER_TWO, "PWD", this.authenticationService, this.authenticationComponent); + + // try and remove user two permissions from private site + try + { + this.siteService.removeMembership("testMembershipPrivate", USER_TWO); + fail("Cannot remove a users permissions from a private site"); + } + catch (Exception exception) + { + // Ignore because as expected + } + + // Try and remove user threes membership from public site + try + { + this.siteService.removeMembership("testMembership", USER_THREE); + fail("Cannot remove membership"); + } + catch (Exception exception) + { + // Ignore because as expected + } + + // Try and remove own membership + this.siteService.removeMembership("testMembership", USER_TWO); + } public void testContainer() {