Make RefControl package-private

This commit makes RefControl package-private by removing all references
by migrating all callers to PermissionBackend. It makes the following
non-trivial changes:

1) Decompose ref-ownership into READ_CONFIG and WRITE_CONFIG.
WRITE_CONFIG serves as the traditional isOwner() while READ_CONFIG can
be used to check if the user can read the ref config. This defaults to
READ on refs/meta/config for now but can be more specific in the future.

2) Add a new READ_PRIVATE_CHANGES permission to RefPermission to account
for canReadPrivateChanges() and isEditVisible(). This is used for
VisibleRefsFilter.

This commit leaves a TODO for the future on how to treat ref owners in
emails. As of now, we still upgrade owners to 'TO' when they are on
either 'CC' or 'BCC'. This will change in a follow-up change as it is
hard to support on top of a permission backend as it involves many
permission checks on every email sent as well as confusing as internally
we don't have a ref owner anymore.

Change-Id: Ia6fa468dac49588241b52b4451fe79bcf6776077
This commit is contained in:
Patrick Hiesel
2017-08-25 15:55:26 +02:00
parent e3762b84ec
commit 1851a8b786
9 changed files with 105 additions and 44 deletions

View File

@@ -19,11 +19,13 @@ import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.ProjectAccess;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.GroupBackend;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.ContributorAgreementsChecker;
import com.google.gerrit.server.project.NoSuchProjectException;
@@ -64,6 +66,8 @@ class ChangeProjectAccess extends ProjectAccessHandler<ProjectAccess> {
Provider<SetParent> setParent,
GitReferenceUpdated gitRefUpdated,
ContributorAgreementsChecker contributorAgreements,
Provider<CurrentUser> user,
PermissionBackend permissionBackend,
@Assisted("projectName") Project.NameKey projectName,
@Nullable @Assisted ObjectId base,
@Assisted List<AccessSection> sectionList,
@@ -75,6 +79,8 @@ class ChangeProjectAccess extends ProjectAccessHandler<ProjectAccess> {
metaDataUpdateFactory,
allProjects,
setParent,
user.get(),
permissionBackend,
projectName,
base,
sectionList,

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.httpd.rpc.project;
import static com.google.gerrit.server.permissions.GlobalPermission.ADMINISTRATE_SERVER;
import static com.google.gerrit.server.permissions.RefPermission.CREATE_CHANGE;
import static com.google.gerrit.server.permissions.RefPermission.READ;
import static com.google.gerrit.server.permissions.RefPermission.WRITE_CONFIG;
import com.google.common.collect.Maps;
import com.google.gerrit.common.data.AccessSection;
@@ -145,7 +146,7 @@ class ProjectAccessFactory extends Handler<ProjectAccess> {
}
} else if (RefConfigSection.isValid(name)) {
if (pc.controlForRef(name).isOwner()) {
if (check(perm, name, WRITE_CONFIG)) {
local.add(section);
ownerOf.add(name);

View File

@@ -30,12 +30,15 @@ import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
import com.google.gerrit.httpd.rpc.Handler;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.GroupBackend;
import com.google.gerrit.server.account.GroupBackends;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.permissions.RefPermission;
import com.google.gerrit.server.project.ContributorAgreementsChecker;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectControl;
@@ -59,6 +62,8 @@ public abstract class ProjectAccessHandler<T> extends Handler<T> {
private final AllProjectsName allProjects;
private final Provider<SetParent> setParent;
private final ContributorAgreementsChecker contributorAgreements;
private final CurrentUser user;
private final PermissionBackend permissionBackend;
protected final Project.NameKey projectName;
protected final ObjectId base;
@@ -73,6 +78,8 @@ public abstract class ProjectAccessHandler<T> extends Handler<T> {
MetaDataUpdate.User metaDataUpdateFactory,
AllProjectsName allProjects,
Provider<SetParent> setParent,
CurrentUser user,
PermissionBackend permissionBackend,
Project.NameKey projectName,
ObjectId base,
List<AccessSection> sectionList,
@@ -85,6 +92,8 @@ public abstract class ProjectAccessHandler<T> extends Handler<T> {
this.metaDataUpdateFactory = metaDataUpdateFactory;
this.allProjects = allProjects;
this.setParent = setParent;
this.user = user;
this.permissionBackend = permissionBackend;
this.projectName = projectName;
this.base = base;
@@ -111,6 +120,7 @@ public abstract class ProjectAccessHandler<T> extends Handler<T> {
try (MetaDataUpdate md = metaDataUpdateFactory.create(projectName)) {
ProjectConfig config = ProjectConfig.read(md, base);
Set<String> toDelete = scanSectionNames(config);
PermissionBackend.ForProject forProject = permissionBackend.user(user).project(projectName);
for (AccessSection section : mergeSections(sectionList)) {
String name = section.getName();
@@ -122,7 +132,7 @@ public abstract class ProjectAccessHandler<T> extends Handler<T> {
replace(config, toDelete, section);
} else if (AccessSection.isValid(name)) {
if (checkIfOwner && !projectControl.controlForRef(name).isOwner()) {
if (checkIfOwner && !forProject.ref(name).test(RefPermission.WRITE_CONFIG)) {
continue;
}
@@ -138,7 +148,7 @@ public abstract class ProjectAccessHandler<T> extends Handler<T> {
config.remove(config.getAccessSection(name));
}
} else if (!checkIfOwner || projectControl.controlForRef(name).isOwner()) {
} else if (!checkIfOwner || forProject.ref(name).test(RefPermission.WRITE_CONFIG)) {
config.remove(config.getAccessSection(name));
}
}

View File

@@ -30,6 +30,7 @@ import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.Sequences;
import com.google.gerrit.server.account.GroupBackend;
import com.google.gerrit.server.change.ChangeInserter;
@@ -96,6 +97,7 @@ public class ReviewProjectAccess extends ProjectAccessHandler<Change.Id> {
Provider<SetParent> setParent,
Sequences seq,
ContributorAgreementsChecker contributorAgreements,
Provider<CurrentUser> user,
@Assisted("projectName") Project.NameKey projectName,
@Nullable @Assisted ObjectId base,
@Assisted List<AccessSection> sectionList,
@@ -107,6 +109,8 @@ public class ReviewProjectAccess extends ProjectAccessHandler<Change.Id> {
metaDataUpdateFactory,
allProjects,
setParent,
user.get(),
permissionBackend,
projectName,
base,
sectionList,