Line data Source code
1 : // Copyright (C) 2017 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.server.permissions; 16 : 17 : import com.google.gerrit.extensions.api.access.CoreOrPluginProjectPermission; 18 : import com.google.gerrit.extensions.api.access.GlobalOrPluginPermission; 19 : import com.google.gerrit.extensions.conditions.BooleanCondition; 20 : import com.google.gerrit.extensions.conditions.PrivateInternals_BooleanCondition; 21 : import com.google.gerrit.server.CurrentUser; 22 : import java.util.Objects; 23 : 24 : /** {@link BooleanCondition} to evaluate a permission. */ 25 63 : public abstract class PermissionBackendCondition 26 : extends PrivateInternals_BooleanCondition.SubclassOnlyInCoreServer { 27 : Boolean value; 28 : 29 : /** 30 : * Assign a specific {@code testOrFalse} result to this condition. 31 : * 32 : * <p>By setting the condition to a specific value the condition will bypass calling {@link 33 : * PermissionBackend} during {@code value()}, and immediately return the set value instead. 34 : * 35 : * @param val value to return from {@code value()}. 36 : */ 37 : public void set(boolean val) { 38 57 : value = val; 39 57 : } 40 : 41 : @Override 42 : public abstract String toString(); 43 : 44 : @Override 45 : public boolean evaluatesTrivially() { 46 : // PermissionBackendCondition needs to contact PermissionBackend so trivial evaluation is not 47 : // possible. 48 57 : return false; 49 : } 50 : 51 : @Override 52 : public BooleanCondition reduce() { 53 : // No reductions can be made 54 57 : return this; 55 : } 56 : 57 : public static class WithUser extends PermissionBackendCondition { 58 : private final PermissionBackend.WithUser impl; 59 : private final GlobalOrPluginPermission perm; 60 : private final CurrentUser user; 61 : 62 : public WithUser( 63 63 : PermissionBackend.WithUser impl, GlobalOrPluginPermission perm, CurrentUser user) { 64 63 : this.impl = impl; 65 63 : this.perm = perm; 66 63 : this.user = user; 67 63 : } 68 : 69 : public PermissionBackend.WithUser withUser() { 70 0 : return impl; 71 : } 72 : 73 : public GlobalOrPluginPermission permission() { 74 0 : return perm; 75 : } 76 : 77 : @Override 78 : public boolean value() { 79 14 : return value != null ? value : impl.testOrFalse(perm); 80 : } 81 : 82 : @Override 83 : public String toString() { 84 0 : return "PermissionBackendCondition.WithUser(" + perm + ")"; 85 : } 86 : 87 : @Override 88 : public int hashCode() { 89 15 : return Objects.hash(perm, hashForUser(user)); 90 : } 91 : 92 : @Override 93 : public boolean equals(Object obj) { 94 1 : if (!(obj instanceof WithUser)) { 95 0 : return false; 96 : } 97 1 : WithUser other = (WithUser) obj; 98 1 : return Objects.equals(perm, other.perm) && usersAreEqual(user, other.user); 99 : } 100 : } 101 : 102 : public static class ForProject extends PermissionBackendCondition { 103 : private final PermissionBackend.ForProject impl; 104 : private final CoreOrPluginProjectPermission perm; 105 : private final CurrentUser user; 106 : 107 : public ForProject( 108 58 : PermissionBackend.ForProject impl, CoreOrPluginProjectPermission perm, CurrentUser user) { 109 58 : this.impl = impl; 110 58 : this.perm = perm; 111 58 : this.user = user; 112 58 : } 113 : 114 : public PermissionBackend.ForProject project() { 115 0 : return impl; 116 : } 117 : 118 : public CoreOrPluginProjectPermission permission() { 119 0 : return perm; 120 : } 121 : 122 : @Override 123 : public boolean value() { 124 57 : return value != null ? value : impl.testOrFalse(perm); 125 : } 126 : 127 : @Override 128 : public String toString() { 129 0 : return "PermissionBackendCondition.ForProject(" + perm + ")"; 130 : } 131 : 132 : @Override 133 : public int hashCode() { 134 58 : return Objects.hash(perm, impl.resourcePath(), hashForUser(user)); 135 : } 136 : 137 : @Override 138 : public boolean equals(Object obj) { 139 2 : if (!(obj instanceof ForProject)) { 140 0 : return false; 141 : } 142 2 : ForProject other = (ForProject) obj; 143 2 : return Objects.equals(perm, other.perm) 144 2 : && Objects.equals(impl.resourcePath(), other.impl.resourcePath()) 145 2 : && usersAreEqual(user, other.user); 146 : } 147 : } 148 : 149 : public static class ForRef extends PermissionBackendCondition { 150 : private final PermissionBackend.ForRef impl; 151 : private final RefPermission perm; 152 : private final CurrentUser user; 153 : 154 58 : public ForRef(PermissionBackend.ForRef impl, RefPermission perm, CurrentUser user) { 155 58 : this.impl = impl; 156 58 : this.perm = perm; 157 58 : this.user = user; 158 58 : } 159 : 160 : public PermissionBackend.ForRef ref() { 161 0 : return impl; 162 : } 163 : 164 : public RefPermission permission() { 165 0 : return perm; 166 : } 167 : 168 : @Override 169 : public boolean value() { 170 57 : return value != null ? value : impl.testOrFalse(perm); 171 : } 172 : 173 : @Override 174 : public String toString() { 175 0 : return "PermissionBackendCondition.ForRef(" + perm + ")"; 176 : } 177 : 178 : @Override 179 : public int hashCode() { 180 58 : return Objects.hash(perm, impl.resourcePath(), hashForUser(user)); 181 : } 182 : 183 : @Override 184 : public boolean equals(Object obj) { 185 7 : if (!(obj instanceof ForRef)) { 186 0 : return false; 187 : } 188 7 : ForRef other = (ForRef) obj; 189 7 : return Objects.equals(perm, other.perm) 190 7 : && Objects.equals(impl.resourcePath(), other.impl.resourcePath()) 191 7 : && usersAreEqual(user, other.user); 192 : } 193 : } 194 : 195 : public static class ForChange extends PermissionBackendCondition { 196 : private final PermissionBackend.ForChange impl; 197 : private final ChangePermissionOrLabel perm; 198 : private final CurrentUser user; 199 : 200 : public ForChange( 201 58 : PermissionBackend.ForChange impl, ChangePermissionOrLabel perm, CurrentUser user) { 202 58 : this.impl = impl; 203 58 : this.perm = perm; 204 58 : this.user = user; 205 58 : } 206 : 207 : public PermissionBackend.ForChange change() { 208 0 : return impl; 209 : } 210 : 211 : public ChangePermissionOrLabel permission() { 212 0 : return perm; 213 : } 214 : 215 : @Override 216 : public boolean value() { 217 57 : return value != null ? value : impl.testOrFalse(perm); 218 : } 219 : 220 : @Override 221 : public String toString() { 222 0 : return "PermissionBackendCondition.ForChange(" + perm + ")"; 223 : } 224 : 225 : @Override 226 : public int hashCode() { 227 58 : return Objects.hash(perm, impl.resourcePath(), hashForUser(user)); 228 : } 229 : 230 : @Override 231 : public boolean equals(Object obj) { 232 58 : if (!(obj instanceof ForChange)) { 233 0 : return false; 234 : } 235 58 : ForChange other = (ForChange) obj; 236 58 : return Objects.equals(perm, other.perm) 237 58 : && Objects.equals(impl.resourcePath(), other.impl.resourcePath()) 238 58 : && usersAreEqual(user, other.user); 239 : } 240 : } 241 : 242 : private static int hashForUser(CurrentUser user) { 243 58 : if (!user.isIdentifiedUser()) { 244 0 : return 0; 245 : } 246 58 : return user.getAccountId().get(); 247 : } 248 : 249 : private static boolean usersAreEqual(CurrentUser user1, CurrentUser user2) { 250 58 : if (user1.isIdentifiedUser() && user2.isIdentifiedUser()) { 251 58 : return user1.getAccountId().equals(user2.getAccountId()); 252 : } 253 0 : return false; 254 : } 255 : }