summaryrefslogtreecommitdiffstats
path: root/gerrit-server/src/main/java/com/google/gerrit/server/group/ListGroups.java
diff options
context:
space:
mode:
Diffstat (limited to 'gerrit-server/src/main/java/com/google/gerrit/server/group/ListGroups.java')
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/group/ListGroups.java234
1 files changed, 234 insertions, 0 deletions
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/group/ListGroups.java b/gerrit-server/src/main/java/com/google/gerrit/server/group/ListGroups.java
new file mode 100644
index 0000000000..03ec06722a
--- /dev/null
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/group/ListGroups.java
@@ -0,0 +1,234 @@
+// 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.base.Objects;
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.gerrit.common.data.GroupDescriptions;
+import com.google.gerrit.common.data.GroupReference;
+import com.google.gerrit.common.errors.NoSuchGroupException;
+import com.google.gerrit.common.groups.ListGroupsOption;
+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.extensions.restapi.TopLevelResource;
+import com.google.gerrit.extensions.restapi.Url;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.AccountGroup;
+import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.OutputFormat;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.GetGroups;
+import com.google.gerrit.server.account.GroupCache;
+import com.google.gerrit.server.account.GroupComparator;
+import com.google.gerrit.server.account.GroupControl;
+import com.google.gerrit.server.group.GroupJson.GroupInfo;
+import com.google.gerrit.server.project.ProjectControl;
+import com.google.gson.reflect.TypeToken;
+import com.google.gwtorm.server.OrmException;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+import org.kohsuke.args4j.Option;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+/** List groups visible to the calling user. */
+public class ListGroups implements RestReadView<TopLevelResource> {
+
+ protected final GroupCache groupCache;
+
+ private final GroupControl.Factory groupControlFactory;
+ private final GroupControl.GenericFactory genericGroupControlFactory;
+ private final Provider<IdentifiedUser> identifiedUser;
+ private final IdentifiedUser.GenericFactory userFactory;
+ private final Provider<GetGroups> accountGetGroups;
+ private final GroupJson json;
+ private EnumSet<ListGroupsOption> options;
+
+ @Option(name = "--project", aliases = {"-p"},
+ usage = "projects for which the groups should be listed")
+ private final List<ProjectControl> projects = new ArrayList<ProjectControl>();
+
+ @Option(name = "--visible-to-all", usage = "to list only groups that are visible to all registered users")
+ private boolean visibleToAll;
+
+ @Option(name = "--type", usage = "type of group")
+ private AccountGroup.Type groupType;
+
+ @Option(name = "--user", aliases = {"-u"},
+ usage = "user for which the groups should be listed")
+ private Account.Id user;
+
+ @Option(name = "--owned", usage = "to list only groups that are owned by the specified user"
+ + " or by the calling user if no user was specifed")
+ private boolean owned;
+
+ private Set<AccountGroup.UUID> groupsToInspect = Sets.newHashSet();
+
+ @Option(name = "-q", usage = "group to inspect")
+ void addGroup(final AccountGroup.UUID id) {
+ groupsToInspect.add(id);
+ }
+
+ @Option(name = "-m", metaVar = "MATCH", usage = "match group substring")
+ private String matchSubstring;
+
+ @Option(name = "-o", multiValued = true, usage = "Output options per group")
+ public void addOption(ListGroupsOption o) {
+ options.add(o);
+ }
+
+ @Option(name = "-O", usage = "Output option flags, in hex")
+ void setOptionFlagsHex(String hex) {
+ options.addAll(ListGroupsOption.fromBits(Integer.parseInt(hex, 16)));
+ }
+
+ @Inject
+ protected ListGroups(final GroupCache groupCache,
+ final GroupControl.Factory groupControlFactory,
+ final GroupControl.GenericFactory genericGroupControlFactory,
+ final Provider<IdentifiedUser> identifiedUser,
+ final IdentifiedUser.GenericFactory userFactory,
+ final Provider<GetGroups> accountGetGroups, GroupJson json) {
+ this.groupCache = groupCache;
+ this.groupControlFactory = groupControlFactory;
+ this.genericGroupControlFactory = genericGroupControlFactory;
+ this.identifiedUser = identifiedUser;
+ this.userFactory = userFactory;
+ this.accountGetGroups = accountGetGroups;
+ this.json = json;
+ this.options = EnumSet.noneOf(ListGroupsOption.class);
+ }
+
+ public Account.Id getUser() {
+ return user;
+ }
+
+ public List<ProjectControl> getProjects() {
+ return projects;
+ }
+
+ @Override
+ public Object apply(TopLevelResource resource) throws AuthException,
+ BadRequestException, ResourceConflictException, Exception {
+ final Map<String, GroupInfo> output = Maps.newTreeMap();
+ for (GroupInfo info : get()) {
+ output.put(Objects.firstNonNull(
+ info.name,
+ "Group " + Url.decode(info.id)), info);
+ info.name = null;
+ }
+ return OutputFormat.JSON.newGson().toJsonTree(output,
+ new TypeToken<Map<String, GroupInfo>>() {}.getType());
+ }
+
+ public List<GroupInfo> get() throws OrmException {
+ List<GroupInfo> groupInfos;
+ if (user != null) {
+ if (owned) {
+ groupInfos = getGroupsOwnedBy(userFactory.create(user));
+ } else {
+ groupInfos = accountGetGroups.get().apply(
+ new AccountResource(userFactory.create(user)));
+ }
+ } else {
+ if (owned) {
+ groupInfos = getGroupsOwnedBy(identifiedUser.get());
+ } else {
+ List<AccountGroup> groupList;
+ if (!projects.isEmpty()) {
+ Map<AccountGroup.UUID, AccountGroup> groups = Maps.newHashMap();
+ for (final ProjectControl projectControl : projects) {
+ final Set<GroupReference> groupsRefs = projectControl.getAllGroups();
+ for (final GroupReference groupRef : groupsRefs) {
+ final AccountGroup group = groupCache.get(groupRef.getUUID());
+ if (group != null) {
+ groups.put(group.getGroupUUID(), group);
+ }
+ }
+ }
+ groupList = filterGroups(groups.values());
+ } else {
+ groupList = filterGroups(groupCache.all());
+ }
+ groupInfos = Lists.newArrayListWithCapacity(groupList.size());
+ for (AccountGroup group : groupList) {
+ groupInfos.add(json.addOptions(options).format(
+ GroupDescriptions.forAccountGroup(group)));
+ }
+ }
+ }
+ return groupInfos;
+ }
+
+ private List<GroupInfo> getGroupsOwnedBy(IdentifiedUser user)
+ throws OrmException {
+ List<GroupInfo> groups = Lists.newArrayList();
+ for (AccountGroup g : filterGroups(groupCache.all())) {
+ GroupControl ctl = groupControlFactory.controlFor(g);
+ try {
+ if (genericGroupControlFactory.controlFor(user, g.getGroupUUID())
+ .isOwner()) {
+ groups.add(json.addOptions(options).format(ctl.getGroup()));
+ }
+ } catch (NoSuchGroupException e) {
+ continue;
+ }
+ }
+ return groups;
+ }
+
+ private List<AccountGroup> filterGroups(final Iterable<AccountGroup> groups) {
+ final List<AccountGroup> filteredGroups = Lists.newArrayList();
+ final boolean isAdmin =
+ identifiedUser.get().getCapabilities().canAdministrateServer();
+ for (final AccountGroup group : groups) {
+ if (!Strings.isNullOrEmpty(matchSubstring)) {
+ if (!group.getName().toLowerCase(Locale.US)
+ .contains(matchSubstring.toLowerCase(Locale.US))) {
+ continue;
+ }
+ }
+ if (!isAdmin) {
+ final GroupControl c = groupControlFactory.controlFor(group);
+ if (!c.isVisible()) {
+ continue;
+ }
+ }
+ if ((visibleToAll && !group.isVisibleToAll())
+ || (groupType != null && !groupType.equals(group.getType()))) {
+ continue;
+ }
+ if (!groupsToInspect.isEmpty()
+ && !groupsToInspect.contains(group.getGroupUUID())) {
+ continue;
+ }
+ filteredGroups.add(group);
+ }
+ Collections.sort(filteredGroups, new GroupComparator());
+ return filteredGroups;
+ }
+}