diff --git a/config/alfresco/public-services-security-context.xml b/config/alfresco/public-services-security-context.xml
index e2c0dfce60..1e74305a36 100644
--- a/config/alfresco/public-services-security-context.xml
+++ b/config/alfresco/public-services-security-context.xml
@@ -975,6 +975,7 @@
org.alfresco.service.cmr.site.SiteService.hasCreateSitePermissions=ACL_ALLOW
org.alfresco.service.cmr.site.SiteService.isMember=ACL_ALLOW
org.alfresco.service.cmr.site.SiteService.listMembers=ACL_ALLOW
+ org.alfresco.service.cmr.site.SiteService.listMembersInfo=ACL_ALLOW
org.alfresco.service.cmr.site.SiteService.listSites=ACL_ALLOW,AFTER_ACL_NODE.sys:base.ReadProperties
org.alfresco.service.cmr.site.SiteService.removeMembership=ACL_ALLOW
org.alfresco.service.cmr.site.SiteService.setMembership=ACL_ALLOW
diff --git a/config/alfresco/site-services-context.xml b/config/alfresco/site-services-context.xml
index c1a1519d22..5409b4f5f1 100644
--- a/config/alfresco/site-services-context.xml
+++ b/config/alfresco/site-services-context.xml
@@ -35,6 +35,7 @@
listSites
getSite
listMembers
+ listMembersInfo
getMembersRole
isMember
getContainer
diff --git a/source/java/org/alfresco/repo/site/SiteMemberInfoImpl.java b/source/java/org/alfresco/repo/site/SiteMemberInfoImpl.java
new file mode 100644
index 0000000000..2613d863ee
--- /dev/null
+++ b/source/java/org/alfresco/repo/site/SiteMemberInfoImpl.java
@@ -0,0 +1,89 @@
+
+package org.alfresco.repo.site;
+
+import java.io.Serializable;
+
+import org.alfresco.service.cmr.site.SiteMemberInfo;
+
+/**
+ * Site member's information class
+ *
+ * @author Jamal Kaabi-Mofrad
+ * @since Odin
+ */
+public class SiteMemberInfoImpl implements SiteMemberInfo, Serializable
+{
+ private static final long serialVersionUID = -5902865692214513762L;
+
+ private String memberName;
+
+ private String memberRole;
+
+ private boolean memberOfGroup;
+
+ /**
+ * Constructor
+ *
+ * @param memberName The name of an individual or a group
+ * @param memberRole The role of the individual or group
+ * @param isMemberOfGroup Whether a member belongs to a group with access
+ * rights to the site or not
+ */
+ public SiteMemberInfoImpl(String memberName, String memberRole, boolean isMemberOfGroup)
+ {
+ this.memberName = memberName;
+ this.memberRole = memberRole;
+ this.memberOfGroup = isMemberOfGroup;
+ }
+
+ /**
+ * @see org.alfresco.service.cmr.site.SiteMemberInfo#getMemberName()
+ */
+ @Override
+ public String getMemberName()
+ {
+ return this.memberName;
+ }
+
+ /**
+ * @see org.alfresco.service.cmr.site.SiteMemberInfo#getMemberRole()
+ */
+ @Override
+ public String getMemberRole()
+ {
+ return memberRole;
+ }
+
+ /**
+ * @see org.alfresco.service.cmr.site.SiteMemberInfo#isMemberOfGroup()
+ */
+ @Override
+ public boolean isMemberOfGroup()
+ {
+ return memberOfGroup;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((this.memberName == null) ? 0 : this.memberName.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj) { return true; }
+ if (obj == null) { return false; }
+ if (!(obj instanceof SiteMemberInfoImpl)) { return false; }
+ SiteMemberInfoImpl other = (SiteMemberInfoImpl) obj;
+ if (this.memberName == null)
+ {
+ if (other.memberName != null) { return false; }
+ }
+ else if (!this.memberName.equals(other.memberName)) { return false; }
+ return true;
+ }
+}
diff --git a/source/java/org/alfresco/repo/site/SiteServiceImpl.java b/source/java/org/alfresco/repo/site/SiteServiceImpl.java
index 921b72fd28..116e3ed815 100644
--- a/source/java/org/alfresco/repo/site/SiteServiceImpl.java
+++ b/source/java/org/alfresco/repo/site/SiteServiceImpl.java
@@ -47,9 +47,9 @@ 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;
import org.alfresco.repo.node.getchildren.GetChildrenCannedQuery;
import org.alfresco.repo.node.getchildren.GetChildrenCannedQueryFactory;
-import org.alfresco.repo.node.getchildren.FilterPropString.FilterTypeString;
import org.alfresco.repo.policy.BehaviourFilter;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent;
@@ -78,13 +78,14 @@ import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.AccessPermission;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.AuthorityService;
+import org.alfresco.service.cmr.security.AuthorityService.AuthorityFilter;
import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.cmr.security.NoSuchPersonException;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.security.PublicServiceAccessService;
-import org.alfresco.service.cmr.security.AuthorityService.AuthorityFilter;
import org.alfresco.service.cmr.site.SiteInfo;
+import org.alfresco.service.cmr.site.SiteMemberInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.cmr.site.SiteVisibility;
import org.alfresco.service.cmr.tagging.TaggingService;
@@ -1511,36 +1512,77 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
}
}
+ /**
+ * @see org.alfresco.service.cmr.site.SiteService#listMembersInfo(String,
+ * String, String, int, boolean)
+ */
+ public List listMembersInfo(String shortName, final String nameFilter, final String roleFilter, final int size, final boolean collapseGroups)
+ {
+ // MT share - for activity service system callback
+ if (tenantService.isEnabled()
+ && (AuthenticationUtil.SYSTEM_USER_NAME.equals(AuthenticationUtil
+ .getRunAsUser())) && tenantService.isTenantName(shortName))
+ {
+ final String tenantDomain = tenantService.getDomain(shortName);
+ final String sName = tenantService.getBaseName(shortName, true);
+
+ return AuthenticationUtil.runAs(
+ new AuthenticationUtil.RunAsWork>()
+ {
+ public List doWork() throws Exception
+ {
+ return listMembersInfoImpl(sName, nameFilter, roleFilter, size,
+ collapseGroups);
+ }
+ }, tenantService.getDomainUser(AuthenticationUtil.getSystemUserName(),
+ tenantDomain));
+ }
+ else
+ {
+ return listMembersInfoImpl(shortName, nameFilter, roleFilter, size, collapseGroups);
+ }
+ }
+
private Map listMembersImpl(String shortName, String nameFilter, String roleFilter, int size, boolean collapseGroups)
+ {
+ Map members = new HashMap(32);
+
+ List list = listMembersInfoImpl(shortName, nameFilter, roleFilter, size,
+ collapseGroups);
+ for (SiteMemberInfo info : list)
+ members.put(info.getMemberName(), info.getMemberRole());
+
+ return members;
+ }
+
+ private List listMembersInfoImpl(String shortName, String nameFilter,
+ String roleFilter, int size, boolean collapseGroups)
{
NodeRef siteNodeRef = getSiteNodeRef(shortName);
- if (siteNodeRef == null)
- {
- throw new SiteDoesNotExistException(shortName);
- }
-
+ if (siteNodeRef == null) { throw new SiteDoesNotExistException(shortName); }
+
// Build an array of name filter tokens pre lowercased to test against person properties
// We require that matching people have at least one match against one of these on
- // either their firstname or last name
+ // either their firstname or last name
String nameFilterLower = null;
String[] nameFilters = new String[0];
if (nameFilter != null && nameFilter.length() != 0)
{
StringTokenizer t = new StringTokenizer(nameFilter, " ");
nameFilters = new String[t.countTokens()];
- for (int i=0; t.hasMoreTokens(); i++)
+ for (int i = 0; t.hasMoreTokens(); i++)
{
nameFilters[i] = t.nextToken().toLowerCase();
}
nameFilterLower = nameFilter.toLowerCase();
}
-
- Map members = new HashMap(32);
+
+ List members = new ArrayList(32);
QName siteType = directNodeService.getType(siteNodeRef);
Set permissions = this.permissionService.getSettablePermissions(siteType);
Map groupsToExpand = new HashMap(32);
-
+
AUTHORITY_FIND: for (String permission : permissions)
{
if (roleFilter == null || roleFilter.length() == 0 || roleFilter.equals(permission))
@@ -1551,68 +1593,68 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
{
switch (AuthorityType.getAuthorityType(authority))
{
- case USER:
- boolean addUser = true;
- if (nameFilter != null && nameFilter.length() != 0 && !nameFilter.equals(authority))
- {
- // found a filter - does it match person first/last name?
- addUser = matchPerson(nameFilters, authority);
- }
- if (addUser)
- {
- // Add the user and their permission to the returned map
- members.put(authority, permission);
-
- // break on max size limit reached
- if (members.size() == size) break AUTHORITY_FIND;
- }
- break;
- case GROUP:
- if (collapseGroups)
- {
- if (!groupsToExpand.containsKey(authority))
+ case USER:
+ boolean addUser = true;
+ if (nameFilter != null && nameFilter.length() != 0 && !nameFilter.equals(authority))
{
- groupsToExpand.put(authority, permission);
+ // found a filter - does it match person first/last name?
+ addUser = matchPerson(nameFilters, authority);
}
- }
- else
- {
- if (nameFilter != null && nameFilter.length() != 0)
+ if (addUser)
{
- // found a filter - does it match Group name part?
- if (matchByFilter(authority.substring(GROUP_PREFIX_LENGTH).toLowerCase(), nameFilterLower))
+ // Add the user and their permission to the returned map
+ members.add(new SiteMemberInfoImpl(authority, permission, false));
+
+ // break on max size limit reached
+ if (members.size() == size) break AUTHORITY_FIND;
+ }
+ break;
+ case GROUP:
+ if (collapseGroups)
+ {
+ if (!groupsToExpand.containsKey(authority))
{
- members.put(authority, permission);
- }
- else
- {
- // Does it match on the Group Display Name part instead?
- String displayName = authorityService.getAuthorityDisplayName(authority);
- if(displayName != null && matchByFilter(displayName.toLowerCase(), nameFilterLower))
- {
- members.put(authority, permission);
- }
+ groupsToExpand.put(authority, permission);
}
}
else
{
- // No name filter add this group
- members.put(authority, permission);
+ if (nameFilter != null && nameFilter.length() != 0)
+ {
+ // found a filter - does it match Group name part?
+ if (matchByFilter(authority.substring(GROUP_PREFIX_LENGTH).toLowerCase(), nameFilterLower))
+ {
+ members.add(new SiteMemberInfoImpl(authority, permission, false));
+ }
+ else
+ {
+ // Does it match on the Group Display Name part instead?
+ String displayName = authorityService.getAuthorityDisplayName(authority);
+ if (displayName != null && matchByFilter(displayName.toLowerCase(), nameFilterLower))
+ {
+ members.add(new SiteMemberInfoImpl(authority, permission, false));
+ }
+ }
+ }
+ else
+ {
+ // No name filter add this group
+ members.add(new SiteMemberInfoImpl(authority, permission, false));
+ }
+
+ // break on max size limit reached
+ if (members.size() == size) break AUTHORITY_FIND;
}
-
- // break on max size limit reached
- if (members.size() == size) break AUTHORITY_FIND;
- }
- break;
+ break;
}
}
}
}
-
+
if (collapseGroups)
{
- for (Map.Entry entry : groupsToExpand.entrySet())
- {
+ for (Map.Entry entry : groupsToExpand.entrySet())
+ {
Set subUsers = this.authorityService.getContainedAuthorities(AuthorityType.USER, entry.getKey(), false);
for (String subUser : subUsers)
{
@@ -1624,19 +1666,19 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
}
if (addUser)
{
- // Add the collapsed user into the members list if they do not already appear in the list
- if (members.containsKey(subUser) == false)
+ SiteMemberInfo memberInfo = new SiteMemberInfoImpl(subUser,entry.getValue(), true);
+ // Add the collapsed user into the members list if they do not already appear in the list
+ if (members.contains(memberInfo) == false)
{
- members.put(subUser, entry.getValue());
+ members.add(memberInfo);
}
-
+
// break on max size limit reached
if (members.size() == size) break;
}
}
- }
+ }
}
-
return members;
}
diff --git a/source/java/org/alfresco/repo/site/SiteServiceImplTest.java b/source/java/org/alfresco/repo/site/SiteServiceImplTest.java
index 5d36579bf8..3d8b3e12b7 100644
--- a/source/java/org/alfresco/repo/site/SiteServiceImplTest.java
+++ b/source/java/org/alfresco/repo/site/SiteServiceImplTest.java
@@ -61,6 +61,7 @@ import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.site.SiteInfo;
+import org.alfresco.service.cmr.site.SiteMemberInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.cmr.site.SiteVisibility;
import org.alfresco.service.cmr.tagging.TaggingService;
@@ -2180,4 +2181,59 @@ public class SiteServiceImplTest extends BaseAlfrescoSpringTest
this.scriptService.executeScript(location, model);
}
+ public void testListMembersInfo()
+ {
+ String siteShortName = "testMemberInfo";
+
+ // Create a site as user one
+ this.siteService.createSite(TEST_SITE_PRESET, siteShortName, TEST_TITLE, TEST_DESCRIPTION,
+ SiteVisibility.PRIVATE);
+
+ // Get the members of the site and check that user one is a manager
+ List members = this.siteService.listMembersInfo(siteShortName, null, null, 0, false);
+ assertNotNull(members);
+ assertEquals(1, members.size());
+ SiteMemberInfo user = members.get(0);
+ assertNotNull(user);
+ assertTrue(user.getMemberName().equals(USER_ONE));
+ assertEquals(SiteModel.SITE_MANAGER, user.getMemberRole());
+ assertFalse("USER_ONE is NOT member of any group", user.isMemberOfGroup());
+
+ // GROUP_TWO - USER_TWO, USER_THREE
+ this.siteService.setMembership(siteShortName, this.groupTwo, SiteModel.SITE_COLLABORATOR);
+ this.siteService.setMembership(siteShortName, USER_FOUR, SiteModel.SITE_CONSUMER);
+
+ // Get the members of the site in expanded list
+ members = this.siteService.listMembersInfo(siteShortName, null, null, 0, true);
+ assertNotNull(members);
+ assertEquals(4, members.size());
+ // Get USER_TWO who is a member of group two
+ user = lookupMemberInfoByUserName(members, USER_TWO);
+ assertNotNull(user);
+ assertEquals(SiteModel.SITE_COLLABORATOR, user.getMemberRole());
+ assertTrue("USER_TWO is member of group two", user.isMemberOfGroup());
+ // Get USER_THREE who is a member of group two
+ user = lookupMemberInfoByUserName(members, USER_THREE);
+ assertNotNull(user);
+ assertEquals(SiteModel.SITE_COLLABORATOR, user.getMemberRole());
+ assertTrue("USER_THREE is member of group two", user.isMemberOfGroup());
+ // Get USER_FOUR
+ user = lookupMemberInfoByUserName(members, USER_FOUR);
+ assertNotNull(user);
+ assertEquals(SiteModel.SITE_CONSUMER, user.getMemberRole());
+ assertFalse("USER_FOUR is NOT member of any group", user.isMemberOfGroup());
+ }
+
+ private SiteMemberInfo lookupMemberInfoByUserName(List members, String name)
+ {
+ for (SiteMemberInfo info : members)
+ {
+ if (name.equals(info.getMemberName()))
+ {
+ return info;
+ }
+ }
+ return null;
+ }
+
}
diff --git a/source/java/org/alfresco/service/cmr/site/SiteMemberInfo.java b/source/java/org/alfresco/service/cmr/site/SiteMemberInfo.java
new file mode 100644
index 0000000000..ed0de35fec
--- /dev/null
+++ b/source/java/org/alfresco/service/cmr/site/SiteMemberInfo.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2005-2012 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+
+package org.alfresco.service.cmr.site;
+
+/**
+ * Site member's information. The member can either be an individual or a group.
+ *
+ * @author Jamal Kaabi-Mofrad
+ * @since odin
+ */
+public interface SiteMemberInfo
+{
+
+ /**
+ * Get the member's name. The name can either be the name of an individual
+ * or a group
+ *
+ * @return String member's name
+ */
+ public String getMemberName();
+
+
+ /**
+ * Get the member's role
+ *
+ * @return String member's role
+ */
+ public String getMemberRole();
+
+
+ /**
+ * Indicates whether a member belongs to a group with access rights to the
+ * site or not
+ *
+ * @return true if the member belongs to a group with access
+ * rights, otherwise false
+ */
+ public boolean isMemberOfGroup();
+
+}
diff --git a/source/java/org/alfresco/service/cmr/site/SiteService.java b/source/java/org/alfresco/service/cmr/site/SiteService.java
index a5f7c56437..1466c75aaf 100644
--- a/source/java/org/alfresco/service/cmr/site/SiteService.java
+++ b/source/java/org/alfresco/service/cmr/site/SiteService.java
@@ -246,6 +246,21 @@ public interface SiteService
@NotAuditable
Map listMembers(String shortName, String nameFilter, String roleFilter, int size, boolean collapseGroups);
+ /**
+ * List the members of the site. This includes both users and groups if collapseGroups is set to false, otherwise all
+ * groups that are members are collapsed into their component users and listed.
+ *
+ *
+ * @param shortName site short name
+ * @param nameFilter name filter
+ * @param roleFilter role filter
+ * @param size max results size crop if >0
+ * @param collapseGroups true if collapse member groups into user list, false otherwise
+ * @return List of site authorities’ information objects
+ */
+ @NotAuditable
+ List listMembersInfo(String shortName, String nameFilter, String roleFilter, int size, boolean collapseGroups);
+
/**
* Gets the role of the specified user.
*