diff --git a/Documentation/rest-api.txt b/Documentation/rest-api.txt index 7e7704461b..08b1d99ca3 100644 --- a/Documentation/rest-api.txt +++ b/Documentation/rest-api.txt @@ -315,6 +315,53 @@ and accepts the same options as query parameters. } ---- +[[group-members]] +/groups/*/members/ (List Group Members) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Lists the members of a group. + +---- +)]}' +[ + { + "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" + } +] +---- + +[[included-groups]] +/groups/*/groups/ (List Included Groups) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Lists the included groups of a group. + +---- +)]}' +[ + { + "kind": "gerritcodereview#group", + "id": "uuid-7ca042f4d5847936fcb90ca91057673157fd06fc", + "name": "MyProject-Verifiers", + "uuid": "7ca042f4d5847936fcb90ca91057673157fd06fc", + "group_id": 38, + "is_visible_to_all": false, + "owner_uuid": "7ca042f4d5847936fcb90ca91057673157fd06fc" + } +] +---- + [[changes]] /changes/ (Query Changes) ~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountResource.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountResource.java index 8964b98d36..9dc423ad42 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountResource.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountResource.java @@ -28,7 +28,7 @@ public class AccountResource implements RestResource { private final IdentifiedUser user; - AccountResource(IdentifiedUser user) { + public AccountResource(IdentifiedUser user) { this.user = user; } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/GroupControl.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/GroupControl.java index 06a3eba780..836e73fd6a 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/account/GroupControl.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/GroupControl.java @@ -69,6 +69,15 @@ public class GroupControl { } return c; } + + public GroupControl validateFor(final AccountGroup.UUID groupUUID) + throws NoSuchGroupException { + final GroupControl c = controlFor(groupUUID); + if (!c.isVisible()) { + throw new NoSuchGroupException(groupUUID); + } + return c; + } } private final CurrentUser user; diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java index ff8a5eb4f2..2449bf5723 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java @@ -43,6 +43,7 @@ import com.google.gerrit.server.account.EmailExpander; import com.google.gerrit.server.account.GroupBackend; import com.google.gerrit.server.account.GroupCacheImpl; import com.google.gerrit.server.account.GroupControl; +import com.google.gerrit.server.account.GroupDetailFactory; import com.google.gerrit.server.account.GroupIncludeCacheImpl; import com.google.gerrit.server.account.GroupInfoCacheFactory; import com.google.gerrit.server.account.IncludingGroupMembership; @@ -154,6 +155,7 @@ public class GerritGlobalModule extends FactoryModule { factory(ChangeQueryBuilder.Factory.class); factory(GroupInfoCacheFactory.Factory.class); factory(VisibleGroups.Factory.class); + factory(GroupDetailFactory.Factory.class); factory(InternalUser.Factory.class); factory(ProjectNode.Factory.class); factory(ProjectState.Factory.class); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritRequestModule.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritRequestModule.java index 2784f30681..b7360ff4c2 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritRequestModule.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritRequestModule.java @@ -20,7 +20,6 @@ import com.google.gerrit.server.ApprovalsUtil; import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.RequestCleanup; import com.google.gerrit.server.account.AccountControl; -import com.google.gerrit.server.account.GroupDetailFactory; import com.google.gerrit.server.account.GroupMembers; import com.google.gerrit.server.account.PerformCreateGroup; import com.google.gerrit.server.account.PerformRenameGroup; @@ -84,7 +83,6 @@ public class GerritRequestModule extends FactoryModule { factory(MergeFailSender.Factory.class); factory(PerformCreateGroup.Factory.class); factory(PerformRenameGroup.Factory.class); - factory(GroupDetailFactory.Factory.class); factory(GroupMembers.Factory.class); factory(CreateProject.Factory.class); factory(SuggestParentCandidates.Factory.class); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/group/GetGroup.java b/gerrit-server/src/main/java/com/google/gerrit/server/group/GetGroup.java index f7c7fb89c1..769225b0f7 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/group/GetGroup.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/group/GetGroup.java @@ -28,14 +28,18 @@ class GetGroup implements RestReadView { @Override public Object apply(GroupResource resource) throws AuthException, BadRequestException, ResourceConflictException, Exception { - GroupDescription.Basic group = resource.getControl().getGroup(); + return parse(resource.getControl().getGroup()); + } + + public static GroupInfo parse(final GroupDescription.Basic group) { GroupInfo info = new GroupInfo(); - info.name = resource.getName(); - info.uuid = resource.getGroupUUID().get(); + info.name = group.getName(); + info.uuid = group.getGroupUUID().get(); info.isVisibleToAll = group.isVisibleToAll(); if (group instanceof GroupDescription.Internal) { final AccountGroup internalGroup = ((GroupDescription.Internal) group).getAccountGroup(); + info.groupId = internalGroup.getId().get(); info.description = Strings.emptyToNull(internalGroup.getDescription()); info.ownerUuid = internalGroup.getOwnerGroupUUID().get(); } @@ -43,11 +47,12 @@ class GetGroup implements RestReadView { return info; } - static class GroupInfo { + public static class GroupInfo { final String kind = "gerritcodereview#group"; String id; String name; String uuid; + int groupId; String description; boolean isVisibleToAll; String ownerUuid; diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/group/GetIncludedGroup.java b/gerrit-server/src/main/java/com/google/gerrit/server/group/GetIncludedGroup.java new file mode 100644 index 0000000000..cc5373109b --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/group/GetIncludedGroup.java @@ -0,0 +1,30 @@ +// Copyright (C) 2013 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.server.group; + +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.server.group.GetGroup.GroupInfo; + +public class GetIncludedGroup implements RestReadView { + + @Override + public GroupInfo apply(final IncludedGroupResource resource) throws AuthException, + BadRequestException, ResourceConflictException, Exception { + return GetGroup.parse(resource.getControl().getGroup()); + } +} diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/group/GetMember.java b/gerrit-server/src/main/java/com/google/gerrit/server/group/GetMember.java new file mode 100644 index 0000000000..fc610a279c --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/group/GetMember.java @@ -0,0 +1,30 @@ +// Copyright (C) 2013 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.server.group; + +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.server.group.MembersCollection.MemberInfo; + +public class GetMember implements RestReadView { + + @Override + public MemberInfo apply(final MemberResource resource) throws AuthException, + BadRequestException, ResourceConflictException, Exception { + return MembersCollection.parse(resource.getUser().getAccount()); + } +} diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/group/GroupsCollection.java b/gerrit-server/src/main/java/com/google/gerrit/server/group/GroupsCollection.java index c085521687..23cb807e1f 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/group/GroupsCollection.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/group/GroupsCollection.java @@ -72,7 +72,12 @@ public class GroupsCollection implements } else if(!(user instanceof IdentifiedUser)) { throw new ResourceNotFoundException(id); } + return parse(id, groupControlFactory); + } + public static GroupResource parse(final String id, + final GroupControl.Factory groupControlFactory) + throws ResourceNotFoundException { final String decodedId = Url.decode(id); final GroupControl ctl; try { diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/group/IncludedGroupResource.java b/gerrit-server/src/main/java/com/google/gerrit/server/group/IncludedGroupResource.java new file mode 100644 index 0000000000..7d12151905 --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/group/IncludedGroupResource.java @@ -0,0 +1,28 @@ +// Copyright (C) 2013 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.server.group; + +import com.google.gerrit.extensions.restapi.RestView; +import com.google.gerrit.server.account.GroupControl; +import com.google.inject.TypeLiteral; + +public class IncludedGroupResource extends GroupResource { + public static final TypeLiteral> INCLUDED_GROUP_KIND = + new TypeLiteral>() {}; + + IncludedGroupResource(final GroupControl control) { + super(control); + } +} diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/group/IncludedGroupsCollection.java b/gerrit-server/src/main/java/com/google/gerrit/server/group/IncludedGroupsCollection.java new file mode 100644 index 0000000000..b82901c650 --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/group/IncludedGroupsCollection.java @@ -0,0 +1,84 @@ +// Copyright (C) 2013 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.server.group; + +import com.google.gerrit.common.data.GroupDetail; +import com.google.gerrit.extensions.registration.DynamicMap; +import com.google.gerrit.extensions.restapi.AuthException; +import com.google.gerrit.extensions.restapi.ChildCollection; +import com.google.gerrit.extensions.restapi.ResourceNotFoundException; +import com.google.gerrit.extensions.restapi.RestView; +import com.google.gerrit.reviewdb.client.AccountGroup; +import com.google.gerrit.reviewdb.client.AccountGroupInclude; +import com.google.gerrit.server.account.GroupCache; +import com.google.gerrit.server.account.GroupControl; +import com.google.gerrit.server.account.GroupDetailFactory; +import com.google.inject.Inject; +import com.google.inject.Provider; + +public class IncludedGroupsCollection implements + ChildCollection { + + private final DynamicMap> views; + private final Provider list; + private final GroupControl.Factory groupControlFactory; + private final GroupCache groupCache; + private final GroupDetailFactory.Factory groupDetailFactory; + + @Inject + IncludedGroupsCollection(final DynamicMap> views, + final Provider list, + final GroupControl.Factory groupControlFactory, + final GroupCache groupCache, + final GroupDetailFactory.Factory groupDetailFactory) { + this.views = views; + this.list = list; + this.groupControlFactory = groupControlFactory; + this.groupCache = groupCache; + this.groupDetailFactory = groupDetailFactory; + } + + @Override + public RestView list() throws ResourceNotFoundException, + AuthException { + return list.get(); + } + + @Override + public IncludedGroupResource parse(final GroupResource parent, final String id) + throws ResourceNotFoundException, Exception { + final GroupResource groupResource = + GroupsCollection.parse(id, groupControlFactory); + final AccountGroup group = + groupCache.get(parent.getControl().getGroup().getGroupUUID()); + final GroupDetail groupDetail = + groupDetailFactory.create(group.getId()).call(); + if (groupDetail.includes != null) { + for (final AccountGroupInclude groupInclude : groupDetail.includes) { + final AccountGroup includedGroup = + groupCache.get(groupInclude.getIncludeId()); + if (includedGroup.getGroupUUID().equals(groupResource.getGroupUUID())) { + return new IncludedGroupResource(groupResource.getControl()); + } + } + } + throw new ResourceNotFoundException(id); + } + + @Override + public DynamicMap> views() { + return views; + } +} diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/group/ListIncludedGroups.java b/gerrit-server/src/main/java/com/google/gerrit/server/group/ListIncludedGroups.java new file mode 100644 index 0000000000..58f6981aac --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/group/ListIncludedGroups.java @@ -0,0 +1,72 @@ +// Copyright (C) 2013 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.server.group; + +import com.google.common.collect.Lists; +import com.google.gerrit.common.data.GroupDescriptions; +import com.google.gerrit.common.data.GroupDetail; +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.AccountGroup; +import com.google.gerrit.reviewdb.client.AccountGroupInclude; +import com.google.gerrit.server.account.GroupCache; +import com.google.gerrit.server.account.GroupControl; +import com.google.gerrit.server.account.GroupDetailFactory; +import com.google.gerrit.server.group.GetGroup.GroupInfo; +import com.google.inject.Inject; + +import java.util.List; + +public class ListIncludedGroups implements RestReadView { + private final GroupControl.Factory groupControlFactory; + private final GroupCache groupCache; + private final GroupDetailFactory.Factory groupDetailFactory; + + @Inject + ListIncludedGroups(final GroupControl.Factory groupControlFactory, + final GroupCache groupCache, + final GroupDetailFactory.Factory groupDetailFactory) { + this.groupControlFactory = groupControlFactory; + this.groupCache = groupCache; + this.groupDetailFactory = groupDetailFactory; + } + + @Override + public List apply(final GroupResource resource) + throws AuthException, BadRequestException, ResourceConflictException, + Exception { + final List includedGroups = Lists.newArrayList(); + + final GroupControl groupControl = + groupControlFactory.validateFor(resource.getGroupUUID()); + final AccountGroup group = + groupCache.get(groupControl.getGroup().getGroupUUID()); + final GroupDetail groupDetail = + groupDetailFactory.create(group.getId()).call(); + + if (groupDetail.includes != null) { + for (final AccountGroupInclude groupInclude : groupDetail.includes) { + final AccountGroup includedGroup = + groupCache.get(groupInclude.getIncludeId()); + includedGroups.add(GetGroup.parse(GroupDescriptions + .forAccountGroup(includedGroup))); + } + } + + return includedGroups; + } +} diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/group/ListMembers.java b/gerrit-server/src/main/java/com/google/gerrit/server/group/ListMembers.java new file mode 100644 index 0000000000..ace3138891 --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/group/ListMembers.java @@ -0,0 +1,73 @@ +// Copyright (C) 2013 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.server.group; + +import com.google.common.collect.Lists; +import com.google.gerrit.common.data.GroupDetail; +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.AccountGroupMember; +import com.google.gerrit.server.account.AccountCache; +import com.google.gerrit.server.account.GroupCache; +import com.google.gerrit.server.account.GroupControl; +import com.google.gerrit.server.account.GroupDetailFactory; +import com.google.gerrit.server.group.MembersCollection.MemberInfo; +import com.google.inject.Inject; + +import java.util.List; + +public class ListMembers implements RestReadView { + private final GroupControl.Factory groupControlFactory; + private final GroupCache groupCache; + private final GroupDetailFactory.Factory groupDetailFactory; + private final AccountCache accountCache; + + @Inject + ListMembers(final GroupControl.Factory groupControlFactory, + final GroupCache groupCache, + final GroupDetailFactory.Factory groupDetailFactory, + final AccountCache accountCache) { + this.groupControlFactory = groupControlFactory; + this.groupCache = groupCache; + this.groupDetailFactory = groupDetailFactory; + this.accountCache = accountCache; + } + + @Override + public List apply(final GroupResource resource) throws AuthException, + BadRequestException, ResourceConflictException, Exception { + final List members = Lists.newArrayList(); + + final GroupControl groupControl = + groupControlFactory.validateFor(resource.getGroupUUID()); + final AccountGroup group = + groupCache.get(groupControl.getGroup().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)); + } + } + + return members; + } +} diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/group/MemberResource.java b/gerrit-server/src/main/java/com/google/gerrit/server/group/MemberResource.java new file mode 100644 index 0000000000..6249fc148f --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/group/MemberResource.java @@ -0,0 +1,29 @@ +// Copyright (C) 2013 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.server.group; + +import com.google.gerrit.extensions.restapi.RestView; +import com.google.gerrit.server.IdentifiedUser; +import com.google.gerrit.server.account.AccountResource; +import com.google.inject.TypeLiteral; + +public class MemberResource extends AccountResource { + public static final TypeLiteral> MEMBER_KIND = + new TypeLiteral>() {}; + + public MemberResource(IdentifiedUser user) { + super(user); + } +} diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/group/MembersCollection.java b/gerrit-server/src/main/java/com/google/gerrit/server/group/MembersCollection.java new file mode 100644 index 0000000000..00d5896a0d --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/group/MembersCollection.java @@ -0,0 +1,114 @@ +// Copyright (C) 2013 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.server.group; + +import com.google.gerrit.common.data.GroupDetail; +import com.google.gerrit.extensions.registration.DynamicMap; +import com.google.gerrit.extensions.restapi.AuthException; +import com.google.gerrit.extensions.restapi.ChildCollection; +import com.google.gerrit.extensions.restapi.ResourceNotFoundException; +import com.google.gerrit.extensions.restapi.RestView; +import com.google.gerrit.reviewdb.client.Account; +import com.google.gerrit.reviewdb.client.AccountGroup; +import com.google.gerrit.reviewdb.client.AccountGroupMember; +import com.google.gerrit.server.IdentifiedUser; +import com.google.gerrit.server.account.GroupCache; +import com.google.gerrit.server.account.GroupDetailFactory; +import com.google.gerrit.server.util.Url; +import com.google.inject.Inject; +import com.google.inject.Provider; + +public class MembersCollection implements + ChildCollection { + + private final DynamicMap> views; + private final Provider list; + private final IdentifiedUser.GenericFactory userGenericFactory; + private final GroupCache groupCache; + private final GroupDetailFactory.Factory groupDetailFactory; + + @Inject + MembersCollection(final DynamicMap> views, + final Provider list, + final IdentifiedUser.GenericFactory userGenericFactory, + final GroupCache groupCache, + final GroupDetailFactory.Factory groupDetailFactory) { + this.views = views; + this.list = list; + this.userGenericFactory = userGenericFactory; + this.groupCache = groupCache; + this.groupDetailFactory = groupDetailFactory; + } + + @Override + public RestView list() throws ResourceNotFoundException, + AuthException { + return list.get(); + } + + @Override + public MemberResource parse(final GroupResource parent, final String id) + throws ResourceNotFoundException, Exception { + final Account.Id accountId; + try { + accountId = new Account.Id(Integer.parseInt(Url.decode(id))); + } catch (NumberFormatException e) { + throw new ResourceNotFoundException(id); + } + + final AccountGroup group = + groupCache.get(parent.getControl().getGroup().getGroupUUID()); + final GroupDetail groupDetail = + groupDetailFactory.create(group.getId()).call(); + if (groupDetail.members != null) { + for (final AccountGroupMember member : groupDetail.members) { + if (member.getAccountId().equals(accountId)) { + return new MemberResource( + userGenericFactory.create(accountId)); + } + } + } + throw new ResourceNotFoundException(id); + } + + @Override + public DynamicMap> views() { + return views; + } + + public static MemberInfo parse(final Account account) { + final MemberInfo accountInfo = new MemberInfo(); + accountInfo.setId(account.getId()); + accountInfo.fullName = account.getFullName(); + accountInfo.preferredEmail = account.getPreferredEmail(); + accountInfo.userName = account.getUserName(); + return accountInfo; + } + + static class MemberInfo { + final String kind = "gerritcodereview#member"; + + String fullName; + String id; + int accountId; + String preferredEmail; + String userName; + + void setId(Account.Id i) { + accountId = i.get(); + id = Url.encode(Integer.toString(accountId)); + } + } +} diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/group/Module.java b/gerrit-server/src/main/java/com/google/gerrit/server/group/Module.java index 58f15069d3..3bf1e1f215 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/group/Module.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/group/Module.java @@ -15,6 +15,8 @@ package com.google.gerrit.server.group; import static com.google.gerrit.server.group.GroupResource.GROUP_KIND; +import static com.google.gerrit.server.group.IncludedGroupResource.INCLUDED_GROUP_KIND; +import static com.google.gerrit.server.group.MemberResource.MEMBER_KIND; import com.google.gerrit.extensions.registration.DynamicMap; import com.google.gerrit.extensions.restapi.RestApiModule; @@ -25,7 +27,15 @@ public class Module extends RestApiModule { bind(GroupsCollection.class); DynamicMap.mapOf(binder(), GROUP_KIND); + DynamicMap.mapOf(binder(), MEMBER_KIND); + DynamicMap.mapOf(binder(), INCLUDED_GROUP_KIND); get(GROUP_KIND).to(GetGroup.class); + + child(GROUP_KIND, "members").to(MembersCollection.class); + get(MEMBER_KIND).to(GetMember.class); + + child(GROUP_KIND, "groups").to(IncludedGroupsCollection.class); + get(INCLUDED_GROUP_KIND).to(GetIncludedGroup.class); } }