| // 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() {} |
| } |