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

Add an option to the ls-groups SSH command that allows to list only
those groups for which any permission is assigned to a project.

Change-Id: Ied7274d433a38eae82b4970154004eb9cc4216c2
Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
This commit is contained in:
Edwin Kempin
2011-09-05 15:48:33 +02:00
parent cf6c35942d
commit e11aeae5c0
5 changed files with 131 additions and 17 deletions

View File

@@ -9,6 +9,7 @@ SYNOPSIS
--------
[verse]
'ssh' -p <port> <host> 'gerrit ls-groups'
[--project <NAME>]
DESCRIPTION
-----------
@@ -26,6 +27,17 @@ SCRIPTING
---------
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
--------
@@ -39,6 +51,15 @@ List visible groups:
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
------
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.GroupList;
import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.common.errors.NoSuchGroupException;
import com.google.gerrit.reviewdb.AccountGroup;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gwtorm.client.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import org.apache.commons.collections.CollectionUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
public class VisibleGroups {
@@ -39,6 +44,8 @@ public class VisibleGroups {
private final GroupControl.Factory groupControlFactory;
private final GroupDetailFactory.Factory groupDetailFactory;
private Collection<ProjectControl> projects;
@Inject
VisibleGroups(final Provider<IdentifiedUser> currentUser,
final GroupCache groupCache,
@@ -50,24 +57,59 @@ public class VisibleGroups {
this.groupDetailFactory = groupDetailFactory;
}
public void setProjects(final Collection<ProjectControl> projects) {
this.projects = projects;
}
public GroupList get() throws OrmException, NoSuchGroupException {
final IdentifiedUser user = identifiedUser.get();
final List<AccountGroup> list = new ArrayList<AccountGroup>();
if (user.getCapabilities().canAdministrateServer()) {
CollectionUtils.addAll(list, groupCache.all().iterator());
final Iterable<AccountGroup> groups;
if (projects != null && !projects.isEmpty()) {
groups = getGroupsForProjects();
} else {
for(final AccountGroup group : groupCache.all()) {
final GroupControl c = groupControlFactory.controlFor(group);
if (c.isVisible()) {
list.add(c.getAccountGroup());
groups = groupCache.all();
}
return createGroupList(filterGroups(groups));
}
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>();
for(AccountGroup group : list) {
l.add(groupDetailFactory.create(group.getId()).call());
private List<AccountGroup> filterGroups(final Iterable<AccountGroup> groups) {
final List<AccountGroup> filteredGroups = new LinkedList<AccountGroup>();
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.data.AccessSection;
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.PermissionRule;
import com.google.gerrit.common.data.PermissionRule.Action;
@@ -253,6 +254,19 @@ public class ProjectControl {
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 {
if (! (user instanceof IdentifiedUser)) {
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.errors.NoSuchGroupException;
import com.google.gerrit.server.account.VisibleGroups;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.sshd.BaseCommand;
import com.google.gwtorm.client.OrmException;
import com.google.inject.Inject;
import org.apache.sshd.server.Environment;
import org.kohsuke.args4j.Option;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
public class ListGroupsCommand extends BaseCommand {
@Inject
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
public void start(final Environment env) throws IOException {
startThread(new CommandRunnable() {
@@ -46,9 +55,10 @@ public class ListGroupsCommand extends BaseCommand {
private void display() throws Failure {
final PrintWriter stdout = toPrintWriter(out);
try {
final GroupList visibleGroups =
visibleGroupsFactory.create().get();
for (final GroupDetail groupDetail : visibleGroups.getGroups()) {
final VisibleGroups visibleGroups = visibleGroupsFactory.create();
visibleGroups.setProjects(projects);
final GroupList groupList = visibleGroups.get();
for (final GroupDetail groupDetail : groupList.getGroups()) {
stdout.print(groupDetail.group.getName() + "\n");
}
} catch (OrmException e) {