Convert RequireCapability checks to PermissionBackend

Replace CapabilityUtils with support in PermissionBackend to check if
the caller has at least one of the specified permissions parsed from
class annotation.

This enables hiding canPerform(String) from CapabilityControl, which
makes it much harder to bypass the PermissionBackend.

Assume anyone with ADMINISTRATE_SERVER also has any PluginPermission.
This is carried over from CapabilityUtils, which skip any further
checks when the user has canAdministrateServer.

Update the error message in GarbageCollectionIT to now be the generic
"maintain server not permitted".

Change-Id: I9458bd55fa1c9709557ae1ad95a57a1d968c52a3
This commit is contained in:
Shawn Pearce
2017-02-20 14:57:11 -08:00
committed by David Pursehouse
parent e9e1af205c
commit 79a899e505
19 changed files with 311 additions and 245 deletions

View File

@@ -95,8 +95,10 @@ import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.OptionUtil;
import com.google.gerrit.server.OutputFormat;
import com.google.gerrit.server.account.CapabilityUtils;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.util.http.RequestUtil;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
@@ -188,6 +190,7 @@ public class RestApiServlet extends HttpServlet {
final Provider<CurrentUser> currentUser;
final DynamicItem<WebSession> webSession;
final Provider<ParameterParser> paramParser;
final PermissionBackend permissionBackend;
final AuditService auditService;
final RestApiMetrics metrics;
final Pattern allowOrigin;
@@ -197,12 +200,14 @@ public class RestApiServlet extends HttpServlet {
Provider<CurrentUser> currentUser,
DynamicItem<WebSession> webSession,
Provider<ParameterParser> paramParser,
PermissionBackend permissionBackend,
AuditService auditService,
RestApiMetrics metrics,
@GerritServerConfig Config cfg) {
this.currentUser = currentUser;
this.webSession = webSession;
this.paramParser = paramParser;
this.permissionBackend = permissionBackend;
this.auditService = auditService;
this.metrics = metrics;
allowOrigin = makeAllowOrigin(cfg);
@@ -263,7 +268,10 @@ public class RestApiServlet extends HttpServlet {
List<IdString> path = splitPath(req);
RestCollection<RestResource, RestResource> rc = members.get();
CapabilityUtils.checkRequiresCapability(globals.currentUser, null, rc.getClass());
globals
.permissionBackend
.user(globals.currentUser)
.checkAny(GlobalPermission.fromAnnotation(rc.getClass()));
viewData = new ViewData(null, null);
@@ -1106,9 +1114,12 @@ public class RestApiServlet extends HttpServlet {
return "GET".equals(req.getMethod()) || "HEAD".equals(req.getMethod());
}
private void checkRequiresCapability(ViewData viewData) throws AuthException {
CapabilityUtils.checkRequiresCapability(
globals.currentUser, viewData.pluginName, viewData.view.getClass());
private void checkRequiresCapability(ViewData d)
throws AuthException, PermissionBackendException {
globals
.permissionBackend
.user(globals.currentUser)
.checkAny(GlobalPermission.fromAnnotation(d.pluginName, d.view.getClass()));
}
private static long handleException(