Merge "Prevent inheriting from multiple projects"

This commit is contained in:
Dave Borowitz 2016-11-13 18:38:03 +00:00 committed by Gerrit Code Review
commit dc09b8ce72
2 changed files with 41 additions and 0 deletions

View File

@ -20,6 +20,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.fail;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.GitUtil;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.TestProjectInput;
import com.google.gerrit.common.data.Permission;
@ -28,10 +29,13 @@ import com.google.gerrit.extensions.api.projects.ProjectInput;
import com.google.gerrit.extensions.client.ChangeStatus;
import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.project.Util;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.revwalk.RevObject;
@ -143,6 +147,36 @@ public class ConfigChangeIT extends AbstractDaemonTest {
.isEqualTo(parent.name);
}
@Test
public void rejectDoubleInheritance() throws Exception {
setApiUser(admin);
// Create separate projects to test the config
Project.NameKey parent = createProject("projectToInheritFrom");
Project.NameKey child = createProject("projectWithMalformedConfig");
String config = gApi.projects()
.name(child.get())
.branch(RefNames.REFS_CONFIG).file("project.config").asString();
// Append and push malformed project config
String pattern = "[access]\n"
+ "\tinheritFrom = " + allProjects.get() + "\n";
String doubleInherit = pattern + "\tinheritFrom = " + parent.get() + "\n";
config = config.replace(pattern, doubleInherit);
TestRepository<InMemoryRepository> childRepo =
cloneProject(child, admin);
// Fetch meta ref
GitUtil.fetch(childRepo, RefNames.REFS_CONFIG + ":cfg");
childRepo.reset("cfg");
PushOneCommit push = pushFactory.create(
db, admin.getIdent(), childRepo, "Subject", "project.config",
config);
PushOneCommit.Result res = push.to(RefNames.REFS_CONFIG);
res.assertErrorStatus();
res.assertMessage("cannot inherit from multiple projects");
}
private void fetchRefsMetaConfig() throws Exception {
git().fetch().setRefSpecs(new RefSpec("refs/meta/config:refs/meta/config"))
.call();

View File

@ -489,6 +489,13 @@ public class ProjectConfig extends VersionedMetaData implements ValidationError.
if (p.getDescription() == null) {
p.setDescription("");
}
if (rc.getStringList(ACCESS, null, KEY_INHERIT_FROM).length > 1) {
// The config must not contain more than one parent to inherit from
// as there is no guarantee which of the parents would be used then.
error(new ValidationError(PROJECT_CONFIG,
"Cannot inherit from multiple projects"));
}
p.setParentName(rc.getString(ACCESS, null, KEY_INHERIT_FROM));
p.setUseContributorAgreements(getEnum(rc, RECEIVE, null, KEY_REQUIRE_CONTRIBUTOR_AGREEMENT, InheritableBoolean.INHERIT));