Refactor capability check out from REST and SSH code

Move the code to one place to simplfy the maintenance.

Change-Id: Ief075899e7d7f3d383ffbbe03ec75c7d20768cc0
This commit is contained in:
David Ostrovsky
2013-08-31 14:13:20 +02:00
parent 8b97cd57a8
commit c544351617
3 changed files with 104 additions and 100 deletions

View File

@@ -17,10 +17,9 @@ package com.google.gerrit.sshd;
import com.google.common.base.Strings;
import com.google.common.collect.Sets;
import com.google.common.util.concurrent.Atomics;
import com.google.gerrit.extensions.annotations.CapabilityScope;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.account.CapabilityUtils;
import com.google.gerrit.server.args4j.SubcommandHandler;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -29,8 +28,6 @@ import com.google.inject.assistedinject.Assisted;
import org.apache.sshd.server.Command;
import org.apache.sshd.server.Environment;
import org.kohsuke.args4j.Argument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.StringWriter;
@@ -43,9 +40,6 @@ import java.util.concurrent.atomic.AtomicReference;
* Command that dispatches to a subcommand from its command table.
*/
final class DispatchCommand extends BaseCommand {
private static final Logger log = LoggerFactory
.getLogger(DispatchCommand.class);
interface Factory {
DispatchCommand create(Map<String, CommandProvider> map);
}
@@ -121,50 +115,17 @@ final class DispatchCommand extends BaseCommand {
private void checkRequiresCapability(Command cmd)
throws UnloggedFailure {
RequiresCapability rc = getRequiresCapability(cmd.getClass());
if (rc != null) {
CurrentUser user = currentUser.get();
CapabilityControl ctl = user.getCapabilities();
String capability = rc.value();
if (cmd instanceof BaseCommand) {
String pluginName = ((BaseCommand) cmd).getPluginName();
if (pluginName != null && !"gerrit".equals(pluginName)
&& (rc.scope() == CapabilityScope.PLUGIN
|| rc.scope() == CapabilityScope.CONTEXT)) {
capability = String.format("%s-%s", pluginName, rc.value());
} else if (rc.scope() == CapabilityScope.PLUGIN) {
log.error(String.format(
"Class %s uses @%s(scope=%s), but is not within a plugin",
cmd.getClass().getName(),
RequiresCapability.class.getSimpleName(),
CapabilityScope.PLUGIN.name()));
throw new UnloggedFailure(
BaseCommand.STATUS_NOT_ADMIN,
"fatal: cannot check capability");
}
}
if (!ctl.canPerform(capability) && !ctl.canAdministrateServer()) {
String msg = String.format(
"fatal: %s does not have \"%s\" capability.",
user.getUserName(), capability);
throw new UnloggedFailure(BaseCommand.STATUS_NOT_ADMIN, msg);
}
String pluginName = null;
if (cmd instanceof BaseCommand) {
pluginName = ((BaseCommand) cmd).getPluginName();
}
}
private static RequiresCapability getRequiresCapability(Class<?> clazz) {
RequiresCapability rc = clazz.getAnnotation(RequiresCapability.class);
if (rc != null) {
return rc;
try {
CapabilityUtils.checkRequiresCapability(currentUser,
pluginName, cmd.getClass());
} catch (AuthException e) {
throw new UnloggedFailure(BaseCommand.STATUS_NOT_ADMIN,
e.getMessage());
}
if (clazz.getSuperclass() != null) {
return getRequiresCapability(clazz.getSuperclass());
}
return null;
}
@Override