Merge "Support recursive group resolution in list members REST endpoint"
This commit is contained in:
@@ -337,6 +337,45 @@ Lists the direct members of a group.
|
||||
]
|
||||
----
|
||||
|
||||
To resolve the included groups of a group recursively and to list all
|
||||
members the parameter `recursive` can be set.
|
||||
|
||||
----
|
||||
GET /groups/834ec36dd5e0ed21a2ff5d7e2255da082d63bbd7/members/?recursive HTTP/1.0
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Disposition: attachment
|
||||
Content-Type: application/json;charset=UTF-8
|
||||
|
||||
)]}'
|
||||
[
|
||||
{
|
||||
"kind": "gerritcodereview#member",
|
||||
"full_name": "Jane Roe",
|
||||
"id": "1000097",
|
||||
"account_id": 1000097,
|
||||
"preferred_email": "jane.roe@example.com",
|
||||
"user_name": "jane"
|
||||
},
|
||||
{
|
||||
"kind": "gerritcodereview#member",
|
||||
"full_name": "John Doe",
|
||||
"id": "1000096",
|
||||
"account_id": 1000096,
|
||||
"preferred_email": "john.doe@example.com",
|
||||
"user_name": "doe"
|
||||
},
|
||||
{
|
||||
"kind": "gerritcodereview#member",
|
||||
"full_name": "Richard Roe",
|
||||
"id": "1000098",
|
||||
"account_id": 1000098,
|
||||
"preferred_email": "richard.roe@example.com",
|
||||
"user_name": "richard"
|
||||
}
|
||||
]
|
||||
----
|
||||
|
||||
[[included-groups]]
|
||||
/groups/*/groups/ (List Included Groups)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@@ -15,27 +15,39 @@
|
||||
package com.google.gerrit.server.group;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gerrit.common.data.GroupDetail;
|
||||
import com.google.gerrit.common.errors.NoSuchGroupException;
|
||||
import com.google.gerrit.extensions.restapi.AuthException;
|
||||
import com.google.gerrit.extensions.restapi.BadRequestException;
|
||||
import com.google.gerrit.extensions.restapi.ResourceConflictException;
|
||||
import com.google.gerrit.extensions.restapi.RestReadView;
|
||||
import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroupIncludeByUuid;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroupMember;
|
||||
import com.google.gerrit.server.account.AccountCache;
|
||||
import com.google.gerrit.server.account.GroupCache;
|
||||
import com.google.gerrit.server.account.GroupDetailFactory;
|
||||
import com.google.gerrit.server.group.MembersCollection.MemberInfo;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import org.kohsuke.args4j.Option;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ListMembers implements RestReadView<GroupResource> {
|
||||
private final GroupCache groupCache;
|
||||
private final GroupDetailFactory.Factory groupDetailFactory;
|
||||
private final AccountCache accountCache;
|
||||
|
||||
@Option(name = "--recursive", usage = "to resolve included groups recursively")
|
||||
private boolean recursive;
|
||||
|
||||
@Inject
|
||||
ListMembers(final GroupCache groupCache,
|
||||
final GroupDetailFactory.Factory groupDetailFactory,
|
||||
@@ -46,22 +58,49 @@ public class ListMembers implements RestReadView<GroupResource> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MemberInfo> apply(final GroupResource resource) throws AuthException,
|
||||
BadRequestException, ResourceConflictException, Exception {
|
||||
final List<MemberInfo> members = Lists.newArrayList();
|
||||
public List<MemberInfo> apply(final GroupResource resource)
|
||||
throws AuthException, BadRequestException, ResourceConflictException,
|
||||
Exception {
|
||||
final Map<Account.Id, MemberInfo> members =
|
||||
getMembers(resource.getGroupUUID(), new HashSet<AccountGroup.UUID>());
|
||||
return Lists.newArrayList(members.values());
|
||||
}
|
||||
|
||||
private Map<Account.Id, MemberInfo> getMembers(
|
||||
final AccountGroup.UUID groupUUID,
|
||||
final HashSet<AccountGroup.UUID> seenGroups) throws OrmException,
|
||||
NoSuchGroupException {
|
||||
seenGroups.add(groupUUID);
|
||||
|
||||
final Map<Account.Id, MemberInfo> members = Maps.newHashMap();
|
||||
final AccountGroup group = groupCache.get(groupUUID);
|
||||
if (group == null) {
|
||||
// the included group is an external group and can't be resolved
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
final AccountGroup group =
|
||||
groupCache.get(resource.getGroupUUID());
|
||||
final GroupDetail groupDetail =
|
||||
groupDetailFactory.create(group.getId()).call();
|
||||
|
||||
if (groupDetail.members != null) {
|
||||
for (final AccountGroupMember member : groupDetail.members) {
|
||||
final Account account = accountCache.get(member.getAccountId()).getAccount();
|
||||
members.add(MembersCollection.parse(account));
|
||||
for (final AccountGroupMember m : groupDetail.members) {
|
||||
if (!members.containsKey(m.getAccountId())) {
|
||||
final Account account =
|
||||
accountCache.get(m.getAccountId()).getAccount();
|
||||
members.put(account.getId(), MembersCollection.parse(account));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (recursive) {
|
||||
if (groupDetail.includes != null) {
|
||||
for (final AccountGroupIncludeByUuid includedGroup : groupDetail.includes) {
|
||||
if (!seenGroups.contains(includedGroup.getIncludeUUID())) {
|
||||
members.putAll(getMembers(includedGroup.getIncludeUUID(), seenGroups));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return members;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user