diff --git a/source/java/org/alfresco/rest/api/impl/GroupsImpl.java b/source/java/org/alfresco/rest/api/impl/GroupsImpl.java index 8859bf2072..8a361e9568 100644 --- a/source/java/org/alfresco/rest/api/impl/GroupsImpl.java +++ b/source/java/org/alfresco/rest/api/impl/GroupsImpl.java @@ -29,6 +29,7 @@ import org.alfresco.query.CannedQueryPageDetails; import org.alfresco.query.PagingRequest; import org.alfresco.query.PagingResults; import org.alfresco.repo.security.authority.AuthorityDAO; +import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authority.AuthorityInfo; import org.alfresco.repo.security.authority.UnknownAuthorityException; import org.alfresco.rest.antlr.WhereClauseParser; @@ -39,6 +40,7 @@ import org.alfresco.rest.api.model.GroupMember; import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException; import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException; import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; +import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException; import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; import org.alfresco.rest.framework.resource.parameters.Paging; import org.alfresco.rest.framework.resource.parameters.Parameters; @@ -56,6 +58,8 @@ import java.text.Collator; import java.util.*; import java.util.stream.Collectors; +import static org.alfresco.repo.security.authentication.AuthenticationUtil.runAsSystem; + /** * Centralises access to groups services and maps between representations. * @@ -190,10 +194,20 @@ public class GroupsImpl implements Groups } @Override - public CollectionWithPagingInfo getGroupsByPersonId(String personId, Parameters parameters) + public CollectionWithPagingInfo getGroupsByPersonId(String requestedPersonId, Parameters parameters) { // Canonicalize the person ID, performing -me- alias substitution. - personId = people.validatePerson(personId); + final String personId = people.validatePerson(requestedPersonId); + + // Non-admins can only access their own data + // TODO: this is also in PeopleImpl.update(personId,personInfo) - refactor? + boolean isAdmin = authorityService.hasAdminAuthority(); + String currentUserId = AuthenticationUtil.getFullyAuthenticatedUser(); + if (!isAdmin && !currentUserId.equalsIgnoreCase(personId)) + { + // The user is not an admin user and is not attempting to update *their own* details. + throw new PermissionDeniedException(); + } final List includeParam = parameters.getInclude(); Paging paging = parameters.getPaging(); @@ -203,7 +217,8 @@ public class GroupsImpl implements Groups Pair sortProp = getGroupsSortProp(parameters); // Get all the authorities for a user, including but not limited to, groups. - final Set userAuthorities = authorityService.getAuthoritiesForUser(personId); + Set userAuthorities = runAsSystem( + () -> authorityService.getAuthoritiesForUser(personId)); // Filter, transform and sort the list of user authorities into // a suitable list of AuthorityInfo objects. 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 30798862e3..3cc4e13dab 100644 --- a/source/test-java/org/alfresco/rest/api/tests/GroupsTest.java +++ b/source/test-java/org/alfresco/rest/api/tests/GroupsTest.java @@ -415,10 +415,28 @@ public class GroupsTest extends AbstractSingleNetworkSiteTest return groupsProxy.getGroupMembers(groupId, createParams(paging, otherParams), errorMessage, expectedStatus); } - private ListResponse getGroupsByPersonId(String userId, final PublicApiClient.Paging paging, Map otherParams, String errorMessage, int expectedStatus) throws Exception + private ListResponse getGroupsByPersonId(String userId, final PublicApiClient.Paging paging, + Map otherParams) throws Exception + { + return getGroupsByPersonId( + userId, + paging, + otherParams, + HttpServletResponse.SC_OK); + } + + private ListResponse getGroupsByPersonId( + String userId, + final PublicApiClient.Paging paging, + Map otherParams, + int expectedStatus) throws Exception { final Groups groupsProxy = publicApiClient.groups(); - return groupsProxy.getGroupsByPersonId(userId, createParams(paging, otherParams), errorMessage, expectedStatus); + return groupsProxy.getGroupsByPersonId( + userId, + createParams(paging, otherParams), + "Incorrect response when getting groups for user ID " + userId, + expectedStatus); } private ListResponse getGroupMembers(String groupId, final PublicApiClient.Paging paging, Map otherParams) throws Exception @@ -460,7 +478,7 @@ public class GroupsTest extends AbstractSingleNetworkSiteTest } } - private void canGetGroupsForUserId() throws ParseException, PublicApiException + private void canGetGroupsForUserId() throws Exception { Person personAlice; { @@ -525,18 +543,49 @@ public class GroupsTest extends AbstractSingleNetworkSiteTest } // As Alice -// setRequestContext(networkOne.getId(), personAlice.getId(), "password"); + 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()); -// } + { + 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()); + } + + // +ve: check skip count. + { + // Sort params + Map otherParams = new HashMap<>(); + addOrderBy(otherParams, org.alfresco.rest.api.Groups.PARAM_DISPLAY_NAME, false); + + // Paging and list groups + + int skipCount = 0; + int maxItems = 4; + Paging paging = getPaging(skipCount, maxItems); + + ListResponse resp = getGroupsByPersonId(personAlice.getId(), paging, otherParams); + + // Paging and list groups with skip count. + + skipCount = 2; + maxItems = 2; + paging = getPaging(skipCount, maxItems); + + ListResponse sublistResponse = getGroupsByPersonId(personAlice.getId(), paging, otherParams); + + List expectedSublist = sublist(resp.getList(), skipCount, maxItems); + checkList(expectedSublist, sublistResponse.getPaging(), sublistResponse); + } + + // -ve: check skip count. + { + getGroupsByPersonId(personAlice.getId(), getPaging(-1, null), null, HttpServletResponse.SC_BAD_REQUEST); + } } private void testGetGroupMembersByGroupId() throws Exception