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
This commit is contained in:
Dave Borowitz
2015-08-26 09:51:27 -04:00
parent b84c227162
commit b8336f176a
45 changed files with 521 additions and 164 deletions

View File

@@ -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<ProjectResource, Input> {
public Map<String, Map<String, ConfigValue>> pluginConfigValues;
}
private final Config gerritConfig;
private final boolean serverEnableSignedPush;
private final Provider<MetaDataUpdate.User> metaDataUpdateFactory;
private final ProjectCache projectCache;
private final GitRepositoryManager gitMgr;
@@ -92,7 +91,7 @@ public class PutConfig implements RestModifyView<ProjectResource, Input> {
private final ChangeHooks hooks;
@Inject
PutConfig(@GerritServerConfig Config gerritConfig,
PutConfig(@EnableSignedPush boolean serverEnableSignedPush,
Provider<MetaDataUpdate.User> metaDataUpdateFactory,
ProjectCache projectCache,
GitRepositoryManager gitMgr,
@@ -104,7 +103,7 @@ public class PutConfig implements RestModifyView<ProjectResource, Input> {
DynamicMap<RestView<ProjectResource>> views,
ChangeHooks hooks,
Provider<CurrentUser> 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<ProjectResource, Input> {
}
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) {