LCOV - code coverage report
Current view: top level - entities - AccessSection.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 53 55 96.4 %
Date: 2022-11-19 15:00:39 Functions: 22 23 95.7 %

          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             : import static java.util.Objects.requireNonNull;
      19             : 
      20             : import com.google.auto.value.AutoValue;
      21             : import com.google.auto.value.extension.memoized.Memoized;
      22             : import com.google.common.collect.ImmutableList;
      23             : import com.google.gerrit.common.Nullable;
      24             : import java.util.ArrayList;
      25             : import java.util.List;
      26             : import java.util.Optional;
      27             : import java.util.function.Consumer;
      28             : import java.util.regex.Pattern;
      29             : 
      30             : /** Portion of a {@link Project} describing access rules. */
      31             : @AutoValue
      32         153 : public abstract class AccessSection implements Comparable<AccessSection> {
      33             :   /** Special name given to the global capabilities; not a valid reference. */
      34             :   public static final String GLOBAL_CAPABILITIES = "GLOBAL_CAPABILITIES";
      35             :   /** Pattern that matches all references in a project. */
      36             :   public static final String ALL = "refs/*";
      37             : 
      38             :   /** Pattern that matches all branches in a project. */
      39             :   public static final String HEADS = "refs/heads/*";
      40             : 
      41             :   /** Prefix that triggers a regular expression pattern. */
      42             :   public static final String REGEX_PREFIX = "^";
      43             : 
      44             :   /** Name of the access section. It could be a ref pattern or something else. */
      45             :   public abstract String getName();
      46             : 
      47             :   /**
      48             :    * A compiled regular expression in case {@link #getName()} is a regular expression. This is
      49             :    * memoized to save callers from compiling patterns for every use.
      50             :    */
      51             :   @Memoized
      52             :   public Optional<Pattern> getNamePattern() {
      53         145 :     if (isValidRefSectionName(getName())
      54         145 :         && getName().startsWith(REGEX_PREFIX)
      55           1 :         && !getName().contains("${")) {
      56           1 :       return Optional.of(Pattern.compile(getName()));
      57             :     }
      58         145 :     return Optional.empty();
      59             :   }
      60             : 
      61             :   public abstract ImmutableList<Permission> getPermissions();
      62             : 
      63             :   public static AccessSection create(String name) {
      64           3 :     return builder(name).build();
      65             :   }
      66             : 
      67             :   public static Builder builder(String name) {
      68         153 :     return new AutoValue_AccessSection.Builder().setName(name).setPermissions(ImmutableList.of());
      69             :   }
      70             : 
      71             :   /** Returns true if the name is likely to be a valid reference section name. */
      72             :   public static boolean isValidRefSectionName(String name) {
      73         151 :     return name.startsWith("refs/") || name.startsWith("^refs/");
      74             :   }
      75             : 
      76             :   @Nullable
      77             :   public Permission getPermission(String name) {
      78         152 :     requireNonNull(name);
      79         152 :     for (Permission p : getPermissions()) {
      80         152 :       if (p.getName().equalsIgnoreCase(name)) {
      81         149 :         return p;
      82             :       }
      83         152 :     }
      84         152 :     return null;
      85             :   }
      86             : 
      87             :   @Override
      88             :   public final int compareTo(AccessSection o) {
      89         151 :     return comparePattern().compareTo(o.comparePattern());
      90             :   }
      91             : 
      92             :   private String comparePattern() {
      93         151 :     if (getName().startsWith(REGEX_PREFIX)) {
      94           0 :       return getName().substring(REGEX_PREFIX.length());
      95             :     }
      96         151 :     return getName();
      97             :   }
      98             : 
      99             :   @Override
     100             :   public final String toString() {
     101           0 :     return "AccessSection[" + getName() + "]";
     102             :   }
     103             : 
     104             :   public Builder toBuilder() {
     105         151 :     Builder b = autoToBuilder();
     106         151 :     b.getPermissions().stream().map(Permission::toBuilder).forEach(p -> b.addPermission(p));
     107         151 :     return b;
     108             :   }
     109             : 
     110             :   protected abstract Builder autoToBuilder();
     111             : 
     112             :   @AutoValue.Builder
     113             :   public abstract static class Builder {
     114             :     private final List<Permission.Builder> permissionBuilders;
     115             : 
     116         153 :     protected Builder() {
     117         153 :       permissionBuilders = new ArrayList<>();
     118         153 :     }
     119             : 
     120             :     public abstract Builder setName(String name);
     121             : 
     122             :     public abstract String getName();
     123             : 
     124             :     public Builder modifyPermissions(Consumer<List<Permission.Builder>> modification) {
     125         153 :       modification.accept(permissionBuilders);
     126         153 :       return this;
     127             :     }
     128             : 
     129             :     public Builder addPermission(Permission.Builder permission) {
     130         153 :       requireNonNull(permission, "permission must be non-null");
     131         153 :       return modifyPermissions(p -> p.add(permission));
     132             :     }
     133             : 
     134             :     public Builder remove(Permission.Builder permission) {
     135           6 :       requireNonNull(permission, "permission must be non-null");
     136           6 :       return removePermission(permission.getName());
     137             :     }
     138             : 
     139             :     public Builder removePermission(String name) {
     140           9 :       requireNonNull(name, "name must be non-null");
     141           9 :       return modifyPermissions(
     142           9 :           p -> p.removeIf(permissionBuilder -> name.equalsIgnoreCase(permissionBuilder.getName())));
     143             :     }
     144             : 
     145             :     public Permission.Builder upsertPermission(String permissionName) {
     146         152 :       requireNonNull(permissionName, "permissionName must be non-null");
     147             : 
     148         152 :       Optional<Permission.Builder> maybePermission =
     149         152 :           permissionBuilders.stream()
     150         152 :               .filter(p -> p.getName().equalsIgnoreCase(permissionName))
     151         152 :               .findAny();
     152         152 :       if (maybePermission.isPresent()) {
     153         152 :         return maybePermission.get();
     154             :       }
     155             : 
     156         152 :       Permission.Builder permission = Permission.builder(permissionName);
     157         152 :       modifyPermissions(p -> p.add(permission));
     158         152 :       return permission;
     159             :     }
     160             : 
     161             :     public AccessSection build() {
     162         153 :       setPermissions(
     163         153 :           permissionBuilders.stream().map(Permission.Builder::build).collect(toImmutableList()));
     164         153 :       if (getPermissions().size()
     165         153 :           > getPermissions().stream()
     166         153 :               .map(Permission::getName)
     167         153 :               .map(String::toLowerCase)
     168         153 :               .distinct()
     169         153 :               .count()) {
     170           1 :         throw new IllegalArgumentException("duplicate permissions: " + getPermissions());
     171             :       }
     172         153 :       return autoBuild();
     173             :     }
     174             : 
     175             :     protected abstract AccessSection autoBuild();
     176             : 
     177             :     protected abstract ImmutableList<Permission> getPermissions();
     178             : 
     179             :     abstract Builder setPermissions(ImmutableList<Permission> permissions);
     180             :   }
     181             : }

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