blob: 1b874463701523a460bb2203080e5cff09a51c01 [file] [log] [blame]
// Copyright (C) 2018 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 static com.google.common.base.Preconditions.checkState;
import static java.util.Objects.requireNonNull;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.entities.Permission;
import com.google.gerrit.extensions.api.access.GlobalOrPluginPermission;
import com.google.gerrit.extensions.api.access.PluginPermission;
import com.google.gerrit.extensions.api.access.PluginProjectPermission;
import com.google.gerrit.server.permissions.AbstractLabelPermission.ForUser;
import java.util.EnumSet;
import java.util.Optional;
import java.util.Set;
/**
* Mappings from {@link com.google.gerrit.extensions.api.access.GerritPermission} enum instances to
* the permission names used by {@link DefaultPermissionBackend}.
*
* <p>These should be considered implementation details of {@code DefaultPermissionBackend}; a
* backend that doesn't respect the default permission model will not need to consult these.
* However, implementations may also choose to respect certain aspects of the default permission
* model, so this class is provided as public to aid those implementations.
*/
public class DefaultPermissionMappings {
private static final ImmutableBiMap<GlobalPermission, String> CAPABILITIES =
ImmutableBiMap.<GlobalPermission, String>builder()
.put(GlobalPermission.ACCESS_DATABASE, GlobalCapability.ACCESS_DATABASE)
.put(GlobalPermission.ADMINISTRATE_SERVER, GlobalCapability.ADMINISTRATE_SERVER)
.put(GlobalPermission.CREATE_ACCOUNT, GlobalCapability.CREATE_ACCOUNT)
.put(GlobalPermission.CREATE_GROUP, GlobalCapability.CREATE_GROUP)
.put(GlobalPermission.CREATE_PROJECT, GlobalCapability.CREATE_PROJECT)
.put(GlobalPermission.EMAIL_REVIEWERS, GlobalCapability.EMAIL_REVIEWERS)
.put(GlobalPermission.FLUSH_CACHES, GlobalCapability.FLUSH_CACHES)
.put(GlobalPermission.KILL_TASK, GlobalCapability.KILL_TASK)
.put(GlobalPermission.MAINTAIN_SERVER, GlobalCapability.MAINTAIN_SERVER)
.put(GlobalPermission.MODIFY_ACCOUNT, GlobalCapability.MODIFY_ACCOUNT)
.put(GlobalPermission.READ_AS, GlobalCapability.READ_AS)
.put(GlobalPermission.RUN_AS, GlobalCapability.RUN_AS)
.put(GlobalPermission.RUN_GC, GlobalCapability.RUN_GC)
.put(GlobalPermission.STREAM_EVENTS, GlobalCapability.STREAM_EVENTS)
.put(GlobalPermission.VIEW_ACCESS, GlobalCapability.VIEW_ACCESS)
.put(GlobalPermission.VIEW_ALL_ACCOUNTS, GlobalCapability.VIEW_ALL_ACCOUNTS)
.put(GlobalPermission.VIEW_CACHES, GlobalCapability.VIEW_CACHES)
.put(GlobalPermission.VIEW_CONNECTIONS, GlobalCapability.VIEW_CONNECTIONS)
.put(GlobalPermission.VIEW_PLUGINS, GlobalCapability.VIEW_PLUGINS)
.put(GlobalPermission.VIEW_QUEUE, GlobalCapability.VIEW_QUEUE)
.put(GlobalPermission.VIEW_SECONDARY_EMAILS, GlobalCapability.VIEW_SECONDARY_EMAILS)
.build();
static {
checkMapContainsAllEnumValues(CAPABILITIES, GlobalPermission.class);
}
private static final ImmutableBiMap<ProjectPermission, String> PROJECT_PERMISSIONS =
ImmutableBiMap.<ProjectPermission, String>builder()
.put(ProjectPermission.READ, Permission.READ)
.build();
private static final ImmutableBiMap<RefPermission, String> REF_PERMISSIONS =
ImmutableBiMap.<RefPermission, String>builder()
.put(RefPermission.READ, Permission.READ)
.put(RefPermission.CREATE, Permission.CREATE)
.put(RefPermission.DELETE, Permission.DELETE)
.put(RefPermission.UPDATE, Permission.PUSH)
.put(RefPermission.FORGE_AUTHOR, Permission.FORGE_AUTHOR)
.put(RefPermission.FORGE_COMMITTER, Permission.FORGE_COMMITTER)
.put(RefPermission.FORGE_SERVER, Permission.FORGE_SERVER)
.put(RefPermission.CREATE_TAG, Permission.CREATE_TAG)
.put(RefPermission.CREATE_SIGNED_TAG, Permission.CREATE_SIGNED_TAG)
.put(RefPermission.READ_PRIVATE_CHANGES, Permission.VIEW_PRIVATE_CHANGES)
.build();
private static final ImmutableBiMap<ChangePermission, String> CHANGE_PERMISSIONS =
ImmutableBiMap.<ChangePermission, String>builder()
.put(ChangePermission.READ, Permission.READ)
.put(ChangePermission.ABANDON, Permission.ABANDON)
.put(ChangePermission.EDIT_CUSTOM_KEYED_VALUES, Permission.EDIT_CUSTOM_KEYED_VALUES)
.put(ChangePermission.EDIT_HASHTAGS, Permission.EDIT_HASHTAGS)
.put(ChangePermission.EDIT_TOPIC_NAME, Permission.EDIT_TOPIC_NAME)
.put(ChangePermission.REMOVE_REVIEWER, Permission.REMOVE_REVIEWER)
.put(ChangePermission.ADD_PATCH_SET, Permission.ADD_PATCH_SET)
.put(ChangePermission.REBASE, Permission.REBASE)
.put(ChangePermission.REVERT, Permission.REVERT)
.put(ChangePermission.SUBMIT, Permission.SUBMIT)
.put(ChangePermission.SUBMIT_AS, Permission.SUBMIT_AS)
.put(
ChangePermission.TOGGLE_WORK_IN_PROGRESS_STATE,
Permission.TOGGLE_WORK_IN_PROGRESS_STATE)
.build();
private static <T extends Enum<T>> void checkMapContainsAllEnumValues(
ImmutableMap<T, String> actual, Class<T> clazz) {
Set<T> expected = EnumSet.allOf(clazz);
checkState(
actual.keySet().equals(expected),
"all %s values must be defined, found: %s",
clazz.getSimpleName(),
actual.keySet());
}
public static String globalPermissionName(GlobalPermission globalPermission) {
return requireNonNull(CAPABILITIES.get(globalPermission));
}
public static Optional<GlobalPermission> globalPermission(String capabilityName) {
return Optional.ofNullable(CAPABILITIES.inverse().get(capabilityName));
}
public static String pluginCapabilityName(PluginPermission pluginPermission) {
return pluginPermission.pluginName() + '-' + pluginPermission.capability();
}
public static String pluginProjectPermissionName(PluginProjectPermission pluginPermission) {
return "plugin-" + pluginPermission.pluginName() + '-' + pluginPermission.permission();
}
public static String globalOrPluginPermissionName(GlobalOrPluginPermission permission) {
return permission instanceof GlobalPermission
? globalPermissionName((GlobalPermission) permission)
: pluginCapabilityName((PluginPermission) permission);
}
public static Optional<String> projectPermissionName(ProjectPermission projectPermission) {
return Optional.ofNullable(PROJECT_PERMISSIONS.get(projectPermission));
}
public static Optional<ProjectPermission> projectPermission(String permissionName) {
return Optional.ofNullable(PROJECT_PERMISSIONS.inverse().get(permissionName));
}
public static Optional<String> refPermissionName(RefPermission refPermission) {
return Optional.ofNullable(REF_PERMISSIONS.get(refPermission));
}
public static Optional<RefPermission> refPermission(String permissionName) {
return Optional.ofNullable(REF_PERMISSIONS.inverse().get(permissionName));
}
public static Optional<String> changePermissionName(ChangePermission changePermission) {
return Optional.ofNullable(CHANGE_PERMISSIONS.get(changePermission));
}
public static Optional<ChangePermission> changePermission(String permissionName) {
return Optional.ofNullable(CHANGE_PERMISSIONS.inverse().get(permissionName));
}
public static String labelPermissionName(AbstractLabelPermission labelPermission) {
if (labelPermission instanceof LabelPermission) {
if (labelPermission.forUser() == ForUser.ON_BEHALF_OF) {
return Permission.forLabelAs(labelPermission.label());
}
return Permission.forLabel(labelPermission.label());
} else if (labelPermission instanceof LabelRemovalPermission) {
return Permission.forRemoveLabel(labelPermission.label());
}
throw new IllegalStateException("invalid AbstractLabelPermission subtype");
}
// TODO(dborowitz): Can these share a common superinterface?
public static String labelPermissionName(AbstractLabelPermission.WithValue labelPermission) {
if (labelPermission instanceof LabelPermission.WithValue) {
if (labelPermission.forUser() == ForUser.ON_BEHALF_OF) {
return Permission.forLabelAs(labelPermission.label());
}
return Permission.forLabel(labelPermission.label());
} else if (labelPermission instanceof LabelRemovalPermission.WithValue) {
return Permission.forRemoveLabel(labelPermission.label());
}
throw new IllegalStateException("invalid AbstractLabelPermission.WithValue subtype");
}
private DefaultPermissionMappings() {}
}