Merge "ls-groups: add option to list groups for a project"

This commit is contained in:
Martin Fick
2011-11-07 14:45:15 -08:00
committed by gerrit code review
5 changed files with 131 additions and 17 deletions

View File

@@ -9,6 +9,7 @@ SYNOPSIS
-------- --------
[verse] [verse]
'ssh' -p <port> <host> 'gerrit ls-groups' 'ssh' -p <port> <host> 'gerrit ls-groups'
[--project <NAME>]
DESCRIPTION DESCRIPTION
----------- -----------
@@ -26,6 +27,17 @@ SCRIPTING
--------- ---------
This command is intended to be used in scripts. This command is intended to be used in scripts.
OPTIONS
-------
--project::
-p::
Name of the project for which the groups should be listed. Only
groups are listed for which any permission is set on this project
(or for which a permission is inherited from a parent project).
Multiple --project options may be specified to specify additional
projects. In this case all groups are listed that have a
permission for any of the specified projects.
EXAMPLES EXAMPLES
-------- --------
@@ -39,6 +51,15 @@ List visible groups:
Registered Users Registered Users
===== =====
List all groups for which any permission is set for the project
"MyProject":
=====
$ ssh -p 29418 review.example.com gerrit ls-groups --project MyProject
MyProject_Committers
Project Owners
Registered Users
=====
GERRIT GERRIT
------ ------
Part of link:index.html[Gerrit Code Review] Part of link:index.html[Gerrit Code Review]

View File

@@ -0,0 +1,27 @@
// Copyright (C) 2011 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.account;
import com.google.gerrit.reviewdb.AccountGroup;
import java.util.Comparator;
public class GroupComparator implements Comparator<AccountGroup> {
@Override
public int compare(final AccountGroup group1, final AccountGroup group2) {
return group1.getName().compareTo(group2.getName());
}
}

View File

@@ -16,17 +16,22 @@ package com.google.gerrit.server.account;
import com.google.gerrit.common.data.GroupDetail; import com.google.gerrit.common.data.GroupDetail;
import com.google.gerrit.common.data.GroupList; import com.google.gerrit.common.data.GroupList;
import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.common.errors.NoSuchGroupException; import com.google.gerrit.common.errors.NoSuchGroupException;
import com.google.gerrit.reviewdb.AccountGroup; import com.google.gerrit.reviewdb.AccountGroup;
import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gwtorm.client.OrmException; import com.google.gwtorm.client.OrmException;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provider; import com.google.inject.Provider;
import org.apache.commons.collections.CollectionUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
public class VisibleGroups { public class VisibleGroups {
@@ -39,6 +44,8 @@ public class VisibleGroups {
private final GroupControl.Factory groupControlFactory; private final GroupControl.Factory groupControlFactory;
private final GroupDetailFactory.Factory groupDetailFactory; private final GroupDetailFactory.Factory groupDetailFactory;
private Collection<ProjectControl> projects;
@Inject @Inject
VisibleGroups(final Provider<IdentifiedUser> currentUser, VisibleGroups(final Provider<IdentifiedUser> currentUser,
final GroupCache groupCache, final GroupCache groupCache,
@@ -50,24 +57,59 @@ public class VisibleGroups {
this.groupDetailFactory = groupDetailFactory; this.groupDetailFactory = groupDetailFactory;
} }
public void setProjects(final Collection<ProjectControl> projects) {
this.projects = projects;
}
public GroupList get() throws OrmException, NoSuchGroupException { public GroupList get() throws OrmException, NoSuchGroupException {
final IdentifiedUser user = identifiedUser.get(); final Iterable<AccountGroup> groups;
final List<AccountGroup> list = new ArrayList<AccountGroup>(); if (projects != null && !projects.isEmpty()) {
if (user.getCapabilities().canAdministrateServer()) { groups = getGroupsForProjects();
CollectionUtils.addAll(list, groupCache.all().iterator());
} else { } else {
for(final AccountGroup group : groupCache.all()) { groups = groupCache.all();
final GroupControl c = groupControlFactory.controlFor(group); }
if (c.isVisible()) { return createGroupList(filterGroups(groups));
list.add(c.getAccountGroup()); }
private Set<AccountGroup> getGroupsForProjects() throws NoSuchGroupException {
final SortedSet<AccountGroup> groups =
new TreeSet<AccountGroup>(new GroupComparator());
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) {
throw new NoSuchGroupException(groupRef.getUUID());
} }
groups.add(group);
} }
} }
return groups;
}
List<GroupDetail> l = new ArrayList<GroupDetail>(); private List<AccountGroup> filterGroups(final Iterable<AccountGroup> groups) {
for(AccountGroup group : list) { final List<AccountGroup> filteredGroups = new LinkedList<AccountGroup>();
l.add(groupDetailFactory.create(group.getId()).call()); final boolean isAdmin =
identifiedUser.get().getCapabilities().canAdministrateServer();
for (final AccountGroup group : groups) {
if (!isAdmin) {
final GroupControl c = groupControlFactory.controlFor(group);
if (!c.isVisible()) {
continue;
}
}
filteredGroups.add(group);
} }
return new GroupList(l, user.getCapabilities().canCreateGroup()); return filteredGroups;
}
private GroupList createGroupList(final List<AccountGroup> groups)
throws OrmException, NoSuchGroupException {
final List<GroupDetail> groupDetailList = new ArrayList<GroupDetail>();
for (final AccountGroup group : groups) {
groupDetailList.add(groupDetailFactory.create(group.getId()).call());
}
return new GroupList(groupDetailList, identifiedUser.get()
.getCapabilities().canCreateGroup());
} }
} }

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.server.project;
import com.google.gerrit.common.PageLinks; import com.google.gerrit.common.PageLinks;
import com.google.gerrit.common.data.AccessSection; import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.Capable; import com.google.gerrit.common.data.Capable;
import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.common.data.Permission; import com.google.gerrit.common.data.Permission;
import com.google.gerrit.common.data.PermissionRule; import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.reviewdb.AbstractAgreement; import com.google.gerrit.reviewdb.AbstractAgreement;
@@ -252,6 +253,19 @@ public class ProjectControl {
return Capable.OK; return Capable.OK;
} }
public Set<GroupReference> getAllGroups() {
final Set<GroupReference> all = new HashSet<GroupReference>();
for (final SectionMatcher matcher : access()) {
final AccessSection section = matcher.section;
for (final Permission permission : section.getPermissions()) {
for (final PermissionRule rule : permission.getRules()) {
all.add(rule.getGroup());
}
}
}
return all;
}
private Capable verifyActiveContributorAgreement() throws OrmException { private Capable verifyActiveContributorAgreement() throws OrmException {
if (! (user instanceof IdentifiedUser)) { if (! (user instanceof IdentifiedUser)) {
return new Capable("Must be logged in to verify Contributor Agreement"); return new Capable("Must be logged in to verify Contributor Agreement");

View File

@@ -18,20 +18,29 @@ import com.google.gerrit.common.data.GroupDetail;
import com.google.gerrit.common.data.GroupList; import com.google.gerrit.common.data.GroupList;
import com.google.gerrit.common.errors.NoSuchGroupException; import com.google.gerrit.common.errors.NoSuchGroupException;
import com.google.gerrit.server.account.VisibleGroups; import com.google.gerrit.server.account.VisibleGroups;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.sshd.BaseCommand; import com.google.gerrit.sshd.BaseCommand;
import com.google.gwtorm.client.OrmException; import com.google.gwtorm.client.OrmException;
import com.google.inject.Inject; import com.google.inject.Inject;
import org.apache.sshd.server.Environment; import org.apache.sshd.server.Environment;
import org.kohsuke.args4j.Option;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
public class ListGroupsCommand extends BaseCommand { public class ListGroupsCommand extends BaseCommand {
@Inject @Inject
private VisibleGroups.Factory visibleGroupsFactory; private VisibleGroups.Factory visibleGroupsFactory;
@Option(name = "--project", aliases = {"-p"},
usage = "projects for which the groups should be listed")
private final List<ProjectControl> projects = new ArrayList<ProjectControl>();
@Override @Override
public void start(final Environment env) throws IOException { public void start(final Environment env) throws IOException {
startThread(new CommandRunnable() { startThread(new CommandRunnable() {
@@ -46,9 +55,10 @@ public class ListGroupsCommand extends BaseCommand {
private void display() throws Failure { private void display() throws Failure {
final PrintWriter stdout = toPrintWriter(out); final PrintWriter stdout = toPrintWriter(out);
try { try {
final GroupList visibleGroups = final VisibleGroups visibleGroups = visibleGroupsFactory.create();
visibleGroupsFactory.create().get(); visibleGroups.setProjects(projects);
for (final GroupDetail groupDetail : visibleGroups.getGroups()) { final GroupList groupList = visibleGroups.get();
for (final GroupDetail groupDetail : groupList.getGroups()) {
stdout.print(groupDetail.group.getName() + "\n"); stdout.print(groupDetail.group.getName() + "\n");
} }
} catch (OrmException e) { } catch (OrmException e) {