From b8336f176afb28c2b7bdf193571df932ea819321 Mon Sep 17 00:00:00 2001 From: Dave Borowitz Date: Wed, 26 Aug 2015 09:51:27 -0400 Subject: [PATCH] Move most GPG-related code to a gerrit-gpg module Bouncy Castle is still an optional dependency for Gerrit, so we want to avoid accidentally attempting to load Bouncy Castle classes when they might not be available. Rather than try to guard every org.bouncycastle.* reference with a hasPGP() check, reduce the surface area of calls that actually require Bouncy Castle. Move almost all code that calls Bouncy Castle into a new module, gerrit-gpg. Callers need only interact with this module by installing the GpgModule, which is careful to protect all Bouncy Castle class loading with the appropriate havePGP() check. Moreover, this module doesn't need to be installed in the gerrit-server package at all, so we can break the compile-time dependency between gerrit-server and Bouncy Castle, so accidentally introducing a dependency on Bouncy Castle results in a compile error. The REST API and extension APIs dealing with GPG keys only refer to the GpgKeyInfo POJO, and don't need to actually refer to Bouncy Castle classes. Add a shim interface, GpgApiAdapter, that is used by AccountApiImpl to process GPG keys. GpgModule binds this interface to either the Bouncy Castle enabled implementation, or a not-implemented implementation. Since there are various places in the server code where we want to inspect whether signed push is enabled at the server level, but we don't want to have to call into gerrit-gpg code to do this, bind a boolean with @EnableSignedPush from GpgModule. Change-Id: Idbab00a52d86216cae73d02876d56be54aef6581 --- gerrit-acceptance-tests/BUCK | 2 + .../acceptance/api/accounts/AccountIT.java | 19 +++- .../restapi/NotImplementedException.java | 6 +- gerrit-gpg/BUCK | 65 ++++++++++++ .../google/gerrit/gpg}/BouncyCastleUtil.java | 2 +- .../com/google/gerrit}/gpg/CheckResult.java | 2 +- .../com/google/gerrit}/gpg/Fingerprint.java | 2 +- .../gerrit}/gpg/GerritPublicKeyChecker.java | 4 +- .../java/com/google/gerrit/gpg/GpgModule.java | 99 +++++++++++++++++++ .../google/gerrit}/gpg/PublicKeyChecker.java | 4 +- .../google/gerrit}/gpg/PublicKeyStore.java | 2 +- .../gerrit}/gpg/PushCertificateChecker.java | 6 +- .../google/gerrit}/gpg/SignedPushModule.java | 17 ++-- .../gerrit}/gpg/SignedPushPreReceiveHook.java | 2 +- .../gerrit/gpg/api/GpgApiAdapterImpl.java | 83 ++++++++++++++++ .../google/gerrit/gpg/api}/GpgKeyApiImpl.java | 18 ++-- .../gerrit/gpg/server}/DeleteGpgKey.java | 9 +- .../com/google/gerrit/gpg/server/GpgKey.java | 38 +++++++ .../google/gerrit/gpg/server}/GpgKeys.java | 20 ++-- .../gerrit/gpg/server}/PostGpgKeys.java | 17 ++-- .../gpg/GerritPublicKeyCheckerTest.java | 3 +- .../gerrit}/gpg/PublicKeyCheckerTest.java | 4 +- .../gerrit}/gpg/PublicKeyStoreTest.java | 9 +- .../gpg/PushCertificateCheckerTest.java | 7 +- .../google/gerrit/gpg/testutil}/TestKey.java | 4 +- gerrit-pgm/BUCK | 1 + .../java/com/google/gerrit/pgm/Daemon.java | 11 ++- .../gerrit/reviewdb/client/RefNames.java | 2 +- gerrit-server/BUCK | 11 +-- .../gerrit/server/EnableSignedPush.java | 29 ++++++ .../google/gerrit/server/GpgException.java | 33 +++++++ .../server/account/AccountResource.java | 18 ---- .../google/gerrit/server/account/Module.java | 7 -- .../server/api/accounts/AccountApiImpl.java | 34 ++----- .../server/api/accounts/GpgApiAdapter.java | 34 +++++++ .../gerrit/server/api/accounts/Module.java | 1 - .../server/config/GerritGlobalModule.java | 2 - .../gerrit/server/config/GetServerInfo.java | 13 ++- .../gerrit/server/project/ConfigInfo.java | 7 +- .../gerrit/server/project/GetConfig.java | 12 +-- .../gerrit/server/project/PutConfig.java | 14 +-- .../gerrit/testutil/InMemoryModule.java | 2 + gerrit-war/BUCK | 1 + .../gerrit/httpd/WebAppInitializer.java | 8 +- tools/eclipse/BUCK | 1 + 45 files changed, 521 insertions(+), 164 deletions(-) create mode 100644 gerrit-gpg/BUCK rename {gerrit-server/src/main/java/com/google/gerrit/server/util => gerrit-gpg/src/main/java/com/google/gerrit/gpg}/BouncyCastleUtil.java (98%) rename {gerrit-server/src/main/java/com/google/gerrit/server/git => gerrit-gpg/src/main/java/com/google/gerrit}/gpg/CheckResult.java (97%) rename {gerrit-server/src/main/java/com/google/gerrit/server/git => gerrit-gpg/src/main/java/com/google/gerrit}/gpg/Fingerprint.java (98%) rename {gerrit-server/src/main/java/com/google/gerrit/server/git => gerrit-gpg/src/main/java/com/google/gerrit}/gpg/GerritPublicKeyChecker.java (97%) create mode 100644 gerrit-gpg/src/main/java/com/google/gerrit/gpg/GpgModule.java rename {gerrit-server/src/main/java/com/google/gerrit/server/git => gerrit-gpg/src/main/java/com/google/gerrit}/gpg/PublicKeyChecker.java (95%) rename {gerrit-server/src/main/java/com/google/gerrit/server/git => gerrit-gpg/src/main/java/com/google/gerrit}/gpg/PublicKeyStore.java (99%) rename {gerrit-server/src/main/java/com/google/gerrit/server/git => gerrit-gpg/src/main/java/com/google/gerrit}/gpg/PushCertificateChecker.java (96%) rename {gerrit-server/src/main/java/com/google/gerrit/server/git => gerrit-gpg/src/main/java/com/google/gerrit}/gpg/SignedPushModule.java (92%) rename {gerrit-server/src/main/java/com/google/gerrit/server/git => gerrit-gpg/src/main/java/com/google/gerrit}/gpg/SignedPushPreReceiveHook.java (98%) create mode 100644 gerrit-gpg/src/main/java/com/google/gerrit/gpg/api/GpgApiAdapterImpl.java rename {gerrit-server/src/main/java/com/google/gerrit/server/api/accounts => gerrit-gpg/src/main/java/com/google/gerrit/gpg/api}/GpgKeyApiImpl.java (80%) rename {gerrit-server/src/main/java/com/google/gerrit/server/account => gerrit-gpg/src/main/java/com/google/gerrit/gpg/server}/DeleteGpgKey.java (91%) create mode 100644 gerrit-gpg/src/main/java/com/google/gerrit/gpg/server/GpgKey.java rename {gerrit-server/src/main/java/com/google/gerrit/server/account => gerrit-gpg/src/main/java/com/google/gerrit/gpg/server}/GpgKeys.java (92%) rename {gerrit-server/src/main/java/com/google/gerrit/server/account => gerrit-gpg/src/main/java/com/google/gerrit/gpg/server}/PostGpgKeys.java (94%) rename {gerrit-server/src/test/java/com/google/gerrit/server/git => gerrit-gpg/src/test/java/com/google/gerrit}/gpg/GerritPublicKeyCheckerTest.java (98%) rename {gerrit-server/src/test/java/com/google/gerrit/server/git => gerrit-gpg/src/test/java/com/google/gerrit}/gpg/PublicKeyCheckerTest.java (95%) rename {gerrit-server/src/test/java/com/google/gerrit/server/git => gerrit-gpg/src/test/java/com/google/gerrit}/gpg/PublicKeyStoreTest.java (96%) rename {gerrit-server/src/test/java/com/google/gerrit/server/git => gerrit-gpg/src/test/java/com/google/gerrit}/gpg/PushCertificateCheckerTest.java (96%) rename {gerrit-server/src/test/java/com/google/gerrit/server/git/gpg => gerrit-gpg/src/test/java/com/google/gerrit/gpg/testutil}/TestKey.java (99%) create mode 100644 gerrit-server/src/main/java/com/google/gerrit/server/EnableSignedPush.java create mode 100644 gerrit-server/src/main/java/com/google/gerrit/server/GpgException.java create mode 100644 gerrit-server/src/main/java/com/google/gerrit/server/api/accounts/GpgApiAdapter.java diff --git a/gerrit-acceptance-tests/BUCK b/gerrit-acceptance-tests/BUCK index 0888216ed0..833070b7dd 100644 --- a/gerrit-acceptance-tests/BUCK +++ b/gerrit-acceptance-tests/BUCK @@ -5,6 +5,8 @@ java_library( '//gerrit-common:annotations', '//gerrit-common:server', '//gerrit-extension-api:api', + '//gerrit-gpg:gpg', + '//gerrit-gpg:testutil', '//gerrit-launcher:launcher', '//gerrit-lucene:lucene', '//gerrit-httpd:httpd', diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/accounts/AccountIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/accounts/AccountIT.java index 91d3f11a12..c6482a9304 100644 --- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/accounts/AccountIT.java +++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/accounts/AccountIT.java @@ -17,7 +17,7 @@ package com.google.gerrit.acceptance.api.accounts; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assert_; -import static com.google.gerrit.server.git.gpg.PublicKeyStore.keyToString; +import static com.google.gerrit.gpg.PublicKeyStore.keyToString; import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.base.Function; @@ -33,21 +33,23 @@ import com.google.gerrit.extensions.common.GpgKeyInfo; import com.google.gerrit.extensions.restapi.BadRequestException; import com.google.gerrit.extensions.restapi.ResourceConflictException; import com.google.gerrit.extensions.restapi.ResourceNotFoundException; +import com.google.gerrit.gpg.Fingerprint; +import com.google.gerrit.gpg.PublicKeyStore; +import com.google.gerrit.gpg.server.GpgKeys; +import com.google.gerrit.gpg.testutil.TestKey; import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.reviewdb.client.AccountExternalId; import com.google.gerrit.reviewdb.client.RefNames; import com.google.gerrit.server.IdentifiedUser; -import com.google.gerrit.server.account.GpgKeys; import com.google.gerrit.server.config.AllUsersName; -import com.google.gerrit.server.git.gpg.Fingerprint; -import com.google.gerrit.server.git.gpg.PublicKeyStore; -import com.google.gerrit.server.git.gpg.TestKey; +import com.google.gerrit.testutil.ConfigSuite; import com.google.inject.Inject; import com.google.inject.Provider; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRing; +import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.lib.Repository; @@ -65,6 +67,13 @@ import java.util.List; import java.util.Map; public class AccountIT extends AbstractDaemonTest { + @ConfigSuite.Default + public static Config enableSignedPushConfig() { + Config cfg = new Config(); + cfg.setBoolean("receive", null, "enableSignedPush", true); + return cfg; + } + @Inject private Provider publicKeyStoreProvider; diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/restapi/NotImplementedException.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/restapi/NotImplementedException.java index 10d0a147f2..566159d850 100644 --- a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/restapi/NotImplementedException.java +++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/restapi/NotImplementedException.java @@ -19,6 +19,10 @@ public class NotImplementedException extends UnsupportedOperationException { private static final long serialVersionUID = 1L; public NotImplementedException() { - super("Not implemented."); + this("Not implemented"); + } + + public NotImplementedException(String message) { + super(message); } } diff --git a/gerrit-gpg/BUCK b/gerrit-gpg/BUCK new file mode 100644 index 0000000000..592a519030 --- /dev/null +++ b/gerrit-gpg/BUCK @@ -0,0 +1,65 @@ +java_library( + name = 'gpg', + srcs = glob(['src/main/java/**/*.java']), + deps = [ + '//gerrit-common:server', + '//gerrit-extension-api:api', + '//gerrit-reviewdb:server', + '//gerrit-server:server', + '//lib:guava', + '//lib:gwtorm', + '//lib/guice:guice', + '//lib/guice:guice-assistedinject', + '//lib/guice:guice-servlet', + '//lib/jgit:jgit', + '//lib/log:api', + ], + provided_deps = [ + '//lib/bouncycastle:bcprov', + '//lib/bouncycastle:bcpg', + ], + visibility = ['PUBLIC'], +) + +TESTUTIL_SRCS = [ + 'src/test/java/com/google/gerrit/gpg/testutil/TestKey.java', +] + +java_library( + name = 'testutil', + srcs = TESTUTIL_SRCS, + deps = [ + ':gpg', + '//lib:guava', + '//lib/bouncycastle:bcpg', + '//lib/bouncycastle:bcprov', + '//lib/jgit:jgit', + ], + visibility = ['PUBLIC'], +) + +java_test( + name = 'gpg_tests', + srcs = glob( + ['src/test/java/**/*.java'], + excludes = TESTUTIL_SRCS, + ), + deps = [ + ':gpg', + ':testutil', + '//gerrit-extension-api:api', + '//gerrit-reviewdb:server', + '//gerrit-server:server', + '//gerrit-server:testutil', + '//lib:guava', + '//lib:gwtorm', + '//lib:truth', + '//lib/bouncycastle:bcpg', + '//lib/bouncycastle:bcprov', + '//lib/guice:guice', + '//lib/jgit:jgit', + '//lib/jgit:junit', + ], + source_under_test = [':gpg'], + visibility = ['//tools/eclipse:classpath'], +) diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/util/BouncyCastleUtil.java b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/BouncyCastleUtil.java similarity index 98% rename from gerrit-server/src/main/java/com/google/gerrit/server/util/BouncyCastleUtil.java rename to gerrit-gpg/src/main/java/com/google/gerrit/gpg/BouncyCastleUtil.java index ba87d58e3d..ef065a173d 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/util/BouncyCastleUtil.java +++ b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/BouncyCastleUtil.java @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.gerrit.server.util; +package com.google.gerrit.gpg; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPPublicKey; diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/CheckResult.java b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/CheckResult.java similarity index 97% rename from gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/CheckResult.java rename to gerrit-gpg/src/main/java/com/google/gerrit/gpg/CheckResult.java index 71321ba0a9..c41ecbecc7 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/CheckResult.java +++ b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/CheckResult.java @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.gerrit.server.git.gpg; +package com.google.gerrit.gpg; import java.util.ArrayList; import java.util.Arrays; diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/Fingerprint.java b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/Fingerprint.java similarity index 98% rename from gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/Fingerprint.java rename to gerrit-gpg/src/main/java/com/google/gerrit/gpg/Fingerprint.java index bc70cb3ef5..6fd8bace11 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/Fingerprint.java +++ b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/Fingerprint.java @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.gerrit.server.git.gpg; +package com.google.gerrit.gpg; import static com.google.common.base.Preconditions.checkArgument; diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/GerritPublicKeyChecker.java b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/GerritPublicKeyChecker.java similarity index 97% rename from gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/GerritPublicKeyChecker.java rename to gerrit-gpg/src/main/java/com/google/gerrit/gpg/GerritPublicKeyChecker.java index 851808c3d1..69a09f0233 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/GerritPublicKeyChecker.java +++ b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/GerritPublicKeyChecker.java @@ -12,10 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.gerrit.server.git.gpg; +package com.google.gerrit.gpg; +import static com.google.gerrit.gpg.PublicKeyStore.keyIdToString; import static com.google.gerrit.reviewdb.client.AccountExternalId.SCHEME_GPGKEY; -import static com.google.gerrit.server.git.gpg.PublicKeyStore.keyIdToString; import com.google.common.collect.FluentIterable; import com.google.common.collect.Ordering; diff --git a/gerrit-gpg/src/main/java/com/google/gerrit/gpg/GpgModule.java b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/GpgModule.java new file mode 100644 index 0000000000..fc1953a1cf --- /dev/null +++ b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/GpgModule.java @@ -0,0 +1,99 @@ +// Copyright (C) 2015 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.gpg; + +import static com.google.gerrit.gpg.server.GpgKey.GPG_KEY_KIND; +import static com.google.gerrit.server.account.AccountResource.ACCOUNT_KIND; + +import com.google.gerrit.extensions.api.accounts.GpgKeyApi; +import com.google.gerrit.extensions.common.GpgKeyInfo; +import com.google.gerrit.extensions.registration.DynamicMap; +import com.google.gerrit.extensions.restapi.IdString; +import com.google.gerrit.extensions.restapi.NotImplementedException; +import com.google.gerrit.extensions.restapi.RestApiModule; +import com.google.gerrit.gpg.api.GpgApiAdapterImpl; +import com.google.gerrit.gpg.api.GpgKeyApiImpl; +import com.google.gerrit.gpg.server.DeleteGpgKey; +import com.google.gerrit.gpg.server.GpgKeys; +import com.google.gerrit.gpg.server.PostGpgKeys; +import com.google.gerrit.server.EnableSignedPush; +import com.google.gerrit.server.account.AccountResource; +import com.google.gerrit.server.api.accounts.GpgApiAdapter; + +import org.eclipse.jgit.lib.Config; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; +import java.util.Map; + +public class GpgModule extends RestApiModule { + private static final Logger log = LoggerFactory.getLogger(GpgModule.class); + + private final Config cfg; + + public GpgModule(Config cfg) { + this.cfg = cfg; + } + + @Override + protected void configure() { + boolean configEnableSignedPush = + cfg.getBoolean("receive", null, "enableSignedPush", false); + boolean havePgp = BouncyCastleUtil.havePGP(); + boolean enableSignedPush = configEnableSignedPush && havePgp; + bindConstant().annotatedWith(EnableSignedPush.class).to(enableSignedPush); + + if (configEnableSignedPush && !havePgp) { + log.info("Bouncy Castle PGP not installed; signed push verification is" + + " disabled"); + } + if (!enableSignedPush) { + bind(GpgApiAdapter.class).to(NoGpgApi.class); + return; + } + + install(new SignedPushModule()); + bind(GpgApiAdapter.class).to(GpgApiAdapterImpl.class); + factory(GpgKeyApiImpl.Factory.class); + + DynamicMap.mapOf(binder(), GPG_KEY_KIND); + + child(ACCOUNT_KIND, "gpgkeys").to(GpgKeys.class); + post(ACCOUNT_KIND, "gpgkeys").to(PostGpgKeys.class); + get(GPG_KEY_KIND).to(GpgKeys.Get.class); + delete(GPG_KEY_KIND).to(DeleteGpgKey.class); + } + + private static class NoGpgApi implements GpgApiAdapter { + private static final String MSG = "GPG key APIs disabled"; + + @Override + public Map listGpgKeys(AccountResource account) { + throw new NotImplementedException(MSG); + } + + @Override + public Map putGpgKeys(AccountResource account, + List add, List delete) { + throw new NotImplementedException(MSG); + } + + @Override + public GpgKeyApi gpgKey(AccountResource account, IdString idStr) { + throw new NotImplementedException(MSG); + } + } +} diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/PublicKeyChecker.java b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/PublicKeyChecker.java similarity index 95% rename from gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/PublicKeyChecker.java rename to gerrit-gpg/src/main/java/com/google/gerrit/gpg/PublicKeyChecker.java index 62cb563d9d..7b7aabb3e1 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/PublicKeyChecker.java +++ b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/PublicKeyChecker.java @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.gerrit.server.git.gpg; +package com.google.gerrit.gpg; -import static com.google.gerrit.server.git.gpg.PublicKeyStore.keyIdToString; +import static com.google.gerrit.gpg.PublicKeyStore.keyIdToString; import org.bouncycastle.openpgp.PGPPublicKey; diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/PublicKeyStore.java b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/PublicKeyStore.java similarity index 99% rename from gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/PublicKeyStore.java rename to gerrit-gpg/src/main/java/com/google/gerrit/gpg/PublicKeyStore.java index 7115c3fc60..3736a7c74b 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/PublicKeyStore.java +++ b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/PublicKeyStore.java @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.gerrit.server.git.gpg; +package com.google.gerrit.gpg; import static com.google.common.base.Preconditions.checkState; import static org.eclipse.jgit.lib.Constants.OBJ_BLOB; diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/PushCertificateChecker.java b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/PushCertificateChecker.java similarity index 96% rename from gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/PushCertificateChecker.java rename to gerrit-gpg/src/main/java/com/google/gerrit/gpg/PushCertificateChecker.java index fcef3a3635..80b87f7175 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/PushCertificateChecker.java +++ b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/PushCertificateChecker.java @@ -12,10 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.gerrit.server.git.gpg; +package com.google.gerrit.gpg; -import static com.google.gerrit.server.git.gpg.PublicKeyStore.keyIdToString; -import static com.google.gerrit.server.git.gpg.PublicKeyStore.keyToString; +import static com.google.gerrit.gpg.PublicKeyStore.keyIdToString; +import static com.google.gerrit.gpg.PublicKeyStore.keyToString; import org.bouncycastle.bcpg.ArmoredInputStream; import org.bouncycastle.openpgp.PGPException; diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/SignedPushModule.java b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/SignedPushModule.java similarity index 92% rename from gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/SignedPushModule.java rename to gerrit-gpg/src/main/java/com/google/gerrit/gpg/SignedPushModule.java index 88bda9a388..750880682b 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/SignedPushModule.java +++ b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/SignedPushModule.java @@ -12,19 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.gerrit.server.git.gpg; +package com.google.gerrit.gpg; import com.google.common.base.Strings; 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.EnableSignedPush; import com.google.gerrit.server.config.AllUsersName; import com.google.gerrit.server.config.GerritServerConfig; import com.google.gerrit.server.git.GitRepositoryManager; import com.google.gerrit.server.git.ReceivePackInitializer; 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; import com.google.inject.Provider; @@ -44,20 +44,14 @@ import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Random; -public class SignedPushModule extends AbstractModule { +class SignedPushModule extends AbstractModule { private static final Logger log = LoggerFactory.getLogger(SignedPushModule.class); - public static boolean isEnabled(Config cfg) { - return cfg.getBoolean("receive", null, "enableSignedPush", false); - } - @Override protected void configure() { if (!BouncyCastleUtil.havePGP()) { - log.info("BouncyCastle PGP not installed; signed push verification is" - + " disabled"); - return; + throw new ProvisionException("Bouncy Castle PGP not installed"); } bind(PublicKeyChecker.class).to(GerritPublicKeyChecker.class); bind(PublicKeyStore.class).toProvider(StoreProvider.class); @@ -73,12 +67,13 @@ public class SignedPushModule extends AbstractModule { @Inject Initializer(@GerritServerConfig Config cfg, + @EnableSignedPush boolean enableSignedPush, SignedPushPreReceiveHook hook, ProjectCache projectCache) { this.hook = hook; this.projectCache = projectCache; - if (isEnabled(cfg)) { + if (enableSignedPush) { String seed = cfg.getString("receive", null, "certNonceSeed"); if (Strings.isNullOrEmpty(seed)) { seed = randomString(64); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/SignedPushPreReceiveHook.java b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/SignedPushPreReceiveHook.java similarity index 98% rename from gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/SignedPushPreReceiveHook.java rename to gerrit-gpg/src/main/java/com/google/gerrit/gpg/SignedPushPreReceiveHook.java index f5e9f09653..8618f208f6 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/git/gpg/SignedPushPreReceiveHook.java +++ b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/SignedPushPreReceiveHook.java @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.gerrit.server.git.gpg; +package com.google.gerrit.gpg; import com.google.gerrit.server.config.AllUsersName; import com.google.gerrit.server.git.GitRepositoryManager; diff --git a/gerrit-gpg/src/main/java/com/google/gerrit/gpg/api/GpgApiAdapterImpl.java b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/api/GpgApiAdapterImpl.java new file mode 100644 index 0000000000..64b9e859e2 --- /dev/null +++ b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/api/GpgApiAdapterImpl.java @@ -0,0 +1,83 @@ +// Copyright (C) 2015 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.gpg.api; + +import com.google.gerrit.extensions.api.accounts.GpgKeyApi; +import com.google.gerrit.extensions.common.GpgKeyInfo; +import com.google.gerrit.extensions.restapi.IdString; +import com.google.gerrit.extensions.restapi.RestApiException; +import com.google.gerrit.gpg.server.GpgKeys; +import com.google.gerrit.gpg.server.PostGpgKeys; +import com.google.gerrit.server.GpgException; +import com.google.gerrit.server.account.AccountResource; +import com.google.gerrit.server.api.accounts.GpgApiAdapter; +import com.google.gwtorm.server.OrmException; +import com.google.inject.Inject; + +import org.bouncycastle.openpgp.PGPException; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +public class GpgApiAdapterImpl implements GpgApiAdapter { + private final PostGpgKeys postGpgKeys; + private final GpgKeys gpgKeys; + private final GpgKeyApiImpl.Factory gpgKeyApiFactory; + + @Inject + GpgApiAdapterImpl( + PostGpgKeys postGpgKeys, + GpgKeys gpgKeys, + GpgKeyApiImpl.Factory gpgKeyApiFactory) { + this.postGpgKeys = postGpgKeys; + this.gpgKeys = gpgKeys; + this.gpgKeyApiFactory = gpgKeyApiFactory; + } + + @Override + public Map listGpgKeys(AccountResource account) + throws RestApiException, GpgException { + try { + return gpgKeys.list().apply(account); + } catch (OrmException | PGPException | IOException e) { + throw new GpgException(e); + } + } + + @Override + public Map putGpgKeys(AccountResource account, + List add, List delete) + throws RestApiException, GpgException { + PostGpgKeys.Input in = new PostGpgKeys.Input(); + in.add = add; + in.delete = delete; + try { + return postGpgKeys.apply(account, in); + } catch (PGPException | OrmException | IOException e) { + throw new GpgException(e); + } + } + + @Override + public GpgKeyApi gpgKey(AccountResource account, IdString idStr) + throws RestApiException, GpgException { + try { + return gpgKeyApiFactory.create(gpgKeys.parse(account, idStr)); + } catch (PGPException | OrmException | IOException e) { + throw new GpgException(e); + } + } +} diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/api/accounts/GpgKeyApiImpl.java b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/api/GpgKeyApiImpl.java similarity index 80% rename from gerrit-server/src/main/java/com/google/gerrit/server/api/accounts/GpgKeyApiImpl.java rename to gerrit-gpg/src/main/java/com/google/gerrit/gpg/api/GpgKeyApiImpl.java index e42c2f6d13..ab301840e8 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/api/accounts/GpgKeyApiImpl.java +++ b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/api/GpgKeyApiImpl.java @@ -12,14 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.gerrit.server.api.accounts; +package com.google.gerrit.gpg.api; import com.google.gerrit.extensions.api.accounts.GpgKeyApi; import com.google.gerrit.extensions.common.GpgKeyInfo; import com.google.gerrit.extensions.restapi.RestApiException; -import com.google.gerrit.server.account.AccountResource; -import com.google.gerrit.server.account.DeleteGpgKey; -import com.google.gerrit.server.account.GpgKeys; +import com.google.gerrit.gpg.server.DeleteGpgKey; +import com.google.gerrit.gpg.server.GpgKey; +import com.google.gerrit.gpg.server.GpgKeys; import com.google.gwtorm.server.OrmException; import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.AssistedInject; @@ -28,20 +28,20 @@ import org.bouncycastle.openpgp.PGPException; import java.io.IOException; -class GpgKeyApiImpl implements GpgKeyApi { - interface Factory { - GpgKeyApiImpl create(AccountResource.GpgKey rsrc); +public class GpgKeyApiImpl implements GpgKeyApi { + public interface Factory { + GpgKeyApiImpl create(GpgKey rsrc); } private final GpgKeys.Get get; private final DeleteGpgKey delete; - private final AccountResource.GpgKey rsrc; + private final GpgKey rsrc; @AssistedInject GpgKeyApiImpl( GpgKeys.Get get, DeleteGpgKey delete, - @Assisted AccountResource.GpgKey rsrc) { + @Assisted GpgKey rsrc) { this.get = get; this.delete = delete; this.rsrc = rsrc; diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteGpgKey.java b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/server/DeleteGpgKey.java similarity index 91% rename from gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteGpgKey.java rename to gerrit-gpg/src/main/java/com/google/gerrit/gpg/server/DeleteGpgKey.java index b7e63cf165..baac7147c6 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteGpgKey.java +++ b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/server/DeleteGpgKey.java @@ -12,20 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.gerrit.server.account; +package com.google.gerrit.gpg.server; -import static com.google.gerrit.server.git.gpg.PublicKeyStore.keyIdToString; +import static com.google.gerrit.gpg.PublicKeyStore.keyIdToString; import com.google.common.io.BaseEncoding; import com.google.gerrit.extensions.restapi.ResourceConflictException; import com.google.gerrit.extensions.restapi.Response; import com.google.gerrit.extensions.restapi.RestModifyView; +import com.google.gerrit.gpg.PublicKeyStore; +import com.google.gerrit.gpg.server.DeleteGpgKey.Input; import com.google.gerrit.reviewdb.client.AccountExternalId; import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.server.GerritPersonIdent; -import com.google.gerrit.server.account.AccountResource.GpgKey; -import com.google.gerrit.server.account.DeleteGpgKey.Input; -import com.google.gerrit.server.git.gpg.PublicKeyStore; import com.google.gwtorm.server.OrmException; import com.google.inject.Inject; import com.google.inject.Provider; diff --git a/gerrit-gpg/src/main/java/com/google/gerrit/gpg/server/GpgKey.java b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/server/GpgKey.java new file mode 100644 index 0000000000..2fe7eb661c --- /dev/null +++ b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/server/GpgKey.java @@ -0,0 +1,38 @@ +// Copyright (C) 2015 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.gpg.server; + +import com.google.gerrit.extensions.restapi.RestView; +import com.google.gerrit.server.IdentifiedUser; +import com.google.gerrit.server.account.AccountResource; +import com.google.inject.TypeLiteral; + +import org.bouncycastle.openpgp.PGPPublicKeyRing; + +public class GpgKey extends AccountResource { + public static final TypeLiteral> GPG_KEY_KIND = + new TypeLiteral>() {}; + + private final PGPPublicKeyRing keyRing; + + public GpgKey(IdentifiedUser user, PGPPublicKeyRing keyRing) { + super(user); + this.keyRing = keyRing; + } + + public PGPPublicKeyRing getKeyRing() { + return keyRing; + } +} diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/GpgKeys.java b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/server/GpgKeys.java similarity index 92% rename from gerrit-server/src/main/java/com/google/gerrit/server/account/GpgKeys.java rename to gerrit-gpg/src/main/java/com/google/gerrit/gpg/server/GpgKeys.java index bbcdd0632a..b22ca0e905 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/account/GpgKeys.java +++ b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/server/GpgKeys.java @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.gerrit.server.account; +package com.google.gerrit.gpg.server; import static com.google.gerrit.reviewdb.client.AccountExternalId.SCHEME_GPGKEY; import static java.nio.charset.StandardCharsets.UTF_8; @@ -31,13 +31,13 @@ import com.google.gerrit.extensions.restapi.IdString; import com.google.gerrit.extensions.restapi.ResourceNotFoundException; import com.google.gerrit.extensions.restapi.RestReadView; import com.google.gerrit.extensions.restapi.RestView; +import com.google.gerrit.gpg.BouncyCastleUtil; +import com.google.gerrit.gpg.Fingerprint; +import com.google.gerrit.gpg.PublicKeyStore; import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.reviewdb.client.AccountExternalId; import com.google.gerrit.reviewdb.server.ReviewDb; -import com.google.gerrit.server.account.AccountResource.GpgKey; -import com.google.gerrit.server.git.gpg.Fingerprint; -import com.google.gerrit.server.git.gpg.PublicKeyStore; -import com.google.gerrit.server.util.BouncyCastleUtil; +import com.google.gerrit.server.account.AccountResource; import com.google.gwtorm.server.OrmException; import com.google.inject.Inject; import com.google.inject.Provider; @@ -60,17 +60,17 @@ import java.util.Map; @Singleton public class GpgKeys implements - ChildCollection { + ChildCollection { private static final Logger log = LoggerFactory.getLogger(GpgKeys.class); public static String MIME_TYPE = "application/pgp-keys"; - private final DynamicMap> views; + private final DynamicMap> views; private final Provider db; private final Provider storeProvider; @Inject - GpgKeys(DynamicMap> views, + GpgKeys(DynamicMap> views, Provider db, Provider storeProvider) { this.views = views; @@ -102,7 +102,7 @@ public class GpgKeys implements for (PGPPublicKeyRing keyRing : store.get(keyId)) { PGPPublicKey key = keyRing.getPublicKey(); if (Arrays.equals(key.getFingerprint(), fp)) { - return new AccountResource.GpgKey(parent.getUser(), keyRing); + return new GpgKey(parent.getUser(), keyRing); } } } @@ -172,7 +172,7 @@ public class GpgKeys implements } @Singleton - public static class Get implements RestReadView { + public static class Get implements RestReadView { @Override public GpgKeyInfo apply(GpgKey rsrc) throws IOException { return toJson(rsrc.getKeyRing()); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/PostGpgKeys.java b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/server/PostGpgKeys.java similarity index 94% rename from gerrit-server/src/main/java/com/google/gerrit/server/account/PostGpgKeys.java rename to gerrit-gpg/src/main/java/com/google/gerrit/gpg/server/PostGpgKeys.java index 776f9831c8..670adbaea2 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/account/PostGpgKeys.java +++ b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/server/PostGpgKeys.java @@ -12,10 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.gerrit.server.account; +package com.google.gerrit.gpg.server; -import static com.google.gerrit.server.git.gpg.PublicKeyStore.keyIdToString; -import static com.google.gerrit.server.git.gpg.PublicKeyStore.keyToString; +import static com.google.gerrit.gpg.PublicKeyStore.keyIdToString; +import static com.google.gerrit.gpg.PublicKeyStore.keyToString; import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.base.Function; @@ -32,14 +32,15 @@ import com.google.gerrit.extensions.restapi.BadRequestException; import com.google.gerrit.extensions.restapi.ResourceConflictException; import com.google.gerrit.extensions.restapi.ResourceNotFoundException; import com.google.gerrit.extensions.restapi.RestModifyView; +import com.google.gerrit.gpg.CheckResult; +import com.google.gerrit.gpg.Fingerprint; +import com.google.gerrit.gpg.PublicKeyChecker; +import com.google.gerrit.gpg.PublicKeyStore; +import com.google.gerrit.gpg.server.PostGpgKeys.Input; import com.google.gerrit.reviewdb.client.AccountExternalId; import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.server.GerritPersonIdent; -import com.google.gerrit.server.account.PostGpgKeys.Input; -import com.google.gerrit.server.git.gpg.CheckResult; -import com.google.gerrit.server.git.gpg.Fingerprint; -import com.google.gerrit.server.git.gpg.PublicKeyChecker; -import com.google.gerrit.server.git.gpg.PublicKeyStore; +import com.google.gerrit.server.account.AccountResource; import com.google.gwtorm.server.OrmException; import com.google.inject.Inject; import com.google.inject.Provider; diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/git/gpg/GerritPublicKeyCheckerTest.java b/gerrit-gpg/src/test/java/com/google/gerrit/gpg/GerritPublicKeyCheckerTest.java similarity index 98% rename from gerrit-server/src/test/java/com/google/gerrit/server/git/gpg/GerritPublicKeyCheckerTest.java rename to gerrit-gpg/src/test/java/com/google/gerrit/gpg/GerritPublicKeyCheckerTest.java index 4b00d5caf4..e65ba002c9 100644 --- a/gerrit-server/src/test/java/com/google/gerrit/server/git/gpg/GerritPublicKeyCheckerTest.java +++ b/gerrit-gpg/src/test/java/com/google/gerrit/gpg/GerritPublicKeyCheckerTest.java @@ -12,12 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.gerrit.server.git.gpg; +package com.google.gerrit.gpg; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.truth.Truth.assertThat; import com.google.common.collect.ImmutableList; +import com.google.gerrit.gpg.testutil.TestKey; import com.google.gerrit.lifecycle.LifecycleManager; import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.reviewdb.client.AccountExternalId; diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/git/gpg/PublicKeyCheckerTest.java b/gerrit-gpg/src/test/java/com/google/gerrit/gpg/PublicKeyCheckerTest.java similarity index 95% rename from gerrit-server/src/test/java/com/google/gerrit/server/git/gpg/PublicKeyCheckerTest.java rename to gerrit-gpg/src/test/java/com/google/gerrit/gpg/PublicKeyCheckerTest.java index a82619ca2b..ebc3e584c9 100644 --- a/gerrit-server/src/test/java/com/google/gerrit/server/git/gpg/PublicKeyCheckerTest.java +++ b/gerrit-gpg/src/test/java/com/google/gerrit/gpg/PublicKeyCheckerTest.java @@ -12,10 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.gerrit.server.git.gpg; +package com.google.gerrit.gpg; import static org.junit.Assert.assertEquals; +import com.google.gerrit.gpg.testutil.TestKey; + import org.junit.Before; import org.junit.Test; diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/git/gpg/PublicKeyStoreTest.java b/gerrit-gpg/src/test/java/com/google/gerrit/gpg/PublicKeyStoreTest.java similarity index 96% rename from gerrit-server/src/test/java/com/google/gerrit/server/git/gpg/PublicKeyStoreTest.java rename to gerrit-gpg/src/test/java/com/google/gerrit/gpg/PublicKeyStoreTest.java index c84757eb77..f48f9d806a 100644 --- a/gerrit-server/src/test/java/com/google/gerrit/server/git/gpg/PublicKeyStoreTest.java +++ b/gerrit-gpg/src/test/java/com/google/gerrit/gpg/PublicKeyStoreTest.java @@ -12,16 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.gerrit.server.git.gpg; +package com.google.gerrit.gpg; -import static com.google.gerrit.server.git.gpg.PublicKeyStore.keyIdToString; -import static com.google.gerrit.server.git.gpg.PublicKeyStore.keyObjectId; -import static com.google.gerrit.server.git.gpg.PublicKeyStore.keyToString; +import static com.google.gerrit.gpg.PublicKeyStore.keyIdToString; +import static com.google.gerrit.gpg.PublicKeyStore.keyObjectId; +import static com.google.gerrit.gpg.PublicKeyStore.keyToString; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import com.google.gerrit.gpg.testutil.TestKey; import com.google.gerrit.reviewdb.client.RefNames; import org.bouncycastle.openpgp.PGPPublicKey; diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/git/gpg/PushCertificateCheckerTest.java b/gerrit-gpg/src/test/java/com/google/gerrit/gpg/PushCertificateCheckerTest.java similarity index 96% rename from gerrit-server/src/test/java/com/google/gerrit/server/git/gpg/PushCertificateCheckerTest.java rename to gerrit-gpg/src/test/java/com/google/gerrit/gpg/PushCertificateCheckerTest.java index aa2a2c7637..238156c43b 100644 --- a/gerrit-server/src/test/java/com/google/gerrit/server/git/gpg/PushCertificateCheckerTest.java +++ b/gerrit-gpg/src/test/java/com/google/gerrit/gpg/PushCertificateCheckerTest.java @@ -12,13 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.gerrit.server.git.gpg; +package com.google.gerrit.gpg; -import static com.google.gerrit.server.git.gpg.PublicKeyStore.keyIdToString; -import static com.google.gerrit.server.git.gpg.PublicKeyStore.keyToString; +import static com.google.gerrit.gpg.PublicKeyStore.keyIdToString; +import static com.google.gerrit.gpg.PublicKeyStore.keyToString; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; +import com.google.gerrit.gpg.testutil.TestKey; import com.google.gerrit.reviewdb.client.RefNames; import org.bouncycastle.bcpg.ArmoredOutputStream; diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/git/gpg/TestKey.java b/gerrit-gpg/src/test/java/com/google/gerrit/gpg/testutil/TestKey.java similarity index 99% rename from gerrit-server/src/test/java/com/google/gerrit/server/git/gpg/TestKey.java rename to gerrit-gpg/src/test/java/com/google/gerrit/gpg/testutil/TestKey.java index 321f01bba9..614818e28e 100644 --- a/gerrit-server/src/test/java/com/google/gerrit/server/git/gpg/TestKey.java +++ b/gerrit-gpg/src/test/java/com/google/gerrit/gpg/testutil/TestKey.java @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.gerrit.server.git.gpg; +package com.google.gerrit.gpg.testutil; -import static com.google.gerrit.server.git.gpg.PublicKeyStore.keyIdToString; +import static com.google.gerrit.gpg.PublicKeyStore.keyIdToString; import com.google.common.collect.ImmutableList; diff --git a/gerrit-pgm/BUCK b/gerrit-pgm/BUCK index b52e7af116..80c37f7836 100644 --- a/gerrit-pgm/BUCK +++ b/gerrit-pgm/BUCK @@ -100,6 +100,7 @@ java_library( ':init-api', ':util', '//gerrit-cache-h2:cache-h2', + '//gerrit-gpg:gpg', '//gerrit-lucene:lucene', '//gerrit-oauth:oauth', '//gerrit-openid:openid', diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java index 0cc3349f07..da87a20c11 100644 --- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java +++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java @@ -20,6 +20,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.MoreObjects; import com.google.gerrit.common.ChangeHookRunner; +import com.google.gerrit.gpg.GpgModule; import com.google.gerrit.httpd.AllRequestFilter; import com.google.gerrit.httpd.GerritOptions; import com.google.gerrit.httpd.GetUserFilter; @@ -143,6 +144,7 @@ public class Daemon extends SiteProgram { private final LifecycleManager manager = new LifecycleManager(); private Injector dbInjector; private Injector cfgInjector; + private Config config; private Injector sysInjector; private Injector sshInjector; private Injector webInjector; @@ -272,14 +274,15 @@ public class Daemon extends SiteProgram { dbInjector = createDbInjector(MULTI_USER); } cfgInjector = createCfgInjector(); + config = cfgInjector.getInstance( + Key.get(Config.class, GerritServerConfig.class)); sysInjector = createSysInjector(); sysInjector.getInstance(PluginGuiceEnvironment.class) .setDbCfgInjector(dbInjector, cfgInjector); manager.add(dbInjector, cfgInjector, sysInjector); if (!consoleLog) { - manager.add(ErrorLogFile.start(getSitePath(), - cfgInjector.getInstance(Key.get(Config.class, GerritServerConfig.class)))); + manager.add(ErrorLogFile.start(getSitePath(), config)); } sshd &= !sshdOff(); @@ -300,8 +303,7 @@ public class Daemon extends SiteProgram { } private boolean sshdOff() { - Config cfg = cfgInjector.getInstance(Key.get(Config.class, GerritServerConfig.class)); - return new SshAddressesModule().getListenAddresses(cfg).isEmpty(); + return new SshAddressesModule().getListenAddresses(config).isEmpty(); } private String myVersion() { @@ -335,6 +337,7 @@ public class Daemon extends SiteProgram { modules.add(new SignedTokenEmailTokenVerifier.Module()); modules.add(new PluginRestApiModule()); modules.add(new RestCacheAdminModule()); + modules.add(new GpgModule(config)); modules.add(createIndexModule()); if (MoreObjects.firstNonNull(httpd, true)) { modules.add(new CanonicalWebUrlModule() { diff --git a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/RefNames.java b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/RefNames.java index 707664f7f1..9468d2d8cc 100644 --- a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/RefNames.java +++ b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/RefNames.java @@ -59,7 +59,7 @@ public class RefNames { /** * Special ref for GPG public keys used by {@link - * com.google.gerrit.server.git.gpg.SignedPushPreReceiveHook}. + * com.google.gerrit.gpg.SignedPushPreReceiveHook}. */ public static final String REFS_GPG_KEYS = "refs/meta/gpg-keys"; diff --git a/gerrit-server/BUCK b/gerrit-server/BUCK index 61c4cff80f..f7bb86f7c4 100644 --- a/gerrit-server/BUCK +++ b/gerrit-server/BUCK @@ -72,9 +72,6 @@ java_library( ], provided_deps = [ '//lib:servlet-api-3_1', - '//lib/bouncycastle:bcprov', - '//lib/bouncycastle:bcpg', - '//lib/bouncycastle:bcpkix', ], visibility = ['PUBLIC'], ) @@ -88,7 +85,6 @@ java_sources( TESTUTIL = glob([ 'src/test/java/com/google/gerrit/testutil/**/*.java', 'src/test/java/com/google/gerrit/server/project/Util.java', - 'src/test/java/com/google/gerrit/server/git/gpg/TestKey.java', ]) java_library( name = 'testutil', @@ -98,14 +94,13 @@ java_library( '//gerrit-common:server', '//gerrit-cache-h2:cache-h2', '//gerrit-extension-api:api', + '//gerrit-gpg:gpg', '//gerrit-lucene:lucene', '//gerrit-reviewdb:server', '//lib:gwtorm', '//lib:h2', '//lib:truth', '//lib/auto:auto-value', - '//lib/bouncycastle:bcpg', - '//lib/bouncycastle:bcprov', '//lib/guice:guice', '//lib/guice:guice-servlet', '//lib/jgit:jgit', @@ -211,6 +206,7 @@ java_test( '//gerrit-common:annotations', '//gerrit-common:server', '//gerrit-extension-api:api', + '//gerrit-gpg:gpg', '//gerrit-reviewdb:server', '//gerrit-server/src/main/prolog:common', '//lib:args4j', @@ -218,9 +214,6 @@ java_test( '//lib:guava', '//lib:gwtorm', '//lib:truth', - '//lib/bouncycastle:bcprov', - '//lib/bouncycastle:bcpg', - '//lib/bouncycastle:bcpkix', '//lib/guice:guice', '//lib/guice:guice-assistedinject', '//lib/jgit:jgit', diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/EnableSignedPush.java b/gerrit-server/src/main/java/com/google/gerrit/server/EnableSignedPush.java new file mode 100644 index 0000000000..13942a67ff --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/EnableSignedPush.java @@ -0,0 +1,29 @@ +// Copyright (C) 2015 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.server; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import com.google.inject.BindingAnnotation; + +import java.lang.annotation.Retention; + +/** + * Marker on a boolean indicating whether signed push is enabled on the server. + */ +@Retention(RUNTIME) +@BindingAnnotation +public @interface EnableSignedPush { +} diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/GpgException.java b/gerrit-server/src/main/java/com/google/gerrit/server/GpgException.java new file mode 100644 index 0000000000..5ed27b5813 --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/GpgException.java @@ -0,0 +1,33 @@ +// Copyright (C) 2015 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.server; + +/** Generic exception type for GPG-related exceptions. */ +public class GpgException extends Exception { + private static final long serialVersionUID = 1L; + + public GpgException(String message) { + super(message); + } + + public GpgException(Throwable cause) { + super(cause); + } + + public GpgException(String message, Throwable cause) { + super(message, cause); + } +} + diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountResource.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountResource.java index 7b5beadb75..75e5ae5185 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountResource.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountResource.java @@ -22,8 +22,6 @@ import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.change.ChangeResource; import com.google.inject.TypeLiteral; -import org.bouncycastle.openpgp.PGPPublicKeyRing; - public class AccountResource implements RestResource { public static final TypeLiteral> ACCOUNT_KIND = new TypeLiteral>() {}; @@ -37,9 +35,6 @@ public class AccountResource implements RestResource { public static final TypeLiteral> SSH_KEY_KIND = new TypeLiteral>() {}; - public static final TypeLiteral> GPG_KEY_KIND = - new TypeLiteral>() {}; - public static final TypeLiteral> STARRED_CHANGE_KIND = new TypeLiteral>() {}; @@ -101,19 +96,6 @@ public class AccountResource implements RestResource { } } - public static class GpgKey extends AccountResource { - private final PGPPublicKeyRing keyRing; - - public GpgKey(IdentifiedUser user, PGPPublicKeyRing keyRing) { - super(user); - this.keyRing = keyRing; - } - - public PGPPublicKeyRing getKeyRing() { - return keyRing; - } - } - public static class StarredChange extends AccountResource { private final ChangeResource change; diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/Module.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/Module.java index fe1035590e..7cf1e377c7 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/account/Module.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/Module.java @@ -17,7 +17,6 @@ package com.google.gerrit.server.account; import static com.google.gerrit.server.account.AccountResource.ACCOUNT_KIND; import static com.google.gerrit.server.account.AccountResource.CAPABILITY_KIND; import static com.google.gerrit.server.account.AccountResource.EMAIL_KIND; -import static com.google.gerrit.server.account.AccountResource.GPG_KEY_KIND; import static com.google.gerrit.server.account.AccountResource.SSH_KEY_KIND; import static com.google.gerrit.server.account.AccountResource.STARRED_CHANGE_KIND; @@ -33,7 +32,6 @@ public class Module extends RestApiModule { DynamicMap.mapOf(binder(), ACCOUNT_KIND); DynamicMap.mapOf(binder(), CAPABILITY_KIND); DynamicMap.mapOf(binder(), EMAIL_KIND); - DynamicMap.mapOf(binder(), GPG_KEY_KIND); DynamicMap.mapOf(binder(), SSH_KEY_KIND); DynamicMap.mapOf(binder(), STARRED_CHANGE_KIND); @@ -62,11 +60,6 @@ public class Module extends RestApiModule { get(SSH_KEY_KIND).to(GetSshKey.class); delete(SSH_KEY_KIND).to(DeleteSshKey.class); - child(ACCOUNT_KIND, "gpgkeys").to(GpgKeys.class); - post(ACCOUNT_KIND, "gpgkeys").to(PostGpgKeys.class); - get(GPG_KEY_KIND).to(GpgKeys.Get.class); - delete(GPG_KEY_KIND).to(DeleteGpgKey.class); - get(ACCOUNT_KIND, "avatar").to(GetAvatar.class); get(ACCOUNT_KIND, "avatar.change.url").to(GetAvatarChangeUrl.class); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/api/accounts/AccountApiImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/api/accounts/AccountApiImpl.java index 85e519bdf2..c6e4ad1fd5 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/api/accounts/AccountApiImpl.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/api/accounts/AccountApiImpl.java @@ -23,11 +23,10 @@ import com.google.gerrit.extensions.common.GpgKeyInfo; import com.google.gerrit.extensions.restapi.IdString; import com.google.gerrit.extensions.restapi.RestApiException; import com.google.gerrit.extensions.restapi.TopLevelResource; +import com.google.gerrit.server.GpgException; import com.google.gerrit.server.account.AccountLoader; import com.google.gerrit.server.account.AccountResource; import com.google.gerrit.server.account.CreateEmail; -import com.google.gerrit.server.account.GpgKeys; -import com.google.gerrit.server.account.PostGpgKeys; import com.google.gerrit.server.account.StarredChanges; import com.google.gerrit.server.change.ChangeResource; import com.google.gerrit.server.change.ChangesCollection; @@ -35,9 +34,6 @@ import com.google.gwtorm.server.OrmException; import com.google.inject.Inject; import com.google.inject.assistedinject.Assisted; -import org.bouncycastle.openpgp.PGPException; - -import java.io.IOException; import java.util.List; import java.util.Map; @@ -52,9 +48,7 @@ public class AccountApiImpl implements AccountApi { private final StarredChanges.Create starredChangesCreate; private final StarredChanges.Delete starredChangesDelete; private final CreateEmail.Factory createEmailFactory; - private final PostGpgKeys postGpgKeys; - private final GpgKeys gpgKeys; - private final GpgKeyApiImpl.Factory gpgKeyApiFactory; + private final GpgApiAdapter gpgApiAdapter; @Inject AccountApiImpl(AccountLoader.Factory ailf, @@ -62,9 +56,7 @@ public class AccountApiImpl implements AccountApi { StarredChanges.Create starredChangesCreate, StarredChanges.Delete starredChangesDelete, CreateEmail.Factory createEmailFactory, - PostGpgKeys postGpgKeys, - GpgKeys gpgKeys, - GpgKeyApiImpl.Factory gpgKeyApiFactory, + GpgApiAdapter gpgApiAdapter, @Assisted AccountResource account) { this.account = account; this.accountLoaderFactory = ailf; @@ -72,9 +64,7 @@ public class AccountApiImpl implements AccountApi { this.starredChangesCreate = starredChangesCreate; this.starredChangesDelete = starredChangesDelete; this.createEmailFactory = createEmailFactory; - this.postGpgKeys = postGpgKeys; - this.gpgKeys = gpgKeys; - this.gpgKeyApiFactory = gpgKeyApiFactory; + this.gpgApiAdapter = gpgApiAdapter; } @Override @@ -131,8 +121,8 @@ public class AccountApiImpl implements AccountApi { @Override public Map listGpgKeys() throws RestApiException { try { - return gpgKeys.list().apply(account); - } catch (OrmException | PGPException | IOException e) { + return gpgApiAdapter.listGpgKeys(account); + } catch (GpgException e) { throw new RestApiException("Cannot list GPG keys", e); } } @@ -140,12 +130,9 @@ public class AccountApiImpl implements AccountApi { @Override public Map putGpgKeys(List add, List delete) throws RestApiException { - PostGpgKeys.Input in = new PostGpgKeys.Input(); - in.add = add; - in.delete = delete; try { - return postGpgKeys.apply(account, in); - } catch (PGPException | OrmException | IOException e) { + return gpgApiAdapter.putGpgKeys(account, add, delete); + } catch (GpgException e) { throw new RestApiException("Cannot add GPG key", e); } } @@ -153,9 +140,8 @@ public class AccountApiImpl implements AccountApi { @Override public GpgKeyApi gpgKey(String id) throws RestApiException { try { - IdString idStr = IdString.fromDecoded(id); - return gpgKeyApiFactory.create(gpgKeys.parse(account, idStr)); - } catch (PGPException | OrmException | IOException e) { + return gpgApiAdapter.gpgKey(account, IdString.fromDecoded(id)); + } catch (GpgException e) { throw new RestApiException("Cannot get PGP key", e); } } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/api/accounts/GpgApiAdapter.java b/gerrit-server/src/main/java/com/google/gerrit/server/api/accounts/GpgApiAdapter.java new file mode 100644 index 0000000000..9faa418916 --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/api/accounts/GpgApiAdapter.java @@ -0,0 +1,34 @@ +// Copyright (C) 2015 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.server.api.accounts; + +import com.google.gerrit.extensions.api.accounts.GpgKeyApi; +import com.google.gerrit.extensions.common.GpgKeyInfo; +import com.google.gerrit.extensions.restapi.IdString; +import com.google.gerrit.extensions.restapi.RestApiException; +import com.google.gerrit.server.GpgException; +import com.google.gerrit.server.account.AccountResource; + +import java.util.List; +import java.util.Map; + +public interface GpgApiAdapter { + Map listGpgKeys(AccountResource account) + throws RestApiException, GpgException; + Map putGpgKeys(AccountResource account, List add, + List delete) throws RestApiException, GpgException; + GpgKeyApi gpgKey(AccountResource account, IdString idStr) + throws RestApiException, GpgException; +} diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/api/accounts/Module.java b/gerrit-server/src/main/java/com/google/gerrit/server/api/accounts/Module.java index 6ac538d06c..935c4d73f9 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/api/accounts/Module.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/api/accounts/Module.java @@ -23,6 +23,5 @@ public class Module extends FactoryModule { bind(Accounts.class).to(AccountsImpl.class); factory(AccountApiImpl.Factory.class); - factory(GpgKeyApiImpl.Factory.class); } } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java index 3716934e7b..cf1053d5ad 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java @@ -83,7 +83,6 @@ import com.google.gerrit.server.git.NotesBranchUtil; import com.google.gerrit.server.git.ReceivePackInitializer; import com.google.gerrit.server.git.TagCache; import com.google.gerrit.server.git.TransferConfig; -import com.google.gerrit.server.git.gpg.SignedPushModule; import com.google.gerrit.server.git.validators.CommitValidationListener; import com.google.gerrit.server.git.validators.CommitValidators; import com.google.gerrit.server.git.validators.MergeValidationListener; @@ -181,7 +180,6 @@ public class GerritGlobalModule extends FactoryModule { install(new NoteDbModule()); install(new PrologModule()); install(new SshAddressesModule()); - install(new SignedPushModule()); install(ThreadLocalRequestContext.module()); bind(AccountResolver.class); 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 f45bf7c94c..b75d7750bc 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,12 +29,12 @@ import com.google.gerrit.extensions.registration.DynamicMap; import com.google.gerrit.extensions.restapi.RestReadView; import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.reviewdb.client.AuthType; +import com.google.gerrit.server.EnableSignedPush; import com.google.gerrit.server.account.Realm; import com.google.gerrit.server.avatar.AvatarProvider; import com.google.gerrit.server.change.ArchiveFormat; import com.google.gerrit.server.change.GetArchive; import com.google.gerrit.server.change.Submit; -import com.google.gerrit.server.git.gpg.SignedPushModule; import com.google.inject.Inject; import org.eclipse.jgit.lib.Config; @@ -63,6 +63,7 @@ public class GetServerInfo implements RestReadView { private final String anonymousCowardName; private final GitwebConfig gitwebConfig; private final DynamicItem avatar; + private final boolean enableSignedPush; @Inject public GetServerInfo( @@ -77,7 +78,8 @@ public class GetServerInfo implements RestReadView { AllUsersName allUsersName, @AnonymousCowardName String anonymousCowardName, GitwebConfig gitwebConfig, - DynamicItem avatar) { + DynamicItem avatar, + @EnableSignedPush boolean enableSignedPush) { this.config = config; this.authConfig = authConfig; this.realm = realm; @@ -90,6 +92,7 @@ public class GetServerInfo implements RestReadView { this.anonymousCowardName = anonymousCowardName; this.gitwebConfig = gitwebConfig; this.avatar = avatar; + this.enableSignedPush = enableSignedPush; } @Override @@ -110,7 +113,7 @@ public class GetServerInfo implements RestReadView { info.urlAliases = !urlAliases.isEmpty() ? urlAliases : null; info.user = getUserInfo(anonymousCowardName); - info.receive = getReceiveInfo(config); + info.receive = getReceiveInfo(); return info; } @@ -298,9 +301,9 @@ public class GetServerInfo implements RestReadView { return info; } - private ReceiveInfo getReceiveInfo(Config cfg) { + private ReceiveInfo getReceiveInfo() { ReceiveInfo info = new ReceiveInfo(); - info.enableSignedPush = SignedPushModule.isEnabled(cfg); + info.enableSignedPush = enableSignedPush; return info; } 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 1801712880..ae8fd53504 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 @@ -31,11 +31,8 @@ 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.TransferConfig; -import com.google.gerrit.server.git.gpg.SignedPushModule; import com.google.inject.util.Providers; -import org.eclipse.jgit.lib.Config; - import java.util.Arrays; import java.util.List; import java.util.Map; @@ -58,7 +55,7 @@ public class ConfigInfo { public Map commentlinks; public ThemeInfo theme; - public ConfigInfo(Config gerritConfig, + public ConfigInfo(boolean serverEnableSignedPush, ProjectControl control, TransferConfig config, DynamicMap pluginConfigEntries, @@ -112,7 +109,7 @@ public class ConfigInfo { this.useContentMerge = useContentMerge; this.requireChangeId = requireChangeId; this.createNewChangeForAllNotInTarget = createNewChangeForAllNotInTarget; - if (SignedPushModule.isEnabled(gerritConfig)) { + if (serverEnableSignedPush) { this.enableSignedPush = enableSignedPush; } 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 2ab10c9a49..469da93545 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 @@ -17,19 +17,17 @@ package com.google.gerrit.server.project; 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.EnableSignedPush; 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 boolean serverEnableSignedPush; private final TransferConfig config; private final DynamicMap pluginConfigEntries; private final PluginConfigFactory cfgFactory; @@ -37,13 +35,13 @@ public class GetConfig implements RestReadView { private final DynamicMap> views; @Inject - public GetConfig(@GerritServerConfig Config gerritConfig, + public GetConfig(@EnableSignedPush boolean serverEnableSignedPush, TransferConfig config, DynamicMap pluginConfigEntries, PluginConfigFactory cfgFactory, AllProjectsNameProvider allProjects, DynamicMap> views) { - this.gerritConfig = gerritConfig; + this.serverEnableSignedPush = serverEnableSignedPush; this.config = config; this.pluginConfigEntries = pluginConfigEntries; this.allProjects = allProjects; @@ -53,7 +51,7 @@ public class GetConfig implements RestReadView { @Override public ConfigInfo apply(ProjectResource resource) { - return new ConfigInfo(gerritConfig, resource.getControl(), config, + return new ConfigInfo(serverEnableSignedPush, resource.getControl(), config, pluginConfigEntries, cfgFactory, allProjects, views); } } 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 7a4fb6eb8b..e52904301f 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 @@ -31,9 +31,9 @@ import com.google.gerrit.reviewdb.client.Branch; import com.google.gerrit.reviewdb.client.Project; import com.google.gerrit.reviewdb.client.RefNames; import com.google.gerrit.server.CurrentUser; +import com.google.gerrit.server.EnableSignedPush; 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; @@ -48,7 +48,6 @@ 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; @@ -78,7 +77,7 @@ public class PutConfig implements RestModifyView { public Map> pluginConfigValues; } - private final Config gerritConfig; + private final boolean serverEnableSignedPush; private final Provider metaDataUpdateFactory; private final ProjectCache projectCache; private final GitRepositoryManager gitMgr; @@ -92,7 +91,7 @@ public class PutConfig implements RestModifyView { private final ChangeHooks hooks; @Inject - PutConfig(@GerritServerConfig Config gerritConfig, + PutConfig(@EnableSignedPush boolean serverEnableSignedPush, Provider metaDataUpdateFactory, ProjectCache projectCache, GitRepositoryManager gitMgr, @@ -104,7 +103,7 @@ public class PutConfig implements RestModifyView { DynamicMap> views, ChangeHooks hooks, Provider currentUser) { - this.gerritConfig = gerritConfig; + this.serverEnableSignedPush = serverEnableSignedPush; this.metaDataUpdateFactory = metaDataUpdateFactory; this.projectCache = projectCache; this.gitMgr = gitMgr; @@ -214,8 +213,9 @@ public class PutConfig implements RestModifyView { } ProjectState state = projectStateFactory.create(projectConfig); - return new ConfigInfo(gerritConfig, state.controlFor(currentUser.get()), - config, pluginConfigEntries, cfgFactory, allProjects, views); + return new ConfigInfo(serverEnableSignedPush, + 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/test/java/com/google/gerrit/testutil/InMemoryModule.java b/gerrit-server/src/test/java/com/google/gerrit/testutil/InMemoryModule.java index 1dda48708b..e5cd619145 100644 --- a/gerrit-server/src/test/java/com/google/gerrit/testutil/InMemoryModule.java +++ b/gerrit-server/src/test/java/com/google/gerrit/testutil/InMemoryModule.java @@ -21,6 +21,7 @@ import com.google.common.util.concurrent.MoreExecutors; import com.google.gerrit.common.ChangeHooks; import com.google.gerrit.common.DisabledChangeHooks; import com.google.gerrit.extensions.config.FactoryModule; +import com.google.gerrit.gpg.GpgModule; import com.google.gerrit.reviewdb.client.AuthType; import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.server.GerritPersonIdent; @@ -186,6 +187,7 @@ public class InMemoryModule extends FactoryModule { install(new DefaultCacheFactory.Module()); install(new FakeEmailSender.Module()); install(new SignedTokenEmailTokenVerifier.Module()); + install(new GpgModule(cfg)); IndexType indexType = null; try { diff --git a/gerrit-war/BUCK b/gerrit-war/BUCK index 1f82849394..27b1f4a84f 100644 --- a/gerrit-war/BUCK +++ b/gerrit-war/BUCK @@ -6,6 +6,7 @@ java_library( deps = [ '//gerrit-cache-h2:cache-h2', '//gerrit-extension-api:api', + '//gerrit-gpg:gpg', '//gerrit-httpd:httpd', '//gerrit-lucene:lucene', '//gerrit-oauth:oauth', diff --git a/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java b/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java index 55be2df857..905d776cfc 100644 --- a/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java +++ b/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java @@ -19,6 +19,7 @@ import static com.google.inject.Stage.PRODUCTION; import com.google.common.base.Splitter; import com.google.gerrit.common.ChangeHookRunner; +import com.google.gerrit.gpg.GpgModule; import com.google.gerrit.httpd.auth.oauth.OAuthModule; import com.google.gerrit.httpd.auth.openid.OpenIdModule; import com.google.gerrit.httpd.plugins.HttpPluginModule; @@ -107,6 +108,7 @@ public class WebAppInitializer extends GuiceServletContextListener private Path sitePath; private Injector dbInjector; private Injector cfgInjector; + private Config config; private Injector sysInjector; private Injector webInjector; private Injector sshInjector; @@ -163,6 +165,8 @@ public class WebAppInitializer extends GuiceServletContextListener } cfgInjector = createCfgInjector(); + config = cfgInjector.getInstance( + Key.get(Config.class, GerritServerConfig.class)); sysInjector = createSysInjector(); if (!sshdOff()) { sshInjector = createSshInjector(); @@ -202,8 +206,7 @@ public class WebAppInitializer extends GuiceServletContextListener } private boolean sshdOff() { - Config cfg = cfgInjector.getInstance(Key.get(Config.class, GerritServerConfig.class)); - return new SshAddressesModule().getListenAddresses(cfg).isEmpty(); + return new SshAddressesModule().getListenAddresses(config).isEmpty(); } private Injector createDbInjector() { @@ -294,6 +297,7 @@ public class WebAppInitializer extends GuiceServletContextListener modules.add(new SignedTokenEmailTokenVerifier.Module()); modules.add(new PluginRestApiModule()); modules.add(new RestCacheAdminModule()); + modules.add(new GpgModule(config)); AbstractModule changeIndexModule; switch (IndexModule.getIndexType(cfgInjector)) { case LUCENE: diff --git a/tools/eclipse/BUCK b/tools/eclipse/BUCK index 865c9d72c0..57f3afbcd9 100644 --- a/tools/eclipse/BUCK +++ b/tools/eclipse/BUCK @@ -4,6 +4,7 @@ java_library( name = 'classpath', deps = LIBS + PGMLIBS + [ '//gerrit-acceptance-tests:lib', + '//gerrit-gpg:gpg_tests', '//gerrit-gwtdebug:gwtdebug', '//gerrit-gwtui:ui_module', '//gerrit-gwtui:ui_tests',