Disable capability endpoints when not using default backend
The capability names exposed by these endpoints are implementation details of the DefaultPermissionBackend. A different implementation may choose to hide the GlobalPermission enum names from the user entirely, so it doesn't make sense to expose them. Change-Id: I69ea38064ccbf1c04a976e7bcb4629ab5d66aeef
This commit is contained in:
@@ -84,6 +84,11 @@ public class DefaultPermissionBackend extends PermissionBackend {
|
||||
return new WithUserImpl(identifiedUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean usesDefaultCapabilities() {
|
||||
return true;
|
||||
}
|
||||
|
||||
class WithUserImpl extends WithUser {
|
||||
private final CurrentUser user;
|
||||
private Boolean admin;
|
||||
|
@@ -23,6 +23,7 @@ import com.google.gerrit.common.data.LabelType;
|
||||
import com.google.gerrit.extensions.api.access.GlobalOrPluginPermission;
|
||||
import com.google.gerrit.extensions.conditions.BooleanCondition;
|
||||
import com.google.gerrit.extensions.restapi.AuthException;
|
||||
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
|
||||
import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.reviewdb.client.Branch;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
@@ -112,6 +113,29 @@ public abstract class PermissionBackend {
|
||||
*/
|
||||
public abstract WithUser absentUser(Account.Id user);
|
||||
|
||||
/**
|
||||
* Check whether this {@code PermissionBackend} respects the same global capabilities as the
|
||||
* {@link DefaultPermissionBackend}.
|
||||
*
|
||||
* <p>If true, then it makes sense for downstream callers to refer to built-in Gerrit capability
|
||||
* names in user-facing error messages, for example.
|
||||
*
|
||||
* @return whether this is the default permission backend.
|
||||
*/
|
||||
public boolean usesDefaultCapabilities() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw {@link ResourceNotFoundException} if this backend does not use the default global
|
||||
* capabilities.
|
||||
*/
|
||||
public void checkUsesDefaultCapabilities() throws ResourceNotFoundException {
|
||||
if (!usesDefaultCapabilities()) {
|
||||
throw new ResourceNotFoundException("Gerrit capabilities not used on this server");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk evaluate a set of {@link PermissionBackendCondition} for view handling.
|
||||
*
|
||||
|
@@ -60,6 +60,7 @@ class Capabilities implements ChildCollection<AccountResource, AccountResource.C
|
||||
@Override
|
||||
public Capability parse(AccountResource parent, IdString id)
|
||||
throws ResourceNotFoundException, AuthException, PermissionBackendException {
|
||||
permissionBackend.checkUsesDefaultCapabilities();
|
||||
IdentifiedUser target = parent.getUser();
|
||||
if (self.get() != target) {
|
||||
permissionBackend.currentUser().check(GlobalPermission.ADMINISTRATE_SERVER);
|
||||
|
@@ -23,8 +23,9 @@ import com.google.gerrit.extensions.api.access.GlobalOrPluginPermission;
|
||||
import com.google.gerrit.extensions.api.access.PluginPermission;
|
||||
import com.google.gerrit.extensions.config.CapabilityDefinition;
|
||||
import com.google.gerrit.extensions.registration.DynamicMap;
|
||||
import com.google.gerrit.extensions.restapi.AuthException;
|
||||
import com.google.gerrit.extensions.restapi.BinaryResult;
|
||||
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
|
||||
import com.google.gerrit.extensions.restapi.RestApiException;
|
||||
import com.google.gerrit.extensions.restapi.RestReadView;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.gerrit.server.OptionUtil;
|
||||
@@ -75,7 +76,8 @@ class GetCapabilities implements RestReadView<AccountResource> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object apply(AccountResource rsrc) throws AuthException, PermissionBackendException {
|
||||
public Object apply(AccountResource rsrc) throws RestApiException, PermissionBackendException {
|
||||
permissionBackend.checkUsesDefaultCapabilities();
|
||||
PermissionBackend.WithUser perm = permissionBackend.currentUser();
|
||||
if (self.get() != rsrc.getUser()) {
|
||||
perm.check(GlobalPermission.ADMINISTRATE_SERVER);
|
||||
@@ -158,8 +160,16 @@ class GetCapabilities implements RestReadView<AccountResource> {
|
||||
|
||||
@Singleton
|
||||
static class CheckOne implements RestReadView<AccountResource.Capability> {
|
||||
private final PermissionBackend permissionBackend;
|
||||
|
||||
@Inject
|
||||
CheckOne(PermissionBackend permissionBackend) {
|
||||
this.permissionBackend = permissionBackend;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryResult apply(Capability resource) {
|
||||
public BinaryResult apply(Capability resource) throws ResourceNotFoundException {
|
||||
permissionBackend.checkUsesDefaultCapabilities();
|
||||
return BinaryResult.create("ok\n");
|
||||
}
|
||||
}
|
||||
|
@@ -18,9 +18,11 @@ import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gerrit.common.data.GlobalCapability;
|
||||
import com.google.gerrit.extensions.config.CapabilityDefinition;
|
||||
import com.google.gerrit.extensions.registration.DynamicMap;
|
||||
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
|
||||
import com.google.gerrit.extensions.restapi.RestReadView;
|
||||
import com.google.gerrit.server.config.CapabilityConstants;
|
||||
import com.google.gerrit.server.config.ConfigResource;
|
||||
import com.google.gerrit.server.permissions.PermissionBackend;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.Singleton;
|
||||
@@ -36,16 +38,20 @@ public class ListCapabilities implements RestReadView<ConfigResource> {
|
||||
private static final Logger log = LoggerFactory.getLogger(ListCapabilities.class);
|
||||
private static final Pattern PLUGIN_NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9-]+$");
|
||||
|
||||
private final PermissionBackend permissionBackend;
|
||||
private final DynamicMap<CapabilityDefinition> pluginCapabilities;
|
||||
|
||||
@Inject
|
||||
public ListCapabilities(DynamicMap<CapabilityDefinition> pluginCapabilities) {
|
||||
public ListCapabilities(
|
||||
PermissionBackend permissionBackend, DynamicMap<CapabilityDefinition> pluginCapabilities) {
|
||||
this.permissionBackend = permissionBackend;
|
||||
this.pluginCapabilities = pluginCapabilities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, CapabilityInfo> apply(ConfigResource resource)
|
||||
throws IllegalAccessException, NoSuchFieldException {
|
||||
throws ResourceNotFoundException, IllegalAccessException, NoSuchFieldException {
|
||||
permissionBackend.checkUsesDefaultCapabilities();
|
||||
return ImmutableMap.<String, CapabilityInfo>builder()
|
||||
.putAll(collectCoreCapabilities())
|
||||
.putAll(collectPluginCapabilities())
|
||||
|
@@ -20,11 +20,15 @@ import com.google.gerrit.common.data.GlobalCapability;
|
||||
import com.google.gerrit.extensions.annotations.Exports;
|
||||
import com.google.gerrit.extensions.config.CapabilityDefinition;
|
||||
import com.google.gerrit.extensions.registration.DynamicMap;
|
||||
import com.google.gerrit.reviewdb.client.Account.Id;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.gerrit.server.permissions.PermissionBackend;
|
||||
import com.google.gerrit.server.restapi.config.ListCapabilities;
|
||||
import com.google.gerrit.server.restapi.config.ListCapabilities.CapabilityInfo;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Singleton;
|
||||
import java.util.Map;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -48,6 +52,7 @@ public class ListCapabilitiesTest {
|
||||
return "Print Hello";
|
||||
}
|
||||
});
|
||||
bind(PermissionBackend.class).to(FakePermissionBackend.class);
|
||||
}
|
||||
};
|
||||
injector = Guice.createInjector(mod);
|
||||
@@ -68,4 +73,27 @@ public class ListCapabilitiesTest {
|
||||
assertThat(m.get(pluginCapability).id).isEqualTo(pluginCapability);
|
||||
assertThat(m.get(pluginCapability).name).isEqualTo("Print Hello");
|
||||
}
|
||||
|
||||
@Singleton
|
||||
private static class FakePermissionBackend extends PermissionBackend {
|
||||
@Override
|
||||
public WithUser currentUser() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WithUser user(CurrentUser user) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WithUser absentUser(Id user) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean usesDefaultCapabilities() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user