Test GlobalCapabilities with PermissionBackend
Add GlobalPermission enum mapping the simple boolean GlobalCapabilities to be checked by PermissionBackend. Rewrite GetCapabilities handler in terms of this API. Change-Id: Ie06a4f6b18b7bdfabbaa58c6aa9becbc1d9b6136
This commit is contained in:

committed by
David Pursehouse

parent
cd84f3bb83
commit
625049c020
@@ -15,6 +15,7 @@
|
||||
package com.google.gerrit.common.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -115,6 +116,9 @@ public class GlobalCapability {
|
||||
|
||||
private static final List<String> NAMES_ALL;
|
||||
private static final List<String> NAMES_LC;
|
||||
private static final String[] RANGE_NAMES = {
|
||||
QUERY_LIMIT, BATCH_CHANGES_LIMIT,
|
||||
};
|
||||
|
||||
static {
|
||||
NAMES_ALL = new ArrayList<>();
|
||||
@@ -158,7 +162,16 @@ public class GlobalCapability {
|
||||
|
||||
/** @return true if the capability should have a range attached. */
|
||||
public static boolean hasRange(String varName) {
|
||||
return QUERY_LIMIT.equalsIgnoreCase(varName) || BATCH_CHANGES_LIMIT.equalsIgnoreCase(varName);
|
||||
for (String n : RANGE_NAMES) {
|
||||
if (n.equalsIgnoreCase(varName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static List<String> getRangeNames() {
|
||||
return Collections.unmodifiableList(Arrays.asList(RANGE_NAMES));
|
||||
}
|
||||
|
||||
/** @return the valid range for the capability if it has one, otherwise null. */
|
||||
|
@@ -26,6 +26,8 @@ import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.gerrit.server.PeerDaemonUser;
|
||||
import com.google.gerrit.server.git.QueueProvider;
|
||||
import com.google.gerrit.server.group.SystemGroupBackend;
|
||||
import com.google.gerrit.server.permissions.GlobalPermission;
|
||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||
import com.google.gerrit.server.project.ProjectCache;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
@@ -75,21 +77,6 @@ public class CapabilityControl {
|
||||
return canAdministrateServer;
|
||||
}
|
||||
|
||||
/** @return true if the user can create an account for another user. */
|
||||
public boolean canCreateAccount() {
|
||||
return canPerform(GlobalCapability.CREATE_ACCOUNT) || canAdministrateServer();
|
||||
}
|
||||
|
||||
/** @return true if the user can create a group. */
|
||||
public boolean canCreateGroup() {
|
||||
return canPerform(GlobalCapability.CREATE_GROUP) || canAdministrateServer();
|
||||
}
|
||||
|
||||
/** @return true if the user can create a project. */
|
||||
public boolean canCreateProject() {
|
||||
return canPerform(GlobalCapability.CREATE_PROJECT) || canAdministrateServer();
|
||||
}
|
||||
|
||||
/** @return true if the user can email reviewers. */
|
||||
public boolean canEmailReviewers() {
|
||||
if (canEmailReviewers == null) {
|
||||
@@ -100,11 +87,6 @@ public class CapabilityControl {
|
||||
return canEmailReviewers;
|
||||
}
|
||||
|
||||
/** @return true if the user can kill any running task. */
|
||||
public boolean canKillTask() {
|
||||
return canPerform(GlobalCapability.KILL_TASK) || canMaintainServer();
|
||||
}
|
||||
|
||||
/** @return true if the user can modify an account for another user. */
|
||||
public boolean canModifyAccount() {
|
||||
return canPerform(GlobalCapability.MODIFY_ACCOUNT) || canAdministrateServer();
|
||||
@@ -120,26 +102,11 @@ public class CapabilityControl {
|
||||
return canPerform(GlobalCapability.VIEW_CACHES) || canMaintainServer();
|
||||
}
|
||||
|
||||
/** @return true if the user can flush the server's caches. */
|
||||
public boolean canFlushCaches() {
|
||||
return canPerform(GlobalCapability.FLUSH_CACHES) || canMaintainServer();
|
||||
}
|
||||
|
||||
/** @return true if the user can perform basic server maintenance. */
|
||||
public boolean canMaintainServer() {
|
||||
return canPerform(GlobalCapability.MAINTAIN_SERVER) || canAdministrateServer();
|
||||
}
|
||||
|
||||
/** @return true if the user can view open connections. */
|
||||
public boolean canViewConnections() {
|
||||
return canPerform(GlobalCapability.VIEW_CONNECTIONS) || canAdministrateServer();
|
||||
}
|
||||
|
||||
/** @return true if the user can view the installed plugins. */
|
||||
public boolean canViewPlugins() {
|
||||
return canPerform(GlobalCapability.VIEW_PLUGINS) || canAdministrateServer();
|
||||
}
|
||||
|
||||
/** @return true if the user can view the entire queue. */
|
||||
public boolean canViewQueue() {
|
||||
return canPerform(GlobalCapability.VIEW_QUEUE) || canMaintainServer();
|
||||
@@ -150,16 +117,6 @@ public class CapabilityControl {
|
||||
return canPerform(GlobalCapability.ACCESS_DATABASE);
|
||||
}
|
||||
|
||||
/** @return true if the user can stream Gerrit events. */
|
||||
public boolean canStreamEvents() {
|
||||
return canPerform(GlobalCapability.STREAM_EVENTS) || canAdministrateServer();
|
||||
}
|
||||
|
||||
/** @return true if the user can run the Git garbage collection. */
|
||||
public boolean canRunGC() {
|
||||
return canPerform(GlobalCapability.RUN_GC) || canMaintainServer();
|
||||
}
|
||||
|
||||
/** @return true if the user can impersonate another user. */
|
||||
public boolean canRunAs() {
|
||||
return canPerform(GlobalCapability.RUN_AS);
|
||||
@@ -278,4 +235,43 @@ public class CapabilityControl {
|
||||
private static boolean match(GroupMembership groups, PermissionRule rule) {
|
||||
return groups.contains(rule.getGroup().getUUID());
|
||||
}
|
||||
|
||||
/** Do not use unless inside DefaultPermissionBackend. */
|
||||
public boolean doCanForDefaultPermissionBackend(GlobalPermission perm)
|
||||
throws PermissionBackendException {
|
||||
switch (perm) {
|
||||
case ACCESS_DATABASE:
|
||||
return canAccessDatabase();
|
||||
case ADMINISTRATE_SERVER:
|
||||
return canAdministrateServer();
|
||||
case EMAIL_REVIEWERS:
|
||||
return canEmailReviewers();
|
||||
case MAINTAIN_SERVER:
|
||||
return canMaintainServer();
|
||||
case MODIFY_ACCOUNT:
|
||||
return canModifyAccount();
|
||||
case RUN_AS:
|
||||
return canRunAs();
|
||||
case VIEW_ALL_ACCOUNTS:
|
||||
return canViewAllAccounts();
|
||||
case VIEW_CACHES:
|
||||
return canViewCaches();
|
||||
case VIEW_QUEUE:
|
||||
return canViewQueue();
|
||||
|
||||
case FLUSH_CACHES:
|
||||
case KILL_TASK:
|
||||
case RUN_GC:
|
||||
return canPerform(perm.permissionName()) || canMaintainServer();
|
||||
|
||||
case CREATE_ACCOUNT:
|
||||
case CREATE_GROUP:
|
||||
case CREATE_PROJECT:
|
||||
case STREAM_EVENTS:
|
||||
case VIEW_CONNECTIONS:
|
||||
case VIEW_PLUGINS:
|
||||
return canPerform(perm.permissionName()) || canAdministrateServer();
|
||||
}
|
||||
throw new PermissionBackendException(perm + " unsupported");
|
||||
}
|
||||
}
|
||||
|
@@ -14,23 +14,7 @@
|
||||
|
||||
package com.google.gerrit.server.account;
|
||||
|
||||
import static com.google.gerrit.common.data.GlobalCapability.ACCESS_DATABASE;
|
||||
import static com.google.gerrit.common.data.GlobalCapability.CREATE_ACCOUNT;
|
||||
import static com.google.gerrit.common.data.GlobalCapability.CREATE_GROUP;
|
||||
import static com.google.gerrit.common.data.GlobalCapability.CREATE_PROJECT;
|
||||
import static com.google.gerrit.common.data.GlobalCapability.EMAIL_REVIEWERS;
|
||||
import static com.google.gerrit.common.data.GlobalCapability.FLUSH_CACHES;
|
||||
import static com.google.gerrit.common.data.GlobalCapability.KILL_TASK;
|
||||
import static com.google.gerrit.common.data.GlobalCapability.MAINTAIN_SERVER;
|
||||
import static com.google.gerrit.common.data.GlobalCapability.MODIFY_ACCOUNT;
|
||||
import static com.google.gerrit.common.data.GlobalCapability.PRIORITY;
|
||||
import static com.google.gerrit.common.data.GlobalCapability.RUN_GC;
|
||||
import static com.google.gerrit.common.data.GlobalCapability.STREAM_EVENTS;
|
||||
import static com.google.gerrit.common.data.GlobalCapability.VIEW_ALL_ACCOUNTS;
|
||||
import static com.google.gerrit.common.data.GlobalCapability.VIEW_CACHES;
|
||||
import static com.google.gerrit.common.data.GlobalCapability.VIEW_CONNECTIONS;
|
||||
import static com.google.gerrit.common.data.GlobalCapability.VIEW_PLUGINS;
|
||||
import static com.google.gerrit.common.data.GlobalCapability.VIEW_QUEUE;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.gerrit.common.data.GlobalCapability;
|
||||
@@ -45,12 +29,15 @@ import com.google.gerrit.server.OptionUtil;
|
||||
import com.google.gerrit.server.OutputFormat;
|
||||
import com.google.gerrit.server.account.AccountResource.Capability;
|
||||
import com.google.gerrit.server.git.QueueProvider;
|
||||
import com.google.gerrit.server.permissions.GlobalPermission;
|
||||
import com.google.gerrit.server.permissions.PermissionBackend;
|
||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.Singleton;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -67,34 +54,72 @@ class GetCapabilities implements RestReadView<AccountResource> {
|
||||
|
||||
private Set<String> query;
|
||||
|
||||
private final PermissionBackend permissionBackend;
|
||||
private final Provider<CurrentUser> self;
|
||||
private final DynamicMap<CapabilityDefinition> pluginCapabilities;
|
||||
|
||||
@Inject
|
||||
GetCapabilities(Provider<CurrentUser> self, DynamicMap<CapabilityDefinition> pluginCapabilities) {
|
||||
GetCapabilities(
|
||||
PermissionBackend permissionBackend,
|
||||
Provider<CurrentUser> self,
|
||||
DynamicMap<CapabilityDefinition> pluginCapabilities) {
|
||||
this.permissionBackend = permissionBackend;
|
||||
this.self = self;
|
||||
this.pluginCapabilities = pluginCapabilities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object apply(AccountResource resource) throws AuthException {
|
||||
if (self.get() != resource.getUser() && !self.get().getCapabilities().canAdministrateServer()) {
|
||||
throw new AuthException("restricted to administrator");
|
||||
public Object apply(AccountResource rsrc) throws AuthException, PermissionBackendException {
|
||||
PermissionBackend.WithUser perm = permissionBackend.user(self);
|
||||
if (self.get() != rsrc.getUser()) {
|
||||
perm.check(GlobalPermission.ADMINISTRATE_SERVER);
|
||||
perm = permissionBackend.user(rsrc.getUser());
|
||||
}
|
||||
|
||||
CapabilityControl cc = resource.getUser().getCapabilities();
|
||||
Map<String, Object> have = new LinkedHashMap<>();
|
||||
for (String name : GlobalCapability.getAllNames()) {
|
||||
if (want(name)) {
|
||||
if (GlobalCapability.hasRange(name)) {
|
||||
if (cc.hasExplicitRange(name)) {
|
||||
have.put(name, new Range(cc.getRange(name)));
|
||||
}
|
||||
} else if (!name.equals(PRIORITY) && cc.canPerform(name)) {
|
||||
have.put(name, true);
|
||||
for (GlobalPermission p : testGlobalPermissions(perm)) {
|
||||
have.put(p.permissionName(), true);
|
||||
}
|
||||
addRanges(have, rsrc);
|
||||
addPluginCapabilities(have, rsrc);
|
||||
addPriority(have, rsrc);
|
||||
|
||||
return OutputFormat.JSON
|
||||
.newGson()
|
||||
.toJsonTree(have, new TypeToken<Map<String, Object>>() {}.getType());
|
||||
}
|
||||
|
||||
private Set<GlobalPermission> testGlobalPermissions(PermissionBackend.WithUser perm)
|
||||
throws PermissionBackendException {
|
||||
EnumSet<GlobalPermission> toTest;
|
||||
if (query != null) {
|
||||
toTest = EnumSet.noneOf(GlobalPermission.class);
|
||||
for (GlobalPermission p : GlobalPermission.values()) {
|
||||
if (want(p.permissionName())) {
|
||||
toTest.add(p);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
toTest = EnumSet.allOf(GlobalPermission.class);
|
||||
}
|
||||
return perm.test(toTest);
|
||||
}
|
||||
|
||||
private boolean want(String name) {
|
||||
return query == null || query.contains(name.toLowerCase());
|
||||
}
|
||||
|
||||
private void addRanges(Map<String, Object> have, AccountResource rsrc) {
|
||||
CapabilityControl cc = rsrc.getUser().getCapabilities();
|
||||
for (String name : GlobalCapability.getRangeNames()) {
|
||||
if (want(name) && cc.hasExplicitRange(name)) {
|
||||
have.put(name, new Range(cc.getRange(name)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addPluginCapabilities(Map<String, Object> have, AccountResource rsrc) {
|
||||
CapabilityControl cc = rsrc.getUser().getCapabilities();
|
||||
for (String pluginName : pluginCapabilities.plugins()) {
|
||||
for (String capability : pluginCapabilities.byPlugin(pluginName).keySet()) {
|
||||
String name = String.format("%s-%s", pluginName, capability);
|
||||
@@ -103,47 +128,14 @@ class GetCapabilities implements RestReadView<AccountResource> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
have.put(ACCESS_DATABASE, cc.canAccessDatabase());
|
||||
have.put(CREATE_ACCOUNT, cc.canCreateAccount());
|
||||
have.put(CREATE_GROUP, cc.canCreateGroup());
|
||||
have.put(CREATE_PROJECT, cc.canCreateProject());
|
||||
have.put(EMAIL_REVIEWERS, cc.canEmailReviewers());
|
||||
have.put(FLUSH_CACHES, cc.canFlushCaches());
|
||||
have.put(KILL_TASK, cc.canKillTask());
|
||||
have.put(MAINTAIN_SERVER, cc.canMaintainServer());
|
||||
have.put(MODIFY_ACCOUNT, cc.canModifyAccount());
|
||||
have.put(RUN_GC, cc.canRunGC());
|
||||
have.put(STREAM_EVENTS, cc.canStreamEvents());
|
||||
have.put(VIEW_ALL_ACCOUNTS, cc.canViewAllAccounts());
|
||||
have.put(VIEW_CACHES, cc.canViewCaches());
|
||||
have.put(VIEW_CONNECTIONS, cc.canViewConnections());
|
||||
have.put(VIEW_PLUGINS, cc.canViewPlugins());
|
||||
have.put(VIEW_QUEUE, cc.canViewQueue());
|
||||
|
||||
QueueProvider.QueueType queue = cc.getQueueType();
|
||||
private void addPriority(Map<String, Object> have, AccountResource rsrc) {
|
||||
QueueProvider.QueueType queue = rsrc.getUser().getCapabilities().getQueueType();
|
||||
if (queue != QueueProvider.QueueType.INTERACTIVE
|
||||
|| (query != null && query.contains(PRIORITY))) {
|
||||
have.put(PRIORITY, queue);
|
||||
}
|
||||
|
||||
Iterator<Map.Entry<String, Object>> itr = have.entrySet().iterator();
|
||||
while (itr.hasNext()) {
|
||||
Map.Entry<String, Object> e = itr.next();
|
||||
if (!want(e.getKey())) {
|
||||
itr.remove();
|
||||
} else if (e.getValue() instanceof Boolean && !((Boolean) e.getValue())) {
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
|
||||
return OutputFormat.JSON
|
||||
.newGson()
|
||||
.toJsonTree(have, new TypeToken<Map<String, Object>>() {}.getType());
|
||||
}
|
||||
|
||||
private boolean want(String name) {
|
||||
return query == null || query.contains(name.toLowerCase());
|
||||
}
|
||||
|
||||
private static class Range {
|
||||
|
@@ -0,0 +1,54 @@
|
||||
// Copyright (C) 2017 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.server.permissions;
|
||||
|
||||
import com.google.gerrit.common.data.GlobalCapability;
|
||||
import java.util.Locale;
|
||||
|
||||
public enum GlobalPermission {
|
||||
ACCESS_DATABASE(GlobalCapability.ACCESS_DATABASE),
|
||||
ADMINISTRATE_SERVER(GlobalCapability.ADMINISTRATE_SERVER),
|
||||
CREATE_ACCOUNT(GlobalCapability.CREATE_ACCOUNT),
|
||||
CREATE_GROUP(GlobalCapability.CREATE_GROUP),
|
||||
CREATE_PROJECT(GlobalCapability.CREATE_PROJECT),
|
||||
EMAIL_REVIEWERS(GlobalCapability.EMAIL_REVIEWERS),
|
||||
FLUSH_CACHES(GlobalCapability.FLUSH_CACHES),
|
||||
KILL_TASK(GlobalCapability.KILL_TASK),
|
||||
MAINTAIN_SERVER(GlobalCapability.MAINTAIN_SERVER),
|
||||
MODIFY_ACCOUNT(GlobalCapability.MODIFY_ACCOUNT),
|
||||
RUN_AS(GlobalCapability.RUN_AS),
|
||||
RUN_GC(GlobalCapability.RUN_GC),
|
||||
STREAM_EVENTS(GlobalCapability.STREAM_EVENTS),
|
||||
VIEW_ALL_ACCOUNTS(GlobalCapability.VIEW_ALL_ACCOUNTS),
|
||||
VIEW_CACHES(GlobalCapability.VIEW_CACHES),
|
||||
VIEW_CONNECTIONS(GlobalCapability.VIEW_CONNECTIONS),
|
||||
VIEW_PLUGINS(GlobalCapability.VIEW_PLUGINS),
|
||||
VIEW_QUEUE(GlobalCapability.VIEW_QUEUE);
|
||||
|
||||
private final String name;
|
||||
|
||||
GlobalPermission(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/** @return name used in {@code project.config} permissions. */
|
||||
public String permissionName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String describeForException() {
|
||||
return toString().toLowerCase(Locale.US).replace('_', ' ');
|
||||
}
|
||||
}
|
@@ -36,10 +36,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Checks authorization to perform an action on project, ref, or change.
|
||||
*
|
||||
* <p>{@code PermissionBackend} should be a singleton for the server, acting as a factory for
|
||||
* lightweight request instances.
|
||||
* Checks authorization to perform an action on a project, reference, or change.
|
||||
*
|
||||
* <p>{@code check} methods should be used during action handlers to verify the user is allowed to
|
||||
* exercise the specified permission. For convenience in implementation {@code check} methods throw
|
||||
@@ -50,6 +47,13 @@ import org.slf4j.LoggerFactory;
|
||||
* permission. This is suitable for configuring UI button state, but should not be relied upon to
|
||||
* guard handlers before making state changes.
|
||||
*
|
||||
* <p>{@code PermissionBackend} is a singleton for the server, acting as a factory for lightweight
|
||||
* request instances. Implementation classes may cache supporting data inside of {@link WithUser},
|
||||
* {@link ForProject}, {@link ForRef}, and {@link ForChange} instances, in addition to storing
|
||||
* within {@link CurrentUser} using a {@link com.google.gerrit.server.CurrentUser.PropertyKey}.
|
||||
* {@link GlobalPermission} caching for {@link WithUser} may best cached inside {@link CurrentUser}
|
||||
* as {@link WithUser} instances are frequently created.
|
||||
*
|
||||
* <p>Example use:
|
||||
*
|
||||
* <pre>
|
||||
@@ -128,6 +132,27 @@ public abstract class PermissionBackend {
|
||||
public ForChange change(ChangeNotes notes) {
|
||||
return ref(notes.getChange().getDest()).change(notes);
|
||||
}
|
||||
|
||||
/** Verify scoped user can {@code perm}, throwing if denied. */
|
||||
public abstract void check(GlobalPermission perm)
|
||||
throws AuthException, PermissionBackendException;
|
||||
|
||||
/** Filter {@code permSet} to permissions scoped user might be able to perform. */
|
||||
public abstract Set<GlobalPermission> test(Collection<GlobalPermission> permSet)
|
||||
throws PermissionBackendException;
|
||||
|
||||
public boolean test(GlobalPermission perm) throws PermissionBackendException {
|
||||
return test(EnumSet.of(perm)).contains(perm);
|
||||
}
|
||||
|
||||
public boolean testOrFalse(GlobalPermission perm) {
|
||||
try {
|
||||
return test(perm);
|
||||
} catch (PermissionBackendException e) {
|
||||
logger.warn("Cannot test " + perm + "; assuming false", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** PermissionBackend scoped to a user and project. */
|
||||
|
@@ -16,13 +16,19 @@ package com.google.gerrit.server.project;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.gerrit.extensions.restapi.AuthException;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.gerrit.server.permissions.FailedPermissionBackend;
|
||||
import com.google.gerrit.server.permissions.GlobalPermission;
|
||||
import com.google.gerrit.server.permissions.PermissionBackend;
|
||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
@Singleton
|
||||
class DefaultPermissionBackend extends PermissionBackend {
|
||||
@@ -57,5 +63,28 @@ class DefaultPermissionBackend extends PermissionBackend {
|
||||
return FailedPermissionBackend.project("unavailable", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check(GlobalPermission perm) throws AuthException, PermissionBackendException {
|
||||
if (!can(perm)) {
|
||||
throw new AuthException(perm.describeForException() + " not permitted");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<GlobalPermission> test(Collection<GlobalPermission> permSet)
|
||||
throws PermissionBackendException {
|
||||
EnumSet<GlobalPermission> ok = EnumSet.noneOf(GlobalPermission.class);
|
||||
for (GlobalPermission perm : permSet) {
|
||||
if (can(perm)) {
|
||||
ok.add(perm);
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
private boolean can(GlobalPermission perm) throws PermissionBackendException {
|
||||
return user.getCapabilities().doCanForDefaultPermissionBackend(perm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user