Merge "Allow admins to disable remote plugin installation"
This commit is contained in:
commit
3fa55d48c8
@ -2317,6 +2317,12 @@ may force reloading with link:cmd-plugin.html[gerrit plugin reload].
|
|||||||
+
|
+
|
||||||
Default is 1 minute.
|
Default is 1 minute.
|
||||||
|
|
||||||
|
[[plugins.allowRemoteAdmin]]plugins.allowRemoteAdmin::
|
||||||
|
+
|
||||||
|
Enable remote installation, enable and disable of plugins over HTTP
|
||||||
|
and SSH. If set to true Administrators can install new plugins
|
||||||
|
remotely, or disable existing plugins. Defaults to false.
|
||||||
|
|
||||||
|
|
||||||
[[receive]]
|
[[receive]]
|
||||||
=== Section receive
|
=== Section receive
|
||||||
|
@ -17,6 +17,7 @@ package com.google.gerrit.server.plugins;
|
|||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.gerrit.common.data.GlobalCapability;
|
import com.google.gerrit.common.data.GlobalCapability;
|
||||||
import com.google.gerrit.extensions.annotations.RequiresCapability;
|
import com.google.gerrit.extensions.annotations.RequiresCapability;
|
||||||
|
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
|
||||||
import com.google.gerrit.extensions.restapi.RestModifyView;
|
import com.google.gerrit.extensions.restapi.RestModifyView;
|
||||||
import com.google.gerrit.server.plugins.DisablePlugin.Input;
|
import com.google.gerrit.server.plugins.DisablePlugin.Input;
|
||||||
import com.google.gerrit.server.plugins.ListPlugins.PluginInfo;
|
import com.google.gerrit.server.plugins.ListPlugins.PluginInfo;
|
||||||
@ -35,7 +36,12 @@ class DisablePlugin implements RestModifyView<PluginResource, Input> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PluginInfo apply(PluginResource resource, Input input) {
|
public PluginInfo apply(PluginResource resource, Input input)
|
||||||
|
throws MethodNotAllowedException {
|
||||||
|
if (!loader.isRemoteAdminEnabled()) {
|
||||||
|
throw new MethodNotAllowedException(
|
||||||
|
"remote plugin administration is disabled");
|
||||||
|
}
|
||||||
String name = resource.getName();
|
String name = resource.getName();
|
||||||
loader.disablePlugins(ImmutableSet.of(name));
|
loader.disablePlugins(ImmutableSet.of(name));
|
||||||
return new PluginInfo(loader.get(name));
|
return new PluginInfo(loader.get(name));
|
||||||
|
@ -17,6 +17,7 @@ package com.google.gerrit.server.plugins;
|
|||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.gerrit.common.data.GlobalCapability;
|
import com.google.gerrit.common.data.GlobalCapability;
|
||||||
import com.google.gerrit.extensions.annotations.RequiresCapability;
|
import com.google.gerrit.extensions.annotations.RequiresCapability;
|
||||||
|
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
|
||||||
import com.google.gerrit.extensions.restapi.ResourceConflictException;
|
import com.google.gerrit.extensions.restapi.ResourceConflictException;
|
||||||
import com.google.gerrit.extensions.restapi.RestModifyView;
|
import com.google.gerrit.extensions.restapi.RestModifyView;
|
||||||
import com.google.gerrit.server.plugins.EnablePlugin.Input;
|
import com.google.gerrit.server.plugins.EnablePlugin.Input;
|
||||||
@ -40,7 +41,11 @@ class EnablePlugin implements RestModifyView<PluginResource, Input> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PluginInfo apply(PluginResource resource, Input input)
|
public PluginInfo apply(PluginResource resource, Input input)
|
||||||
throws ResourceConflictException {
|
throws ResourceConflictException, MethodNotAllowedException {
|
||||||
|
if (!loader.isRemoteAdminEnabled()) {
|
||||||
|
throw new MethodNotAllowedException(
|
||||||
|
"remote plugin administration is disabled");
|
||||||
|
}
|
||||||
String name = resource.getName();
|
String name = resource.getName();
|
||||||
try {
|
try {
|
||||||
loader.enablePlugins(ImmutableSet.of(name));
|
loader.enablePlugins(ImmutableSet.of(name));
|
||||||
|
@ -18,6 +18,7 @@ import com.google.gerrit.common.data.GlobalCapability;
|
|||||||
import com.google.gerrit.extensions.annotations.RequiresCapability;
|
import com.google.gerrit.extensions.annotations.RequiresCapability;
|
||||||
import com.google.gerrit.extensions.restapi.BadRequestException;
|
import com.google.gerrit.extensions.restapi.BadRequestException;
|
||||||
import com.google.gerrit.extensions.restapi.DefaultInput;
|
import com.google.gerrit.extensions.restapi.DefaultInput;
|
||||||
|
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
|
||||||
import com.google.gerrit.extensions.restapi.RawInput;
|
import com.google.gerrit.extensions.restapi.RawInput;
|
||||||
import com.google.gerrit.extensions.restapi.Response;
|
import com.google.gerrit.extensions.restapi.Response;
|
||||||
import com.google.gerrit.extensions.restapi.RestModifyView;
|
import com.google.gerrit.extensions.restapi.RestModifyView;
|
||||||
@ -53,8 +54,11 @@ class InstallPlugin implements RestModifyView<TopLevelResource, Input> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Response<PluginInfo> apply(TopLevelResource resource,
|
public Response<PluginInfo> apply(TopLevelResource resource, Input input)
|
||||||
Input input) throws BadRequestException, IOException {
|
throws BadRequestException, MethodNotAllowedException, IOException {
|
||||||
|
if (!loader.isRemoteAdminEnabled()) {
|
||||||
|
throw new MethodNotAllowedException("remote installation is disabled");
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
InputStream in;
|
InputStream in;
|
||||||
if (input.raw != null) {
|
if (input.raw != null) {
|
||||||
@ -102,8 +106,8 @@ class InstallPlugin implements RestModifyView<TopLevelResource, Input> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Response<PluginInfo> apply(PluginResource resource,
|
public Response<PluginInfo> apply(PluginResource resource, Input input)
|
||||||
Input input) throws BadRequestException, IOException {
|
throws BadRequestException, MethodNotAllowedException, IOException {
|
||||||
return new InstallPlugin(loader, resource.getName(), false)
|
return new InstallPlugin(loader, resource.getName(), false)
|
||||||
.apply(TopLevelResource.INSTANCE, input);
|
.apply(TopLevelResource.INSTANCE, input);
|
||||||
}
|
}
|
||||||
|
@ -90,6 +90,7 @@ public class PluginLoader implements LifecycleListener {
|
|||||||
private final Provider<PluginCleanerTask> cleaner;
|
private final Provider<PluginCleanerTask> cleaner;
|
||||||
private final PluginScannerThread scanner;
|
private final PluginScannerThread scanner;
|
||||||
private final Provider<String> urlProvider;
|
private final Provider<String> urlProvider;
|
||||||
|
private final boolean remoteAdmin;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public PluginLoader(SitePaths sitePaths,
|
public PluginLoader(SitePaths sitePaths,
|
||||||
@ -113,6 +114,9 @@ public class PluginLoader implements LifecycleListener {
|
|||||||
cleaner = pct;
|
cleaner = pct;
|
||||||
urlProvider = provider;
|
urlProvider = provider;
|
||||||
|
|
||||||
|
remoteAdmin =
|
||||||
|
cfg.getBoolean("plugins", null, "allowRemoteAdmin", false);
|
||||||
|
|
||||||
long checkFrequency = ConfigUtil.getTimeUnit(cfg,
|
long checkFrequency = ConfigUtil.getTimeUnit(cfg,
|
||||||
"plugins", null, "checkFrequency",
|
"plugins", null, "checkFrequency",
|
||||||
TimeUnit.MINUTES.toMillis(1), TimeUnit.MILLISECONDS);
|
TimeUnit.MINUTES.toMillis(1), TimeUnit.MILLISECONDS);
|
||||||
@ -123,6 +127,10 @@ public class PluginLoader implements LifecycleListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isRemoteAdminEnabled() {
|
||||||
|
return remoteAdmin;
|
||||||
|
}
|
||||||
|
|
||||||
public Plugin get(String name) {
|
public Plugin get(String name) {
|
||||||
Plugin p = running.get(name);
|
Plugin p = running.get(name);
|
||||||
if (p != null) {
|
if (p != null) {
|
||||||
@ -143,6 +151,8 @@ public class PluginLoader implements LifecycleListener {
|
|||||||
|
|
||||||
public void installPluginFromStream(String originalName, InputStream in)
|
public void installPluginFromStream(String originalName, InputStream in)
|
||||||
throws IOException, PluginInstallException {
|
throws IOException, PluginInstallException {
|
||||||
|
checkRemoteInstall();
|
||||||
|
|
||||||
String fileName = originalName;
|
String fileName = originalName;
|
||||||
if (!(fileName.endsWith(".jar") || fileName.endsWith(".js"))) {
|
if (!(fileName.endsWith(".jar") || fileName.endsWith(".js"))) {
|
||||||
fileName += ".jar";
|
fileName += ".jar";
|
||||||
@ -227,6 +237,12 @@ public class PluginLoader implements LifecycleListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void disablePlugins(Set<String> names) {
|
public void disablePlugins(Set<String> names) {
|
||||||
|
if (!isRemoteAdminEnabled()) {
|
||||||
|
log.warn("Remote plugin administration is disabled,"
|
||||||
|
+ " ignoring disablePlugins(" + names + ")");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
for (String name : names) {
|
for (String name : names) {
|
||||||
Plugin active = running.get(name);
|
Plugin active = running.get(name);
|
||||||
@ -255,6 +271,12 @@ public class PluginLoader implements LifecycleListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void enablePlugins(Set<String> names) throws PluginInstallException {
|
public void enablePlugins(Set<String> names) throws PluginInstallException {
|
||||||
|
if (!isRemoteAdminEnabled()) {
|
||||||
|
log.warn("Remote plugin administration is disabled,"
|
||||||
|
+ " ignoring enablePlugins(" + names + ")");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
for (String name : names) {
|
for (String name : names) {
|
||||||
Plugin off = disabled.get(name);
|
Plugin off = disabled.get(name);
|
||||||
@ -748,4 +770,10 @@ public class PluginLoader implements LifecycleListener {
|
|||||||
String fullExt = "." + ext;
|
String fullExt = "." + ext;
|
||||||
return fileName.endsWith(fullExt) || fileName.endsWith(fullExt + ".disabled");
|
return fileName.endsWith(fullExt) || fileName.endsWith(fullExt + ".disabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkRemoteInstall() throws PluginInstallException {
|
||||||
|
if (!isRemoteAdminEnabled()) {
|
||||||
|
throw new PluginInstallException("remote installation is disabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ package com.google.gerrit.server.plugins;
|
|||||||
import com.google.gerrit.extensions.registration.DynamicMap;
|
import com.google.gerrit.extensions.registration.DynamicMap;
|
||||||
import com.google.gerrit.extensions.restapi.AcceptsCreate;
|
import com.google.gerrit.extensions.restapi.AcceptsCreate;
|
||||||
import com.google.gerrit.extensions.restapi.IdString;
|
import com.google.gerrit.extensions.restapi.IdString;
|
||||||
|
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
|
||||||
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
|
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
|
||||||
import com.google.gerrit.extensions.restapi.RestCollection;
|
import com.google.gerrit.extensions.restapi.RestCollection;
|
||||||
import com.google.gerrit.extensions.restapi.RestView;
|
import com.google.gerrit.extensions.restapi.RestView;
|
||||||
@ -58,7 +59,10 @@ public class PluginsCollection implements
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public InstallPlugin create(TopLevelResource parent, IdString id)
|
public InstallPlugin create(TopLevelResource parent, IdString id)
|
||||||
throws ResourceNotFoundException {
|
throws ResourceNotFoundException, MethodNotAllowedException {
|
||||||
|
if (!loader.isRemoteAdminEnabled()) {
|
||||||
|
throw new MethodNotAllowedException("remote installation is disabled");
|
||||||
|
}
|
||||||
return new InstallPlugin(loader, id.get(), true /* created */);
|
return new InstallPlugin(loader, id.get(), true /* created */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,9 @@ final class PluginEnableCommand extends SshCommand {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void run() throws UnloggedFailure {
|
protected void run() throws UnloggedFailure {
|
||||||
|
if (!loader.isRemoteAdminEnabled()) {
|
||||||
|
throw die("remote plugin administration is disabled");
|
||||||
|
}
|
||||||
if (names != null && !names.isEmpty()) {
|
if (names != null && !names.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
loader.enablePlugins(Sets.newHashSet(names));
|
loader.enablePlugins(Sets.newHashSet(names));
|
||||||
|
@ -56,6 +56,9 @@ final class PluginInstallCommand extends SshCommand {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void run() throws UnloggedFailure {
|
protected void run() throws UnloggedFailure {
|
||||||
|
if (!loader.isRemoteAdminEnabled()) {
|
||||||
|
throw die("remote installation is disabled");
|
||||||
|
}
|
||||||
if (Strings.isNullOrEmpty(source)) {
|
if (Strings.isNullOrEmpty(source)) {
|
||||||
throw die("Argument \"-|URL\" is required");
|
throw die("Argument \"-|URL\" is required");
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,10 @@ final class PluginRemoveCommand extends SshCommand {
|
|||||||
private PluginLoader loader;
|
private PluginLoader loader;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void run() {
|
protected void run() throws UnloggedFailure {
|
||||||
|
if (!loader.isRemoteAdminEnabled()) {
|
||||||
|
throw die("remote plugin administration is disabled");
|
||||||
|
}
|
||||||
if (names != null && !names.isEmpty()) {
|
if (names != null && !names.isEmpty()) {
|
||||||
loader.disablePlugins(Sets.newHashSet(names));
|
loader.disablePlugins(Sets.newHashSet(names));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user