Add project config boolean to require signed push on a project
This is controlled by receive.requireSignedPush in the project.config, which is a separate bit from receive.enableSignedPush. (Adding an inheritable tri-state enum would have been complex to implement and have hard-to-define semantics.) requireSignedPush is only inspected if enableSignedPush is true; this allows project owners to temporarily disable signed push entirely e.g. due to a bug, without having to flip both bits. Change-Id: I07999b6fa185d470b30509941473e3158f9dfa2c
This commit is contained in:
		| @@ -164,6 +164,17 @@ configuration] for details. | |||||||
| Default is `INHERIT`, which means that this property is inherited from | Default is `INHERIT`, which means that this property is inherited from | ||||||
| the parent project. | the parent project. | ||||||
|  |  | ||||||
|  | [[receive.requireSignedPush]]receive.requireSignedPush:: | ||||||
|  | + | ||||||
|  | Controls whether server-side signed push validation is required on the | ||||||
|  | project. Only has an effect if signed push validation is enabled on the | ||||||
|  | server, and link:#receive.enableSignedPush is set on the project. 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]] | ||||||
| === Submit section | === Submit section | ||||||
|  |  | ||||||
|   | |||||||
| @@ -732,6 +732,7 @@ link:#config-input[ConfigInput] entity. | |||||||
|     "use_signed_off_by": "INHERIT", |     "use_signed_off_by": "INHERIT", | ||||||
|     "create_new_change_for_all_not_in_target": "INHERIT", |     "create_new_change_for_all_not_in_target": "INHERIT", | ||||||
|     "enable_signed_push": "INHERIT", |     "enable_signed_push": "INHERIT", | ||||||
|  |     "require_signed_push": "INHERIT", | ||||||
|     "require_change_id": "TRUE", |     "require_change_id": "TRUE", | ||||||
|     "max_object_size_limit": "10m", |     "max_object_size_limit": "10m", | ||||||
|     "submit_type": "REBASE_IF_NECESSARY", |     "submit_type": "REBASE_IF_NECESSARY", | ||||||
| @@ -780,6 +781,11 @@ ConfigInfo] entity. | |||||||
|       "configured_value": "INHERIT", |       "configured_value": "INHERIT", | ||||||
|       "inherited_value": false |       "inherited_value": false | ||||||
|     }, |     }, | ||||||
|  |     "require_signed_push": { | ||||||
|  |       "value": false, | ||||||
|  |       "configured_value": "INHERIT", | ||||||
|  |       "inherited_value": false | ||||||
|  |     }, | ||||||
|     "max_object_size_limit": { |     "max_object_size_limit": { | ||||||
|       "value": "10m", |       "value": "10m", | ||||||
|       "configured_value": "10m", |       "configured_value": "10m", | ||||||
| @@ -1982,9 +1988,14 @@ link:#inherited-boolean-info[InheritedBooleanInfo] that tells whether a | |||||||
| valid link:user-changeid.html[Change-Id] footer in any commit uploaded | valid link:user-changeid.html[Change-Id] footer in any commit uploaded | ||||||
| for review is required. This does not apply to commits pushed directly | for review is required. This does not apply to commits pushed directly | ||||||
| to a branch or tag. | to a branch or tag. | ||||||
| |`enable_signed_push`                      |optional| | |`enable_signed_push`| | ||||||
|  | optional, not set if signed push is disabled| | ||||||
| link:#inherited-boolean-info[InheritedBooleanInfo] that tells whether | link:#inherited-boolean-info[InheritedBooleanInfo] that tells whether | ||||||
| signed push validation is enabled on the project. | signed push validation is enabled on the project. | ||||||
|  | |`require_signed_push`| | ||||||
|  | optional, not set if signed push is disabled | ||||||
|  | link:#inherited-boolean-info[InheritedBooleanInfo] that tells whether | ||||||
|  | signed push validation is required on the project. | ||||||
| |`max_object_size_limit`     || | |`max_object_size_limit`     || | ||||||
| The link:config-gerrit.html#receive.maxObjectSizeLimit[max object size | The link:config-gerrit.html#receive.maxObjectSizeLimit[max object size | ||||||
| limit] of this project as a link:#max-object-size-limit-info[ | limit] of this project as a link:#max-object-size-limit-info[ | ||||||
|   | |||||||
| @@ -15,7 +15,6 @@ | |||||||
| package com.google.gerrit.gpg; | package com.google.gerrit.gpg; | ||||||
|  |  | ||||||
| import com.google.common.base.Strings; | import com.google.common.base.Strings; | ||||||
| import com.google.common.collect.Lists; |  | ||||||
| import com.google.gerrit.extensions.registration.DynamicSet; | import com.google.gerrit.extensions.registration.DynamicSet; | ||||||
| import com.google.gerrit.reviewdb.client.Project; | import com.google.gerrit.reviewdb.client.Project; | ||||||
| import com.google.gerrit.server.EnableSignedPush; | import com.google.gerrit.server.EnableSignedPush; | ||||||
| @@ -33,6 +32,7 @@ import com.google.inject.Singleton; | |||||||
|  |  | ||||||
| import org.eclipse.jgit.lib.Config; | import org.eclipse.jgit.lib.Config; | ||||||
| import org.eclipse.jgit.lib.Repository; | import org.eclipse.jgit.lib.Repository; | ||||||
|  | import org.eclipse.jgit.transport.PreReceiveHook; | ||||||
| import org.eclipse.jgit.transport.PreReceiveHookChain; | import org.eclipse.jgit.transport.PreReceiveHookChain; | ||||||
| import org.eclipse.jgit.transport.ReceivePack; | import org.eclipse.jgit.transport.ReceivePack; | ||||||
| import org.eclipse.jgit.transport.SignedPushConfig; | import org.eclipse.jgit.transport.SignedPushConfig; | ||||||
| @@ -42,6 +42,8 @@ import org.slf4j.LoggerFactory; | |||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.security.NoSuchAlgorithmException; | import java.security.NoSuchAlgorithmException; | ||||||
| import java.security.SecureRandom; | import java.security.SecureRandom; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
| import java.util.Random; | import java.util.Random; | ||||||
|  |  | ||||||
| class SignedPushModule extends AbstractModule { | class SignedPushModule extends AbstractModule { | ||||||
| @@ -92,15 +94,22 @@ class SignedPushModule extends AbstractModule { | |||||||
|       if (!ps.isEnableSignedPush()) { |       if (!ps.isEnableSignedPush()) { | ||||||
|         rp.setSignedPushConfig(null); |         rp.setSignedPushConfig(null); | ||||||
|         return; |         return; | ||||||
|       } |       } else if (signedPushConfig == null) { | ||||||
|       if (signedPushConfig == null) { |  | ||||||
|         log.error("receive.enableSignedPush is true for project {} but" |         log.error("receive.enableSignedPush is true for project {} but" | ||||||
|             + " false in gerrit.config, so signed push verification is" |             + " false in gerrit.config, so signed push verification is" | ||||||
|             + " disabled", project.get()); |             + " disabled", project.get()); | ||||||
|  |         rp.setSignedPushConfig(null); | ||||||
|  |         return; | ||||||
|       } |       } | ||||||
|       rp.setSignedPushConfig(signedPushConfig); |       rp.setSignedPushConfig(signedPushConfig); | ||||||
|       rp.setPreReceiveHook(PreReceiveHookChain.newChain(Lists.newArrayList( |  | ||||||
|           hook, rp.getPreReceiveHook()))); |       List<PreReceiveHook> hooks = new ArrayList<>(3); | ||||||
|  |       if (ps.isRequireSignedPush()) { | ||||||
|  |         hooks.add(SignedPushPreReceiveHook.Required.INSTANCE); | ||||||
|  |       } | ||||||
|  |       hooks.add(hook); | ||||||
|  |       hooks.add(rp.getPreReceiveHook()); | ||||||
|  |       rp.setPreReceiveHook(PreReceiveHookChain.newChain(hooks)); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -36,6 +36,21 @@ import java.util.Collection; | |||||||
|  */ |  */ | ||||||
| @Singleton | @Singleton | ||||||
| public class SignedPushPreReceiveHook implements PreReceiveHook { | public class SignedPushPreReceiveHook implements PreReceiveHook { | ||||||
|  |   public static class Required implements PreReceiveHook { | ||||||
|  |     public static final Required INSTANCE = new Required(); | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void onPreReceive(ReceivePack rp, Collection<ReceiveCommand> commands) { | ||||||
|  |       if (rp.getPushCertificate() == null) { | ||||||
|  |         rp.sendMessage("ERROR: Signed push is required"); | ||||||
|  |         reject(commands, "push cert error"); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private Required() { | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   private final Provider<IdentifiedUser> user; |   private final Provider<IdentifiedUser> user; | ||||||
|   private final GerritPushCertificateChecker.Factory checkerFactory; |   private final GerritPushCertificateChecker.Factory checkerFactory; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -43,6 +43,7 @@ public interface AdminConstants extends Constants { | |||||||
|   String useSignedOffBy(); |   String useSignedOffBy(); | ||||||
|   String createNewChangeForAllNotInTarget(); |   String createNewChangeForAllNotInTarget(); | ||||||
|   String enableSignedPush(); |   String enableSignedPush(); | ||||||
|  |   String requireSignedPush(); | ||||||
|   String requireChangeID(); |   String requireChangeID(); | ||||||
|   String headingMaxObjectSizeLimit(); |   String headingMaxObjectSizeLimit(); | ||||||
|   String headingGroupOptions(); |   String headingGroupOptions(); | ||||||
|   | |||||||
| @@ -25,6 +25,7 @@ useContributorAgreements = Require a valid contributor agreement to upload | |||||||
| useSignedOffBy = Require <code>Signed-off-by</code> in commit message | useSignedOffBy = Require <code>Signed-off-by</code> in commit message | ||||||
| createNewChangeForAllNotInTarget = Create a new change for every commit not in the target branch | createNewChangeForAllNotInTarget = Create a new change for every commit not in the target branch | ||||||
| enableSignedPush = Enable signed push | enableSignedPush = Enable signed push | ||||||
|  | requireSignedPush = Require signed push | ||||||
| requireChangeID = Require <code>Change-Id</code> in commit message | requireChangeID = Require <code>Change-Id</code> in commit message | ||||||
| headingMaxObjectSizeLimit = Maximum Git object size limit | headingMaxObjectSizeLimit = Maximum Git object size limit | ||||||
| headingGroupOptions = Group Options | headingGroupOptions = Group Options | ||||||
|   | |||||||
| @@ -84,6 +84,7 @@ public class ProjectInfoScreen extends ProjectScreen { | |||||||
|   private ListBox contentMerge; |   private ListBox contentMerge; | ||||||
|   private ListBox newChangeForAllNotInTarget; |   private ListBox newChangeForAllNotInTarget; | ||||||
|   private ListBox enableSignedPush; |   private ListBox enableSignedPush; | ||||||
|  |   private ListBox requireSignedPush; | ||||||
|   private NpTextBox maxObjectSizeLimit; |   private NpTextBox maxObjectSizeLimit; | ||||||
|   private Label effectiveMaxObjectSizeLimit; |   private Label effectiveMaxObjectSizeLimit; | ||||||
|   private Map<String, Map<String, HasEnabled>> pluginConfigWidgets; |   private Map<String, Map<String, HasEnabled>> pluginConfigWidgets; | ||||||
| @@ -247,6 +248,9 @@ public class ProjectInfoScreen extends ProjectScreen { | |||||||
|       enableSignedPush = newInheritedBooleanBox(); |       enableSignedPush = newInheritedBooleanBox(); | ||||||
|       saveEnabler.listenTo(enableSignedPush); |       saveEnabler.listenTo(enableSignedPush); | ||||||
|       grid.add(Util.C.enableSignedPush(), enableSignedPush); |       grid.add(Util.C.enableSignedPush(), enableSignedPush); | ||||||
|  |       requireSignedPush = newInheritedBooleanBox(); | ||||||
|  |       saveEnabler.listenTo(requireSignedPush); | ||||||
|  |       grid.add(Util.C.requireSignedPush(), requireSignedPush); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     maxObjectSizeLimit = new NpTextBox(); |     maxObjectSizeLimit = new NpTextBox(); | ||||||
| @@ -326,6 +330,9 @@ public class ProjectInfoScreen extends ProjectScreen { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   private void setBool(ListBox box, InheritedBooleanInfo inheritedBoolean) { |   private void setBool(ListBox box, InheritedBooleanInfo inheritedBoolean) { | ||||||
|  |     if (box == null) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|     int inheritedIndex = -1; |     int inheritedIndex = -1; | ||||||
|     for (int i = 0; i < box.getItemCount(); i++) { |     for (int i = 0; i < box.getItemCount(); i++) { | ||||||
|       if (box.getValue(i).startsWith(InheritableBoolean.INHERIT.name())) { |       if (box.getValue(i).startsWith(InheritableBoolean.INHERIT.name())) { | ||||||
| @@ -372,8 +379,9 @@ public class ProjectInfoScreen extends ProjectScreen { | |||||||
|     setBool(contentMerge, result.useContentMerge()); |     setBool(contentMerge, result.useContentMerge()); | ||||||
|     setBool(newChangeForAllNotInTarget, result.createNewChangeForAllNotInTarget()); |     setBool(newChangeForAllNotInTarget, result.createNewChangeForAllNotInTarget()); | ||||||
|     setBool(requireChangeID, result.requireChangeId()); |     setBool(requireChangeID, result.requireChangeId()); | ||||||
|     if (enableSignedPush != null) { |     if (Gerrit.info().receive().enableSignedPush()) { | ||||||
|       setBool(enableSignedPush, result.enableSignedPush()); |       setBool(enableSignedPush, result.enableSignedPush()); | ||||||
|  |       setBool(requireSignedPush, result.requireSignedPush()); | ||||||
|     } |     } | ||||||
|     setSubmitType(result.submitType()); |     setSubmitType(result.submitType()); | ||||||
|     setState(result.state()); |     setState(result.state()); | ||||||
| @@ -644,12 +652,14 @@ public class ProjectInfoScreen extends ProjectScreen { | |||||||
|   private void doSave() { |   private void doSave() { | ||||||
|     enableForm(false); |     enableForm(false); | ||||||
|     saveProject.setEnabled(false); |     saveProject.setEnabled(false); | ||||||
|     InheritableBoolean sp = enableSignedPush != null |     InheritableBoolean esp = enableSignedPush != null | ||||||
|         ? getBool(enableSignedPush) : null; |         ? getBool(enableSignedPush) : null; | ||||||
|  |     InheritableBoolean rsp = requireSignedPush != null | ||||||
|  |         ? getBool(requireSignedPush) : null; | ||||||
|     ProjectApi.setConfig(getProjectKey(), descTxt.getText().trim(), |     ProjectApi.setConfig(getProjectKey(), descTxt.getText().trim(), | ||||||
|         getBool(contributorAgreements), getBool(contentMerge), |         getBool(contributorAgreements), getBool(contentMerge), | ||||||
|         getBool(signedOffBy), getBool(newChangeForAllNotInTarget), getBool(requireChangeID), |         getBool(signedOffBy), getBool(newChangeForAllNotInTarget), getBool(requireChangeID), | ||||||
|         sp, |         esp, rsp, | ||||||
|         maxObjectSizeLimit.getText().trim(), |         maxObjectSizeLimit.getText().trim(), | ||||||
|         SubmitType.valueOf(submitType.getValue(submitType.getSelectedIndex())), |         SubmitType.valueOf(submitType.getValue(submitType.getSelectedIndex())), | ||||||
|         ProjectState.valueOf(state.getValue(state.getSelectedIndex())), |         ProjectState.valueOf(state.getValue(state.getSelectedIndex())), | ||||||
|   | |||||||
| @@ -53,6 +53,9 @@ public class ConfigInfo extends JavaScriptObject { | |||||||
|   public final native InheritedBooleanInfo enableSignedPush() |   public final native InheritedBooleanInfo enableSignedPush() | ||||||
|   /*-{ return this.enable_signed_push; }-*/; |   /*-{ return this.enable_signed_push; }-*/; | ||||||
|  |  | ||||||
|  |   public final native InheritedBooleanInfo requireSignedPush() | ||||||
|  |   /*-{ return this.require_signed_push; }-*/; | ||||||
|  |  | ||||||
|   public final SubmitType submitType() { |   public final SubmitType submitType() { | ||||||
|     return SubmitType.valueOf(submitTypeRaw()); |     return SubmitType.valueOf(submitTypeRaw()); | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -117,6 +117,7 @@ public class ProjectApi { | |||||||
|       InheritableBoolean createNewChangeForAllNotInTarget, |       InheritableBoolean createNewChangeForAllNotInTarget, | ||||||
|       InheritableBoolean requireChangeId, |       InheritableBoolean requireChangeId, | ||||||
|       InheritableBoolean enableSignedPush, |       InheritableBoolean enableSignedPush, | ||||||
|  |       InheritableBoolean requireSignedPush, | ||||||
|       String maxObjectSizeLimit, |       String maxObjectSizeLimit, | ||||||
|       SubmitType submitType, ProjectState state, |       SubmitType submitType, ProjectState state, | ||||||
|       Map<String, Map<String, ConfigParameterValue>> pluginConfigValues, |       Map<String, Map<String, ConfigParameterValue>> pluginConfigValues, | ||||||
| @@ -131,6 +132,9 @@ public class ProjectApi { | |||||||
|     if (enableSignedPush != null) { |     if (enableSignedPush != null) { | ||||||
|       in.setEnableSignedPush(enableSignedPush); |       in.setEnableSignedPush(enableSignedPush); | ||||||
|     } |     } | ||||||
|  |     if (requireSignedPush != null) { | ||||||
|  |       in.setRequireSignedPush(requireSignedPush); | ||||||
|  |     } | ||||||
|     in.setMaxObjectSizeLimit(maxObjectSizeLimit); |     in.setMaxObjectSizeLimit(maxObjectSizeLimit); | ||||||
|     in.setSubmitType(submitType); |     in.setSubmitType(submitType); | ||||||
|     in.setState(state); |     in.setState(state); | ||||||
| @@ -257,6 +261,12 @@ public class ProjectApi { | |||||||
|     private final native void setEnableSignedPushRaw(String v) |     private final native void setEnableSignedPushRaw(String v) | ||||||
|     /*-{ if(v)this.enable_signed_push=v; }-*/; |     /*-{ if(v)this.enable_signed_push=v; }-*/; | ||||||
|  |  | ||||||
|  |     final void setRequireSignedPush(InheritableBoolean v) { | ||||||
|  |       setRequireSignedPushRaw(v.name()); | ||||||
|  |     } | ||||||
|  |     private final native void setRequireSignedPushRaw(String v) | ||||||
|  |     /*-{ if(v)this.require_signed_push=v; }-*/; | ||||||
|  |  | ||||||
|     final native void setMaxObjectSizeLimit(String l) |     final native void setMaxObjectSizeLimit(String l) | ||||||
|     /*-{ if(l)this.max_object_size_limit=l; }-*/; |     /*-{ if(l)this.max_object_size_limit=l; }-*/; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -97,6 +97,7 @@ public final class Project { | |||||||
|   protected InheritableBoolean createNewChangeForAllNotInTarget; |   protected InheritableBoolean createNewChangeForAllNotInTarget; | ||||||
|  |  | ||||||
|   protected InheritableBoolean enableSignedPush; |   protected InheritableBoolean enableSignedPush; | ||||||
|  |   protected InheritableBoolean requireSignedPush; | ||||||
|  |  | ||||||
|   protected Project() { |   protected Project() { | ||||||
|   } |   } | ||||||
| @@ -111,6 +112,7 @@ public final class Project { | |||||||
|     useContentMerge = InheritableBoolean.INHERIT; |     useContentMerge = InheritableBoolean.INHERIT; | ||||||
|     createNewChangeForAllNotInTarget = InheritableBoolean.INHERIT; |     createNewChangeForAllNotInTarget = InheritableBoolean.INHERIT; | ||||||
|     enableSignedPush = InheritableBoolean.INHERIT; |     enableSignedPush = InheritableBoolean.INHERIT; | ||||||
|  |     requireSignedPush = InheritableBoolean.INHERIT; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   public Project.NameKey getNameKey() { |   public Project.NameKey getNameKey() { | ||||||
| @@ -182,6 +184,14 @@ public final class Project { | |||||||
|     enableSignedPush = enable; |     enableSignedPush = enable; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   public InheritableBoolean getRequireSignedPush() { | ||||||
|  |     return requireSignedPush; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void setRequireSignedPush(InheritableBoolean require) { | ||||||
|  |     requireSignedPush = require; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   public void setMaxObjectSizeLimit(final String limit) { |   public void setMaxObjectSizeLimit(final String limit) { | ||||||
|     maxObjectSizeLimit = limit; |     maxObjectSizeLimit = limit; | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -118,6 +118,7 @@ public class ProjectConfig extends VersionedMetaData implements ValidationError. | |||||||
|       "requireContributorAgreement"; |       "requireContributorAgreement"; | ||||||
|   private static final String KEY_CHECK_RECEIVED_OBJECTS = "checkReceivedObjects"; |   private static final String KEY_CHECK_RECEIVED_OBJECTS = "checkReceivedObjects"; | ||||||
|   private static final String KEY_ENABLE_SIGNED_PUSH = "enableSignedPush"; |   private static final String KEY_ENABLE_SIGNED_PUSH = "enableSignedPush"; | ||||||
|  |   private static final String KEY_REQUIRE_SIGNED_PUSH = "requireSignedPush"; | ||||||
|  |  | ||||||
|   private static final String SUBMIT = "submit"; |   private static final String SUBMIT = "submit"; | ||||||
|   private static final String KEY_ACTION = "action"; |   private static final String KEY_ACTION = "action"; | ||||||
| @@ -420,6 +421,8 @@ public class ProjectConfig extends VersionedMetaData implements ValidationError. | |||||||
|     p.setCreateNewChangeForAllNotInTarget(getEnum(rc, RECEIVE, null, KEY_USE_ALL_NOT_IN_TARGET, InheritableBoolean.INHERIT)); |     p.setCreateNewChangeForAllNotInTarget(getEnum(rc, RECEIVE, null, KEY_USE_ALL_NOT_IN_TARGET, InheritableBoolean.INHERIT)); | ||||||
|     p.setEnableSignedPush(getEnum(rc, RECEIVE, null, |     p.setEnableSignedPush(getEnum(rc, RECEIVE, null, | ||||||
|           KEY_ENABLE_SIGNED_PUSH, InheritableBoolean.INHERIT)); |           KEY_ENABLE_SIGNED_PUSH, InheritableBoolean.INHERIT)); | ||||||
|  |     p.setRequireSignedPush(getEnum(rc, RECEIVE, null, | ||||||
|  |           KEY_REQUIRE_SIGNED_PUSH, InheritableBoolean.INHERIT)); | ||||||
|     p.setMaxObjectSizeLimit(rc.getString(RECEIVE, null, KEY_MAX_OBJECT_SIZE_LIMIT)); |     p.setMaxObjectSizeLimit(rc.getString(RECEIVE, null, KEY_MAX_OBJECT_SIZE_LIMIT)); | ||||||
|  |  | ||||||
|     p.setSubmitType(getEnum(rc, SUBMIT, null, KEY_ACTION, defaultSubmitAction)); |     p.setSubmitType(getEnum(rc, SUBMIT, null, KEY_ACTION, defaultSubmitAction)); | ||||||
| @@ -828,6 +831,8 @@ public class ProjectConfig extends VersionedMetaData implements ValidationError. | |||||||
|     set(rc, RECEIVE, null, KEY_MAX_OBJECT_SIZE_LIMIT, validMaxObjectSizeLimit(p.getMaxObjectSizeLimit())); |     set(rc, RECEIVE, null, KEY_MAX_OBJECT_SIZE_LIMIT, validMaxObjectSizeLimit(p.getMaxObjectSizeLimit())); | ||||||
|     set(rc, RECEIVE, null, KEY_ENABLE_SIGNED_PUSH, |     set(rc, RECEIVE, null, KEY_ENABLE_SIGNED_PUSH, | ||||||
|         p.getEnableSignedPush(), InheritableBoolean.INHERIT); |         p.getEnableSignedPush(), InheritableBoolean.INHERIT); | ||||||
|  |     set(rc, RECEIVE, null, KEY_REQUIRE_SIGNED_PUSH, | ||||||
|  |         p.getRequireSignedPush(), InheritableBoolean.INHERIT); | ||||||
|  |  | ||||||
|     set(rc, SUBMIT, null, KEY_ACTION, p.getSubmitType(), defaultSubmitAction); |     set(rc, SUBMIT, null, KEY_ACTION, p.getSubmitType(), defaultSubmitAction); | ||||||
|     set(rc, SUBMIT, null, KEY_MERGE_CONTENT, p.getUseContentMerge(), InheritableBoolean.INHERIT); |     set(rc, SUBMIT, null, KEY_MERGE_CONTENT, p.getUseContentMerge(), InheritableBoolean.INHERIT); | ||||||
|   | |||||||
| @@ -46,6 +46,7 @@ public class ConfigInfo { | |||||||
|   public InheritedBooleanInfo createNewChangeForAllNotInTarget; |   public InheritedBooleanInfo createNewChangeForAllNotInTarget; | ||||||
|   public InheritedBooleanInfo requireChangeId; |   public InheritedBooleanInfo requireChangeId; | ||||||
|   public InheritedBooleanInfo enableSignedPush; |   public InheritedBooleanInfo enableSignedPush; | ||||||
|  |   public InheritedBooleanInfo requireSignedPush; | ||||||
|   public MaxObjectSizeLimitInfo maxObjectSizeLimit; |   public MaxObjectSizeLimitInfo maxObjectSizeLimit; | ||||||
|   public SubmitType submitType; |   public SubmitType submitType; | ||||||
|   public com.google.gerrit.extensions.client.ProjectState state; |   public com.google.gerrit.extensions.client.ProjectState state; | ||||||
| @@ -74,6 +75,7 @@ public class ConfigInfo { | |||||||
|     InheritedBooleanInfo createNewChangeForAllNotInTarget = |     InheritedBooleanInfo createNewChangeForAllNotInTarget = | ||||||
|         new InheritedBooleanInfo(); |         new InheritedBooleanInfo(); | ||||||
|     InheritedBooleanInfo enableSignedPush = new InheritedBooleanInfo(); |     InheritedBooleanInfo enableSignedPush = new InheritedBooleanInfo(); | ||||||
|  |     InheritedBooleanInfo requireSignedPush = new InheritedBooleanInfo(); | ||||||
|  |  | ||||||
|     useContributorAgreements.value = projectState.isUseContributorAgreements(); |     useContributorAgreements.value = projectState.isUseContributorAgreements(); | ||||||
|     useSignedOffBy.value = projectState.isUseSignedOffBy(); |     useSignedOffBy.value = projectState.isUseSignedOffBy(); | ||||||
| @@ -90,6 +92,7 @@ public class ConfigInfo { | |||||||
|     createNewChangeForAllNotInTarget.configuredValue = |     createNewChangeForAllNotInTarget.configuredValue = | ||||||
|         p.getCreateNewChangeForAllNotInTarget(); |         p.getCreateNewChangeForAllNotInTarget(); | ||||||
|     enableSignedPush.configuredValue = p.getEnableSignedPush(); |     enableSignedPush.configuredValue = p.getEnableSignedPush(); | ||||||
|  |     requireSignedPush.configuredValue = p.getRequireSignedPush(); | ||||||
|  |  | ||||||
|     ProjectState parentState = Iterables.getFirst(projectState |     ProjectState parentState = Iterables.getFirst(projectState | ||||||
|         .parents(), null); |         .parents(), null); | ||||||
| @@ -102,6 +105,7 @@ public class ConfigInfo { | |||||||
|       createNewChangeForAllNotInTarget.inheritedValue = |       createNewChangeForAllNotInTarget.inheritedValue = | ||||||
|           parentState.isCreateNewChangeForAllNotInTarget(); |           parentState.isCreateNewChangeForAllNotInTarget(); | ||||||
|       enableSignedPush.inheritedValue = projectState.isEnableSignedPush(); |       enableSignedPush.inheritedValue = projectState.isEnableSignedPush(); | ||||||
|  |       requireSignedPush.inheritedValue = projectState.isRequireSignedPush(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     this.useContributorAgreements = useContributorAgreements; |     this.useContributorAgreements = useContributorAgreements; | ||||||
| @@ -111,6 +115,7 @@ public class ConfigInfo { | |||||||
|     this.createNewChangeForAllNotInTarget = createNewChangeForAllNotInTarget; |     this.createNewChangeForAllNotInTarget = createNewChangeForAllNotInTarget; | ||||||
|     if (serverEnableSignedPush) { |     if (serverEnableSignedPush) { | ||||||
|       this.enableSignedPush = enableSignedPush; |       this.enableSignedPush = enableSignedPush; | ||||||
|  |       this.requireSignedPush = requireSignedPush; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     MaxObjectSizeLimitInfo maxObjectSizeLimit = new MaxObjectSizeLimitInfo(); |     MaxObjectSizeLimitInfo maxObjectSizeLimit = new MaxObjectSizeLimitInfo(); | ||||||
|   | |||||||
| @@ -413,6 +413,15 @@ public class ProjectState { | |||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   public boolean isRequireSignedPush() { | ||||||
|  |     return getInheritableBoolean(new Function<Project, InheritableBoolean>() { | ||||||
|  |       @Override | ||||||
|  |       public InheritableBoolean apply(Project input) { | ||||||
|  |         return input.getRequireSignedPush(); | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   public LabelTypes getLabelTypes() { |   public LabelTypes getLabelTypes() { | ||||||
|     Map<String, LabelType> types = Maps.newLinkedHashMap(); |     Map<String, LabelType> types = Maps.newLinkedHashMap(); | ||||||
|     for (ProjectState s : treeInOrder()) { |     for (ProjectState s : treeInOrder()) { | ||||||
|   | |||||||
| @@ -70,6 +70,7 @@ public class PutConfig implements RestModifyView<ProjectResource, Input> { | |||||||
|     public InheritableBoolean createNewChangeForAllNotInTarget; |     public InheritableBoolean createNewChangeForAllNotInTarget; | ||||||
|     public InheritableBoolean requireChangeId; |     public InheritableBoolean requireChangeId; | ||||||
|     public InheritableBoolean enableSignedPush; |     public InheritableBoolean enableSignedPush; | ||||||
|  |     public InheritableBoolean requireSignedPush; | ||||||
|     public String maxObjectSizeLimit; |     public String maxObjectSizeLimit; | ||||||
|     public SubmitType submitType; |     public SubmitType submitType; | ||||||
|     public com.google.gerrit.extensions.client.ProjectState state; |     public com.google.gerrit.extensions.client.ProjectState state; | ||||||
| @@ -166,8 +167,13 @@ public class PutConfig implements RestModifyView<ProjectResource, Input> { | |||||||
|         p.setRequireChangeID(input.requireChangeId); |         p.setRequireChangeID(input.requireChangeId); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       if (input.enableSignedPush != null) { |       if (serverEnableSignedPush) { | ||||||
|         p.setEnableSignedPush(input.enableSignedPush); |         if (input.enableSignedPush != null) { | ||||||
|  |           p.setEnableSignedPush(input.enableSignedPush); | ||||||
|  |         } | ||||||
|  |         if (input.requireSignedPush != null) { | ||||||
|  |           p.setRequireSignedPush(input.requireSignedPush); | ||||||
|  |         } | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       if (input.maxObjectSizeLimit != null) { |       if (input.maxObjectSizeLimit != null) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Dave Borowitz
					Dave Borowitz