diff --git a/config/alfresco/public-rest-context.xml b/config/alfresco/public-rest-context.xml
index 04f8b9516d..0bae52055f 100644
--- a/config/alfresco/public-rest-context.xml
+++ b/config/alfresco/public-rest-context.xml
@@ -1342,6 +1342,7 @@
+
diff --git a/source/java/org/alfresco/rest/api/impl/GroupsImpl.java b/source/java/org/alfresco/rest/api/impl/GroupsImpl.java
index 5acd43a7b6..8859bf2072 100644
--- a/source/java/org/alfresco/rest/api/impl/GroupsImpl.java
+++ b/source/java/org/alfresco/rest/api/impl/GroupsImpl.java
@@ -25,20 +25,6 @@
*/
package org.alfresco.rest.api.impl;
-import java.text.Collator;
-import java.util.AbstractList;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
import org.alfresco.query.CannedQueryPageDetails;
import org.alfresco.query.PagingRequest;
import org.alfresco.query.PagingResults;
@@ -47,6 +33,7 @@ import org.alfresco.repo.security.authority.AuthorityInfo;
import org.alfresco.repo.security.authority.UnknownAuthorityException;
import org.alfresco.rest.antlr.WhereClauseParser;
import org.alfresco.rest.api.Groups;
+import org.alfresco.rest.api.People;
import org.alfresco.rest.api.model.Group;
import org.alfresco.rest.api.model.GroupMember;
import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException;
@@ -65,6 +52,10 @@ import org.alfresco.util.AlfrescoCollator;
import org.alfresco.util.Pair;
import org.springframework.extensions.surf.util.I18NUtil;
+import java.text.Collator;
+import java.util.*;
+import java.util.stream.Collectors;
+
/**
* Centralises access to groups services and maps between representations.
*
@@ -94,6 +85,8 @@ public class GroupsImpl implements Groups
protected AuthorityService authorityService;
private AuthorityDAO authorityDAO;
+ protected People people;
+
public AuthorityService getAuthorityService()
{
return authorityService;
@@ -109,6 +102,11 @@ public class GroupsImpl implements Groups
this.authorityDAO = authorityDAO;
}
+ public void setPeople(People people)
+ {
+ this.people = people;
+ }
+
public Group create(Group group, Parameters parameters)
{
validateGroup(group);
@@ -194,6 +192,9 @@ public class GroupsImpl implements Groups
@Override
public CollectionWithPagingInfo getGroupsByPersonId(String personId, Parameters parameters)
{
+ // Canonicalize the person ID, performing -me- alias substitution.
+ personId = people.validatePerson(personId);
+
final List includeParam = parameters.getInclude();
Paging paging = parameters.getPaging();
@@ -201,35 +202,28 @@ public class GroupsImpl implements Groups
// v0 api implementation. Should be improved in the future.
Pair sortProp = getGroupsSortProp(parameters);
- final AuthorityType authorityType = AuthorityType.GROUP;
+ // Get all the authorities for a user, including but not limited to, groups.
final Set userAuthorities = authorityService.getAuthoritiesForUser(personId);
- List groupList = userAuthorities.stream().map(this::getAuthorityInfo).collect(Collectors.toList());
- // TODO: if isRoot not null then filter
- AuthorityInfoComparator authorityComparator = new AuthorityInfoComparator(sortProp.getFirst(), sortProp.getSecond());
- Collections.sort(groupList, authorityComparator);
- PagingResults pagingResult = Util.wrapPagingResults(paging, groupList);
+
+ // Filter, transform and sort the list of user authorities into
+ // a suitable list of AuthorityInfo objects.
+ List groupAuthorities = userAuthorities.stream().
+ filter(a -> a.startsWith(AuthorityType.GROUP.getPrefixString())).
+ map(this::getAuthorityInfo).
+ sorted(new AuthorityInfoComparator(sortProp.getFirst(), sortProp.getSecond())).
+ collect(Collectors.toList());
+
+ PagingResults pagingResult = Util.wrapPagingResults(paging, groupAuthorities);
// Create response.
final List page = pagingResult.getPage();
int totalItems = pagingResult.getTotalResultCount().getFirst();
-
- final Set rootAuthorities = getAllRootAuthorities(authorityType);
- List groups = new AbstractList()
- {
- @Override
- public Group get(int index)
- {
- AuthorityInfo authorityInfo = page.get(index);
- return getGroup(authorityInfo, includeParam, rootAuthorities);
- }
-
- @Override
- public int size()
- {
- return page.size();
- }
- };
+ // Transform the page of results into Group objects
+ final Set rootAuthorities = getAllRootAuthorities(AuthorityType.GROUP);
+ List groups = page.stream().
+ map(authority -> getGroup(authority, includeParam, rootAuthorities)).
+ collect(Collectors.toList());
return CollectionWithPagingInfo.asPaged(paging, groups, pagingResult.hasMoreItems(), totalItems);
}
diff --git a/source/test-java/org/alfresco/rest/api/tests/GroupsTest.java b/source/test-java/org/alfresco/rest/api/tests/GroupsTest.java
index fa9079ed1d..30798862e3 100644
--- a/source/test-java/org/alfresco/rest/api/tests/GroupsTest.java
+++ b/source/test-java/org/alfresco/rest/api/tests/GroupsTest.java
@@ -25,15 +25,6 @@
*/
package org.alfresco.rest.api.tests;
-import java.text.ParseException;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.servlet.http.HttpServletResponse;
-
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.rest.AbstractSingleNetworkSiteTest;
import org.alfresco.rest.api.tests.client.PublicApiClient;
@@ -41,8 +32,10 @@ import org.alfresco.rest.api.tests.client.PublicApiClient.Groups;
import org.alfresco.rest.api.tests.client.PublicApiClient.ListResponse;
import org.alfresco.rest.api.tests.client.PublicApiClient.Paging;
import org.alfresco.rest.api.tests.client.PublicApiException;
+import org.alfresco.rest.api.tests.client.RequestContext;
import org.alfresco.rest.api.tests.client.data.Group;
import org.alfresco.rest.api.tests.client.data.GroupMember;
+import org.alfresco.rest.api.tests.client.data.Person;
import org.alfresco.rest.framework.resource.parameters.SortColumn;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.AuthorityType;
@@ -51,6 +44,10 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import javax.servlet.http.HttpServletResponse;
+import java.text.ParseException;
+import java.util.*;
+
import static org.junit.Assert.*;
/**
@@ -455,9 +452,7 @@ public class GroupsTest extends AbstractSingleNetworkSiteTest
try
{
createAuthorityContext(user1);
- setRequestContext(networkAdmin);
canGetGroupsForUserId();
- // TODO: get details for -me- without 403
}
finally
{
@@ -467,9 +462,81 @@ public class GroupsTest extends AbstractSingleNetworkSiteTest
private void canGetGroupsForUserId() throws ParseException, PublicApiException
{
+ Person personAlice;
+ {
+ publicApiClient.setRequestContext(new RequestContext(networkOne.getId(), networkAdmin, "admin"));
+ personAlice = new Person();
+ String aliceId = "alice-" + UUID.randomUUID() + "@" + networkOne.getId();
+ personAlice.setUserName(aliceId);
+ personAlice.setId(aliceId);
+ personAlice.setFirstName("Alice");
+ personAlice.setEmail("alison.smith@example.com");
+ personAlice.setPassword("password");
+ personAlice.setEnabled(true);
+ PublicApiClient.People people = publicApiClient.people();
+ people.create(personAlice);
+ }
+
Groups groupsProxy = publicApiClient.groups();
- ListResponse groups = groupsProxy.getGroupsByPersonId(user1, null, "Couldn't get user's groups", 200);
- assertEquals(5L, (long) groups.getPaging().getCount());
+
+ // As admin
+ setRequestContext(networkOne.getId(), networkAdmin, "admin");
+
+ // New user has only the one default group.
+ {
+ ListResponse groups = groupsProxy.getGroupsByPersonId(personAlice.getId(), null, "Couldn't get user's groups", 200);
+ assertEquals(1L, (long) groups.getPaging().getTotalItems());
+ Iterator it = groups.getList().iterator();
+ assertEquals("GROUP_EVERYONE", it.next().getId());
+ }
+
+ // Add the user to a couple more groups and list them.
+ {
+ AuthenticationUtil.setAdminUserAsFullyAuthenticatedUser();
+ authorityService.addAuthority(groupA.getId(), personAlice.getId());
+ authorityService.addAuthority(groupB.getId(), personAlice.getId());
+
+ ListResponse groups = groupsProxy.getGroupsByPersonId(personAlice.getId(), null, "Couldn't get user's groups", 200);
+ assertEquals(4L, (long) groups.getPaging().getTotalItems());
+ Iterator it = groups.getList().iterator();
+ assertEquals("GROUP_EVERYONE", it.next().getId());
+ assertEquals(rootGroupName, it.next().getId());
+ assertEquals(groupA, it.next());
+ assertEquals(groupB, it.next());
+ }
+
+ // Get network admin's groups by explicit ID.
+ {
+ ListResponse groups = groupsProxy.getGroupsByPersonId(networkAdmin, null, "Couldn't get user's groups", 200);
+ assertEquals(6L, (long) groups.getPaging().getTotalItems());
+ }
+
+ // test -me- alias (as network admin)
+ {
+ ListResponse groups = groupsProxy.getGroupsByPersonId("-me-", null, "Couldn't get user's groups", 200);
+ assertEquals(6L, (long) groups.getPaging().getCount());
+ Iterator it = groups.getList().iterator();
+ assertEquals("GROUP_EVERYONE", it.next().getId());
+ }
+
+ // -ve test: attempt to get groups for non-existent person
+ {
+ groupsProxy.getGroupsByPersonId("i-do-not-exist", null, "Incorrect response", 404);
+ }
+
+ // As Alice
+// setRequestContext(networkOne.getId(), personAlice.getId(), "password");
+
+ // test -me- alias as Alice
+// {
+// ListResponse groups = groupsProxy.getGroupsByPersonId("-me-", null, "Couldn't get user's groups", 200);
+// assertEquals(4L, (long) groups.getPaging().getCount());
+// Iterator it = groups.getList().iterator();
+// assertEquals("GROUP_EVERYONE", it.next().getId());
+// assertEquals(rootGroupName, it.next().getId());
+// assertEquals(groupA, it.next());
+// assertEquals(groupB, it.next());
+// }
}
private void testGetGroupMembersByGroupId() throws Exception