[ all classes ]
[ com.acciente.oacc ]
Coverage Summary for Class: ResourceCreatePermissions (com.acciente.oacc)
Class | Method, % | Line, % |
---|---|---|
ResourceCreatePermissions | 100% (11/ 11) | 78.9% (60/ 76) |
ResourceCreatePermissions$ResourceCreatePermissionImpl | 92.9% (13/ 14) | 73.4% (58/ 79) |
total | 96% (24/ 25) | 76.1% (118/ 155) |
1 /*
2 * Copyright 2009-2018, Acciente LLC
3 *
4 * Acciente LLC licenses this file to you under the
5 * Apache License, Version 2.0 (the "License"); you
6 * may not use this file except in compliance with the
7 * License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in
12 * writing, software distributed under the License is
13 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
14 * OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing
16 * permissions and limitations under the License.
17 */
18 package com.acciente.oacc;
19
20 import com.acciente.oacc.ResourcePermissions.ResourcePermissionImpl;
21
22 import java.io.Serializable;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.concurrent.ConcurrentHashMap;
29 import java.util.concurrent.ConcurrentMap;
30
31 public class ResourceCreatePermissions {
32 // constants for the important system permissions with pre-defined semantics
33 private static final SysPermission SYSPERMISSION_CREATE = new SysPermission(-100, "*CREATE");
34 public static final String CREATE = SYSPERMISSION_CREATE.getPermissionName();
35
36 private static final Map<String, SysPermission> sysPermissionsByName;
37 private static final Map<Long, String> sysPermissionNamesById;
38 private static final List<String> sysPermissionNames;
39 private static final ConcurrentMap<String, ResourceCreatePermission> grantableCreatePermissionsByName;
40 private static final ConcurrentMap<String, ResourceCreatePermission> ungrantableCreatePermissionsByName;
41 private static final ConcurrentMap<ResourcePermission, ResourceCreatePermission> grantableCreatePermissionsByPostCreatePermission;
42 private static final ConcurrentMap<ResourcePermission, ResourceCreatePermission> ungrantableCreatePermissionsByPostCreatePermission;
43
44 static {
45 sysPermissionsByName = new HashMap<>();
46 sysPermissionsByName.put(CREATE, SYSPERMISSION_CREATE);
47
48 sysPermissionNamesById = new HashMap<>(sysPermissionsByName.size());
49 for (SysPermission sysPermission : sysPermissionsByName.values()) {
50 sysPermissionNamesById.put(sysPermission.getSystemPermissionId(), sysPermission.getPermissionName());
51 }
52
53 sysPermissionNames = Collections.unmodifiableList(new ArrayList<>(sysPermissionNamesById.values()));
54
55 grantableCreatePermissionsByName = new ConcurrentHashMap<>(sysPermissionsByName.size());
56 ungrantableCreatePermissionsByName = new ConcurrentHashMap<>(sysPermissionsByName.size());
57 grantableCreatePermissionsByPostCreatePermission = new ConcurrentHashMap<>();
58 ungrantableCreatePermissionsByPostCreatePermission = new ConcurrentHashMap<>();
59 }
60
61 public static List<String> getSysPermissionNames() {
62 return sysPermissionNames;
63 }
64
65 public static String getSysPermissionName(long systemPermissionId) {
66 final String sysPermissionName = sysPermissionNamesById.get(systemPermissionId);
67
68 if (sysPermissionName == null) {
69 throw new IllegalArgumentException("Invalid system permission ID: " + systemPermissionId);
70 }
71
72 return sysPermissionName;
73 }
74
75 /**
76 * Creates a new resource create permission with no post-create permissions (i.e. only resource creation),
77 * but with the option to grant the create-permission to another resource
78 *
79 * @param sysPermissionName the name of the system permission
80 * @return a resource create permission
81 */
82 public static ResourceCreatePermission getInstanceWithGrantOption(String sysPermissionName) {
83 sysPermissionName = getCanonicalSysPermissionName(sysPermissionName);
84
85 ResourceCreatePermission resourceCreatePermission = grantableCreatePermissionsByName.get(sysPermissionName);
86
87 if (resourceCreatePermission == null) {
88 resourceCreatePermission = new ResourceCreatePermissionImpl(sysPermissionName, true);
89 final ResourceCreatePermission cachedInstance
90 = grantableCreatePermissionsByName.putIfAbsent(sysPermissionName, resourceCreatePermission);
91 if (cachedInstance != null) {
92 resourceCreatePermission = cachedInstance;
93 }
94 }
95
96 return resourceCreatePermission;
97 }
98
99
100 /**
101 * Creates a new resource create permission with no post-create permissions (i.e. only resource creation)
102 * without the option to grant the create-permission to another resource
103 *
104 * @param sysPermissionName the name of the system permission
105 * @return a resource create permission
106 */
107 public static ResourceCreatePermission getInstance(String sysPermissionName) {
108 sysPermissionName = getCanonicalSysPermissionName(sysPermissionName);
109
110 ResourceCreatePermission resourceCreatePermission = ungrantableCreatePermissionsByName.get(sysPermissionName);
111
112 if (resourceCreatePermission == null) {
113 resourceCreatePermission = new ResourceCreatePermissionImpl(sysPermissionName, false);
114 final ResourceCreatePermission cachedInstance
115 = ungrantableCreatePermissionsByName.putIfAbsent(sysPermissionName, resourceCreatePermission);
116 if (cachedInstance != null) {
117 resourceCreatePermission = cachedInstance;
118 }
119 }
120
121 return resourceCreatePermission;
122 }
123
124 /**
125 * Creates a new resource create permission with the specified post-create permission
126 * without the option to grant the create-permission to another resource
127 *
128 * @param postCreateResourcePermission the post-create resource permission
129 * @return a resource create permission
130 */
131 public static ResourceCreatePermission getInstance(ResourcePermission postCreateResourcePermission) {
132 assertPostCreatePermissionSpecified(postCreateResourcePermission);
133 // normalize post create permission before cache lookup, to prevent hash collisions from rogue implementations
134 postCreateResourcePermission = ResourcePermissions.getInstance(postCreateResourcePermission);
135
136 ResourceCreatePermission resourceCreatePermission
137 = ungrantableCreatePermissionsByPostCreatePermission.get(postCreateResourcePermission);
138
139 if (resourceCreatePermission == null) {
140 resourceCreatePermission = new ResourceCreatePermissionImpl((ResourcePermissionImpl) postCreateResourcePermission, false);
141 final ResourceCreatePermission cachedInstance
142 = ungrantableCreatePermissionsByPostCreatePermission.putIfAbsent(postCreateResourcePermission, resourceCreatePermission);
143 if (cachedInstance != null) {
144 resourceCreatePermission = cachedInstance;
145 }
146 }
147
148 return resourceCreatePermission;
149 }
150
151 /**
152 * Creates a new resource create permission with the specified post-create permission,
153 * but with the option to grant the create-permission to another resource
154 *
155 * @param postCreateResourcePermission the post-create resource permission
156 * @return a resource create permission
157 */
158 public static ResourceCreatePermission getInstanceWithGrantOption(ResourcePermission postCreateResourcePermission) {
159 assertPostCreatePermissionSpecified(postCreateResourcePermission);
160 // normalize post create permission before cache lookup, to prevent hash collisions from rogue implementations
161 postCreateResourcePermission = ResourcePermissions.getInstance(postCreateResourcePermission);
162
163 ResourceCreatePermission resourceCreatePermission
164 = grantableCreatePermissionsByPostCreatePermission.get(postCreateResourcePermission);
165
166 if (resourceCreatePermission == null) {
167 resourceCreatePermission = new ResourceCreatePermissionImpl((ResourcePermissionImpl) postCreateResourcePermission, true);
168 final ResourceCreatePermission cachedInstance
169 = grantableCreatePermissionsByPostCreatePermission.putIfAbsent(postCreateResourcePermission, resourceCreatePermission);
170 if (cachedInstance != null) {
171 resourceCreatePermission = cachedInstance;
172 }
173 }
174
175 return resourceCreatePermission;
176 }
177
178 public static ResourceCreatePermission getInstance(ResourceCreatePermission resourceCreatePermission) {
179 if (resourceCreatePermission instanceof ResourceCreatePermissions.ResourceCreatePermissionImpl) {
180 return resourceCreatePermission;
181 }
182
183 final ResourceCreatePermission verifiedPermission;
184
185 if (resourceCreatePermission.isSystemPermission()) {
186 if (resourceCreatePermission.isWithGrantOption()) {
187 verifiedPermission = getInstanceWithGrantOption(resourceCreatePermission.getPermissionName());
188 }
189 else {
190 verifiedPermission = getInstance(resourceCreatePermission.getPermissionName());
191 }
192
193 // validate system permission name and id matched
194 if (verifiedPermission.getSystemPermissionId() != resourceCreatePermission.getSystemPermissionId()) {
195 throw new IllegalArgumentException("Invalid system permission id for resource create permission: "
196 + resourceCreatePermission);
197 }
198 }
199 else {
200 if (resourceCreatePermission.isWithGrantOption()) {
201 verifiedPermission = getInstanceWithGrantOption(ResourcePermissions.getInstance(resourceCreatePermission
202 .getPostCreateResourcePermission()));
203 }
204 else {
205 verifiedPermission = getInstance(ResourcePermissions.getInstance(resourceCreatePermission
206 .getPostCreateResourcePermission()));
207 }
208 }
209
210 return verifiedPermission;
211 }
212
213 private static String getCanonicalSysPermissionName(String permissionName) {
214 if (permissionName == null) {
215 throw new IllegalArgumentException("A system permission name is required");
216 }
217
218 permissionName = permissionName.trim();
219
220 if (permissionName.isEmpty()) {
221 throw new IllegalArgumentException("A system permission name is required");
222 }
223 return permissionName;
224 }
225
226 private static void assertPostCreatePermissionSpecified(ResourcePermission postCreateResourcePermission) {
227 if (postCreateResourcePermission == null) {
228 throw new IllegalArgumentException("A post create resource permission is required");
229 }
230 }
231
232 static class ResourceCreatePermissionImpl implements ResourceCreatePermission, Serializable {
233 private static final long serialVersionUID = 2L;
234
235 // permission data
236 private final long systemPermissionId;
237 private final String sysPermissionName;
238 private final ResourcePermissionImpl postCreateResourcePermission;
239 private final boolean withGrantOption;
240
241 private ResourceCreatePermissionImpl(String sysPermissionName,
242 boolean withGrantOption) {
243 SysPermission sysPermission = getSysPermission(sysPermissionName);
244
245 this.systemPermissionId = sysPermission.getSystemPermissionId();
246 this.sysPermissionName = sysPermission.getPermissionName();
247 this.postCreateResourcePermission = null;
248 this.withGrantOption = withGrantOption;
249 }
250
251 private ResourceCreatePermissionImpl(ResourcePermissionImpl postCreateResourcePermission,
252 boolean withGrantOption) {
253 this.systemPermissionId = 0;
254 this.sysPermissionName = null;
255 this.postCreateResourcePermission = postCreateResourcePermission;
256 this.withGrantOption = withGrantOption;
257 }
258
259 @Override
260 public boolean isSystemPermission() {
261 return systemPermissionId != 0;
262 }
263
264 @Override
265 public String getPermissionName() {
266 if (!isSystemPermission()) {
267 throw new IllegalArgumentException(
268 "No system permission name may be retrieved for non-system resource create permission: " + this + ", please check your code");
269 }
270 return sysPermissionName;
271 }
272
273 @Override
274 public long getSystemPermissionId() {
275 if (!isSystemPermission()) {
276 throw new IllegalArgumentException(
277 "No system permission ID may be retrieved for non-system resource create permission: " + this + ", please check your code");
278 }
279 return systemPermissionId;
280 }
281
282 @Override
283 public ResourcePermission getPostCreateResourcePermission() {
284 if (isSystemPermission()) {
285 throw new IllegalArgumentException(
286 "No post create resource permission may be retrieved for system resource create permission: " + this + ", please check your code");
287 }
288 return postCreateResourcePermission;
289 }
290
291 @Override
292 public boolean isWithGrantOption() {
293 return withGrantOption;
294 }
295
296 @Override
297 public boolean isGrantableFrom(ResourceCreatePermission other) {
298 if (other == null) {
299 return false;
300 }
301
302 if (!other.isWithGrantOption()) {
303 return false;
304 }
305
306 if (this.isSystemPermission() != other.isSystemPermission()) {
307 return false;
308 }
309
310 if (this.isSystemPermission()) {
311 return this.systemPermissionId == other.getSystemPermissionId();
312 }
313
314 if (this.postCreateResourcePermission.isWithGrantOption() && !other.getPostCreateResourcePermission().isWithGrantOption()) {
315 return false;
316 }
317
318 return this.postCreateResourcePermission.equalsIgnoreGrantOption(other.getPostCreateResourcePermission());
319 }
320
321 @Override
322 public boolean equals(Object other) {
323 if (this == other) {
324 return true;
325 }
326 if (other == null || getClass() != other.getClass()) {
327 return false;
328 }
329
330 ResourceCreatePermissionImpl otherResourceCreatePermission = (ResourceCreatePermissionImpl) other;
331
332 if (systemPermissionId != otherResourceCreatePermission.systemPermissionId) {
333 return false;
334 }
335 if (sysPermissionName != null
336 ? !sysPermissionName.equals(otherResourceCreatePermission.sysPermissionName)
337 : otherResourceCreatePermission.sysPermissionName != null) {
338 return false;
339 }
340 if (postCreateResourcePermission != null
341 ? !postCreateResourcePermission.equals(otherResourceCreatePermission.postCreateResourcePermission)
342 : otherResourceCreatePermission.postCreateResourcePermission != null) {
343 return false;
344 }
345 if (withGrantOption != otherResourceCreatePermission.withGrantOption) {
346 return false;
347 }
348
349 return true;
350 }
351
352 @Override
353 public boolean equalsIgnoreGrantOption(Object other) {
354 if (this == other) {
355 return true;
356 }
357 if (other == null || getClass() != other.getClass()) {
358 return false;
359 }
360
361 ResourceCreatePermissionImpl otherResourceCreatePermission = (ResourceCreatePermissionImpl) other;
362
363 if (systemPermissionId != otherResourceCreatePermission.systemPermissionId) {
364 return false;
365 }
366 if (sysPermissionName != null
367 ? !sysPermissionName.equals(otherResourceCreatePermission.sysPermissionName)
368 : otherResourceCreatePermission.sysPermissionName != null) {
369 return false;
370 }
371 if (postCreateResourcePermission != null
372 ? !postCreateResourcePermission.equals(otherResourceCreatePermission.postCreateResourcePermission)
373 : otherResourceCreatePermission.postCreateResourcePermission != null) {
374 return false;
375 }
376
377 return true;
378 }
379
380 @Override
381 public int hashCode() {
382 int result = (int) (systemPermissionId ^ (systemPermissionId >>> 32));
383 result = 31 * result + (sysPermissionName != null ? sysPermissionName.hashCode() : 0);
384 result = 31 * result + (postCreateResourcePermission != null ? postCreateResourcePermission.hashCode() : 0);
385 result = 31 * result + (withGrantOption ? 1 : 0);
386 return result;
387 }
388
389 @Override
390 public String toString() {
391 if (postCreateResourcePermission == null) {
392 return withGrantOption ? sysPermissionName + " /G" : sysPermissionName;
393 }
394 else {
395 return "[" + postCreateResourcePermission.toString() + "]" + (withGrantOption ? " /G" : "");
396 }
397 }
398
399 // private static helper method to convert a sys permission name to a sys permission object
400
401 private static SysPermission getSysPermission(String permissionName) {
402 if (permissionName == null) {
403 throw new IllegalArgumentException("A system permission name is required");
404 }
405
406 final String trimmedPermissionName = permissionName.trim();
407
408 if (trimmedPermissionName.isEmpty()) {
409 throw new IllegalArgumentException("A system permission name is required");
410 }
411
412 final SysPermission sysPermission = sysPermissionsByName.get(trimmedPermissionName);
413
414 if (sysPermission == null) {
415 throw new IllegalArgumentException("Invalid system permission name: " + trimmedPermissionName);
416 }
417
418 return sysPermission;
419 }
420 }
421 }