summaryrefslogtreecommitdiffstats
path: root/java/com/google/gerrit/server/permissions/PermissionBackendCondition.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/google/gerrit/server/permissions/PermissionBackendCondition.java')
-rw-r--r--java/com/google/gerrit/server/permissions/PermissionBackendCondition.java253
1 files changed, 253 insertions, 0 deletions
diff --git a/java/com/google/gerrit/server/permissions/PermissionBackendCondition.java b/java/com/google/gerrit/server/permissions/PermissionBackendCondition.java
new file mode 100644
index 0000000000..1b6b0878a8
--- /dev/null
+++ b/java/com/google/gerrit/server/permissions/PermissionBackendCondition.java
@@ -0,0 +1,253 @@
+// Copyright (C) 2017 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 com.google.gerrit.extensions.api.access.GlobalOrPluginPermission;
+import com.google.gerrit.extensions.conditions.BooleanCondition;
+import com.google.gerrit.extensions.conditions.PrivateInternals_BooleanCondition;
+import com.google.gerrit.server.CurrentUser;
+import java.util.Objects;
+
+/** {@link BooleanCondition} to evaluate a permission. */
+public abstract class PermissionBackendCondition
+ extends PrivateInternals_BooleanCondition.SubclassOnlyInCoreServer {
+ Boolean value;
+
+ /**
+ * Assign a specific {@code testOrFalse} result to this condition.
+ *
+ * <p>By setting the condition to a specific value the condition will bypass calling {@link
+ * PermissionBackend} during {@code value()}, and immediately return the set value instead.
+ *
+ * @param val value to return from {@code value()}.
+ */
+ public void set(boolean val) {
+ value = val;
+ }
+
+ @Override
+ public abstract String toString();
+
+ @Override
+ public boolean evaluatesTrivially() {
+ // PermissionBackendCondition needs to contact PermissionBackend so trivial evaluation is not
+ // possible.
+ return false;
+ }
+
+ @Override
+ public BooleanCondition reduce() {
+ // No reductions can be made
+ return this;
+ }
+
+ public static class WithUser extends PermissionBackendCondition {
+ private final PermissionBackend.WithUser impl;
+ private final GlobalOrPluginPermission perm;
+ private final CurrentUser user;
+
+ public WithUser(
+ PermissionBackend.WithUser impl, GlobalOrPluginPermission perm, CurrentUser user) {
+ this.impl = impl;
+ this.perm = perm;
+ this.user = user;
+ }
+
+ public PermissionBackend.WithUser withUser() {
+ return impl;
+ }
+
+ public GlobalOrPluginPermission permission() {
+ return perm;
+ }
+
+ @Override
+ public boolean value() {
+ return value != null ? value : impl.testOrFalse(perm);
+ }
+
+ @Override
+ public String toString() {
+ return "PermissionBackendCondition.WithUser(" + perm + ")";
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(perm, hashForUser(user));
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof WithUser)) {
+ return false;
+ }
+ WithUser other = (WithUser) obj;
+ return Objects.equals(perm, other.perm) && usersAreEqual(user, other.user);
+ }
+ }
+
+ public static class ForProject extends PermissionBackendCondition {
+ private final PermissionBackend.ForProject impl;
+ private final ProjectPermission perm;
+ private final CurrentUser user;
+
+ public ForProject(PermissionBackend.ForProject impl, ProjectPermission perm, CurrentUser user) {
+ this.impl = impl;
+ this.perm = perm;
+ this.user = user;
+ }
+
+ public PermissionBackend.ForProject project() {
+ return impl;
+ }
+
+ public ProjectPermission permission() {
+ return perm;
+ }
+
+ @Override
+ public boolean value() {
+ return value != null ? value : impl.testOrFalse(perm);
+ }
+
+ @Override
+ public String toString() {
+ return "PermissionBackendCondition.ForProject(" + perm + ")";
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(perm, impl.resourcePath(), hashForUser(user));
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof ForProject)) {
+ return false;
+ }
+ ForProject other = (ForProject) obj;
+ return Objects.equals(perm, other.perm)
+ && Objects.equals(impl.resourcePath(), other.impl.resourcePath())
+ && usersAreEqual(user, other.user);
+ }
+ }
+
+ public static class ForRef extends PermissionBackendCondition {
+ private final PermissionBackend.ForRef impl;
+ private final RefPermission perm;
+ private final CurrentUser user;
+
+ public ForRef(PermissionBackend.ForRef impl, RefPermission perm, CurrentUser user) {
+ this.impl = impl;
+ this.perm = perm;
+ this.user = user;
+ }
+
+ public PermissionBackend.ForRef ref() {
+ return impl;
+ }
+
+ public RefPermission permission() {
+ return perm;
+ }
+
+ @Override
+ public boolean value() {
+ return value != null ? value : impl.testOrFalse(perm);
+ }
+
+ @Override
+ public String toString() {
+ return "PermissionBackendCondition.ForRef(" + perm + ")";
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(perm, impl.resourcePath(), hashForUser(user));
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof ForRef)) {
+ return false;
+ }
+ ForRef other = (ForRef) obj;
+ return Objects.equals(perm, other.perm)
+ && Objects.equals(impl.resourcePath(), other.impl.resourcePath())
+ && usersAreEqual(user, other.user);
+ }
+ }
+
+ public static class ForChange extends PermissionBackendCondition {
+ private final PermissionBackend.ForChange impl;
+ private final ChangePermissionOrLabel perm;
+ private final CurrentUser user;
+
+ public ForChange(
+ PermissionBackend.ForChange impl, ChangePermissionOrLabel perm, CurrentUser user) {
+ this.impl = impl;
+ this.perm = perm;
+ this.user = user;
+ }
+
+ public PermissionBackend.ForChange change() {
+ return impl;
+ }
+
+ public ChangePermissionOrLabel permission() {
+ return perm;
+ }
+
+ @Override
+ public boolean value() {
+ return value != null ? value : impl.testOrFalse(perm);
+ }
+
+ @Override
+ public String toString() {
+ return "PermissionBackendCondition.ForChange(" + perm + ")";
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(perm, impl.resourcePath(), hashForUser(user));
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof ForChange)) {
+ return false;
+ }
+ ForChange other = (ForChange) obj;
+ return Objects.equals(perm, other.perm)
+ && Objects.equals(impl.resourcePath(), other.impl.resourcePath())
+ && usersAreEqual(user, other.user);
+ }
+ }
+
+ private static int hashForUser(CurrentUser user) {
+ if (!user.isIdentifiedUser()) {
+ return 0;
+ }
+ return user.getAccountId().get();
+ }
+
+ private static boolean usersAreEqual(CurrentUser user1, CurrentUser user2) {
+ if (user1.isIdentifiedUser() && user2.isIdentifiedUser()) {
+ return user1.getAccountId().equals(user2.getAccountId());
+ }
+ return false;
+ }
+}