ls-projects: Add option to list projects on which a certain group is used
Add a --has-acl-for option to the ls-projects command that allows to list only projects on which access rights for the specified group are assigned directly. 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 (still) used, e.g. before removing a group (by deletion in the database). Change-Id: Iab139425808766fbf4e352584b0035fe1c071d93 Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
This commit is contained in:
@@ -16,6 +16,7 @@ SYNOPSIS
|
|||||||
[--format {text | json | json_compact}]
|
[--format {text | json | json_compact}]
|
||||||
[--all]
|
[--all]
|
||||||
[--limit <N>]
|
[--limit <N>]
|
||||||
|
[--has-acl-for GROUP]
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
@@ -91,6 +92,13 @@ used to unescape the output.
|
|||||||
--limit::
|
--limit::
|
||||||
Cap the number of results to the first N matches.
|
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
|
HTTP
|
||||||
----
|
----
|
||||||
This command is also available over HTTP, as `/projects/` for
|
This command is also available over HTTP, as `/projects/` for
|
||||||
|
@@ -15,11 +15,16 @@
|
|||||||
package com.google.gerrit.server.project;
|
package com.google.gerrit.server.project;
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
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;
|
||||||
import com.google.gerrit.reviewdb.client.Project.NameKey;
|
import com.google.gerrit.reviewdb.client.Project.NameKey;
|
||||||
import com.google.gerrit.server.CurrentUser;
|
import com.google.gerrit.server.CurrentUser;
|
||||||
import com.google.gerrit.server.OutputFormat;
|
import com.google.gerrit.server.OutputFormat;
|
||||||
import com.google.gerrit.server.StringUtil;
|
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.git.GitRepositoryManager;
|
||||||
import com.google.gerrit.server.util.TreeFormatter;
|
import com.google.gerrit.server.util.TreeFormatter;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
@@ -86,6 +91,8 @@ public class ListProjects {
|
|||||||
|
|
||||||
private final CurrentUser currentUser;
|
private final CurrentUser currentUser;
|
||||||
private final ProjectCache projectCache;
|
private final ProjectCache projectCache;
|
||||||
|
private final GroupCache groupCache;
|
||||||
|
private final GroupControl.Factory groupControlFactory;
|
||||||
private final GitRepositoryManager repoManager;
|
private final GitRepositoryManager repoManager;
|
||||||
private final ProjectNode.Factory projectNodeFactory;
|
private final ProjectNode.Factory projectNodeFactory;
|
||||||
|
|
||||||
@@ -115,12 +122,18 @@ public class ListProjects {
|
|||||||
|
|
||||||
private String matchPrefix;
|
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
|
@Inject
|
||||||
protected ListProjects(CurrentUser currentUser, ProjectCache projectCache,
|
protected ListProjects(CurrentUser currentUser, ProjectCache projectCache,
|
||||||
GitRepositoryManager repoManager,
|
GroupCache groupCache, GroupControl.Factory groupControlFactory,
|
||||||
ProjectNode.Factory projectNodeFactory) {
|
GitRepositoryManager repoManager, ProjectNode.Factory projectNodeFactory) {
|
||||||
this.currentUser = currentUser;
|
this.currentUser = currentUser;
|
||||||
this.projectCache = projectCache;
|
this.projectCache = projectCache;
|
||||||
|
this.groupCache = groupCache;
|
||||||
|
this.groupControlFactory = groupControlFactory;
|
||||||
this.repoManager = repoManager;
|
this.repoManager = repoManager;
|
||||||
this.projectNodeFactory = projectNodeFactory;
|
this.projectNodeFactory = projectNodeFactory;
|
||||||
}
|
}
|
||||||
@@ -175,6 +188,22 @@ public class ListProjects {
|
|||||||
//
|
//
|
||||||
continue;
|
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();
|
ProjectInfo info = new ProjectInfo();
|
||||||
if (type == FilterType.PARENT_CANDIDATES) {
|
if (type == FilterType.PARENT_CANDIDATES) {
|
||||||
ProjectState parentState = e.getParentState();
|
ProjectState parentState = e.getParentState();
|
||||||
@@ -194,7 +223,6 @@ public class ListProjects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
final ProjectControl pctl = e.controlFor(currentUser);
|
|
||||||
final boolean isVisible = pctl.isVisible() || (all && pctl.isOwner());
|
final boolean isVisible = pctl.isVisible() || (all && pctl.isOwner());
|
||||||
if (showTree && !format.isJson()) {
|
if (showTree && !format.isJson()) {
|
||||||
treeMap.put(projectName,
|
treeMap.put(projectName,
|
||||||
|
@@ -120,6 +120,7 @@ public class ProjectControl {
|
|||||||
private final Collection<ContributorAgreement> contributorAgreements;
|
private final Collection<ContributorAgreement> contributorAgreements;
|
||||||
|
|
||||||
private List<SectionMatcher> allSections;
|
private List<SectionMatcher> allSections;
|
||||||
|
private List<SectionMatcher> localSections;
|
||||||
private Map<String, RefControl> refControls;
|
private Map<String, RefControl> refControls;
|
||||||
private Boolean declaredOwner;
|
private Boolean declaredOwner;
|
||||||
|
|
||||||
@@ -239,8 +240,17 @@ public class ProjectControl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Set<GroupReference> getAllGroups() {
|
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>();
|
final Set<GroupReference> all = new HashSet<GroupReference>();
|
||||||
for (final SectionMatcher matcher : access()) {
|
for (final SectionMatcher matcher : sectionMatcherList) {
|
||||||
final AccessSection section = matcher.section;
|
final AccessSection section = matcher.section;
|
||||||
for (final Permission permission : section.getPermissions()) {
|
for (final Permission permission : section.getPermissions()) {
|
||||||
for (final PermissionRule rule : permission.getRules()) {
|
for (final PermissionRule rule : permission.getRules()) {
|
||||||
@@ -392,6 +402,13 @@ public class ProjectControl {
|
|||||||
return allSections;
|
return allSections;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<SectionMatcher> localAccess() {
|
||||||
|
if (localSections == null) {
|
||||||
|
localSections = state.getLocalAccessSections();
|
||||||
|
}
|
||||||
|
return localSections;
|
||||||
|
}
|
||||||
|
|
||||||
boolean match(PermissionRule rule) {
|
boolean match(PermissionRule rule) {
|
||||||
return match(rule.getGroup().getUUID());
|
return match(rule.getGroup().getUUID());
|
||||||
}
|
}
|
||||||
|
@@ -174,7 +174,7 @@ public class ProjectState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Get the sections that pertain only to this project. */
|
/** Get the sections that pertain only to this project. */
|
||||||
private List<SectionMatcher> getLocalAccessSections() {
|
List<SectionMatcher> getLocalAccessSections() {
|
||||||
List<SectionMatcher> sm = localAccessSections;
|
List<SectionMatcher> sm = localAccessSections;
|
||||||
if (sm == null) {
|
if (sm == null) {
|
||||||
Collection<AccessSection> fromConfig = config.getAccessSections();
|
Collection<AccessSection> fromConfig = config.getAccessSections();
|
||||||
|
Reference in New Issue
Block a user