Merge "ls-projects: Add option to list projects on which a certain group is used"

This commit is contained in:
Shawn Pearce
2012-10-05 15:06:07 -07:00
committed by Gerrit Code Review
4 changed files with 58 additions and 5 deletions

View File

@@ -16,6 +16,7 @@ SYNOPSIS
[--format {text | json | json_compact}]
[--all]
[--limit <N>]
[--has-acl-for GROUP]
DESCRIPTION
-----------
@@ -91,6 +92,13 @@ used to unescape the output.
--limit::
Cap the number of results to the first N matches.
--has-acl-for::
Display only projects on which access rights for this group are
directly assigned. Projects which only inherit access rights for
this group are not listed.
+
With this option you can find out on which projects a group is used.
HTTP
----
This command is also available over HTTP, as `/projects/` for

View File

@@ -15,11 +15,16 @@
package com.google.gerrit.server.project;
import com.google.common.collect.Maps;
import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.common.errors.NoSuchGroupException;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.Project.NameKey;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.OutputFormat;
import com.google.gerrit.server.StringUtil;
import com.google.gerrit.server.account.GroupCache;
import com.google.gerrit.server.account.GroupControl;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.util.TreeFormatter;
import com.google.gson.reflect.TypeToken;
@@ -86,6 +91,8 @@ public class ListProjects {
private final CurrentUser currentUser;
private final ProjectCache projectCache;
private final GroupCache groupCache;
private final GroupControl.Factory groupControlFactory;
private final GitRepositoryManager repoManager;
private final ProjectNode.Factory projectNodeFactory;
@@ -115,12 +122,18 @@ public class ListProjects {
private String matchPrefix;
@Option(name = "--has-acl-for", metaVar = "GROUP", usage =
"displays only projects on which access rights for this group are directly assigned")
private AccountGroup.Id groupId;
@Inject
protected ListProjects(CurrentUser currentUser, ProjectCache projectCache,
GitRepositoryManager repoManager,
ProjectNode.Factory projectNodeFactory) {
GroupCache groupCache, GroupControl.Factory groupControlFactory,
GitRepositoryManager repoManager, ProjectNode.Factory projectNodeFactory) {
this.currentUser = currentUser;
this.projectCache = projectCache;
this.groupCache = groupCache;
this.groupControlFactory = groupControlFactory;
this.repoManager = repoManager;
this.projectNodeFactory = projectNodeFactory;
}
@@ -175,6 +188,22 @@ public class ListProjects {
//
continue;
}
final ProjectControl pctl = e.controlFor(currentUser);
if (groupId != null) {
try {
if (!groupControlFactory.controlFor(groupId).isVisible()) {
break;
}
} catch (NoSuchGroupException ex) {
break;
}
if (!pctl.getLocalGroups().contains(
GroupReference.forGroup(groupCache.get(groupId)))) {
continue;
}
}
ProjectInfo info = new ProjectInfo();
if (type == FilterType.PARENT_CANDIDATES) {
ProjectState parentState = e.getParentState();
@@ -194,7 +223,6 @@ public class ListProjects {
}
} else {
final ProjectControl pctl = e.controlFor(currentUser);
final boolean isVisible = pctl.isVisible() || (all && pctl.isOwner());
if (showTree && !format.isJson()) {
treeMap.put(projectName,

View File

@@ -120,6 +120,7 @@ public class ProjectControl {
private final Collection<ContributorAgreement> contributorAgreements;
private List<SectionMatcher> allSections;
private List<SectionMatcher> localSections;
private Map<String, RefControl> refControls;
private Boolean declaredOwner;
@@ -239,8 +240,17 @@ public class ProjectControl {
}
public Set<GroupReference> getAllGroups() {
return getGroups(access());
}
public Set<GroupReference> getLocalGroups() {
return getGroups(localAccess());
}
private static Set<GroupReference> getGroups(
final List<SectionMatcher> sectionMatcherList) {
final Set<GroupReference> all = new HashSet<GroupReference>();
for (final SectionMatcher matcher : access()) {
for (final SectionMatcher matcher : sectionMatcherList) {
final AccessSection section = matcher.section;
for (final Permission permission : section.getPermissions()) {
for (final PermissionRule rule : permission.getRules()) {
@@ -392,6 +402,13 @@ public class ProjectControl {
return allSections;
}
private List<SectionMatcher> localAccess() {
if (localSections == null) {
localSections = state.getLocalAccessSections();
}
return localSections;
}
boolean match(PermissionRule rule) {
return match(rule.getGroup().getUUID());
}

View File

@@ -174,7 +174,7 @@ public class ProjectState {
}
/** Get the sections that pertain only to this project. */
private List<SectionMatcher> getLocalAccessSections() {
List<SectionMatcher> getLocalAccessSections() {
List<SectionMatcher> sm = localAccessSections;
if (sm == null) {
Collection<AccessSection> fromConfig = config.getAccessSections();