Merge branch 'stable-2.15' into stable-2.16
* stable-2.15: Add a new extension point SshExecuteCommandInterceptor Change-Id: I96b30bf681a1a96d8f6cf5ca53f70f8bb13dd740
This commit is contained in:
@@ -18,6 +18,7 @@ import com.google.common.base.Strings;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.util.concurrent.Atomics;
|
||||
import com.google.gerrit.extensions.registration.DynamicSet;
|
||||
import com.google.gerrit.extensions.restapi.AuthException;
|
||||
import com.google.gerrit.server.args4j.SubcommandHandler;
|
||||
import com.google.gerrit.server.permissions.GlobalPermission;
|
||||
@@ -44,6 +45,7 @@ final class DispatchCommand extends BaseCommand {
|
||||
private final PermissionBackend permissionBackend;
|
||||
private final Map<String, CommandProvider> commands;
|
||||
private final AtomicReference<Command> atomicCmd;
|
||||
private final DynamicSet<SshExecuteCommandInterceptor> commandInterceptors;
|
||||
|
||||
@Argument(index = 0, required = false, metaVar = "COMMAND", handler = SubcommandHandler.class)
|
||||
private String commandName;
|
||||
@@ -52,10 +54,14 @@ final class DispatchCommand extends BaseCommand {
|
||||
private List<String> args = new ArrayList<>();
|
||||
|
||||
@Inject
|
||||
DispatchCommand(PermissionBackend permissionBackend, @Assisted Map<String, CommandProvider> all) {
|
||||
DispatchCommand(
|
||||
PermissionBackend permissionBackend,
|
||||
DynamicSet<SshExecuteCommandInterceptor> commandInterceptors,
|
||||
@Assisted Map<String, CommandProvider> all) {
|
||||
this.permissionBackend = permissionBackend;
|
||||
commands = all;
|
||||
atomicCmd = Atomics.newReference();
|
||||
this.commandInterceptors = commandInterceptors;
|
||||
}
|
||||
|
||||
Map<String, CommandProvider> getMap() {
|
||||
@@ -84,19 +90,29 @@ final class DispatchCommand extends BaseCommand {
|
||||
|
||||
final Command cmd = p.getProvider().get();
|
||||
checkRequiresCapability(cmd);
|
||||
String actualCommandName = commandName;
|
||||
if (cmd instanceof BaseCommand) {
|
||||
final BaseCommand bc = (BaseCommand) cmd;
|
||||
if (getName().isEmpty()) {
|
||||
bc.setName(commandName);
|
||||
} else {
|
||||
bc.setName(getName() + " " + commandName);
|
||||
if (!getName().isEmpty()) {
|
||||
actualCommandName = getName() + " " + commandName;
|
||||
}
|
||||
bc.setName(actualCommandName);
|
||||
bc.setArguments(args.toArray(new String[args.size()]));
|
||||
|
||||
} else if (!args.isEmpty()) {
|
||||
throw die(commandName + " does not take arguments");
|
||||
}
|
||||
|
||||
for (SshExecuteCommandInterceptor commandInterceptor : commandInterceptors) {
|
||||
if (!commandInterceptor.accept(actualCommandName, args)) {
|
||||
throw new UnloggedFailure(
|
||||
126,
|
||||
String.format(
|
||||
"blocked by %s, contact gerrit administrators for more details",
|
||||
commandInterceptor.name()));
|
||||
}
|
||||
}
|
||||
|
||||
provideStateTo(cmd);
|
||||
atomicCmd.set(cmd);
|
||||
cmd.start(env);
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright (C) 2019 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.sshd;
|
||||
|
||||
import com.google.gerrit.extensions.annotations.ExtensionPoint;
|
||||
import java.util.List;
|
||||
|
||||
@ExtensionPoint
|
||||
public interface SshExecuteCommandInterceptor {
|
||||
|
||||
/**
|
||||
* Check the command and return false if this command must not be run.
|
||||
*
|
||||
* @param command the command
|
||||
* @param arguments the list of arguments
|
||||
* @return whether or not this command with these arguments can be executed
|
||||
*/
|
||||
boolean accept(String command, List<String> arguments);
|
||||
|
||||
default String name() {
|
||||
return this.getClass().getSimpleName();
|
||||
}
|
||||
}
|
||||
@@ -106,6 +106,7 @@ public class SshModule extends LifecycleModule {
|
||||
|
||||
DynamicMap.mapOf(binder(), DynamicOptions.DynamicBean.class);
|
||||
DynamicItem.itemOf(binder(), SshCreateCommandInterceptor.class);
|
||||
DynamicSet.setOf(binder(), SshExecuteCommandInterceptor.class);
|
||||
|
||||
listener().toInstance(registerInParentInjectors());
|
||||
listener().to(SshLog.class);
|
||||
|
||||
Reference in New Issue
Block a user