com.google.gerrit.entities.PermissionRule Maven / Gradle / Ivy
 The newest version!
        
        // Copyright (C) 2010 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.entities;
import com.google.auto.value.AutoValue;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
@AutoValue
public abstract class PermissionRule implements Comparable {
  public static final boolean DEF_FORCE = false;
  public enum Action {
    ALLOW,
    DENY,
    BLOCK,
    INTERACTIVE,
    BATCH
  }
  public abstract Action getAction();
  public abstract boolean getForce();
  public abstract int getMin();
  public abstract int getMax();
  public abstract GroupReference getGroup();
  public static PermissionRule.Builder builder(GroupReference group) {
    return builder().setGroup(group);
  }
  public static PermissionRule create(GroupReference group) {
    return builder().setGroup(group).build();
  }
  protected static Builder builder() {
    return new AutoValue_PermissionRule.Builder()
        .setMin(0)
        .setMax(0)
        .setAction(Action.ALLOW)
        .setForce(DEF_FORCE);
  }
  static PermissionRule merge(PermissionRule src, PermissionRule dest) {
    PermissionRule.Builder result = dest.toBuilder();
    if (dest.getAction() != src.getAction()) {
      if (dest.getAction() == Action.BLOCK || src.getAction() == Action.BLOCK) {
        result.setAction(Action.BLOCK);
      } else if (dest.getAction() == Action.DENY || src.getAction() == Action.DENY) {
        result.setAction(Action.DENY);
      } else if (dest.getAction() == Action.BATCH || src.getAction() == Action.BATCH) {
        result.setAction(Action.BATCH);
      }
    }
    result.setForce(dest.getForce() || src.getForce());
    result.setRange(Math.min(dest.getMin(), src.getMin()), Math.max(dest.getMax(), src.getMax()));
    return result.build();
  }
  public boolean isDeny() {
    return getAction() == Action.DENY;
  }
  public boolean isBlock() {
    return getAction() == Action.BLOCK;
  }
  @Override
  public int compareTo(PermissionRule o) {
    int cmp = action(this) - action(o);
    if (cmp == 0) {
      cmp = range(o) - range(this);
    }
    if (cmp == 0) {
      cmp = group(this).compareTo(group(o));
    }
    return cmp;
  }
  private static int action(PermissionRule a) {
    switch (a.getAction()) {
      case DENY:
        return 0;
      case ALLOW:
      case BATCH:
      case BLOCK:
      case INTERACTIVE:
      default:
        return 1 + a.getAction().ordinal();
    }
  }
  private static int range(PermissionRule a) {
    return Math.abs(a.getMin()) + Math.abs(a.getMax());
  }
  private static String group(PermissionRule a) {
    return a.getGroup().getName() != null ? a.getGroup().getName() : "";
  }
  @Override
  public final String toString() {
    return asString(true);
  }
  public String asString(boolean canUseRange) {
    StringBuilder r = new StringBuilder();
    switch (getAction()) {
      case ALLOW -> {}
      case DENY -> r.append("deny ");
      case BLOCK -> r.append("block ");
      case INTERACTIVE -> r.append("interactive ");
      case BATCH -> r.append("batch ");
    }
    if (getForce()) {
      r.append("+force ");
    }
    if (canUseRange && (getMin() != 0 || getMax() != 0)) {
      if (0 <= getMin()) {
        r.append('+');
      }
      r.append(getMin());
      r.append("..");
      if (0 <= getMax()) {
        r.append('+');
      }
      r.append(getMax());
      r.append(' ');
    }
    r.append(getGroup().toConfigValue());
    return r.toString();
  }
  public static PermissionRule fromString(String src, boolean mightUseRange) {
    final String orig = src;
    final PermissionRule.Builder rule = PermissionRule.builder();
    src = src.trim();
    if (src.startsWith("deny ")) {
      rule.setAction(Action.DENY);
      src = src.substring("deny ".length()).trim();
    } else if (src.startsWith("block ")) {
      rule.setAction(Action.BLOCK);
      src = src.substring("block ".length()).trim();
    } else if (src.startsWith("interactive ")) {
      rule.setAction(Action.INTERACTIVE);
      src = src.substring("interactive ".length()).trim();
    } else if (src.startsWith("batch ")) {
      rule.setAction(Action.BATCH);
      src = src.substring("batch ".length()).trim();
    }
    if (src.startsWith("+force ")) {
      rule.setForce(true);
      src = src.substring("+force ".length()).trim();
    }
    if (mightUseRange && !GroupReference.isGroupReference(src)) {
      int sp = src.indexOf(' ');
      String range = src.substring(0, sp);
      if (range.matches("^([+-]?\\d+)\\.\\.([+-]?\\d+)$")) {
        int dotdot = range.indexOf("..");
        int min = parseInt(range.substring(0, dotdot));
        int max = parseInt(range.substring(dotdot + 2));
        if (min > max) {
          throw new IllegalArgumentException("Invalid range in rule: " + orig);
        }
        rule.setRange(min, max);
      } else {
        throw new IllegalArgumentException("Invalid range in rule: " + orig);
      }
      src = src.substring(sp + 1).trim();
    }
    String groupName = GroupReference.extractGroupName(src);
    if (groupName != null) {
      GroupReference group = GroupReference.create(groupName);
      rule.setGroup(group);
    } else {
      throw new IllegalArgumentException("Rule must include group: " + orig);
    }
    return rule.build();
  }
  public boolean hasRange() {
    return getMin() != 0 || getMax() != 0;
  }
  public static int parseInt(String value) {
    if (value.startsWith("+")) {
      value = value.substring(1);
    }
    return Integer.parseInt(value);
  }
  public abstract Builder toBuilder();
  @AutoValue.Builder
  public abstract static class Builder {
    @CanIgnoreReturnValue
    public Builder setDeny() {
      return setAction(Action.DENY);
    }
    @CanIgnoreReturnValue
    public Builder setBlock() {
      return setAction(Action.BLOCK);
    }
    @CanIgnoreReturnValue
    public Builder setRange(int newMin, int newMax) {
      if (newMax < newMin) {
        setMin(newMax);
        setMax(newMin);
      } else {
        setMin(newMin);
        setMax(newMax);
      }
      return this;
    }
    public abstract Builder setAction(Action action);
    public abstract Builder setGroup(GroupReference groupReference);
    public abstract Builder setForce(boolean newForce);
    public abstract Builder setMin(int min);
    public abstract Builder setMax(int max);
    public abstract GroupReference getGroup();
    public abstract PermissionRule build();
  }
}
     © 2015 - 2025 Weber Informatics LLC | Privacy Policy