diff --git a/Documentation/config-project-config.txt b/Documentation/config-project-config.txt index 276117bc37..0d3ff582e0 100644 --- a/Documentation/config-project-config.txt +++ b/Documentation/config-project-config.txt @@ -154,6 +154,16 @@ up to Gerrit then the JGit checks need to be disabled. + The default value for this is true, false disables the checks. +[[receive.enableSignedPush]]receive.enableSignedPush:: ++ +Controls whether server-side signed push validation is enabled on the +project. Only has an effect if signed push validation is enabled on the +server; see the link:config-gerrit.html#receive.enableSignedPush[global +configuration] for details. ++ +Default is `INHERIT`, which means that this property is inherited from +the parent project. + [[submit-section]] === Submit section diff --git a/Documentation/rest-api-config.txt b/Documentation/rest-api-config.txt index 88aec2e1ca..7b5dd44569 100644 --- a/Documentation/rest-api-config.txt +++ b/Documentation/rest-api-config.txt @@ -1277,6 +1277,20 @@ The maximal memory size. The value is returned with a unit abbreviation The number of open files. |============================ +[[receive-info]] +=== ReceiveInfo +The `ReceiveInfo` entity contains information about the configuration +of git-receive-pack behavior on the server. + +[options="header",cols="1,^1,5"] +|======================================= +|Field Name ||Description +|`enableSignedPush`|optional| +Whether signed push validation support is enabled on the server; see the +link:config-gerrit.html#receive.certNonceSeed[global configuration] for +details. +|======================================= + [[server-info]] === ServerInfo The `ServerInfo` entity contains information about the configuration of @@ -1306,6 +1320,9 @@ GerritInfo] entity. |`gitweb ` |optional| Information about the link:config-gerrit.html#gitweb[gitweb] configuration as link:#git-web-info[GitwebInfo] entity. +|`receive` |optional| +Information about the receive-pack configuration as a +link:#receive-info[ReceiveInfo] entity. |`sshd` |optional| Information about the configuration from the link:config-gerrit.html#sshd[sshd] section as link:#sshd-info[SshdInfo] diff --git a/Documentation/rest-api-projects.txt b/Documentation/rest-api-projects.txt index a25c7bba2f..4658e2ce7b 100644 --- a/Documentation/rest-api-projects.txt +++ b/Documentation/rest-api-projects.txt @@ -731,6 +731,7 @@ link:#config-input[ConfigInput] entity. "use_content_merge": "INHERIT", "use_signed_off_by": "INHERIT", "create_new_change_for_all_not_in_target": "INHERIT", + "enable_signed_push": "INHERIT", "require_change_id": "TRUE", "max_object_size_limit": "10m", "submit_type": "REBASE_IF_NECESSARY", @@ -774,6 +775,11 @@ ConfigInfo] entity. "configured_value": "TRUE", "inherited_value": true }, + "enable_signed_push": { + "value": true, + "configured_value": "INHERIT", + "inherited_value": false + }, "max_object_size_limit": { "value": "10m", "configured_value": "10m", @@ -1902,6 +1908,9 @@ link:#inherited-boolean-info[InheritedBooleanInfo] that tells whether a valid link:user-changeid.html[Change-Id] footer in any commit uploaded for review is required. This does not apply to commits pushed directly to a branch or tag. +|`enable_signed_push` |optional| +link:#inherited-boolean-info[InheritedBooleanInfo] that tells whether +signed push validation is enabled on the project. |`max_object_size_limit` || The link:config-gerrit.html#receive.maxObjectSizeLimit[max object size limit] of this project as a link:#max-object-size-limit-info[ diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java index 86f543a8cc..6fbd678991 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java @@ -42,6 +42,7 @@ public interface AdminConstants extends Constants { String useContributorAgreements(); String useSignedOffBy(); String createNewChangeForAllNotInTarget(); + String enableSignedPush(); String requireChangeID(); String headingMaxObjectSizeLimit(); String headingGroupOptions(); diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties index affbe61bd1..8aaa95ee87 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties @@ -24,6 +24,7 @@ useContentMerge = Allow content merges useContributorAgreements = Require a valid contributor agreement to upload useSignedOffBy = Require Signed-off-by in commit message createNewChangeForAllNotInTarget = Create a new change for every commit not in the target branch +enableSignedPush = Enable signed push requireChangeID = Require Change-Id in commit message headingMaxObjectSizeLimit = Maximum Git object size limit headingGroupOptions = Group Options diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java index 104ef934c8..e6f262c788 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java @@ -82,6 +82,7 @@ public class ProjectInfoScreen extends ProjectScreen { private ListBox state; private ListBox contentMerge; private ListBox newChangeForAllNotInTarget; + private ListBox enableSignedPush; private NpTextBox maxObjectSizeLimit; private Label effectiveMaxObjectSizeLimit; private Map> pluginConfigWidgets; @@ -162,6 +163,9 @@ public class ProjectInfoScreen extends ProjectScreen { submitType.setEnabled(isOwner); setEnabledForUseContentMerge(); newChangeForAllNotInTarget.setEnabled(isOwner); + if (enableSignedPush != null) { + enableSignedPush.setEnabled(isOwner); + } descTxt.setEnabled(isOwner); contributorAgreements.setEnabled(isOwner); signedOffBy.setEnabled(isOwner); @@ -226,6 +230,12 @@ public class ProjectInfoScreen extends ProjectScreen { saveEnabler.listenTo(requireChangeID); grid.addHtml(Util.C.requireChangeID(), requireChangeID); + if (Gerrit.info().receive().enableSignedPush()) { + enableSignedPush = newInheritedBooleanBox(); + saveEnabler.listenTo(enableSignedPush); + grid.add(Util.C.enableSignedPush(), enableSignedPush); + } + maxObjectSizeLimit = new NpTextBox(); saveEnabler.listenTo(maxObjectSizeLimit); effectiveMaxObjectSizeLimit = new Label(); @@ -349,6 +359,9 @@ public class ProjectInfoScreen extends ProjectScreen { setBool(contentMerge, result.useContentMerge()); setBool(newChangeForAllNotInTarget, result.createNewChangeForAllNotInTarget()); setBool(requireChangeID, result.requireChangeId()); + if (enableSignedPush != null) { + setBool(enableSignedPush, result.enableSignedPush()); + } setSubmitType(result.submitType()); setState(result.state()); maxObjectSizeLimit.setText(result.maxObjectSizeLimit().configuredValue()); @@ -618,9 +631,12 @@ public class ProjectInfoScreen extends ProjectScreen { private void doSave() { enableForm(false); saveProject.setEnabled(false); + InheritableBoolean sp = enableSignedPush != null + ? getBool(enableSignedPush) : null; ProjectApi.setConfig(getProjectKey(), descTxt.getText().trim(), getBool(contributorAgreements), getBool(contentMerge), getBool(signedOffBy), getBool(newChangeForAllNotInTarget), getBool(requireChangeID), + sp, maxObjectSizeLimit.getText().trim(), SubmitType.valueOf(submitType.getValue(submitType.getSelectedIndex())), ProjectState.valueOf(state.getValue(state.getSelectedIndex())), diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/config/ServerInfo.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/config/ServerInfo.java index 72b1f4b255..1030f81d21 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/config/ServerInfo.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/config/ServerInfo.java @@ -26,6 +26,7 @@ public class ServerInfo extends JavaScriptObject { public final native SshdInfo sshd() /*-{ return this.sshd; }-*/; public final native SuggestInfo suggest() /*-{ return this.suggest; }-*/; public final native UserConfigInfo user() /*-{ return this.user; }-*/; + public final native ReceiveInfo receive() /*-{ return this.receive; }-*/; public final boolean hasContactStore() { return contactStore() != null; @@ -74,4 +75,12 @@ public class ServerInfo extends JavaScriptObject { protected UserConfigInfo() { } } + + public static class ReceiveInfo extends JavaScriptObject { + public final native boolean enableSignedPush() + /*-{ return this.enable_signed_push || false; }-*/; + + protected ReceiveInfo() { + } + } } diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ConfigInfo.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ConfigInfo.java index b91c5defb0..2c0bab3b97 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ConfigInfo.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ConfigInfo.java @@ -50,6 +50,9 @@ public class ConfigInfo extends JavaScriptObject { public final native InheritedBooleanInfo useSignedOffBy() /*-{ return this.use_signed_off_by; }-*/; + public final native InheritedBooleanInfo enableSignedPush() + /*-{ return this.enable_signed_push; }-*/; + public final SubmitType submitType() { return SubmitType.valueOf(submitTypeRaw()); } diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ProjectApi.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ProjectApi.java index d81dfe5bad..53eba42376 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ProjectApi.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ProjectApi.java @@ -99,7 +99,9 @@ public class ProjectApi { InheritableBoolean useContributorAgreements, InheritableBoolean useContentMerge, InheritableBoolean useSignedOffBy, InheritableBoolean createNewChangeForAllNotInTarget, - InheritableBoolean requireChangeId, String maxObjectSizeLimit, + InheritableBoolean requireChangeId, + InheritableBoolean enableSignedPush, + String maxObjectSizeLimit, SubmitType submitType, ProjectState state, Map> pluginConfigValues, AsyncCallback cb) { @@ -110,6 +112,9 @@ public class ProjectApi { in.setUseSignedOffBy(useSignedOffBy); in.setRequireChangeId(requireChangeId); in.setCreateNewChangeForAllNotInTarget(createNewChangeForAllNotInTarget); + if (enableSignedPush != null) { + in.setEnableSignedPush(enableSignedPush); + } in.setMaxObjectSizeLimit(maxObjectSizeLimit); in.setSubmitType(submitType); in.setState(state); @@ -230,6 +235,12 @@ public class ProjectApi { private final native void setCreateNewChangeForAllNotInTargetRaw(String v) /*-{ if(v)this.create_new_change_for_all_not_in_target=v; }-*/; + final void setEnableSignedPush(InheritableBoolean v) { + setEnableSignedPushRaw(v.name()); + } + private final native void setEnableSignedPushRaw(String v) + /*-{ if(v)this.enable_signed_push=v; }-*/; + final native void setMaxObjectSizeLimit(String l) /*-{ if(l)this.max_object_size_limit=l; }-*/; diff --git a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/Project.java b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/Project.java index 209998ac73..ce1b27f703 100644 --- a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/Project.java +++ b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/Project.java @@ -96,6 +96,8 @@ public final class Project { protected InheritableBoolean createNewChangeForAllNotInTarget; + protected InheritableBoolean enableSignedPush; + protected Project() { } @@ -108,6 +110,7 @@ public final class Project { requireChangeID = InheritableBoolean.INHERIT; useContentMerge = InheritableBoolean.INHERIT; createNewChangeForAllNotInTarget = InheritableBoolean.INHERIT; + enableSignedPush = InheritableBoolean.INHERIT; } public Project.NameKey getNameKey() { @@ -171,6 +174,14 @@ public final class Project { this.createNewChangeForAllNotInTarget = useAllNotInTarget; } + public InheritableBoolean getEnableSignedPush() { + return enableSignedPush; + } + + public void setEnableSignedPush(InheritableBoolean enable) { + enableSignedPush = enable; + } + public void setMaxObjectSizeLimit(final String limit) { maxObjectSizeLimit = limit; } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/GetServerInfo.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/GetServerInfo.java index 673147fc1e..7c39e6d6f4 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/config/GetServerInfo.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/GetServerInfo.java @@ -29,6 +29,7 @@ import com.google.gerrit.reviewdb.client.AuthType; import com.google.gerrit.server.account.Realm; import com.google.gerrit.server.change.ArchiveFormat; import com.google.gerrit.server.change.GetArchive; +import com.google.gerrit.server.git.SignedPushModule; import com.google.inject.Inject; import org.eclipse.jgit.lib.Config; @@ -93,6 +94,7 @@ public class GetServerInfo implements RestReadView { info.sshd = getSshdInfo(config); info.suggest = getSuggestInfo(config); info.user = getUserInfo(anonymousCowardName); + info.receive = getReceiveInfo(config); return info; } @@ -266,6 +268,12 @@ public class GetServerInfo implements RestReadView { return info; } + private ReceiveInfo getReceiveInfo(Config cfg) { + ReceiveInfo info = new ReceiveInfo(); + info.enableSignedPush = SignedPushModule.isEnabled(cfg); + return info; + } + private static Boolean toBoolean(boolean v) { return v ? v : null; } @@ -280,6 +288,7 @@ public class GetServerInfo implements RestReadView { public SshdInfo sshd; public SuggestInfo suggest; public UserConfigInfo user; + public ReceiveInfo receive; } public static class AuthInfo { @@ -343,4 +352,8 @@ public class GetServerInfo implements RestReadView { public static class UserConfigInfo { public String anonymousCowardName; } + + public static class ReceiveInfo { + public Boolean enableSignedPush; + } } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java index b25c0249a7..b0107cc57c 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java @@ -118,6 +118,7 @@ public class ProjectConfig extends VersionedMetaData implements ValidationError. private static final String KEY_REQUIRE_CONTRIBUTOR_AGREEMENT = "requireContributorAgreement"; private static final String KEY_CHECK_RECEIVED_OBJECTS = "checkReceivedObjects"; + private static final String KEY_ENABLE_SIGNED_PUSH = "enableSignedPush"; private static final String SUBMIT = "submit"; private static final String KEY_ACTION = "action"; @@ -418,6 +419,8 @@ public class ProjectConfig extends VersionedMetaData implements ValidationError. p.setUseSignedOffBy(getEnum(rc, RECEIVE, null, KEY_REQUIRE_SIGNED_OFF_BY, InheritableBoolean.INHERIT)); p.setRequireChangeID(getEnum(rc, RECEIVE, null, KEY_REQUIRE_CHANGE_ID, InheritableBoolean.INHERIT)); p.setCreateNewChangeForAllNotInTarget(getEnum(rc, RECEIVE, null, KEY_USE_ALL_NOT_IN_TARGET, InheritableBoolean.INHERIT)); + p.setEnableSignedPush(getEnum(rc, RECEIVE, null, + KEY_ENABLE_SIGNED_PUSH, InheritableBoolean.INHERIT)); p.setMaxObjectSizeLimit(rc.getString(RECEIVE, null, KEY_MAX_OBJECT_SIZE_LIMIT)); p.setSubmitType(getEnum(rc, SUBMIT, null, KEY_ACTION, defaultSubmitAction)); @@ -815,6 +818,8 @@ public class ProjectConfig extends VersionedMetaData implements ValidationError. set(rc, RECEIVE, null, KEY_REQUIRE_CHANGE_ID, p.getRequireChangeID(), InheritableBoolean.INHERIT); set(rc, RECEIVE, null, KEY_USE_ALL_NOT_IN_TARGET, p.getCreateNewChangeForAllNotInTarget(), InheritableBoolean.INHERIT); set(rc, RECEIVE, null, KEY_MAX_OBJECT_SIZE_LIMIT, validMaxObjectSizeLimit(p.getMaxObjectSizeLimit())); + set(rc, RECEIVE, null, KEY_ENABLE_SIGNED_PUSH, + p.getEnableSignedPush(), InheritableBoolean.INHERIT); set(rc, SUBMIT, null, KEY_ACTION, p.getSubmitType(), defaultSubmitAction); set(rc, SUBMIT, null, KEY_MERGE_CONTENT, p.getUseContentMerge(), InheritableBoolean.INHERIT); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/SignedPushModule.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/SignedPushModule.java index e6a73942fb..88a918d001 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/git/SignedPushModule.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/SignedPushModule.java @@ -19,6 +19,8 @@ import com.google.common.collect.Lists; import com.google.gerrit.extensions.registration.DynamicSet; import com.google.gerrit.reviewdb.client.Project; import com.google.gerrit.server.config.GerritServerConfig; +import com.google.gerrit.server.project.ProjectCache; +import com.google.gerrit.server.project.ProjectState; import com.google.gerrit.server.util.BouncyCastleUtil; import com.google.inject.AbstractModule; import com.google.inject.Inject; @@ -58,11 +60,14 @@ public class SignedPushModule extends AbstractModule { private static class Initializer implements ReceivePackInitializer { private final SignedPushConfig signedPushConfig; private final SignedPushPreReceiveHook hook; + private final ProjectCache projectCache; @Inject Initializer(@GerritServerConfig Config cfg, - SignedPushPreReceiveHook hook) { + SignedPushPreReceiveHook hook, + ProjectCache projectCache) { this.hook = hook; + this.projectCache = projectCache; if (isEnabled(cfg)) { String seed = cfg.getString("receive", null, "certNonceSeed"); @@ -80,11 +85,19 @@ public class SignedPushModule extends AbstractModule { @Override public void init(Project.NameKey project, ReceivePack rp) { - rp.setSignedPushConfig(signedPushConfig); - if (signedPushConfig != null) { - rp.setPreReceiveHook(PreReceiveHookChain.newChain(Lists.newArrayList( - hook, rp.getPreReceiveHook()))); + ProjectState ps = projectCache.get(project); + if (!ps.isEnableSignedPush()) { + rp.setSignedPushConfig(null); + return; } + if (signedPushConfig == null) { + log.error("receive.enableSignedPush is true for project {} but" + + " false in gerrit.config, so signed push verification is" + + " disabled", project.get()); + } + rp.setSignedPushConfig(signedPushConfig); + rp.setPreReceiveHook(PreReceiveHookChain.newChain(Lists.newArrayList( + hook, rp.getPreReceiveHook()))); } } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ConfigInfo.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ConfigInfo.java index 1c6782c09d..28700b3043 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ConfigInfo.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ConfigInfo.java @@ -30,9 +30,12 @@ import com.google.gerrit.server.config.PluginConfig; import com.google.gerrit.server.config.PluginConfigFactory; import com.google.gerrit.server.config.ProjectConfigEntry; import com.google.gerrit.server.extensions.webui.UiActions; +import com.google.gerrit.server.git.SignedPushModule; import com.google.gerrit.server.git.TransferConfig; import com.google.inject.util.Providers; +import org.eclipse.jgit.lib.Config; + import java.util.Arrays; import java.util.List; import java.util.Map; @@ -45,6 +48,7 @@ public class ConfigInfo { public InheritedBooleanInfo useSignedOffBy; public InheritedBooleanInfo createNewChangeForAllNotInTarget; public InheritedBooleanInfo requireChangeId; + public InheritedBooleanInfo enableSignedPush; public MaxObjectSizeLimitInfo maxObjectSizeLimit; public SubmitType submitType; public com.google.gerrit.extensions.client.ProjectState state; @@ -54,7 +58,8 @@ public class ConfigInfo { public Map commentlinks; public ThemeInfo theme; - public ConfigInfo(ProjectControl control, + public ConfigInfo(Config gerritConfig, + ProjectControl control, TransferConfig config, DynamicMap pluginConfigEntries, PluginConfigFactory cfgFactory, @@ -71,6 +76,7 @@ public class ConfigInfo { InheritedBooleanInfo requireChangeId = new InheritedBooleanInfo(); InheritedBooleanInfo createNewChangeForAllNotInTarget = new InheritedBooleanInfo(); + InheritedBooleanInfo enableSignedPush = new InheritedBooleanInfo(); useContributorAgreements.value = projectState.isUseContributorAgreements(); useSignedOffBy.value = projectState.isUseSignedOffBy(); @@ -86,6 +92,7 @@ public class ConfigInfo { requireChangeId.configuredValue = p.getRequireChangeID(); createNewChangeForAllNotInTarget.configuredValue = p.getCreateNewChangeForAllNotInTarget(); + enableSignedPush.configuredValue = p.getEnableSignedPush(); ProjectState parentState = Iterables.getFirst(projectState .parents(), null); @@ -97,6 +104,7 @@ public class ConfigInfo { requireChangeId.inheritedValue = parentState.isRequireChangeID(); createNewChangeForAllNotInTarget.inheritedValue = parentState.isCreateNewChangeForAllNotInTarget(); + enableSignedPush.inheritedValue = projectState.isEnableSignedPush(); } this.useContributorAgreements = useContributorAgreements; @@ -104,6 +112,9 @@ public class ConfigInfo { this.useContentMerge = useContentMerge; this.requireChangeId = requireChangeId; this.createNewChangeForAllNotInTarget = createNewChangeForAllNotInTarget; + if (SignedPushModule.isEnabled(gerritConfig)) { + this.enableSignedPush = enableSignedPush; + } MaxObjectSizeLimitInfo maxObjectSizeLimit = new MaxObjectSizeLimitInfo(); maxObjectSizeLimit.value = diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/GetConfig.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/GetConfig.java index bb910970da..2ab10c9a49 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/project/GetConfig.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/GetConfig.java @@ -18,15 +18,18 @@ import com.google.gerrit.extensions.registration.DynamicMap; import com.google.gerrit.extensions.restapi.RestReadView; import com.google.gerrit.extensions.restapi.RestView; import com.google.gerrit.server.config.AllProjectsNameProvider; +import com.google.gerrit.server.config.GerritServerConfig; import com.google.gerrit.server.config.PluginConfigFactory; import com.google.gerrit.server.config.ProjectConfigEntry; import com.google.gerrit.server.git.TransferConfig; import com.google.inject.Inject; import com.google.inject.Singleton; +import org.eclipse.jgit.lib.Config; + @Singleton public class GetConfig implements RestReadView { - + private final Config gerritConfig; private final TransferConfig config; private final DynamicMap pluginConfigEntries; private final PluginConfigFactory cfgFactory; @@ -34,11 +37,13 @@ public class GetConfig implements RestReadView { private final DynamicMap> views; @Inject - public GetConfig(TransferConfig config, + public GetConfig(@GerritServerConfig Config gerritConfig, + TransferConfig config, DynamicMap pluginConfigEntries, PluginConfigFactory cfgFactory, AllProjectsNameProvider allProjects, DynamicMap> views) { + this.gerritConfig = gerritConfig; this.config = config; this.pluginConfigEntries = pluginConfigEntries; this.allProjects = allProjects; @@ -48,7 +53,7 @@ public class GetConfig implements RestReadView { @Override public ConfigInfo apply(ProjectResource resource) { - return new ConfigInfo(resource.getControl(), config, + return new ConfigInfo(gerritConfig, resource.getControl(), config, pluginConfigEntries, cfgFactory, allProjects, views); } } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectState.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectState.java index 2f031a0a3f..1dae042b1c 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectState.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectState.java @@ -406,6 +406,15 @@ public class ProjectState { }); } + public boolean isEnableSignedPush() { + return getInheritableBoolean(new Function() { + @Override + public InheritableBoolean apply(Project input) { + return input.getEnableSignedPush(); + } + }); + } + public LabelTypes getLabelTypes() { Map types = Maps.newLinkedHashMap(); for (ProjectState s : treeInOrder()) { diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/PutConfig.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/PutConfig.java index f212f67f02..da7df8c0ba 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/project/PutConfig.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/PutConfig.java @@ -33,6 +33,7 @@ import com.google.gerrit.reviewdb.client.RefNames; import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.config.AllProjectsNameProvider; +import com.google.gerrit.server.config.GerritServerConfig; import com.google.gerrit.server.config.PluginConfig; import com.google.gerrit.server.config.PluginConfigFactory; import com.google.gerrit.server.config.ProjectConfigEntry; @@ -47,6 +48,7 @@ import com.google.inject.Singleton; import org.eclipse.jgit.errors.ConfigInvalidException; import org.eclipse.jgit.errors.RepositoryNotFoundException; +import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.ObjectId; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -61,6 +63,7 @@ import java.util.Objects; @Singleton public class PutConfig implements RestModifyView { private static final Logger log = LoggerFactory.getLogger(PutConfig.class); + public static class Input { public String description; public InheritableBoolean useContributorAgreements; @@ -68,12 +71,14 @@ public class PutConfig implements RestModifyView { public InheritableBoolean useSignedOffBy; public InheritableBoolean createNewChangeForAllNotInTarget; public InheritableBoolean requireChangeId; + public InheritableBoolean enableSignedPush; public String maxObjectSizeLimit; public SubmitType submitType; public com.google.gerrit.extensions.client.ProjectState state; public Map> pluginConfigValues; } + private final Config gerritConfig; private final MetaDataUpdate.User metaDataUpdateFactory; private final ProjectCache projectCache; private final GitRepositoryManager gitMgr; @@ -87,7 +92,8 @@ public class PutConfig implements RestModifyView { private final ChangeHooks hooks; @Inject - PutConfig(MetaDataUpdate.User metaDataUpdateFactory, + PutConfig(@GerritServerConfig Config gerritConfig, + MetaDataUpdate.User metaDataUpdateFactory, ProjectCache projectCache, GitRepositoryManager gitMgr, ProjectState.Factory projectStateFactory, @@ -98,6 +104,7 @@ public class PutConfig implements RestModifyView { DynamicMap> views, ChangeHooks hooks, Provider currentUser) { + this.gerritConfig = gerritConfig; this.metaDataUpdateFactory = metaDataUpdateFactory; this.projectCache = projectCache; this.gitMgr = gitMgr; @@ -161,6 +168,10 @@ public class PutConfig implements RestModifyView { p.setRequireChangeID(input.requireChangeId); } + if (input.enableSignedPush != null) { + p.setEnableSignedPush(input.enableSignedPush); + } + if (input.maxObjectSizeLimit != null) { p.setMaxObjectSizeLimit(input.maxObjectSizeLimit); } @@ -203,8 +214,8 @@ public class PutConfig implements RestModifyView { } ProjectState state = projectStateFactory.create(projectConfig); - return new ConfigInfo(state.controlFor(currentUser.get()), config, - pluginConfigEntries, cfgFactory, allProjects, views); + return new ConfigInfo(gerritConfig, state.controlFor(currentUser.get()), + config, pluginConfigEntries, cfgFactory, allProjects, views); } catch (ConfigInvalidException err) { throw new ResourceConflictException("Cannot read project " + projectName, err); } catch (IOException err) { diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/AllProjectsCreator.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/AllProjectsCreator.java index 11981766d5..b142bb07b2 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/schema/AllProjectsCreator.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/AllProjectsCreator.java @@ -139,6 +139,7 @@ public class AllProjectsCreator { p.setUseContentMerge(InheritableBoolean.TRUE); p.setUseContributorAgreements(InheritableBoolean.FALSE); p.setUseSignedOffBy(InheritableBoolean.FALSE); + p.setEnableSignedPush(InheritableBoolean.FALSE); AccessSection cap = config.getAccessSection(AccessSection.GLOBAL_CAPABILITIES, true); AccessSection all = config.getAccessSection(AccessSection.ALL, true);