[REPO-5184] [REPO-5185] REST API: Add endpoint to expose the groups of a site (#1041)

* [REPO-5185] REST API: Add endpoint to expose the groups of a site

* fix comments

* * fixed test

* * added isMemberOf group property

* * fixed displayName

* * where class support added

* * rename models

* * fixed java docs

* * fixed braces

* * fxed comments

* fixed test
This commit is contained in:
dhrn
2020-07-09 15:18:59 +05:30
committed by GitHub
parent 6c806a1990
commit c6f5c5876b
13 changed files with 775 additions and 292 deletions

View File

@@ -0,0 +1,70 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* 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 <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.site;
import org.alfresco.service.cmr.site.SiteInfo;
public class AbstractSiteMembership
{
protected final SiteInfo siteInfo;
protected final String id; // contains both userId and authority Id
protected final String role;
public AbstractSiteMembership(SiteInfo siteInfo, String id, String role)
{
if (siteInfo == null)
{
throw new java.lang.IllegalArgumentException();
}
if (id == null)
{
throw new java.lang.IllegalArgumentException("Id required building site membership");
}
if (role == null)
{
throw new java.lang.IllegalArgumentException("Role required building site membership");
}
this.siteInfo = siteInfo;
this.id = id;
this.role = role;
}
public String getId()
{
return id;
}
public SiteInfo getSiteInfo()
{
return siteInfo;
}
public String getRole()
{
return role;
}
}

View File

@@ -0,0 +1,116 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* 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 <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.site;
import org.alfresco.query.AbstractCannedQuery;
import org.alfresco.query.CannedQueryParameters;
import org.alfresco.query.CannedQuerySortDetails;
import org.alfresco.query.CannedQuerySortDetails.SortOrder;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.cmr.site.SiteService.SiteMembersCallback;
import org.alfresco.util.Pair;
import java.util.Set;
import java.util.List;
import java.util.TreeSet;
import java.util.HashSet;
import java.util.ArrayList;
// TODO currently have to read all sites into memory for sorting purposes. Find a way that doesn't
public class SiteGroupCannedQuery extends AbstractCannedQuery<SiteGroupMembership>
{
private AuthorityService authorityService;
private SiteService siteService;
protected SiteGroupCannedQuery(SiteService siteService, AuthorityService authorityService, CannedQueryParameters parameters)
{
super(parameters);
this.authorityService = authorityService;
this.siteService = siteService;
}
@Override
protected List<SiteGroupMembership> queryAndFilter(CannedQueryParameters parameters)
{
SiteMembersCannedQueryParams paramBean = (SiteMembersCannedQueryParams) parameters.getParameterBean();
String siteShortName = paramBean.getShortName();
CannedQuerySortDetails sortDetails = parameters.getSortDetails();
final CQSiteGroupsCallback callback = new CQSiteGroupsCallback(siteShortName, sortDetails.getSortPairs());
siteService.listMembers(siteShortName, null, null, false, true, paramBean.isExpandGroups(), callback);
callback.done();
return callback.getSiteMembers();
}
@Override
protected boolean isApplyPostQuerySorting()
{
// already sorted as a side effect
return false;
}
private class CQSiteGroupsCallback implements SiteMembersCallback
{
private SiteInfo siteInfo;
private Set<SiteGroupMembership> siteGroups;
CQSiteGroupsCallback(String siteShortName, List<Pair<? extends Object, SortOrder>> sortPairs)
{
this.siteInfo = siteService.getSite(siteShortName);
this.siteGroups = sortPairs != null && sortPairs.size() > 0
? new TreeSet<>(SiteGroupMembership.getComparator(sortPairs))
: new HashSet<>();
}
@Override
public void siteMember(String authority, String role)
{
if(authorityService.authorityExists(authority))
{
String displayName = authorityService.getAuthorityDisplayName(authority);
siteGroups.add(new SiteGroupMembership(siteInfo, authority, role, displayName));
}
}
@Override
public boolean isDone()
{
// need to read in all site members for sort
return false;
}
List<SiteGroupMembership> getSiteMembers()
{
return new ArrayList<>(siteGroups);
}
void done() {}
}
}

View File

@@ -0,0 +1,78 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* 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 <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.site;
import org.alfresco.api.AlfrescoPublicApi;
import org.alfresco.query.CannedQuerySortDetails;
import org.alfresco.service.cmr.site.SiteInfo;
import org.alfresco.util.Pair;
import java.util.Comparator;
import java.util.List;
@AlfrescoPublicApi
public class SiteGroupMembership extends AbstractSiteMembership
{
private String displayName;
public SiteGroupMembership(SiteInfo siteInfo, String id, String role, String displayName)
{
super(siteInfo, id, role);
this.displayName = displayName;
}
public String getDisplayName()
{
return displayName;
}
static int compareTo(List<Pair<? extends Object, CannedQuerySortDetails.SortOrder>> sortPairs, SiteGroupMembership o1, SiteGroupMembership o2)
{
String displayName1 = o1.getDisplayName();
String displayName2 = o2.getDisplayName();
String siteRole1 = o1.getRole();
String siteRole2 = o2.getRole();
String shortName1 = o1.getSiteInfo().getShortName();
String shortName2 = o2.getSiteInfo().getShortName();
int groupName = SiteMembershipComparator.safeCompare(displayName1, displayName2);
int siteRole = SiteMembershipComparator.safeCompare(siteRole1, siteRole2);
int siteShortName = SiteMembershipComparator.safeCompare(shortName1, shortName2);
if (siteRole == 0 && siteShortName == 0 && groupName == 0)
return 0;
return SiteMembershipComparator.compareSiteGroupsBody(sortPairs, displayName1, displayName2, siteRole1, siteRole2, groupName, siteRole , 0);
}
static Comparator<SiteGroupMembership> getComparator(List<Pair<?, CannedQuerySortDetails.SortOrder>> sortPairs)
{
return (SiteGroupMembership o1, SiteGroupMembership o2) -> compareTo(sortPairs, o1, o2);
}
}

View File

@@ -1,35 +1,32 @@
/* /*
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited * Copyright (C) 2005 - 2016 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is * the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms: * provided under the following open source license terms:
* *
* Alfresco is free software: you can redistribute it and/or modify * 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 * 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 * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L% * #L%
*/ */
package org.alfresco.repo.site; package org.alfresco.repo.site;
import java.text.Collator;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
@@ -74,13 +71,12 @@ public class SiteMembersCannedQuery extends AbstractCannedQuery<SiteMembership>
SiteMembersCannedQueryParams paramBean = (SiteMembersCannedQueryParams)parameters.getParameterBean(); SiteMembersCannedQueryParams paramBean = (SiteMembersCannedQueryParams)parameters.getParameterBean();
String siteShortName = paramBean.getShortName(); String siteShortName = paramBean.getShortName();
boolean collapseGroups = paramBean.isCollapseGroups();
CannedQuerySortDetails sortDetails = parameters.getSortDetails(); CannedQuerySortDetails sortDetails = parameters.getSortDetails();
List<Pair<? extends Object, SortOrder>> sortPairs = sortDetails.getSortPairs(); List<Pair<? extends Object, SortOrder>> sortPairs = sortDetails.getSortPairs();
final CQSiteMembersCallback callback = new CQSiteMembersCallback(siteShortName, sortPairs); final CQSiteMembersCallback callback = new CQSiteMembersCallback(siteShortName, sortPairs);
siteService.listMembers(siteShortName, null, null, collapseGroups, callback); siteService.listMembers(siteShortName, null, null, true, false, paramBean.isExpandGroups(), callback);
callback.done(); callback.done();
return callback.getSiteMembers(); return callback.getSiteMembers();
@@ -95,19 +91,25 @@ public class SiteMembersCannedQuery extends AbstractCannedQuery<SiteMembership>
private class CQSiteMembersCallback implements SiteMembersCallback private class CQSiteMembersCallback implements SiteMembersCallback
{ {
private String siteShortName;
private SiteInfo siteInfo; private SiteInfo siteInfo;
private Set<SiteMembership> siteMembers; private Set<SiteMembership> siteMembers;
CQSiteMembersCallback(String siteShortName, List<Pair<? extends Object, SortOrder>> sortPairs) CQSiteMembersCallback(String siteShortName, List<Pair<? extends Object, SortOrder>> sortPairs)
{ {
this.siteShortName = siteShortName;
this.siteInfo = siteService.getSite(siteShortName); this.siteInfo = siteService.getSite(siteShortName);
this.siteMembers = sortPairs != null && sortPairs.size() > 0 ? new TreeSet<SiteMembership>(new SiteMembershipComparator(sortPairs, SiteMembershipComparator.Type.MEMBERS)) : new HashSet<SiteMembership>(); this.siteMembers = sortPairs != null && sortPairs.size() > 0
? new TreeSet<SiteMembership>(SiteMembership.getComparator(sortPairs))
: new HashSet<SiteMembership>();
} }
/**
* @deprecated from 7.0.0
*/
@Override @Override
public void siteMember(String authority, String permission) public void siteMember(String authority, String permission) {}
@Override
public void siteMember(String authority, String permission, boolean isMemberOfGroup)
{ {
String firstName = null; String firstName = null;
String lastName = null; String lastName = null;
@@ -115,12 +117,11 @@ public class SiteMembersCannedQuery extends AbstractCannedQuery<SiteMembership>
if(personService.personExists(authority)) if(personService.personExists(authority))
{ {
NodeRef nodeRef = personService.getPerson(authority); NodeRef nodeRef = personService.getPerson(authority);
firstName = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_FIRSTNAME); firstName = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_FIRSTNAME);
lastName = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_LASTNAME); lastName = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_LASTNAME);
} }
SiteMembership siteMember = new SiteMembership(siteInfo, authority, firstName, lastName, permission); siteMembers.add(new SiteMembership(siteInfo, authority, firstName, lastName, permission, isMemberOfGroup));
siteMembers.add(siteMember);
} }
@Override @Override
@@ -131,16 +132,7 @@ public class SiteMembersCannedQuery extends AbstractCannedQuery<SiteMembership>
List<SiteMembership> getSiteMembers() List<SiteMembership> getSiteMembers()
{ {
// "drain" the site memberships into a (sorted) list return new ArrayList<>(siteMembers);
List<SiteMembership> siteMemberships = new ArrayList<SiteMembership>(siteMembers.size());
Iterator<SiteMembership> it = siteMembers.iterator();
while(it.hasNext())
{
siteMemberships.add(it.next());
it.remove();
}
return siteMemberships;
} }
void done() void done()

View File

@@ -1,46 +1,46 @@
/* /*
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited * Copyright (C) 2005 - 2016 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is * the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms: * provided under the following open source license terms:
* *
* Alfresco is free software: you can redistribute it and/or modify * 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 * 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 * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L% * #L%
*/ */
package org.alfresco.repo.site; package org.alfresco.repo.site;
/** /**
* Conveys parameters for the site members canned query. * Conveys parameters for the site members canned query.
* *
* @author steveglover * @author steveglover
* *
*/ */
public class SiteMembersCannedQueryParams public class SiteMembersCannedQueryParams
{ {
private String shortName; private String shortName;
private boolean collapseGroups; final private boolean expandGroups;
public SiteMembersCannedQueryParams(String shortName, boolean collapseGroups) public SiteMembersCannedQueryParams(String shortName, boolean expandGroups)
{ {
super(); super();
this.shortName = shortName; this.shortName = shortName;
this.collapseGroups = collapseGroups; this.expandGroups = expandGroups;
} }
public String getShortName() public String getShortName()
@@ -48,8 +48,8 @@ public class SiteMembersCannedQueryParams
return shortName; return shortName;
} }
public boolean isCollapseGroups() public boolean isExpandGroups()
{ {
return collapseGroups; return expandGroups;
} }
} }

View File

@@ -23,38 +23,36 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L% * #L%
*/ */
package org.alfresco.repo.site; package org.alfresco.repo.site;
import org.alfresco.service.cmr.site.SiteInfo; import org.alfresco.api.AlfrescoPublicApi;
import org.alfresco.service.cmr.site.SiteRole; import org.alfresco.query.CannedQuerySortDetails;
import org.alfresco.service.cmr.site.SiteInfo;
/** import org.alfresco.util.Pair;
* Conveys information for a member of a site.
* import java.util.Comparator;
* @author steveglover import java.util.List;
*
*/ /**
public class SiteMembership * Conveys information for a member of a site.
*
* @author steveglover
*
*/
@AlfrescoPublicApi
public class SiteMembership extends AbstractSiteMembership
{ {
private SiteInfo siteInfo;
private String personId;
private String firstName; private String firstName;
private String lastName; private String lastName;
private String role; private boolean isMemberOfGroup;
public SiteMembership(SiteInfo siteInfo, String personId, String firstName, String lastName, /**
* @deprecated from 7.0.0
*/
public SiteMembership(SiteInfo siteInfo, String id, String firstName, String lastName,
String role) String role)
{ {
super(); super(siteInfo,id, role);
if (siteInfo == null)
{
throw new java.lang.IllegalArgumentException();
}
if (personId == null)
{
throw new java.lang.IllegalArgumentException(
"Person required building site membership of " + siteInfo.getShortName());
}
if (firstName == null) if (firstName == null)
{ {
throw new java.lang.IllegalArgumentException( throw new java.lang.IllegalArgumentException(
@@ -65,49 +63,38 @@ public class SiteMembership
throw new java.lang.IllegalArgumentException( throw new java.lang.IllegalArgumentException(
"LastName required building site membership of " + siteInfo.getShortName()); "LastName required building site membership of " + siteInfo.getShortName());
} }
if (role == null)
{
throw new java.lang.IllegalArgumentException(
"Role required building site membership of " + siteInfo.getShortName());
}
this.siteInfo = siteInfo;
this.personId = personId;
this.firstName = firstName; this.firstName = firstName;
this.lastName = lastName; this.lastName = lastName;
this.role = role;
} }
public SiteMembership(SiteInfo siteInfo, String personId, String role) public SiteMembership(SiteInfo siteInfo, String id, String firstName, String lastName,
String role, boolean isMemberOfGroup)
{ {
super(); super(siteInfo, id, role);
if (siteInfo == null) if (firstName == null)
{
throw new java.lang.IllegalArgumentException();
}
if (personId == null)
{ {
throw new java.lang.IllegalArgumentException( throw new java.lang.IllegalArgumentException(
"Person required building site membership of " + siteInfo.getShortName()); "FirstName required building site membership of " + siteInfo.getShortName());
} }
if (role == null) if (lastName == null)
{ {
throw new java.lang.IllegalArgumentException( throw new java.lang.IllegalArgumentException(
"Role required building site membership of " + siteInfo.getShortName()); "LastName required building site membership of " + siteInfo.getShortName());
} }
this.firstName = firstName;
this.siteInfo = siteInfo; this.lastName = lastName;
this.personId = personId; this.isMemberOfGroup = isMemberOfGroup;
this.role = role;
} }
public SiteInfo getSiteInfo() public SiteMembership(SiteInfo siteInfo, String id, String role)
{ {
return siteInfo; super(siteInfo, id, role);
} }
/** @deprecated from 7.0.0 use getId instead */
public String getPersonId() public String getPersonId()
{ {
return personId; return id;
} }
public String getFirstName() public String getFirstName()
@@ -120,9 +107,9 @@ public class SiteMembership
return lastName; return lastName;
} }
public String getRole() public boolean isMemberOfGroup()
{ {
return role; return isMemberOfGroup;
} }
@Override @Override
@@ -130,7 +117,7 @@ public class SiteMembership
{ {
final int prime = 31; final int prime = 31;
int result = 1; int result = 1;
result = prime * result + ((personId == null) ? 0 : personId.hashCode()); result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((role == null) ? 0 : role.hashCode()); result = prime * result + ((role == null) ? 0 : role.hashCode());
result = prime * result + ((getSiteInfo() == null) ? 0 : getSiteInfo().hashCode()); result = prime * result + ((getSiteInfo() == null) ? 0 : getSiteInfo().hashCode());
return result; return result;
@@ -146,15 +133,19 @@ public class SiteMembership
if (getClass() != obj.getClass()) if (getClass() != obj.getClass())
return false; return false;
SiteMembership other = (SiteMembership) obj; SiteMembership other = (SiteMembership) obj;
if (personId == null) if (id == null)
{ {
if (other.personId != null) if (other.id != null)
return false; return false;
} }
else if (!personId.equals(other.personId)) else if (!id.equals(other.id))
return false; return false;
if (role != other.role) if (role != other.role)
return false; return false;
if (isMemberOfGroup != other.isMemberOfGroup)
return false;
if (getSiteInfo() == null) if (getSiteInfo() == null)
{ {
if (other.getSiteInfo() != null) if (other.getSiteInfo() != null)
@@ -168,8 +159,42 @@ public class SiteMembership
@Override @Override
public String toString() public String toString()
{ {
return "SiteMembership [siteInfo=" + getSiteInfo() + ", personId=" + personId return "SiteMembership [siteInfo=" + getSiteInfo() + ", id=" + id
+ ", firstName=" + firstName + ", lastName=" + lastName + ", role=" + role + "]"; + ", firstName=" + firstName + ", lastName=" + lastName + ", role=" + role +
", isMemberOfGroup = " + isMemberOfGroup + "]";
} }
static int compareTo(List<Pair<? extends Object, CannedQuerySortDetails.SortOrder>> sortPairs, SiteMembership o1, SiteMembership o2)
{
String personId1 = o1.getPersonId();
String personId2 = o2.getPersonId();
String firstName1 = o1.getFirstName();
String firstName2 = o2.getFirstName();
String lastName1 = o1.getLastName();
String lastName2 = o2.getLastName();
String siteRole1 = o1.getRole();
String siteRole2 = o2.getRole();
String shortName1 = o1.getSiteInfo().getShortName();
String shortName2 = o2.getSiteInfo().getShortName();
int personId = SiteMembershipComparator.safeCompare(personId1, personId2);
int firstName = SiteMembershipComparator.safeCompare(firstName1, firstName2);
int siteShortName = SiteMembershipComparator.safeCompare(shortName1, shortName2);
int lastName = SiteMembershipComparator.safeCompare(lastName1, lastName2);
int siteRole = SiteMembershipComparator.safeCompare(siteRole1, siteRole2);
if (siteRole == 0 && siteShortName == 0 && personId == 0)
{
// equals contract
return 0;
}
return SiteMembershipComparator.compareSiteMembersBody(sortPairs, personId1, personId2, lastName1, lastName2, siteRole1, siteRole2, personId, firstName, lastName, siteRole, 0);
}
static Comparator<SiteMembership> getComparator(List<Pair<?, CannedQuerySortDetails.SortOrder>> sortPairs)
{
return (SiteMembership o1, SiteMembership o2) -> compareTo(sortPairs, o1, o2);
}
} }

View File

@@ -55,7 +55,7 @@ public class SiteMembershipComparator implements Comparator<SiteMembership>
this.comparatorType = comparatorType; this.comparatorType = comparatorType;
} }
private <T extends Object> int safeCompare(Comparable<T> o1, T o2) static <T extends Object> int safeCompare(Comparable<T> o1, T o2)
{ {
int ret = 0; int ret = 0;
@@ -115,8 +115,8 @@ public class SiteMembershipComparator implements Comparator<SiteMembership>
return ret; return ret;
} }
private int compareMembersBody(String personId1, String personId2, String lastName1, String lastName2, String siteRole1, String siteRole2, int personId, int firstName, static int compareSiteMembersBody(List<Pair<? extends Object, SortOrder>> sortPairs, String personId1, String personId2, String lastName1, String lastName2, String siteRole1, String siteRole2, int personId, int firstName,
int lastName, int siteRole, int ret) int lastName, int siteRole, int ret)
{ {
for (Pair<? extends Object, SortOrder> pair : sortPairs) for (Pair<? extends Object, SortOrder> pair : sortPairs)
{ {
@@ -161,6 +161,38 @@ public class SiteMembershipComparator implements Comparator<SiteMembership>
return ret; return ret;
} }
static int compareSiteGroupsBody(List<Pair<? extends Object, SortOrder>> sortPairs, String displayName1, String displayName2, String siteRole1, String siteRole2, int displayName, int siteRole, int ret)
{
for (Pair<? extends Object, SortOrder> pair : sortPairs)
{
Object name = pair.getFirst();
SortOrder sortOrder = pair.getSecond();
int multiplier = sortOrder.equals(SortOrder.ASCENDING) ? 1 : -1;
if (name.equals(SiteService.SortFields.DisplayName))
{
if (displayName1 == null || displayName2 == null)
{
continue;
}
ret = displayName * multiplier;
}
else if (name.equals(SiteService.SortFields.Role))
{
if (siteRole1 == null || siteRole2 == null)
{
continue;
}
ret = siteRole * multiplier;
}
if (ret != 0)
{
break;
}
}
return ret;
}
private int compareSitesBody(String shortName1, String shortName2, String siteRole1, String siteRole2, String siteTitle1, String siteTitle2, int siteShortName, int siteRole, private int compareSitesBody(String shortName1, String shortName2, String siteRole1, String siteRole2, String siteTitle1, String siteTitle2, int siteShortName, int siteRole,
int siteTitle, int ret) int siteTitle, int ret)
{ {
@@ -245,7 +277,7 @@ public class SiteMembershipComparator implements Comparator<SiteMembership>
} }
case MEMBERS: case MEMBERS:
{ {
ret = compareMembersBody(personId1, personId2, lastName1, lastName2, siteRole1, siteRole2, personId, firstName, lastName, siteRole, ret); ret = compareSiteMembersBody(sortPairs, personId1, personId2, lastName1, lastName2, siteRole1, siteRole2, personId, firstName, lastName, siteRole, ret);
break; break;
} }
} }

View File

@@ -41,6 +41,7 @@ import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.sync.events.types.Event; import org.alfresco.sync.events.types.Event;
@@ -1732,20 +1733,19 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
{ {
public Void doWork() throws Exception public Void doWork() throws Exception
{ {
listMembersImpl(sName, nameFilter, roleFilter, collapseGroups, callback); listMembersImpl(sName, nameFilter, roleFilter, collapseGroups, callback, true, true);
return null; return null;
} }
}, tenantDomain); }, tenantDomain);
} }
else else
{ {
listMembersImpl(shortName, nameFilter, roleFilter, collapseGroups, callback); listMembersImpl(shortName, nameFilter, roleFilter, collapseGroups, callback, true, true);
} }
} }
// note that this may return an authority more than once // note that this may return an authority more than once
protected void listMembersImpl(String shortName, String nameFilter, String roleFilter, boolean collapseGroups, SiteMembersCallback callback) protected void listMembersImpl(String shortName, String nameFilter, String roleFilter, boolean expandGroups, SiteMembersCallback callback, boolean includeUsers, boolean includeGroups) {
{
NodeRef siteNodeRef = getSiteNodeRef(shortName); NodeRef siteNodeRef = getSiteNodeRef(shortName);
if (siteNodeRef == null) if (siteNodeRef == null)
{ {
@@ -1770,39 +1770,37 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
{ {
switch (AuthorityType.getAuthorityType(authority)) switch (AuthorityType.getAuthorityType(authority))
{ {
case USER: case USER:
boolean addUser = true; if(includeUsers)
if (nameFilter != null && nameFilter.length() != 0 && !nameFilter.equals(authority))
{ {
// found a filter - does it match person first/last name? if (isAcceptedName(nameFilter, authority))
addUser = matchPerson(nameFilters, authority); {
} // Add the user and their permission to the returned map
if (addUser) callback.siteMember(authority, permission, false);
{ }
// Add the user and their permission to the returned map if(callback.isDone())
callback.siteMember(authority, permission); {
} break;
if(callback.isDone()) }
{
break;
} }
break; break;
case GROUP: case GROUP:
if (collapseGroups) if (expandGroups)
{ {
if (!groupsToExpand.containsKey(authority)) if (!groupsToExpand.containsKey(authority))
{ {
groupsToExpand.put(authority, permission); groupsToExpand.put(authority, permission);
} }
} }
else else if (includeGroups)
{ {
if (nameFilter != null && nameFilter.length() != 0) if (nameFilter != null && nameFilter.length() != 0)
{ {
// found a filter - does it match Group name part? // found a filter - does it match Group name part?
if (authority.substring(GROUP_PREFIX_LENGTH).toLowerCase().contains(nameFilterLower)) if (authority.substring(GROUP_PREFIX_LENGTH).toLowerCase().contains(nameFilterLower))
{ {
callback.siteMember(authority, permission); callback.siteMember(authority, permission, false);
} }
else else
{ {
@@ -1810,14 +1808,14 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
String displayName = authorityService.getAuthorityDisplayName(authority); String displayName = authorityService.getAuthorityDisplayName(authority);
if(displayName != null && displayName.toLowerCase().contains(nameFilterLower)) if(displayName != null && displayName.toLowerCase().contains(nameFilterLower))
{ {
callback.siteMember(authority, permission); callback.siteMember(authority, permission, false);
} }
} }
} }
else else
{ {
// No name filter add this group // No name filter add this group
callback.siteMember(authority, permission); callback.siteMember(authority, permission, false);
} }
if(callback.isDone()) if(callback.isDone())
@@ -1834,24 +1832,17 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
} }
} }
if (collapseGroups) if (expandGroups && includeUsers)
{ {
for (Map.Entry<String,String> entry : groupsToExpand.entrySet()) for (Map.Entry<String,String> entry : groupsToExpand.entrySet())
{ {
Set<String> subUsers = this.authorityService.getContainedAuthorities(AuthorityType.USER, entry.getKey(), false); Set<String> subUsers = this.authorityService.getContainedAuthorities(AuthorityType.USER, entry.getKey(), false);
for (String subUser : subUsers) for (String subUser : subUsers)
{ {
boolean addUser = true; if (isAcceptedName(nameFilter, subUser))
if (nameFilter != null && nameFilter.length() != 0 && !nameFilter.equals(subUser))
{
// found a filter - does it match person first/last name?
addUser = matchPerson(nameFilters, subUser);
}
if (addUser)
{ {
// Add the collapsed user into the members list if they do not already appear in the list // Add the collapsed user into the members list if they do not already appear in the list
callback.siteMember(subUser, entry.getValue()); callback.siteMember(subUser, entry.getValue(), true);
} }
if(callback.isDone()) if(callback.isDone())
@@ -1885,23 +1876,7 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
public PagingResults<SiteMembership> listMembersPaged(String shortName, boolean collapseGroups, List<Pair<SiteService.SortFields, Boolean>> sortProps, PagingRequest pagingRequest) public PagingResults<SiteMembership> listMembersPaged(String shortName, boolean collapseGroups, List<Pair<SiteService.SortFields, Boolean>> sortProps, PagingRequest pagingRequest)
{ {
CannedQueryPageDetails pageDetails = new CannedQueryPageDetails(pagingRequest.getSkipCount(), pagingRequest.getMaxItems()); CannedQueryParameters params = getCannedQueryParameters(shortName, collapseGroups, sortProps, pagingRequest);
// sort details
CannedQuerySortDetails sortDetails = null;
if(sortProps != null)
{
List<Pair<? extends Object, SortOrder>> sortPairs = new ArrayList<Pair<? extends Object, SortOrder>>(sortProps.size());
for (Pair<SiteService.SortFields, Boolean> sortProp : sortProps)
{
sortPairs.add(new Pair<SiteService.SortFields, SortOrder>(sortProp.getFirst(), (sortProp.getSecond() ? SortOrder.ASCENDING : SortOrder.DESCENDING)));
}
sortDetails = new CannedQuerySortDetails(sortPairs);
}
SiteMembersCannedQueryParams parameterBean = new SiteMembersCannedQueryParams(shortName, collapseGroups);
CannedQueryParameters params = new CannedQueryParameters(parameterBean, pageDetails, sortDetails, pagingRequest.getRequestTotalCountMax(), pagingRequest.getQueryExecutionId());
CannedQuery<SiteMembership> query = new SiteMembersCannedQuery(this, personService, nodeService, params); CannedQuery<SiteMembership> query = new SiteMembersCannedQuery(this, personService, nodeService, params);
@@ -1952,7 +1927,7 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
return listMembers(shortName, nameFilter, roleFilter, size, false); return listMembers(shortName, nameFilter, roleFilter, size, false);
} }
public Map<String, String> listMembers(String shortName, final String nameFilter, final String roleFilter, final int size, final boolean collapseGroups) public Map<String, String> listMembers(String shortName, final String nameFilter, final String roleFilter, final int size, final boolean expandGroups)
{ {
// MT share - for activity service remote system callback (deprecated) // MT share - for activity service remote system callback (deprecated)
if (tenantService.isEnabled() && if (tenantService.isEnabled() &&
@@ -1967,13 +1942,13 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
{ {
public Map<String, String> doWork() throws Exception public Map<String, String> doWork() throws Exception
{ {
return listMembersImpl(sName, nameFilter, roleFilter, size, collapseGroups); return listMembersImpl(sName, nameFilter, roleFilter, size, expandGroups);
} }
}, tenantDomain); }, tenantDomain);
} }
else else
{ {
return listMembersImpl(shortName, nameFilter, roleFilter, size, collapseGroups); return listMembersImpl(shortName, nameFilter, roleFilter, size, expandGroups);
} }
} }
@@ -1981,7 +1956,7 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
* @see org.alfresco.service.cmr.site.SiteService#listMembersInfo(String, * @see org.alfresco.service.cmr.site.SiteService#listMembersInfo(String,
* String, String, int, boolean) * String, String, int, boolean)
*/ */
public List<SiteMemberInfo> listMembersInfo(String shortName, final String nameFilter, final String roleFilter, final int size, final boolean collapseGroups) public List<SiteMemberInfo> listMembersInfo(String shortName, final String nameFilter, final String roleFilter, final int size, final boolean expandGroups)
{ {
// MT share - for activity service system callback // MT share - for activity service system callback
if (tenantService.isEnabled() if (tenantService.isEnabled()
@@ -1992,26 +1967,18 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
final String sName = tenantService.getBaseName(shortName, true); final String sName = tenantService.getBaseName(shortName, true);
return AuthenticationUtil.runAs( return AuthenticationUtil.runAs(
new AuthenticationUtil.RunAsWork<List<SiteMemberInfo>>() () -> listMembersInfoImpl(sName, nameFilter, roleFilter, size, expandGroups),
{ tenantService.getDomainUser(AuthenticationUtil.getSystemUserName(), tenantDomain));
public List<SiteMemberInfo> doWork() throws Exception
{
return listMembersInfoImpl(sName, nameFilter, roleFilter, size,
collapseGroups);
}
}, tenantService.getDomainUser(AuthenticationUtil.getSystemUserName(),
tenantDomain));
} }
else else
{ {
return listMembersInfoImpl(shortName, nameFilter, roleFilter, size, collapseGroups); return listMembersInfoImpl(shortName, nameFilter, roleFilter, size, expandGroups);
} }
} }
protected Map<String, String> listMembersImpl(String shortName, String nameFilter, String roleFilter, int size, boolean collapseGroups) protected Map<String, String> listMembersImpl(String shortName, String nameFilter, String roleFilter, int size, boolean expandGroups)
{ {
List<SiteMemberInfo> list = listMembersInfoImpl(shortName, nameFilter, roleFilter, size, List<SiteMemberInfo> list = listMembersInfoImpl(shortName, nameFilter, roleFilter, size, expandGroups);
collapseGroups);
Map<String, String> members = new HashMap<String, String>(list.size()); Map<String, String> members = new HashMap<String, String>(list.size());
for (SiteMemberInfo info : list) for (SiteMemberInfo info : list)
@@ -2021,7 +1988,7 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
} }
protected List<SiteMemberInfo> listMembersInfoImpl(String shortName, String nameFilter, protected List<SiteMemberInfo> listMembersInfoImpl(String shortName, String nameFilter,
String roleFilter, int size, boolean collapseGroups) String roleFilter, int size, boolean expandGroups)
{ {
NodeRef siteNodeRef = getSiteNodeRef(shortName); NodeRef siteNodeRef = getSiteNodeRef(shortName);
if (siteNodeRef == null) if (siteNodeRef == null)
@@ -2074,7 +2041,7 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
} }
break; break;
case GROUP: case GROUP:
if (collapseGroups) if (expandGroups)
{ {
if (!groupsToExpand.containsKey(authority)) if (!groupsToExpand.containsKey(authority))
{ {
@@ -2120,21 +2087,14 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
} }
} }
if ((collapseGroups) && (members.size() < size)) if ((expandGroups) && (members.size() < size))
{ {
GROUP_EXPAND: for (Map.Entry<String, String> entry : groupsToExpand.entrySet()) GROUP_EXPAND: for (Map.Entry<String, String> entry : groupsToExpand.entrySet())
{ {
Set<String> subUsers = this.authorityService.getContainedAuthorities(AuthorityType.USER, entry.getKey(), false); Set<String> subUsers = this.authorityService.getContainedAuthorities(AuthorityType.USER, entry.getKey(), false);
for (String subUser : subUsers) for (String subUser : subUsers)
{ {
boolean addUser = true; if (isAcceptedName(nameFilter, subUser))
if (nameFilter != null && nameFilter.length() != 0 && !nameFilter.equals(subUser))
{
// found a filter - does it match person first/last name?
addUser = matchPerson(nameFilters, subUser);
}
if (addUser)
{ {
SiteMemberInfo memberInfo = new SiteMemberInfoImpl(subUser,entry.getValue(), true); 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 // Add the collapsed user into the members list if they do not already appear in the list
@@ -2164,6 +2124,17 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
return members; return members;
} }
private boolean isAcceptedName(String nameFilter, String name)
{
boolean addUser = true;
if (nameFilter != null && nameFilter.length() != 0 && !nameFilter.equals(name))
{
// found a filter - does it match person first/last name?
addUser = matchPerson(tokenizeFilterLowercase(nameFilter), name);
}
return addUser;
}
/** /**
* Helper to match name filters to Person properties. * Helper to match name filters to Person properties.
* *
@@ -2856,7 +2827,8 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
final TaggingService taggingService) final TaggingService taggingService)
{ {
// Does the site exist? // Does the site exist?
if(siteService.getSite(siteShortName) == null) { if(siteService.getSite(siteShortName) == null)
{
// Either the site doesn't exist, or you're not allowed to see it // Either the site doesn't exist, or you're not allowed to see it
if(! create) if(! create)
{ {
@@ -3412,4 +3384,45 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
this.eventPublisher = eventPublisher; this.eventPublisher = eventPublisher;
} }
@Override
public void listMembers(String shortName, final String nameFilter, final String roleFilter, boolean includeUsers, boolean includeGroups, boolean expandGroups, SiteMembersCallback callback)
{
// 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);
TenantUtil.runAsSystemTenant(() -> {
listMembersImpl(sName, nameFilter, roleFilter, expandGroups, callback, includeUsers, includeGroups);
return null;
}, tenantDomain);
}
else
{
listMembersImpl(shortName, nameFilter, roleFilter, expandGroups, callback, includeUsers, includeGroups);
}
}
@Override
public PagingResults<SiteGroupMembership> listGroupMembersPaged(String shortName, List<Pair<SortFields, Boolean>> sortProps, PagingRequest pagingRequest)
{
CannedQueryParameters params = getCannedQueryParameters(shortName, false, sortProps, pagingRequest);
CannedQuery<SiteGroupMembership> query = new SiteGroupCannedQuery(this, authorityService, params);
CannedQueryResults<SiteGroupMembership> results = query.execute();
return getPagingResults(pagingRequest, results);
}
private CannedQueryParameters getCannedQueryParameters(String shortName, boolean expandGroups, List<Pair<SortFields, Boolean>> sortProps, PagingRequest pagingRequest)
{
CannedQueryPageDetails pageDetails = new CannedQueryPageDetails(pagingRequest.getSkipCount(), pagingRequest.getMaxItems());
List<Pair<? extends Object, SortOrder>> sortPairs = sortProps.stream().map(props -> new Pair<SortFields, SortOrder>(props.getFirst(), (props.getSecond() ? SortOrder.ASCENDING : SortOrder.DESCENDING))).collect(Collectors.toList());
CannedQuerySortDetails sortDetails = new CannedQuerySortDetails(sortPairs);
SiteMembersCannedQueryParams parameterBean = new SiteMembersCannedQueryParams(shortName, expandGroups);
return new CannedQueryParameters(parameterBean, pageDetails, sortDetails, pagingRequest.getRequestTotalCountMax(), pagingRequest.getQueryExecutionId());
}
} }

View File

@@ -1,28 +1,28 @@
/* /*
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited * Copyright (C) 2005 - 2016 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is * the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms: * provided under the following open source license terms:
* *
* Alfresco is free software: you can redistribute it and/or modify * 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 * 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 * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L% * #L%
*/ */
package org.alfresco.service.cmr.site; package org.alfresco.service.cmr.site;
import java.io.Serializable; import java.io.Serializable;
@@ -35,6 +35,7 @@ import org.alfresco.query.PagingRequest;
import org.alfresco.query.PagingResults; import org.alfresco.query.PagingResults;
import org.alfresco.repo.node.getchildren.FilterProp; import org.alfresco.repo.node.getchildren.FilterProp;
import org.alfresco.repo.security.authority.UnknownAuthorityException; import org.alfresco.repo.security.authority.UnknownAuthorityException;
import org.alfresco.repo.site.SiteGroupMembership;
import org.alfresco.repo.site.SiteMembership; import org.alfresco.repo.site.SiteMembership;
import org.alfresco.service.Auditable; import org.alfresco.service.Auditable;
import org.alfresco.service.NotAuditable; import org.alfresco.service.NotAuditable;
@@ -55,14 +56,24 @@ public interface SiteService
{ {
static String DOCUMENT_LIBRARY = "documentLibrary"; static String DOCUMENT_LIBRARY = "documentLibrary";
public enum SortFields { LastName, FirstName, Role, SiteShortName, SiteTitle, Username }; public enum SortFields { LastName, FirstName, Role, SiteShortName, SiteTitle, Username, DisplayName };
public interface SiteMembersCallback public interface SiteMembersCallback
{ {
/*
* A site member along with his/her Site permission /**
*/ * @deprecated from 7.0.0 onwards, use #siteMember(String, String, boolean) instead
public void siteMember(String authority, String permission); * A site member along with his/her Site permission
*/
public void siteMember(String authority, String permission);
/*
* A site member along with his/her Site permission
*/
public default void siteMember(String authority, String permission, boolean isMemberOfGroup)
{
siteMember(authority, permission);
}
/** /**
* Return true to break out of the loop early. * Return true to break out of the loop early.
@@ -309,6 +320,7 @@ public interface SiteService
void deleteSite(String shortName); void deleteSite(String shortName);
/** /**
* @deprecated from 7.0.0, use #listMembers(String, String, String, boolean, boolean, boolean, SiteMembersCallback) instead
* List the members of the site. This includes both users and groups. * List the members of the site. This includes both users and groups.
* <p> * <p>
* Name and role filters are optional and if not specified all the members of the site are returned. * Name and role filters are optional and if not specified all the members of the site are returned.
@@ -316,12 +328,29 @@ public interface SiteService
* @param shortName site short name * @param shortName site short name
* @param nameFilter name filter * @param nameFilter name filter
* @param roleFilter role filter * @param roleFilter role filter
* @param collapseGroups true if collapse member groups into user list, false otherwise * @param collapseGroups true if includes group member into user list, false otherwise
* @param callback callback * @param callback callback
*/ */
@NotAuditable @NotAuditable
void listMembers(String shortName, final String nameFilter, final String roleFilter, boolean collapseGroups, SiteMembersCallback callback); void listMembers(String shortName, final String nameFilter, final String roleFilter, boolean collapseGroups, SiteMembersCallback callback);
/**
* List the members of the site. This includes both users and groups.
* Users and groups can be controlled by passing params
* <p>
* Name and role filters are optional and if not specified all the members of the site are returned.
*
* @param shortName site short name
* @param nameFilter name filter
* @param roleFilter role filter
* @param includeUsers includes the users
* @param includeGroups include the groups
* @param expandGroups true if expand group member into user list, false otherwise
* @param callback callback
*/
@NotAuditable
void listMembers(String shortName, final String nameFilter, final String roleFilter, final boolean includeUsers, final boolean includeGroups, final boolean expandGroups, SiteMembersCallback callback);
/** /**
* List the members of the site. This includes both users and groups. * List the members of the site. This includes both users and groups.
* <p> * <p>
@@ -344,7 +373,7 @@ public interface SiteService
* @param nameFilter name filter * @param nameFilter name filter
* @param roleFilter role filter * @param roleFilter role filter
* @param size max results size crop if >0 * @param size max results size crop if >0
* @param collapseGroups true if collapse member groups into user list, false otherwise * @param collapseGroups true if includes group member into user list, false otherwise
* @return the authority name and their role * @return the authority name and their role
*/ */
@NotAuditable @NotAuditable
@@ -358,8 +387,8 @@ public interface SiteService
* @param shortName site short name * @param shortName site short name
* @param nameFilter name filter * @param nameFilter name filter
* @param roleFilter role filter * @param roleFilter role filter
* @param size max results size crop if >0 * @param size max results size crop if >0
* @param collapseGroups true if collapse member groups into user list, false otherwise * @param collapseGroups true if includes group member into user list, false otherwise
* @return List of site authorities information objects * @return List of site authorities information objects
*/ */
@NotAuditable @NotAuditable
@@ -554,4 +583,16 @@ public interface SiteService
*/ */
@NotAuditable @NotAuditable
boolean isSiteAdmin(String userName); boolean isSiteAdmin(String userName);
/**
* Returns a paged list of the groups for the site.
*
* @param shortName site short name
* @param sortProps sorting options
* @param pagingRequest the paging request
*
* @return the authority name and their role
*/
@NotAuditable
PagingResults<SiteGroupMembership> listGroupMembersPaged(String shortName, List<Pair<SortFields, Boolean>> sortProps, PagingRequest pagingRequest);
} }

View File

@@ -1029,6 +1029,7 @@
org.alfresco.service.cmr.site.SiteService.listMembers=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.listMembersInfo=ACL_ALLOW
org.alfresco.service.cmr.site.SiteService.listMembersPaged=ACL_ALLOW org.alfresco.service.cmr.site.SiteService.listMembersPaged=ACL_ALLOW
org.alfresco.service.cmr.site.SiteService.listGroupMembersPaged=ACL_ALLOW
org.alfresco.service.cmr.site.SiteService.listSiteMemberships=ACL_ALLOW org.alfresco.service.cmr.site.SiteService.listSiteMemberships=ACL_ALLOW
org.alfresco.service.cmr.site.SiteService.listSites=ACL_ALLOW,AFTER_ACL_NODE.sys:base.ReadProperties org.alfresco.service.cmr.site.SiteService.listSites=ACL_ALLOW,AFTER_ACL_NODE.sys:base.ReadProperties
org.alfresco.service.cmr.site.SiteService.listSitesPaged=ACL_ALLOW,AFTER_ACL_NODE.sys:base.ReadProperties org.alfresco.service.cmr.site.SiteService.listSitesPaged=ACL_ALLOW,AFTER_ACL_NODE.sys:base.ReadProperties

View File

@@ -48,10 +48,10 @@ public class SiteMembershipTest
String lastName = UUID.randomUUID().toString(); String lastName = UUID.randomUUID().toString();
String role = "Consumer"; String role = "Consumer";
String personErrorMessage = "Person required building site membership of "; String idErrorMessage = "Id required building site membership";
String firstNameErrorMessage = "FirstName required building site membership of "; String firstNameErrorMessage = "FirstName required building site membership of ";
String lastNameErrorMessage = "LastName required building site membership of "; String lastNameErrorMessage = "LastName required building site membership of ";
String roleErrorMessage = "Role required building site membership of "; String roleErrorMessage = "Role required building site membership";
@Before @Before
public void createSite() public void createSite()
@@ -73,7 +73,7 @@ public class SiteMembershipTest
} }
catch (IllegalArgumentException e) catch (IllegalArgumentException e)
{ {
assertEquals(personErrorMessage + siteInfo.getShortName(), e.getMessage()); assertEquals(idErrorMessage, e.getMessage());
} }
try try
@@ -82,7 +82,7 @@ public class SiteMembershipTest
} }
catch (IllegalArgumentException e) catch (IllegalArgumentException e)
{ {
assertEquals(personErrorMessage + siteInfo.getShortName(), e.getMessage()); assertEquals(idErrorMessage, e.getMessage());
} }
} }
@@ -95,7 +95,7 @@ public class SiteMembershipTest
} }
catch (IllegalArgumentException e) catch (IllegalArgumentException e)
{ {
assertEquals(roleErrorMessage + siteInfo.getShortName(), e.getMessage()); assertEquals(roleErrorMessage, e.getMessage());
} }
try try
@@ -104,7 +104,7 @@ public class SiteMembershipTest
} }
catch (IllegalArgumentException e) catch (IllegalArgumentException e)
{ {
assertEquals(roleErrorMessage + siteInfo.getShortName(), e.getMessage()); assertEquals(roleErrorMessage, e.getMessage());
} }
} }
@@ -122,7 +122,7 @@ public class SiteMembershipTest
} }
@Test @Test
public void testNullLastNale() throws Exception public void testNullLastName() throws Exception
{ {
try try
{ {

View File

@@ -38,6 +38,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.query.PagingRequest; import org.alfresco.query.PagingRequest;
@@ -247,7 +248,7 @@ public class SiteServiceImplMoreTest
// Create site // Create site
final TestSiteAndMemberInfo testSiteAndMemberInfo = final TestSiteAndMemberInfo testSiteAndMemberInfo =
perMethodTestSites.createTestSiteWithUserPerRole(siteShortName, "sitePreset", SiteVisibility.PUBLIC, AuthenticationUtil.getAdminUserName()); perMethodTestSites.createTestSiteWithUserPerRole(siteShortName, "sitePreset", SiteVisibility.PUBLIC, AuthenticationUtil.getAdminUserName());
// Delete permissions and site // Delete permissions and site
final Map<String, String> membersBefore = TRANSACTION_HELPER.doInTransaction(new RetryingTransactionCallback<Map<String, String>>() final Map<String, String> membersBefore = TRANSACTION_HELPER.doInTransaction(new RetryingTransactionCallback<Map<String, String>>()
{ {
@@ -857,6 +858,67 @@ public class SiteServiceImplMoreTest
}); });
} }
@Test public void testSiteGroupsPaged()
{
// Choose a site name that will link back to this test case...
final String siteShortName = testName.getMethodName();
log.debug("Creating test site called: " + siteShortName);
TRANSACTION_HELPER.doInTransaction(() ->
{
perMethodTestSites.createTestSiteWithGroups(siteShortName, "sitePreset", SiteVisibility.PUBLIC, AuthenticationUtil.getAdminUserName(), 10);
List<Pair<SiteService.SortFields, Boolean>> sortProps = new ArrayList<Pair<SiteService.SortFields, Boolean>>(1);
sortProps.add(new Pair<SiteService.SortFields, Boolean>(SiteService.SortFields.DisplayName, true));
PagingResults<SiteGroupMembership> pagedMembers = SITE_SERVICE.listGroupMembersPaged(siteShortName, sortProps, new PagingRequest(5));
assertNotNull(pagedMembers);
assertNotNull(pagedMembers.getQueryExecutionId());
assertTrue(pagedMembers.hasMoreItems());
assertEquals(pagedMembers.getPage().size(), 5);
log.debug("About to delete site completely.");
SITE_SERVICE.deleteSite(siteShortName);
return null;
});
}
@Test public void testSiteMembersPagedV2()
{
// Choose a site name that will link back to this test case...
final String siteShortName = testName.getMethodName();
log.debug("Creating test site called: " + siteShortName);
TRANSACTION_HELPER.doInTransaction(() ->
{
perMethodTestSites.createTestSiteWithGroups(siteShortName, "sitePreset", SiteVisibility.PUBLIC, AuthenticationUtil.getAdminUserName(), 10);
List<Pair<SiteService.SortFields, Boolean>> sortProps = new ArrayList<Pair<SiteService.SortFields, Boolean>>(1);
sortProps.add(new Pair<SiteService.SortFields, Boolean>(SiteService.SortFields.FirstName, true));
PagingResults<SiteMembership> pagedMembers = SITE_SERVICE.listMembersPaged(siteShortName, true, sortProps, new PagingRequest(25));
assertNotNull(pagedMembers);
assertNotNull(pagedMembers.getQueryExecutionId());
assertFalse(pagedMembers.hasMoreItems());
assertEquals(pagedMembers.getPage().size(), 11);
List<SiteMembership> users = pagedMembers.getPage().stream().filter((member) -> !member.isMemberOfGroup()).collect(Collectors.toList());
List<SiteMembership> groupsUsers = pagedMembers.getPage().stream().filter(SiteMembership::isMemberOfGroup).collect(Collectors.toList());
assertEquals(users.size(), 1);
assertEquals(groupsUsers.size(), 10);
pagedMembers = SITE_SERVICE.listMembersPaged(siteShortName, false, sortProps, new PagingRequest(100));
assertNotNull(pagedMembers);
assertNotNull(pagedMembers.getQueryExecutionId());
assertFalse(pagedMembers.hasMoreItems());
assertEquals(pagedMembers.getPage().size(), 1);
users = pagedMembers.getPage().stream().filter((member) -> !member.isMemberOfGroup()).collect(Collectors.toList());
groupsUsers = pagedMembers.getPage().stream().filter(SiteMembership::isMemberOfGroup).collect(Collectors.toList());
assertEquals(users.size(), 1);
assertEquals(groupsUsers.size(), 0);
log.debug("About to delete site completely.");
SITE_SERVICE.deleteSite(siteShortName);
return null;
});
}
@Test public void testTokenizer() @Test public void testTokenizer()
{ {
String[] res = SiteServiceImpl.tokenizeFilterLowercase("Fred"); String[] res = SiteServiceImpl.tokenizeFilterLowercase("Fred");

View File

@@ -1,33 +1,32 @@
/* /*
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited * Copyright (C) 2005 - 2016 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is * the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms: * provided under the following open source license terms:
* *
* Alfresco is free software: you can redistribute it and/or modify * 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 * 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 * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L% * #L%
*/ */
package org.alfresco.util.test.junitrules; package org.alfresco.util.test.junitrules;
import java.util.ArrayList; import java.io.Serializable;
import java.util.Date; import java.util.*;
import java.util.List;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.domain.activities.ActivityPostDAO; import org.alfresco.repo.domain.activities.ActivityPostDAO;
@@ -39,6 +38,9 @@ import org.alfresco.repo.site.SiteModel;
import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.site.SiteInfo; import org.alfresco.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService; import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.cmr.site.SiteVisibility; import org.alfresco.service.cmr.site.SiteVisibility;
@@ -280,7 +282,58 @@ public class TemporarySites extends AbstractPersonRule
userNames.get(2), userNames.get(2),
userNames.get(3)); userNames.get(3));
} }
/*
* This method creates a test site with n groups.
*/
public List<String> createTestSiteWithGroups(final String siteShortName, String sitePreset, SiteVisibility visibility, String siteCreator, int noOfGroups) {
// create the site
this.createSite(sitePreset, siteShortName, null, null, visibility, siteCreator);
// create the users
final RetryingTransactionHelper transactionHelper = appContextRule.getApplicationContext().getBean("retryingTransactionHelper", RetryingTransactionHelper.class);
final SiteService siteService = appContextRule.getApplicationContext().getBean("siteService", SiteService.class);
final AuthorityService authorityService = appContextRule.getApplicationContext().getBean("authorityService", AuthorityService.class);
final PersonService personService = appContextRule.getApplicationContext().getBean("personService", PersonService.class);
AuthenticationUtil.pushAuthentication();
AuthenticationUtil.setFullyAuthenticatedUser(siteCreator);
// Create group with one user and add it to the site
List<String> groupIds = transactionHelper.doInTransaction(new RetryingTransactionCallback<List<String>>() {
public List<String> execute() throws Throwable {
List<String> groups = new ArrayList<String>(noOfGroups);
for (int i = 0; i < noOfGroups; i++) {
String shareRole = SiteModel.STANDARD_PERMISSIONS.get(i % 4);
final String groupName = "Test_Group_" + GUID.generate();
final String userName = "Test_User_" + GUID.generate();
log.debug("Creating temporary site user " + userName);
final Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
properties.put(ContentModel.PROP_USERNAME, userName);
properties.put(ContentModel.PROP_FIRSTNAME, GUID.generate());
properties.put(ContentModel.PROP_LASTNAME, GUID.generate());
properties.put(ContentModel.PROP_EMAIL, GUID.generate() + "@test.com");
personService.createPerson(properties);
log.debug("Creating temporary site group " + groupName);
final String groupId = authorityService.createAuthority(AuthorityType.GROUP, groupName);
authorityService.setAuthorityDisplayName(groupId, GUID.generate());
authorityService.addAuthority(groupId, userName);
siteService.setMembership(siteShortName, groupId, shareRole);
groups.add(userName);
}
return groups;
}
});
return groupIds;
}
/** /**
* A simple POJO class to store the {@link SiteInfo} for this site and its initial, automatically created members' usernames. * A simple POJO class to store the {@link SiteInfo} for this site and its initial, automatically created members' usernames.
* *