diff --git a/src/main/java/org/alfresco/repo/site/AbstractSiteMembership.java b/src/main/java/org/alfresco/repo/site/AbstractSiteMembership.java new file mode 100644 index 0000000000..038612dcfd --- /dev/null +++ b/src/main/java/org/alfresco/repo/site/AbstractSiteMembership.java @@ -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 . + * #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; + } +} diff --git a/src/main/java/org/alfresco/repo/site/SiteGroupCannedQuery.java b/src/main/java/org/alfresco/repo/site/SiteGroupCannedQuery.java new file mode 100644 index 0000000000..d2ff13ee7b --- /dev/null +++ b/src/main/java/org/alfresco/repo/site/SiteGroupCannedQuery.java @@ -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 . + * #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 +{ + 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 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 siteGroups; + + CQSiteGroupsCallback(String siteShortName, List> 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 getSiteMembers() + { + return new ArrayList<>(siteGroups); + } + + void done() {} + } +} diff --git a/src/main/java/org/alfresco/repo/site/SiteGroupMembership.java b/src/main/java/org/alfresco/repo/site/SiteGroupMembership.java new file mode 100644 index 0000000000..1fe53e99c4 --- /dev/null +++ b/src/main/java/org/alfresco/repo/site/SiteGroupMembership.java @@ -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 . + * #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> 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 getComparator(List> sortPairs) + { + return (SiteGroupMembership o1, SiteGroupMembership o2) -> compareTo(sortPairs, o1, o2); + } +} diff --git a/src/main/java/org/alfresco/repo/site/SiteMembersCannedQuery.java b/src/main/java/org/alfresco/repo/site/SiteMembersCannedQuery.java index 0bd1417d25..d2a6e06074 100644 --- a/src/main/java/org/alfresco/repo/site/SiteMembersCannedQuery.java +++ b/src/main/java/org/alfresco/repo/site/SiteMembersCannedQuery.java @@ -1,35 +1,32 @@ -/* - * #%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 . - * #L% - */ +/* + * #%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 . + * #L% + */ package org.alfresco.repo.site; -import java.text.Collator; import java.util.ArrayList; -import java.util.Comparator; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.TreeSet; @@ -74,13 +71,12 @@ public class SiteMembersCannedQuery extends AbstractCannedQuery SiteMembersCannedQueryParams paramBean = (SiteMembersCannedQueryParams)parameters.getParameterBean(); String siteShortName = paramBean.getShortName(); - boolean collapseGroups = paramBean.isCollapseGroups(); CannedQuerySortDetails sortDetails = parameters.getSortDetails(); List> sortPairs = sortDetails.getSortPairs(); 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(); return callback.getSiteMembers(); @@ -95,19 +91,25 @@ public class SiteMembersCannedQuery extends AbstractCannedQuery private class CQSiteMembersCallback implements SiteMembersCallback { - private String siteShortName; private SiteInfo siteInfo; private Set siteMembers; CQSiteMembersCallback(String siteShortName, List> sortPairs) { - this.siteShortName = siteShortName; this.siteInfo = siteService.getSite(siteShortName); - this.siteMembers = sortPairs != null && sortPairs.size() > 0 ? new TreeSet(new SiteMembershipComparator(sortPairs, SiteMembershipComparator.Type.MEMBERS)) : new HashSet(); + this.siteMembers = sortPairs != null && sortPairs.size() > 0 + ? new TreeSet(SiteMembership.getComparator(sortPairs)) + : new HashSet(); } + /** + * @deprecated from 7.0.0 + */ @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 lastName = null; @@ -115,12 +117,11 @@ public class SiteMembersCannedQuery extends AbstractCannedQuery if(personService.personExists(authority)) { NodeRef nodeRef = personService.getPerson(authority); - firstName = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_FIRSTNAME); - lastName = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_LASTNAME); + firstName = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_FIRSTNAME); + lastName = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_LASTNAME); } - SiteMembership siteMember = new SiteMembership(siteInfo, authority, firstName, lastName, permission); - siteMembers.add(siteMember); + siteMembers.add(new SiteMembership(siteInfo, authority, firstName, lastName, permission, isMemberOfGroup)); } @Override @@ -131,16 +132,7 @@ public class SiteMembersCannedQuery extends AbstractCannedQuery List getSiteMembers() { - // "drain" the site memberships into a (sorted) list - - List siteMemberships = new ArrayList(siteMembers.size()); - Iterator it = siteMembers.iterator(); - while(it.hasNext()) - { - siteMemberships.add(it.next()); - it.remove(); - } - return siteMemberships; + return new ArrayList<>(siteMembers); } void done() diff --git a/src/main/java/org/alfresco/repo/site/SiteMembersCannedQueryParams.java b/src/main/java/org/alfresco/repo/site/SiteMembersCannedQueryParams.java index e0000b77fd..ffb85f8e42 100644 --- a/src/main/java/org/alfresco/repo/site/SiteMembersCannedQueryParams.java +++ b/src/main/java/org/alfresco/repo/site/SiteMembersCannedQueryParams.java @@ -1,46 +1,46 @@ -/* - * #%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 . - * #L% - */ +/* + * #%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 . + * #L% + */ package org.alfresco.repo.site; /** * Conveys parameters for the site members canned query. - * + * * @author steveglover * */ public class SiteMembersCannedQueryParams { private String shortName; - private boolean collapseGroups; + final private boolean expandGroups; - public SiteMembersCannedQueryParams(String shortName, boolean collapseGroups) + public SiteMembersCannedQueryParams(String shortName, boolean expandGroups) { super(); this.shortName = shortName; - this.collapseGroups = collapseGroups; + this.expandGroups = expandGroups; } public String getShortName() @@ -48,8 +48,8 @@ public class SiteMembersCannedQueryParams return shortName; } - public boolean isCollapseGroups() + public boolean isExpandGroups() { - return collapseGroups; + return expandGroups; } } diff --git a/src/main/java/org/alfresco/repo/site/SiteMembership.java b/src/main/java/org/alfresco/repo/site/SiteMembership.java index 7bba607d63..f8c4a68330 100644 --- a/src/main/java/org/alfresco/repo/site/SiteMembership.java +++ b/src/main/java/org/alfresco/repo/site/SiteMembership.java @@ -23,38 +23,36 @@ * along with Alfresco. If not, see . * #L% */ -package org.alfresco.repo.site; - -import org.alfresco.service.cmr.site.SiteInfo; -import org.alfresco.service.cmr.site.SiteRole; - -/** - * Conveys information for a member of a site. - * - * @author steveglover - * - */ -public class SiteMembership +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; + +/** + * 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 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) { - super(); - if (siteInfo == null) - { - throw new java.lang.IllegalArgumentException(); - } - if (personId == null) - { - throw new java.lang.IllegalArgumentException( - "Person required building site membership of " + siteInfo.getShortName()); - } + super(siteInfo,id, role); if (firstName == null) { throw new java.lang.IllegalArgumentException( @@ -65,49 +63,38 @@ public class SiteMembership throw new java.lang.IllegalArgumentException( "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.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(); - if (siteInfo == null) - { - throw new java.lang.IllegalArgumentException(); - } - if (personId == null) + super(siteInfo, id, role); + if (firstName == null) { 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( - "Role required building site membership of " + siteInfo.getShortName()); + "LastName required building site membership of " + siteInfo.getShortName()); } - - this.siteInfo = siteInfo; - this.personId = personId; - this.role = role; + this.firstName = firstName; + this.lastName = lastName; + this.isMemberOfGroup = isMemberOfGroup; } - 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() { - return personId; + return id; } public String getFirstName() @@ -120,9 +107,9 @@ public class SiteMembership return lastName; } - public String getRole() + public boolean isMemberOfGroup() { - return role; + return isMemberOfGroup; } @Override @@ -130,7 +117,7 @@ public class SiteMembership { final int prime = 31; 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 + ((getSiteInfo() == null) ? 0 : getSiteInfo().hashCode()); return result; @@ -146,15 +133,19 @@ public class SiteMembership if (getClass() != obj.getClass()) return false; SiteMembership other = (SiteMembership) obj; - if (personId == null) + if (id == null) { - if (other.personId != null) + if (other.id != null) return false; } - else if (!personId.equals(other.personId)) + else if (!id.equals(other.id)) return false; if (role != other.role) return false; + + if (isMemberOfGroup != other.isMemberOfGroup) + return false; + if (getSiteInfo() == null) { if (other.getSiteInfo() != null) @@ -168,8 +159,42 @@ public class SiteMembership @Override public String toString() { - return "SiteMembership [siteInfo=" + getSiteInfo() + ", personId=" + personId - + ", firstName=" + firstName + ", lastName=" + lastName + ", role=" + role + "]"; + return "SiteMembership [siteInfo=" + getSiteInfo() + ", id=" + id + + ", firstName=" + firstName + ", lastName=" + lastName + ", role=" + role + + ", isMemberOfGroup = " + isMemberOfGroup + "]"; } + + static int compareTo(List> 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 getComparator(List> sortPairs) + { + return (SiteMembership o1, SiteMembership o2) -> compareTo(sortPairs, o1, o2); + } } diff --git a/src/main/java/org/alfresco/repo/site/SiteMembershipComparator.java b/src/main/java/org/alfresco/repo/site/SiteMembershipComparator.java index 9fa4916934..72608545f0 100644 --- a/src/main/java/org/alfresco/repo/site/SiteMembershipComparator.java +++ b/src/main/java/org/alfresco/repo/site/SiteMembershipComparator.java @@ -55,7 +55,7 @@ public class SiteMembershipComparator implements Comparator this.comparatorType = comparatorType; } - private int safeCompare(Comparable o1, T o2) + static int safeCompare(Comparable o1, T o2) { int ret = 0; @@ -115,8 +115,8 @@ public class SiteMembershipComparator implements Comparator return ret; } - private int compareMembersBody(String personId1, String personId2, String lastName1, String lastName2, String siteRole1, String siteRole2, int personId, int firstName, - int lastName, int siteRole, int ret) + static int compareSiteMembersBody(List> sortPairs, String personId1, String personId2, String lastName1, String lastName2, String siteRole1, String siteRole2, int personId, int firstName, + int lastName, int siteRole, int ret) { for (Pair pair : sortPairs) { @@ -161,6 +161,38 @@ public class SiteMembershipComparator implements Comparator return ret; } + static int compareSiteGroupsBody(List> sortPairs, String displayName1, String displayName2, String siteRole1, String siteRole2, int displayName, int siteRole, int ret) + { + for (Pair 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, int siteTitle, int ret) { @@ -245,7 +277,7 @@ public class SiteMembershipComparator implements Comparator } 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; } } diff --git a/src/main/java/org/alfresco/repo/site/SiteServiceImpl.java b/src/main/java/org/alfresco/repo/site/SiteServiceImpl.java index fd9a347a85..b209b0c64b 100644 --- a/src/main/java/org/alfresco/repo/site/SiteServiceImpl.java +++ b/src/main/java/org/alfresco/repo/site/SiteServiceImpl.java @@ -41,6 +41,7 @@ import java.util.SortedSet; import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.sync.events.types.Event; @@ -1732,20 +1733,19 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic { public Void doWork() throws Exception { - listMembersImpl(sName, nameFilter, roleFilter, collapseGroups, callback); + listMembersImpl(sName, nameFilter, roleFilter, collapseGroups, callback, true, true); return null; } }, tenantDomain); } 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 - 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); if (siteNodeRef == null) { @@ -1770,39 +1770,37 @@ 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)) + if(includeUsers) { - // 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 - callback.siteMember(authority, permission); - } - if(callback.isDone()) - { - break; + if (isAcceptedName(nameFilter, authority)) + { + // Add the user and their permission to the returned map + callback.siteMember(authority, permission, false); + } + if(callback.isDone()) + { + break; + } } break; case GROUP: - if (collapseGroups) + if (expandGroups) { if (!groupsToExpand.containsKey(authority)) { groupsToExpand.put(authority, permission); } } - else + else if (includeGroups) { if (nameFilter != null && nameFilter.length() != 0) { // found a filter - does it match Group name part? if (authority.substring(GROUP_PREFIX_LENGTH).toLowerCase().contains(nameFilterLower)) { - callback.siteMember(authority, permission); + callback.siteMember(authority, permission, false); } else { @@ -1810,14 +1808,14 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic String displayName = authorityService.getAuthorityDisplayName(authority); if(displayName != null && displayName.toLowerCase().contains(nameFilterLower)) { - callback.siteMember(authority, permission); + callback.siteMember(authority, permission, false); } } } else { // No name filter add this group - callback.siteMember(authority, permission); + callback.siteMember(authority, permission, false); } if(callback.isDone()) @@ -1834,24 +1832,17 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic } } - if (collapseGroups) + if (expandGroups && includeUsers) { for (Map.Entry entry : groupsToExpand.entrySet()) { Set subUsers = this.authorityService.getContainedAuthorities(AuthorityType.USER, entry.getKey(), false); for (String subUser : subUsers) { - boolean addUser = true; - 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) + if (isAcceptedName(nameFilter, subUser)) { // 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()) @@ -1885,23 +1876,7 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic public PagingResults listMembersPaged(String shortName, boolean collapseGroups, List> sortProps, PagingRequest pagingRequest) { - CannedQueryPageDetails pageDetails = new CannedQueryPageDetails(pagingRequest.getSkipCount(), pagingRequest.getMaxItems()); - - // sort details - CannedQuerySortDetails sortDetails = null; - if(sortProps != null) - { - List> sortPairs = new ArrayList>(sortProps.size()); - for (Pair sortProp : sortProps) - { - sortPairs.add(new Pair(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()); + CannedQueryParameters params = getCannedQueryParameters(shortName, collapseGroups, sortProps, pagingRequest); CannedQuery 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); } - public Map listMembers(String shortName, final String nameFilter, final String roleFilter, final int size, final boolean collapseGroups) + public Map listMembers(String shortName, final String nameFilter, final String roleFilter, final int size, final boolean expandGroups) { // MT share - for activity service remote system callback (deprecated) if (tenantService.isEnabled() && @@ -1967,13 +1942,13 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic { public Map doWork() throws Exception { - return listMembersImpl(sName, nameFilter, roleFilter, size, collapseGroups); + return listMembersImpl(sName, nameFilter, roleFilter, size, expandGroups); } }, tenantDomain); } 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, * String, String, int, boolean) */ - public List listMembersInfo(String shortName, final String nameFilter, final String roleFilter, final int size, final boolean collapseGroups) + public List listMembersInfo(String shortName, final String nameFilter, final String roleFilter, final int size, final boolean expandGroups) { // MT share - for activity service system callback if (tenantService.isEnabled() @@ -1992,26 +1967,18 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic 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)); + () -> listMembersInfoImpl(sName, nameFilter, roleFilter, size, expandGroups), + tenantService.getDomainUser(AuthenticationUtil.getSystemUserName(), tenantDomain)); } else { - return listMembersInfoImpl(shortName, nameFilter, roleFilter, size, collapseGroups); + return listMembersInfoImpl(shortName, nameFilter, roleFilter, size, expandGroups); } } - protected Map listMembersImpl(String shortName, String nameFilter, String roleFilter, int size, boolean collapseGroups) + protected Map listMembersImpl(String shortName, String nameFilter, String roleFilter, int size, boolean expandGroups) { - List list = listMembersInfoImpl(shortName, nameFilter, roleFilter, size, - collapseGroups); + List list = listMembersInfoImpl(shortName, nameFilter, roleFilter, size, expandGroups); Map members = new HashMap(list.size()); for (SiteMemberInfo info : list) @@ -2021,7 +1988,7 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic } protected List listMembersInfoImpl(String shortName, String nameFilter, - String roleFilter, int size, boolean collapseGroups) + String roleFilter, int size, boolean expandGroups) { NodeRef siteNodeRef = getSiteNodeRef(shortName); if (siteNodeRef == null) @@ -2074,7 +2041,7 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic } break; case GROUP: - if (collapseGroups) + if (expandGroups) { 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 entry : groupsToExpand.entrySet()) { Set subUsers = this.authorityService.getContainedAuthorities(AuthorityType.USER, entry.getKey(), false); for (String subUser : subUsers) { - boolean addUser = true; - 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) + if (isAcceptedName(nameFilter, subUser)) { 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 @@ -2164,6 +2124,17 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic 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. * @@ -2856,7 +2827,8 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic final TaggingService taggingService) { // 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 if(! create) { @@ -3412,4 +3384,45 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic 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 listGroupMembersPaged(String shortName, List> sortProps, PagingRequest pagingRequest) + { + CannedQueryParameters params = getCannedQueryParameters(shortName, false, sortProps, pagingRequest); + CannedQuery query = new SiteGroupCannedQuery(this, authorityService, params); + + CannedQueryResults results = query.execute(); + + return getPagingResults(pagingRequest, results); + } + + private CannedQueryParameters getCannedQueryParameters(String shortName, boolean expandGroups, List> sortProps, PagingRequest pagingRequest) + { + CannedQueryPageDetails pageDetails = new CannedQueryPageDetails(pagingRequest.getSkipCount(), pagingRequest.getMaxItems()); + + List> sortPairs = sortProps.stream().map(props -> new Pair(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()); + } } diff --git a/src/main/java/org/alfresco/service/cmr/site/SiteService.java b/src/main/java/org/alfresco/service/cmr/site/SiteService.java index 0390b003f8..d1356d21cd 100644 --- a/src/main/java/org/alfresco/service/cmr/site/SiteService.java +++ b/src/main/java/org/alfresco/service/cmr/site/SiteService.java @@ -1,28 +1,28 @@ -/* - * #%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 . - * #L% - */ +/* + * #%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 . + * #L% + */ package org.alfresco.service.cmr.site; import java.io.Serializable; @@ -35,6 +35,7 @@ import org.alfresco.query.PagingRequest; import org.alfresco.query.PagingResults; import org.alfresco.repo.node.getchildren.FilterProp; import org.alfresco.repo.security.authority.UnknownAuthorityException; +import org.alfresco.repo.site.SiteGroupMembership; import org.alfresco.repo.site.SiteMembership; import org.alfresco.service.Auditable; import org.alfresco.service.NotAuditable; @@ -55,14 +56,24 @@ public interface SiteService { 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 { - /* - * A site member along with his/her Site permission - */ - public void siteMember(String authority, String permission); + + /** + * @deprecated from 7.0.0 onwards, use #siteMember(String, String, boolean) instead + * 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. @@ -309,6 +320,7 @@ public interface SiteService 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. *

* 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 nameFilter name 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 */ @NotAuditable 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 + *

+ * 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. *

@@ -344,7 +373,7 @@ public interface SiteService * @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 + * @param collapseGroups true if includes group member into user list, false otherwise * @return the authority name and their role */ @NotAuditable @@ -358,8 +387,8 @@ public interface SiteService * @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 + * @param size max results size crop if >0 + * @param collapseGroups true if includes group member into user list, false otherwise * @return List of site authorities’ information objects */ @NotAuditable @@ -554,4 +583,16 @@ public interface SiteService */ @NotAuditable 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 listGroupMembersPaged(String shortName, List> sortProps, PagingRequest pagingRequest); } diff --git a/src/main/resources/alfresco/public-services-security-context.xml b/src/main/resources/alfresco/public-services-security-context.xml index 0ec2ec1a44..00f8c6c5e8 100644 --- a/src/main/resources/alfresco/public-services-security-context.xml +++ b/src/main/resources/alfresco/public-services-security-context.xml @@ -1029,6 +1029,7 @@ org.alfresco.service.cmr.site.SiteService.listMembers=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.listGroupMembersPaged=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.listSitesPaged=ACL_ALLOW,AFTER_ACL_NODE.sys:base.ReadProperties diff --git a/src/test/java/org/alfresco/repo/site/SiteMembershipTest.java b/src/test/java/org/alfresco/repo/site/SiteMembershipTest.java index 5c787dfa72..847b2e300a 100644 --- a/src/test/java/org/alfresco/repo/site/SiteMembershipTest.java +++ b/src/test/java/org/alfresco/repo/site/SiteMembershipTest.java @@ -48,10 +48,10 @@ public class SiteMembershipTest String lastName = UUID.randomUUID().toString(); 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 lastNameErrorMessage = "LastName required building site membership of "; - String roleErrorMessage = "Role required building site membership of "; + String roleErrorMessage = "Role required building site membership"; @Before public void createSite() @@ -73,7 +73,7 @@ public class SiteMembershipTest } catch (IllegalArgumentException e) { - assertEquals(personErrorMessage + siteInfo.getShortName(), e.getMessage()); + assertEquals(idErrorMessage, e.getMessage()); } try @@ -82,7 +82,7 @@ public class SiteMembershipTest } catch (IllegalArgumentException e) { - assertEquals(personErrorMessage + siteInfo.getShortName(), e.getMessage()); + assertEquals(idErrorMessage, e.getMessage()); } } @@ -95,7 +95,7 @@ public class SiteMembershipTest } catch (IllegalArgumentException e) { - assertEquals(roleErrorMessage + siteInfo.getShortName(), e.getMessage()); + assertEquals(roleErrorMessage, e.getMessage()); } try @@ -104,7 +104,7 @@ public class SiteMembershipTest } catch (IllegalArgumentException e) { - assertEquals(roleErrorMessage + siteInfo.getShortName(), e.getMessage()); + assertEquals(roleErrorMessage, e.getMessage()); } } @@ -122,7 +122,7 @@ public class SiteMembershipTest } @Test - public void testNullLastNale() throws Exception + public void testNullLastName() throws Exception { try { diff --git a/src/test/java/org/alfresco/repo/site/SiteServiceImplMoreTest.java b/src/test/java/org/alfresco/repo/site/SiteServiceImplMoreTest.java index b09e9cdd36..ac9ca27879 100644 --- a/src/test/java/org/alfresco/repo/site/SiteServiceImplMoreTest.java +++ b/src/test/java/org/alfresco/repo/site/SiteServiceImplMoreTest.java @@ -38,6 +38,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import org.alfresco.model.ContentModel; import org.alfresco.query.PagingRequest; @@ -247,7 +248,7 @@ public class SiteServiceImplMoreTest // Create site final TestSiteAndMemberInfo testSiteAndMemberInfo = perMethodTestSites.createTestSiteWithUserPerRole(siteShortName, "sitePreset", SiteVisibility.PUBLIC, AuthenticationUtil.getAdminUserName()); - + // Delete permissions and site final Map membersBefore = TRANSACTION_HELPER.doInTransaction(new RetryingTransactionCallback>() { @@ -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> sortProps = new ArrayList>(1); + sortProps.add(new Pair(SiteService.SortFields.DisplayName, true)); + PagingResults 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> sortProps = new ArrayList>(1); + sortProps.add(new Pair(SiteService.SortFields.FirstName, true)); + PagingResults pagedMembers = SITE_SERVICE.listMembersPaged(siteShortName, true, sortProps, new PagingRequest(25)); + assertNotNull(pagedMembers); + assertNotNull(pagedMembers.getQueryExecutionId()); + assertFalse(pagedMembers.hasMoreItems()); + assertEquals(pagedMembers.getPage().size(), 11); + + List users = pagedMembers.getPage().stream().filter((member) -> !member.isMemberOfGroup()).collect(Collectors.toList()); + List 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() { String[] res = SiteServiceImpl.tokenizeFilterLowercase("Fred"); diff --git a/src/test/java/org/alfresco/util/test/junitrules/TemporarySites.java b/src/test/java/org/alfresco/util/test/junitrules/TemporarySites.java index 7c9122a201..49bd59cc43 100644 --- a/src/test/java/org/alfresco/util/test/junitrules/TemporarySites.java +++ b/src/test/java/org/alfresco/util/test/junitrules/TemporarySites.java @@ -1,33 +1,32 @@ -/* - * #%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 . - * #L% - */ +/* + * #%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 . + * #L% + */ package org.alfresco.util.test.junitrules; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; +import java.io.Serializable; +import java.util.*; import org.alfresco.model.ContentModel; 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.RetryingTransactionCallback; 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.SiteService; import org.alfresco.service.cmr.site.SiteVisibility; @@ -280,7 +282,58 @@ public class TemporarySites extends AbstractPersonRule userNames.get(2), userNames.get(3)); } - + + /* + * This method creates a test site with n groups. + */ + public List 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 groupIds = transactionHelper.doInTransaction(new RetryingTransactionCallback>() { + public List execute() throws Throwable { + List groups = new ArrayList(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 properties = new HashMap(); + 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. *