Disallow creating projects with Gerrit internal refs as branch input
Disallowing creating branches especially for refs/changes and
refs/cache-automerge.
Even though some of the Gerrit internal refs are only relevant for the
All-Users or All-Projects repos, we are disallowing creating branches
with these names to avoid confusion.
Change-Id: I206a406214b288b66c2736a8c62048da591b19e8
diff --git a/Documentation/rest-api-projects.txt b/Documentation/rest-api-projects.txt
index 677fc6d..49bc7e5 100644
--- a/Documentation/rest-api-projects.txt
+++ b/Documentation/rest-api-projects.txt
@@ -4211,8 +4211,10 @@
|`branches` |optional|
A list of branches that should be initially created. +
For the branch names the `refs/heads/` prefix can be omitted. +
-The first entry of the list will be the default branch (ie. the target +
-of the `HEAD` symbolic ref).
+The first entry of the list will be the default branch (ie. the target
+of the `HEAD` symbolic ref). +
+Branches in the Gerrit internal ref space are not allowed, such as
+refs/groups/, refs/changes/, etc...
|`owners` |optional|
A list of groups that should be assigned as project owner. +
Each group in the list must be specified as
diff --git a/java/com/google/gerrit/server/restapi/project/CreateProject.java b/java/com/google/gerrit/server/restapi/project/CreateProject.java
index a5a0034..faab241 100644
--- a/java/com/google/gerrit/server/restapi/project/CreateProject.java
+++ b/java/com/google/gerrit/server/restapi/project/CreateProject.java
@@ -208,4 +208,18 @@
}
return normalizedBranches;
}
+
+ static class ValidBranchListener implements ProjectCreationValidationListener {
+ @Override
+ public void validateNewProject(CreateProjectArgs args) throws ValidationException {
+ for (String branch : args.branch) {
+ if (RefNames.isGerritRef(branch)) {
+ throw new ValidationException(
+ String.format(
+ "Cannot create a project with branch %s. Branches in the Gerrit internal refs namespace are not allowed",
+ branch));
+ }
+ }
+ }
+ }
}
diff --git a/java/com/google/gerrit/server/restapi/project/Module.java b/java/com/google/gerrit/server/restapi/project/Module.java
index 517b888..9217077 100644
--- a/java/com/google/gerrit/server/restapi/project/Module.java
+++ b/java/com/google/gerrit/server/restapi/project/Module.java
@@ -29,6 +29,7 @@
import com.google.gerrit.server.config.GerritConfigListener;
import com.google.gerrit.server.project.RefValidationHelper;
import com.google.gerrit.server.restapi.change.CherryPickCommit;
+import com.google.gerrit.server.validators.ProjectCreationValidationListener;
public class Module extends RestApiModule {
@@ -47,6 +48,8 @@
DynamicMap.mapOf(binder(), LABEL_KIND);
DynamicSet.bind(binder(), GerritConfigListener.class).to(SetParent.class);
+ DynamicSet.bind(binder(), ProjectCreationValidationListener.class)
+ .to(CreateProject.ValidBranchListener.class);
create(PROJECT_KIND).to(CreateProject.class);
put(PROJECT_KIND).to(PutProject.class);
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java b/javatests/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java
index 10fd65f..e5c5952 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java
@@ -53,6 +53,7 @@
import com.google.gerrit.extensions.restapi.Url;
import com.google.gerrit.server.group.SystemGroupBackend;
import com.google.gerrit.server.project.ProjectState;
+import com.google.gerrit.server.validators.ValidationException;
import com.google.inject.Inject;
import java.util.Collections;
import java.util.Optional;
@@ -328,6 +329,21 @@
}
@Test
+ public void createProjectWithInvalidBranch() throws Exception {
+ String newProjectName = name("newProject");
+ ProjectInput in = new ProjectInput();
+ in.name = newProjectName;
+ in.createEmptyCommit = true;
+ in.branches = ImmutableList.of("refs/heads/test", "refs/changes/34/1234");
+ Throwable thrown =
+ assertThrows(ResourceConflictException.class, () -> gApi.projects().create(in));
+ assertThat(thrown).hasCauseThat().isInstanceOf(ValidationException.class);
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Cannot create a project with branch refs/changes/34/1234");
+ }
+
+ @Test
public void createProjectWithCapability() throws Exception {
projectOperations
.allProjectsForUpdate()