Prevent inheriting from multiple projects
Adding more than one project to inherit from manually in project.config will silently ignore all but the last value, which is likely not what the user expects. Reject the config instead. Change-Id: I8139746a31e1ba78a88c54ed486920acf5544c1d
This commit is contained in:
parent
a16f8a3973
commit
69e27a3c5c
@ -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();
|
||||
|
@ -479,6 +479,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));
|
||||
|
Loading…
Reference in New Issue
Block a user