diff --git a/config/alfresco/site-services-context.xml b/config/alfresco/site-services-context.xml index 8d82847d14..f87be402b8 100644 --- a/config/alfresco/site-services-context.xml +++ b/config/alfresco/site-services-context.xml @@ -59,6 +59,18 @@ + + + + + + + + + + + + @@ -77,6 +89,9 @@ ./${spaces.company_home.childname}/st:sites + + + diff --git a/source/java/org/alfresco/repo/site/RoleComparatorImpl.java b/source/java/org/alfresco/repo/site/RoleComparatorImpl.java new file mode 100644 index 0000000000..3bc31457db --- /dev/null +++ b/source/java/org/alfresco/repo/site/RoleComparatorImpl.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2005-2009 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.repo.site; + +import java.util.Comparator; +import java.util.Map; + +/* package scope */class RoleComparatorImpl implements Comparator +{ + private Map rolePrecedence; + + public RoleComparatorImpl() + { + } + + public RoleComparatorImpl(Map rolePrecedence) + { + this.setRolePrecedence(rolePrecedence); + } + + @Override + public int compare(String first, String second) + { + int firstRank = getRolePrecedence().get(first); + int secondRank = getRolePrecedence().get(second); + + return secondRank - firstRank; + } + + public void init() + { + + } + public void setRolePrecedence(Map rolePrecedence) + { + this.rolePrecedence = rolePrecedence; + } + public Map getRolePrecedence() + { + return rolePrecedence; + } +} + + diff --git a/source/java/org/alfresco/repo/site/RoleComparatorImplTest.java b/source/java/org/alfresco/repo/site/RoleComparatorImplTest.java new file mode 100644 index 0000000000..2cdbcbcdc2 --- /dev/null +++ b/source/java/org/alfresco/repo/site/RoleComparatorImplTest.java @@ -0,0 +1,52 @@ +package org.alfresco.repo.site; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.SortedSet; +import java.util.TreeSet; + +import junit.framework.TestCase; + + +public class RoleComparatorImplTest extends TestCase +{ + public void testRoleComparator() + { + Map rolePrecedence = new HashMap(); + rolePrecedence.put("SiteManager", 4); + rolePrecedence.put("SiteCollaborator", 3); + rolePrecedence.put("SiteContributor", 2); + rolePrecedence.put("SiteConsumer", 1); + Comparator roleComparator = new RoleComparatorImpl(rolePrecedence); + + + List roles = new ArrayList(); + roles.add("SiteConsumer"); + assertEquals("SiteConsumer", sort(roles, roleComparator)); + roles.add("SiteConsumer"); + assertEquals("SiteConsumer", sort(roles, roleComparator)); + roles.add("SiteContributor"); + assertEquals("SiteContributor", sort(roles, roleComparator)); + roles.add("SiteConsumer"); + assertEquals("SiteContributor", sort(roles, roleComparator)); + roles.add("SiteManager"); + assertEquals("SiteManager", sort(roles, roleComparator)); + roles.add("SiteCollaborator"); + assertEquals("SiteManager", sort(roles, roleComparator)); + } + + + + private String sort(List list, Comparator comparator) + { + SortedSet sortedRoles = new TreeSet(comparator); + for (String role : list) + { + sortedRoles.add(role); + } + return sortedRoles.first(); + } +} diff --git a/source/java/org/alfresco/repo/site/SiteServiceImpl.java b/source/java/org/alfresco/repo/site/SiteServiceImpl.java index 3565b0c834..58825483b7 100644 --- a/source/java/org/alfresco/repo/site/SiteServiceImpl.java +++ b/source/java/org/alfresco/repo/site/SiteServiceImpl.java @@ -26,12 +26,15 @@ package org.alfresco.repo.site; import java.io.Serializable; import java.util.ArrayList; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.SortedSet; import java.util.StringTokenizer; +import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; import org.alfresco.model.ContentModel; @@ -133,6 +136,7 @@ public class SiteServiceImpl implements SiteService, SiteModel private TenantService tenantService; private TenantAdminService tenantAdminService; private RetryingTransactionHelper retryingTransactionHelper; + private Comparator roleComparator ; /** @@ -1026,6 +1030,11 @@ public class SiteServiceImpl implements SiteService, SiteModel members.put(group, permission); } } + else + { + // No name filter add this group + members.put(group, permission); + } } else { @@ -1102,11 +1111,26 @@ public class SiteServiceImpl implements SiteService, SiteModel List roles = getMembersRoles(shortName, authorityName); if (roles.isEmpty() == false) { - result = roles.get(0); + if(roleComparator != null) + { + // Need to sort the roles into the most important first. + SortedSet sortedRoles = new TreeSet(roleComparator); + for (String role : roles) + { + sortedRoles.add(role); + } + result = sortedRoles.first(); + } + else + { + // don't search on precedence + result = roles.get(0); + } + } return result; } - + public List getMembersRoles(String shortName, String authorityName) { List result = new ArrayList(5); @@ -1126,6 +1150,8 @@ public class SiteServiceImpl implements SiteService, SiteModel * Helper method to get the permission groups for a given authority on a site. * Returns empty List if the user does not have a explicit membership to the site. * + * A user permission will take precedence over a permission obtained via a group. + * * @param siteShortName site short name * @param authorityName authority name * @return List Permission groups, empty list if no explicit membership set @@ -1134,6 +1160,24 @@ public class SiteServiceImpl implements SiteService, SiteModel { List result = new ArrayList(5); Set roles = this.permissionService.getSettablePermissions(SiteModel.TYPE_SITE); + + for (String role : roles) + { + String roleGroup = getSiteRoleGroup(siteShortName, role, true); + Set authorities = this.authorityService.getContainedAuthorities(AuthorityType.USER, roleGroup, true); + if (authorities.contains(authorityName) == true) + { + result.add(roleGroup); + } + } + + // If there are user permissions then they take priority + if(result.size() > 0) + { + return result; + } + + // Now do a deep search through all users and groups for (String role : roles) { String roleGroup = getSiteRoleGroup(siteShortName, role, true); @@ -1549,4 +1593,13 @@ public class SiteServiceImpl implements SiteService, SiteModel return ""; } } + + public void setRoleComparator(Comparator roleComparator) { + this.roleComparator = roleComparator; + } + + public Comparator getRoleComparator() { + return roleComparator; + } + } diff --git a/source/java/org/alfresco/repo/site/SiteServiceImplTest.java b/source/java/org/alfresco/repo/site/SiteServiceImplTest.java index a413590ee2..0a7b7b4061 100644 --- a/source/java/org/alfresco/repo/site/SiteServiceImplTest.java +++ b/source/java/org/alfresco/repo/site/SiteServiceImplTest.java @@ -68,8 +68,11 @@ public class SiteServiceImplTest extends BaseAlfrescoSpringTest private static final String USER_ONE = "UserOne_SiteServiceImplTest"; private static final String USER_TWO = "UserTwo_SiteServiceImplTest"; private static final String USER_THREE = "UserThree_SiteServiceImplTest"; + private static final String USER_FOUR = "UserFour_SiteServiceImplTest"; private static final String GROUP_ONE = "GrpOne_SiteServiceImplTest"; private static final String GROUP_TWO = "GrpTwo_SiteServiceImplTest"; + private static final String GROUP_THREE = "GrpThree_SiteServiceImplTest"; + private static final String GROUP_FOUR = "GrpFour_SiteServiceImplTest"; private SiteService siteService; private ScriptService scriptService; @@ -82,6 +85,8 @@ public class SiteServiceImplTest extends BaseAlfrescoSpringTest private String groupOne; private String groupTwo; + private String groupThree; + private String groupFour; /** * Called during the transaction setup @@ -104,14 +109,24 @@ public class SiteServiceImplTest extends BaseAlfrescoSpringTest createUser(USER_ONE); createUser(USER_TWO); createUser(USER_THREE); + createUser(USER_FOUR); // Create the test groups this.groupOne = this.authorityService.createAuthority(AuthorityType.GROUP, null, GROUP_ONE); this.authorityService.addAuthority(this.groupOne, USER_TWO); + this.groupTwo = this.authorityService.createAuthority(AuthorityType.GROUP, null, GROUP_TWO); this.authorityService.addAuthority(this.groupTwo, USER_TWO); this.authorityService.addAuthority(this.groupTwo, USER_THREE); + + this.groupThree = this.authorityService.createAuthority(AuthorityType.GROUP, null, GROUP_THREE); + this.authorityService.addAuthority(this.groupThree, USER_TWO); + this.authorityService.addAuthority(this.groupThree, USER_THREE); + + this.groupFour = this.authorityService.createAuthority(AuthorityType.GROUP, this.groupThree, GROUP_FOUR); + this.authorityService.addAuthority(this.groupFour, USER_FOUR); + // Set the current authentication this.authenticationComponent.setCurrentUser(USER_ONE); } @@ -683,106 +698,141 @@ public class SiteServiceImplTest extends BaseAlfrescoSpringTest assertEquals("information", siteInfo.getCustomProperties().get(additionalInformationQName)); } + + public void testGroupMembership() + { + // USER_ONE - SiteAdmin + // GROUP_ONE - USER_TWO + // GROUP_TWO - USER_TWO, USER_THREE + + // Create a site as user one + this.siteService.createSite(TEST_SITE_PRESET, "testMembership", TEST_TITLE, TEST_DESCRIPTION, SiteVisibility.PRIVATE); -// TODO MER Temp remove this test - failing. -// public void testGroupMembership() -// { -// // USER_ONE - SiteAdmin -// // GROUP_ONE - USER_TWO -// // GROUP_TWO - USER_TWO, USER_THREE -// -// // Create a site as user one -// this.siteService.createSite(TEST_SITE_PRESET, "testMembership", TEST_TITLE, TEST_DESCRIPTION, SiteVisibility.PRIVATE); -// -// // Get the members of the site and check that user one is a manager -// Map members = this.siteService.listMembers("testMembership", null, null, 0); -// assertNotNull(members); -// assertEquals(1, members.size()); -// assertTrue(members.containsKey(USER_ONE)); -// assertEquals(SiteModel.SITE_MANAGER, members.get(USER_ONE)); -// -// // Add a group -// this.siteService.setMembership("testMembership", this.groupTwo, SiteModel.SITE_CONSUMER); -// // - is the group in the list of all members? -// members = this.siteService.listMembers("testMembership", null, null, 0); -// assertNotNull(members); -// assertEquals(2, members.size()); -// assertTrue(members.containsKey(USER_ONE)); -// assertEquals(SiteModel.SITE_MANAGER, members.get(USER_ONE)); -// assertTrue(members.containsKey(this.groupTwo)); -// assertEquals(SiteModel.SITE_CONSUMER, members.get(this.groupTwo)); -// // - is the user in the expanded list? -// members = this.siteService.listMembers("testMembership", null, null, 0, true); -// assertNotNull(members); -// assertEquals(3, members.size()); -// assertTrue(members.containsKey(USER_ONE)); -// assertEquals(SiteModel.SITE_MANAGER, members.get(USER_ONE)); -// assertTrue(members.containsKey(USER_TWO)); -// assertEquals(SiteModel.SITE_CONSUMER, members.get(USER_TWO)); -// assertTrue(members.containsKey(USER_THREE)); -// assertEquals(SiteModel.SITE_CONSUMER, members.get(USER_THREE)); -// // - is the user a member? -// assertTrue(this.siteService.isMember("testMembership", USER_ONE)); -// assertTrue(this.siteService.isMember("testMembership", USER_TWO)); -// assertTrue(this.siteService.isMember("testMembership", USER_THREE)); -// // - is the group a member? -// assertTrue(this.siteService.isMember("testMembership", this.groupTwo)); -// // - can we get the roles for the various members directly -// assertEquals(SiteModel.SITE_MANAGER, this.siteService.getMembersRole("testMembership", USER_ONE)); -// assertEquals(SiteModel.SITE_CONSUMER, this.siteService.getMembersRole("testMembership", USER_TWO)); -// assertEquals(SiteModel.SITE_CONSUMER, this.siteService.getMembersRole("testMembership", USER_THREE)); -// assertEquals(SiteModel.SITE_CONSUMER, this.siteService.getMembersRole("testMembership", this.groupTwo)); -// -// // Add a group member as an explicit member -// this.siteService.setMembership("testMembership", USER_THREE, SiteModel.SITE_COLLABORATOR); -// // - check the explicit members list -// members = this.siteService.listMembers("testMembership", null, null, 0); -// assertNotNull(members); -// assertEquals(3, members.size()); -// assertTrue(members.containsKey(USER_ONE)); -// assertEquals(SiteModel.SITE_MANAGER, members.get(USER_ONE)); -// assertTrue(members.containsKey(USER_THREE)); -// assertEquals(SiteModel.SITE_COLLABORATOR, members.get(USER_THREE)); -// assertTrue(members.containsKey(this.groupTwo)); -// assertEquals(SiteModel.SITE_CONSUMER, members.get(this.groupTwo)); -// // - check the expanded members list -// members = this.siteService.listMembers("testMembership", null, null, 0, true); -// assertNotNull(members); -// assertEquals(3, members.size()); -// assertTrue(members.containsKey(USER_ONE)); -// assertEquals(SiteModel.SITE_MANAGER, members.get(USER_ONE)); -// assertTrue(members.containsKey(USER_TWO)); -// assertEquals(SiteModel.SITE_CONSUMER, members.get(USER_TWO)); -// assertTrue(members.containsKey(USER_THREE)); -// assertEquals(SiteModel.SITE_COLLABORATOR, members.get(USER_THREE)); -// // - check is member -// assertTrue(this.siteService.isMember("testMembership", USER_ONE)); -// assertTrue(this.siteService.isMember("testMembership", USER_TWO)); -// assertTrue(this.siteService.isMember("testMembership", USER_THREE)); -// // - is the group a member? -// assertTrue(this.siteService.isMember("testMembership", this.groupTwo)); -// // - check get role directly -// assertEquals(SiteModel.SITE_MANAGER, this.siteService.getMembersRole("testMembership", USER_ONE)); -// assertEquals(SiteModel.SITE_CONSUMER, this.siteService.getMembersRole("testMembership", USER_TWO)); -// assertEquals(SiteModel.SITE_COLLABORATOR, this.siteService.getMembersRole("testMembership", USER_THREE)); -// assertEquals(SiteModel.SITE_CONSUMER, this.siteService.getMembersRole("testMembership", this.groupTwo)); -// -// // Check permissions of added group -// -// // Update the permissions of the group -// -// // Add other group with higher role -// // - is group in list? -// // - is new user a member? -// // - does redefined user have highest role? -// -// // Add group user as a specific user with higher role -// // - check that the user's role is higher that the group? -// -// // Add a group with a sub-group -// -// // Remove groups -// } + // Get the members of the site and check that user one is a manager + Map members = this.siteService.listMembers("testMembership", null, null, 0); + assertNotNull(members); + assertEquals(1, members.size()); + assertTrue(members.containsKey(USER_ONE)); + assertEquals(SiteModel.SITE_MANAGER, members.get(USER_ONE)); + + /** + * Test of isMember - ONE is member, TWO and THREE are not + */ + assertTrue(this.siteService.isMember("testMembership", USER_ONE)); + assertTrue(!this.siteService.isMember("testMembership", USER_TWO)); + assertTrue(!this.siteService.isMember("testMembership", USER_THREE)); + + /** + * Add a group (GROUP_TWO) with role consumer + */ + this.siteService.setMembership("testMembership", this.groupTwo, SiteModel.SITE_CONSUMER); + // - is the group in the list of all members? + members = this.siteService.listMembers("testMembership", null, null, 0); + + assertNotNull(members); + assertEquals(2, members.size()); + assertTrue(members.containsKey(USER_ONE)); + assertEquals(SiteModel.SITE_MANAGER, members.get(USER_ONE)); + assertTrue(members.containsKey(this.groupTwo)); + assertEquals(SiteModel.SITE_CONSUMER, members.get(this.groupTwo)); + + // - is the user in the expanded list? + members = this.siteService.listMembers("testMembership", null, null, 0, true); + assertNotNull(members); + assertEquals(3, members.size()); + assertTrue(members.containsKey(USER_ONE)); + assertEquals(SiteModel.SITE_MANAGER, members.get(USER_ONE)); + assertTrue(members.containsKey(USER_TWO)); + assertEquals(SiteModel.SITE_CONSUMER, members.get(USER_TWO)); + assertTrue(members.containsKey(USER_THREE)); + assertEquals(SiteModel.SITE_CONSUMER, members.get(USER_THREE)); + + // - is the user a member? + assertTrue(this.siteService.isMember("testMembership", USER_ONE)); + assertTrue(this.siteService.isMember("testMembership", USER_TWO)); + assertTrue(this.siteService.isMember("testMembership", USER_THREE)); + + // - is the group a member? + assertTrue(this.siteService.isMember("testMembership", this.groupTwo)); + + // - can we get the roles for the various members directly + assertEquals(SiteModel.SITE_MANAGER, this.siteService.getMembersRole("testMembership", USER_ONE)); + assertEquals(SiteModel.SITE_CONSUMER, this.siteService.getMembersRole("testMembership", USER_TWO)); + assertEquals(SiteModel.SITE_CONSUMER, this.siteService.getMembersRole("testMembership", USER_THREE)); + assertEquals(SiteModel.SITE_CONSUMER, this.siteService.getMembersRole("testMembership", this.groupTwo)); + + /** + * Add a group member (USER_THREE) as an explicit member + */ + this.siteService.setMembership("testMembership", USER_THREE, SiteModel.SITE_COLLABORATOR); + // - check the explicit members list + members = this.siteService.listMembers("testMembership", null, null, 0); + assertNotNull(members); + assertEquals(3, members.size()); + assertTrue(members.containsKey(USER_ONE)); + assertEquals(SiteModel.SITE_MANAGER, members.get(USER_ONE)); + assertTrue(members.containsKey(USER_THREE)); + assertEquals(SiteModel.SITE_COLLABORATOR, members.get(USER_THREE)); + assertTrue(members.containsKey(this.groupTwo)); + assertEquals(SiteModel.SITE_CONSUMER, members.get(this.groupTwo)); + // - check the expanded members list + members = this.siteService.listMembers("testMembership", null, null, 0, true); + assertNotNull(members); + assertEquals(3, members.size()); + assertTrue(members.containsKey(USER_ONE)); + assertEquals(SiteModel.SITE_MANAGER, members.get(USER_ONE)); + assertTrue(members.containsKey(USER_TWO)); + assertEquals(SiteModel.SITE_CONSUMER, members.get(USER_TWO)); + assertTrue(members.containsKey(USER_THREE)); + assertEquals(SiteModel.SITE_COLLABORATOR, members.get(USER_THREE)); + + // - check is member + assertTrue(this.siteService.isMember("testMembership", USER_ONE)); + assertTrue(this.siteService.isMember("testMembership", USER_TWO)); + assertTrue(this.siteService.isMember("testMembership", USER_THREE)); + assertTrue(!this.siteService.isMember("testMembership", USER_FOUR)); + + // - is the group a member? + assertTrue(this.siteService.isMember("testMembership", this.groupTwo)); + // - check get role directly + assertEquals(SiteModel.SITE_MANAGER, this.siteService.getMembersRole("testMembership", USER_ONE)); + assertEquals(SiteModel.SITE_CONSUMER, this.siteService.getMembersRole("testMembership", USER_TWO)); + assertEquals(SiteModel.SITE_COLLABORATOR, this.siteService.getMembersRole("testMembership", USER_THREE)); + assertEquals(SiteModel.SITE_CONSUMER, this.siteService.getMembersRole("testMembership", this.groupTwo)); + + // Check permissions of added group + + // Update the permissions of the group + this.siteService.setMembership("testMembership", USER_THREE, SiteModel.SITE_CONTRIBUTOR); + + /** + * Add other group (GROUP_3) with higher (MANAGER) role + * + * - is group in list? + * - is new user a member? + * - does redefined user have highest role? + * USER_TWO should be Manager from group 3 having higher priority than group 2 + * USER_THREE should still be Contributor from explicit membership. + * USER_FOUR should be Manager - from group 4 sub-group + */ + this.siteService.setMembership("testMembership", this.groupThree, SiteModel.SITE_MANAGER); + + assertTrue(this.siteService.isMember("testMembership", USER_ONE)); + assertTrue(this.siteService.isMember("testMembership", USER_TWO)); + assertTrue(this.siteService.isMember("testMembership", USER_THREE)); + assertTrue(this.siteService.isMember("testMembership", USER_FOUR)); + + assertEquals(SiteModel.SITE_MANAGER, this.siteService.getMembersRole("testMembership", USER_ONE)); + assertEquals(SiteModel.SITE_MANAGER, this.siteService.getMembersRole("testMembership", USER_TWO)); + assertEquals(SiteModel.SITE_CONTRIBUTOR, this.siteService.getMembersRole("testMembership", USER_THREE)); + assertEquals(SiteModel.SITE_MANAGER, this.siteService.getMembersRole("testMembership", this.groupThree)); + + // From sub group four + assertEquals(SiteModel.SITE_MANAGER, this.siteService.getMembersRole("testMembership", USER_FOUR)); + + + // Remove groups + } /** * Tests the visibility of a site