LCOV - code coverage report
Current view: top level - entities - Permission.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 95 103 92.2 %
Date: 2022-11-19 15:00:39 Functions: 33 33 100.0 %

          Line data    Source code
       1             : // Copyright (C) 2010 The Android Open Source Project
       2             : //
       3             : // Licensed under the Apache License, Version 2.0 (the "License");
       4             : // you may not use this file except in compliance with the License.
       5             : // You may obtain a copy of the License at
       6             : //
       7             : // http://www.apache.org/licenses/LICENSE-2.0
       8             : //
       9             : // Unless required by applicable law or agreed to in writing, software
      10             : // distributed under the License is distributed on an "AS IS" BASIS,
      11             : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             : // See the License for the specific language governing permissions and
      13             : // limitations under the License.
      14             : 
      15             : package com.google.gerrit.entities;
      16             : 
      17             : import static com.google.common.collect.ImmutableList.toImmutableList;
      18             : 
      19             : import com.google.auto.value.AutoValue;
      20             : import com.google.common.collect.ImmutableList;
      21             : import com.google.gerrit.common.Nullable;
      22             : import java.util.ArrayList;
      23             : import java.util.Iterator;
      24             : import java.util.List;
      25             : import java.util.function.Consumer;
      26             : 
      27             : /** A single permission within an {@link AccessSection} of a project. */
      28             : @AutoValue
      29         153 : public abstract class Permission implements Comparable<Permission> {
      30             :   public static final String ABANDON = "abandon";
      31             :   public static final String ADD_PATCH_SET = "addPatchSet";
      32             :   public static final String CREATE = "create";
      33             :   public static final String CREATE_SIGNED_TAG = "createSignedTag";
      34             :   public static final String CREATE_TAG = "createTag";
      35             :   public static final String DELETE = "delete";
      36             :   public static final String DELETE_CHANGES = "deleteChanges";
      37             :   public static final String DELETE_OWN_CHANGES = "deleteOwnChanges";
      38             :   public static final String EDIT_ASSIGNEE = "editAssignee";
      39             :   public static final String EDIT_HASHTAGS = "editHashtags";
      40             :   public static final String EDIT_TOPIC_NAME = "editTopicName";
      41             :   public static final String FORGE_AUTHOR = "forgeAuthor";
      42             :   public static final String FORGE_COMMITTER = "forgeCommitter";
      43             :   public static final String FORGE_SERVER = "forgeServerAsCommitter";
      44             :   public static final String LABEL = "label-";
      45             :   public static final String LABEL_AS = "labelAs-";
      46             :   public static final String OWNER = "owner";
      47             :   public static final String PUSH = "push";
      48             :   public static final String PUSH_MERGE = "pushMerge";
      49             :   public static final String READ = "read";
      50             :   public static final String REBASE = "rebase";
      51             :   public static final String REMOVE_REVIEWER = "removeReviewer";
      52             :   public static final String REVERT = "revert";
      53             :   public static final String SUBMIT = "submit";
      54             :   public static final String SUBMIT_AS = "submitAs";
      55             :   public static final String TOGGLE_WORK_IN_PROGRESS_STATE = "toggleWipState";
      56             :   public static final String VIEW_PRIVATE_CHANGES = "viewPrivateChanges";
      57             : 
      58             :   public static final boolean DEF_EXCLUSIVE_GROUP = false;
      59             : 
      60             :   private static final List<String> NAMES_LC;
      61             :   private static final int LABEL_INDEX;
      62             :   private static final int LABEL_AS_INDEX;
      63             : 
      64             :   static {
      65         153 :     NAMES_LC = new ArrayList<>();
      66         153 :     NAMES_LC.add(ABANDON.toLowerCase());
      67         153 :     NAMES_LC.add(ADD_PATCH_SET.toLowerCase());
      68         153 :     NAMES_LC.add(CREATE.toLowerCase());
      69         153 :     NAMES_LC.add(CREATE_SIGNED_TAG.toLowerCase());
      70         153 :     NAMES_LC.add(CREATE_TAG.toLowerCase());
      71         153 :     NAMES_LC.add(DELETE.toLowerCase());
      72         153 :     NAMES_LC.add(DELETE_CHANGES.toLowerCase());
      73         153 :     NAMES_LC.add(DELETE_OWN_CHANGES.toLowerCase());
      74         153 :     NAMES_LC.add(EDIT_ASSIGNEE.toLowerCase());
      75         153 :     NAMES_LC.add(EDIT_HASHTAGS.toLowerCase());
      76         153 :     NAMES_LC.add(EDIT_TOPIC_NAME.toLowerCase());
      77         153 :     NAMES_LC.add(FORGE_AUTHOR.toLowerCase());
      78         153 :     NAMES_LC.add(FORGE_COMMITTER.toLowerCase());
      79         153 :     NAMES_LC.add(FORGE_SERVER.toLowerCase());
      80         153 :     NAMES_LC.add(LABEL.toLowerCase());
      81         153 :     NAMES_LC.add(LABEL_AS.toLowerCase());
      82         153 :     NAMES_LC.add(OWNER.toLowerCase());
      83         153 :     NAMES_LC.add(PUSH.toLowerCase());
      84         153 :     NAMES_LC.add(PUSH_MERGE.toLowerCase());
      85         153 :     NAMES_LC.add(READ.toLowerCase());
      86         153 :     NAMES_LC.add(REBASE.toLowerCase());
      87         153 :     NAMES_LC.add(REMOVE_REVIEWER.toLowerCase());
      88         153 :     NAMES_LC.add(REVERT.toLowerCase());
      89         153 :     NAMES_LC.add(SUBMIT.toLowerCase());
      90         153 :     NAMES_LC.add(SUBMIT_AS.toLowerCase());
      91         153 :     NAMES_LC.add(TOGGLE_WORK_IN_PROGRESS_STATE.toLowerCase());
      92         153 :     NAMES_LC.add(VIEW_PRIVATE_CHANGES.toLowerCase());
      93             : 
      94         153 :     LABEL_INDEX = NAMES_LC.indexOf(Permission.LABEL);
      95         153 :     LABEL_AS_INDEX = NAMES_LC.indexOf(Permission.LABEL_AS.toLowerCase());
      96         153 :   }
      97             : 
      98             :   /** Returns true if the name is recognized as a permission name. */
      99             :   public static boolean isPermission(String varName) {
     100         152 :     return isLabel(varName) || isLabelAs(varName) || NAMES_LC.contains(varName.toLowerCase());
     101             :   }
     102             : 
     103             :   public static boolean hasRange(String varName) {
     104         152 :     return isLabel(varName) || isLabelAs(varName);
     105             :   }
     106             : 
     107             :   /** Returns true if the permission name is actually for a review label. */
     108             :   public static boolean isLabel(String varName) {
     109         152 :     return varName.startsWith(LABEL) && LABEL.length() < varName.length();
     110             :   }
     111             : 
     112             :   /** Returns true if the permission is for impersonated review labels. */
     113             :   public static boolean isLabelAs(String var) {
     114         152 :     return var.startsWith(LABEL_AS) && LABEL_AS.length() < var.length();
     115             :   }
     116             : 
     117             :   /** Returns permission name for the given review label. */
     118             :   public static String forLabel(String labelName) {
     119         104 :     return LABEL + labelName;
     120             :   }
     121             : 
     122             :   /** Returns permission name to apply a label for another user. */
     123             :   public static String forLabelAs(String labelName) {
     124           4 :     return LABEL_AS + labelName;
     125             :   }
     126             : 
     127             :   @Nullable
     128             :   public static String extractLabel(String varName) {
     129          11 :     if (isLabel(varName)) {
     130           5 :       return varName.substring(LABEL.length());
     131          11 :     } else if (isLabelAs(varName)) {
     132           1 :       return varName.substring(LABEL_AS.length());
     133             :     }
     134          11 :     return null;
     135             :   }
     136             : 
     137             :   public static boolean canBeOnAllProjects(String ref, String permissionName) {
     138         152 :     if (AccessSection.ALL.equals(ref)) {
     139         152 :       return !OWNER.equals(permissionName);
     140             :     }
     141         152 :     return true;
     142             :   }
     143             : 
     144             :   /** The permission name, eg. {@code Permission.SUBMIT} */
     145             :   public abstract String getName();
     146             : 
     147             :   protected abstract boolean isExclusiveGroup();
     148             : 
     149             :   public abstract ImmutableList<PermissionRule> getRules();
     150             : 
     151             :   public static Builder builder(String name) {
     152         153 :     return new AutoValue_Permission.Builder()
     153         153 :         .setName(name)
     154         153 :         .setExclusiveGroup(DEF_EXCLUSIVE_GROUP)
     155         153 :         .setRules(ImmutableList.of());
     156             :   }
     157             : 
     158             :   public static Permission create(String name) {
     159           1 :     return builder(name).build();
     160             :   }
     161             : 
     162             :   public String getLabel() {
     163          11 :     return extractLabel(getName());
     164             :   }
     165             : 
     166             :   public boolean getExclusiveGroup() {
     167             :     // Only permit exclusive group behavior on non OWNER permissions,
     168             :     // otherwise an owner might lose access to a delegated subspace.
     169             :     //
     170         153 :     return isExclusiveGroup() && !OWNER.equals(getName());
     171             :   }
     172             : 
     173             :   @Nullable
     174             :   public PermissionRule getRule(GroupReference group) {
     175           5 :     for (PermissionRule r : getRules()) {
     176           5 :       if (sameGroup(r, group)) {
     177           5 :         return r;
     178             :       }
     179           2 :     }
     180             : 
     181           1 :     return null;
     182             :   }
     183             : 
     184             :   private static boolean sameGroup(PermissionRule rule, GroupReference group) {
     185          14 :     if (group.getUUID() != null && rule.getGroup().getUUID() != null) {
     186          14 :       return group.getUUID().equals(rule.getGroup().getUUID());
     187           0 :     } else if (group.getName() != null && rule.getGroup().getName() != null) {
     188           0 :       return group.getName().equals(rule.getGroup().getName());
     189             :     } else {
     190           0 :       return false;
     191             :     }
     192             :   }
     193             : 
     194             :   @Override
     195             :   public final int compareTo(Permission b) {
     196         151 :     int cmp = index(this) - index(b);
     197         151 :     if (cmp == 0) {
     198         151 :       cmp = getName().compareTo(b.getName());
     199             :     }
     200         151 :     return cmp;
     201             :   }
     202             : 
     203             :   private static int index(Permission a) {
     204         151 :     if (isLabel(a.getName())) {
     205         151 :       return LABEL_INDEX;
     206         151 :     } else if (isLabelAs(a.getName())) {
     207           1 :       return LABEL_AS_INDEX;
     208             :     }
     209             : 
     210         151 :     int index = NAMES_LC.indexOf(a.getName().toLowerCase());
     211         151 :     return 0 <= index ? index : NAMES_LC.size();
     212             :   }
     213             : 
     214             :   @Override
     215             :   public final String toString() {
     216           1 :     StringBuilder bldr = new StringBuilder();
     217           1 :     bldr.append(getName()).append(" ");
     218           1 :     if (isExclusiveGroup()) {
     219           0 :       bldr.append("[exclusive] ");
     220             :     }
     221           1 :     bldr.append("[");
     222           1 :     Iterator<PermissionRule> it = getRules().iterator();
     223           1 :     while (it.hasNext()) {
     224           0 :       bldr.append(it.next());
     225           0 :       if (it.hasNext()) {
     226           0 :         bldr.append(", ");
     227             :       }
     228             :     }
     229           1 :     bldr.append("]");
     230           1 :     return bldr.toString();
     231             :   }
     232             : 
     233             :   protected abstract Builder autoToBuilder();
     234             : 
     235             :   public Builder toBuilder() {
     236         153 :     Builder b = autoToBuilder();
     237         153 :     getRules().stream().map(PermissionRule::toBuilder).forEach(r -> b.add(r));
     238         153 :     return b;
     239             :   }
     240             : 
     241             :   @AutoValue.Builder
     242             :   public abstract static class Builder {
     243             :     private final List<PermissionRule.Builder> rulesBuilders;
     244             : 
     245         153 :     Builder() {
     246         153 :       rulesBuilders = new ArrayList<>();
     247         153 :     }
     248             : 
     249             :     public abstract Builder setName(String value);
     250             : 
     251             :     public abstract String getName();
     252             : 
     253             :     public abstract Builder setExclusiveGroup(boolean value);
     254             : 
     255             :     public Builder modifyRules(Consumer<List<PermissionRule.Builder>> modification) {
     256         153 :       modification.accept(rulesBuilders);
     257         153 :       return this;
     258             :     }
     259             : 
     260             :     public Builder add(PermissionRule.Builder rule) {
     261         153 :       return modifyRules(r -> r.add(rule));
     262             :     }
     263             : 
     264             :     public Builder remove(PermissionRule rule) {
     265           2 :       if (rule != null) {
     266           2 :         return removeRule(rule.getGroup());
     267             :       }
     268           0 :       return this;
     269             :     }
     270             : 
     271             :     public Builder removeRule(GroupReference group) {
     272          12 :       return modifyRules(rules -> rules.removeIf(rule -> sameGroup(rule.build(), group)));
     273             :     }
     274             : 
     275             :     public Builder clearRules() {
     276          11 :       return modifyRules(r -> r.clear());
     277             :     }
     278             : 
     279             :     public Permission build() {
     280         153 :       setRules(
     281         153 :           rulesBuilders.stream().map(PermissionRule.Builder::build).collect(toImmutableList()));
     282         153 :       return autoBuild();
     283             :     }
     284             : 
     285             :     public List<PermissionRule.Builder> getRulesBuilders() {
     286           1 :       return rulesBuilders;
     287             :     }
     288             : 
     289             :     protected abstract ImmutableList<PermissionRule> getRules();
     290             : 
     291             :     protected abstract Builder setRules(ImmutableList<PermissionRule> rules);
     292             : 
     293             :     protected abstract Permission autoBuild();
     294             :   }
     295             : }

Generated by: LCOV version 1.16+git.20220603.dfeb750