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