[ all classes ]
[ com.acciente.oacc ]
Coverage Summary for Class: ResourcePermissions (com.acciente.oacc)
Class | Method, % | Line, % |
---|---|---|
ResourcePermissions | 88.9% (8/ 9) | 91.9% (57/ 62) |
ResourcePermissions$ResourcePermissionImpl | 86.7% (13/ 15) | 83.3% (50/ 60) |
total | 87.5% (21/ 24) | 87.7% (107/ 122) |
1 /*
2 * Copyright 2009-2017, 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 java.io.Serializable;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.concurrent.ConcurrentHashMap;
27 import java.util.concurrent.ConcurrentMap;
28
29 public class ResourcePermissions {
30 // constants for the important system permissions with pre-defined semantics
31 private static final SysPermission SYSPERMISSION_INHERIT = new SysPermission(-101, "*INHERIT");
32 public static final String INHERIT = SYSPERMISSION_INHERIT.getPermissionName();
33 private static final SysPermission SYSPERMISSION_IMPERSONATE = new SysPermission(-102, "*IMPERSONATE");
34 public static final String IMPERSONATE = SYSPERMISSION_IMPERSONATE.getPermissionName();
35 private static final SysPermission SYSPERMISSION_RESET_CREDENTIALS = new SysPermission(-103, "*RESET-CREDENTIALS");
36 public static final String RESET_CREDENTIALS = SYSPERMISSION_RESET_CREDENTIALS.getPermissionName();
37 private static final SysPermission SYSPERMISSION_DELETE = new SysPermission(-104, "*DELETE");
38 public static final String DELETE = SYSPERMISSION_DELETE.getPermissionName();
39 private static final SysPermission SYSPERMISSION_QUERY = new SysPermission(-105, "*QUERY");
40 public static final String QUERY = SYSPERMISSION_QUERY.getPermissionName();
41
42 private static final Map<String, SysPermission> sysPermissionsByName;
43 private static final Map<Long, String> sysPermissionNamesById;
44 private static final List<String> sysPermissionNames;
45 private static final ConcurrentMap<String, ResourcePermission> ungrantablePermissionByName;
46 private static final ConcurrentMap<String, ResourcePermission> grantablePermissionByName;
47
48 static {
49 sysPermissionsByName = new HashMap<>();
50 sysPermissionsByName.put(INHERIT, SYSPERMISSION_INHERIT);
51 sysPermissionsByName.put(IMPERSONATE, SYSPERMISSION_IMPERSONATE);
52 sysPermissionsByName.put(RESET_CREDENTIALS, SYSPERMISSION_RESET_CREDENTIALS);
53 sysPermissionsByName.put(DELETE, SYSPERMISSION_DELETE);
54 sysPermissionsByName.put(QUERY, SYSPERMISSION_QUERY);
55
56 sysPermissionNamesById = new HashMap<>(sysPermissionsByName.size());
57 for (SysPermission sysPermission : sysPermissionsByName.values()) {
58 sysPermissionNamesById.put(sysPermission.getSystemPermissionId(), sysPermission.getPermissionName());
59 }
60
61 sysPermissionNames = Collections.unmodifiableList(new ArrayList<>(sysPermissionNamesById.values()));
62
63 ungrantablePermissionByName = new ConcurrentHashMap<>();
64 grantablePermissionByName = new ConcurrentHashMap<>();
65 }
66
67 public static List<String> getSysPermissionNames() {
68 return sysPermissionNames;
69 }
70
71 public static String getSysPermissionName(long systemPermissionId) {
72 final String sysPermissionName = sysPermissionNamesById.get(systemPermissionId);
73
74 if (sysPermissionName == null) {
75 throw new IllegalArgumentException("Invalid system permission ID: " + systemPermissionId);
76 }
77
78 return sysPermissionName;
79 }
80
81 /**
82 * Creates a new resource permission of the specified name without
83 * the option to grant the permission to another resource
84 *
85 * @param permissionName the name of the permission
86 * @return a resource permission
87 */
88 public static ResourcePermission getInstance(String permissionName) {
89 permissionName = getCanonicalPermissionName(permissionName);
90
91 ResourcePermission resourcePermission = ungrantablePermissionByName.get(permissionName);
92
93 if (resourcePermission == null) {
94 resourcePermission = new ResourcePermissionImpl(permissionName, false);
95 final ResourcePermission cachedInstance = ungrantablePermissionByName.putIfAbsent(permissionName, resourcePermission);
96 if (cachedInstance != null) {
97 resourcePermission = cachedInstance;
98 }
99 }
100
101 return resourcePermission;
102 }
103
104 /**
105 * Creates a new resource permission of the specified name, but
106 * with the option to grant the permission to another resource
107 *
108 * @param permissionName the name of the permission
109 * @return a resource permission
110 */
111 public static ResourcePermission getInstanceWithGrantOption(String permissionName) {
112 permissionName = getCanonicalPermissionName(permissionName);
113
114 ResourcePermission resourcePermission = grantablePermissionByName.get(permissionName);
115
116 if (resourcePermission == null) {
117 resourcePermission = new ResourcePermissionImpl(permissionName, true);
118 final ResourcePermission cachedInstance = grantablePermissionByName.putIfAbsent(permissionName, resourcePermission);
119 if (cachedInstance != null) {
120 resourcePermission = cachedInstance;
121 }
122 }
123
124 return resourcePermission;
125 }
126
127 /**
128 * @deprecated as of v2.0.0-rc.5; use {@link #getInstanceWithGrantOption(String)} or {@link #getInstance(String)} instead.
129 */
130 @Deprecated
131 public static ResourcePermission getInstance(String permissionName, boolean withGrant) {
132 return new ResourcePermissionImpl(permissionName, withGrant);
133 }
134
135 public static ResourcePermission getInstance(ResourcePermission resourcePermission) {
136 if (resourcePermission instanceof ResourcePermissions.ResourcePermissionImpl) {
137 return resourcePermission;
138 }
139
140 final ResourcePermission verifiedPermission;
141
142 if (resourcePermission.isWithGrantOption()) {
143 verifiedPermission = getInstanceWithGrantOption(resourcePermission.getPermissionName());
144 }
145 else {
146 verifiedPermission = getInstance(resourcePermission.getPermissionName());
147 }
148
149 // validate system permission name and id matched
150 if (resourcePermission.isSystemPermission() &&
151 verifiedPermission.getSystemPermissionId() != resourcePermission.getSystemPermissionId()){
152 throw new IllegalArgumentException("Invalid system permission id for resource permission: " + resourcePermission);
153 }
154
155 return verifiedPermission;
156 }
157
158 private static String getCanonicalPermissionName(String permissionName) {
159 if (permissionName == null) {
160 throw new IllegalArgumentException("A permission name is required");
161 }
162
163 permissionName = permissionName.trim();
164
165 if (permissionName.isEmpty()) {
166 throw new IllegalArgumentException("A permission name is required");
167 }
168 return permissionName;
169 }
170
171 static class ResourcePermissionImpl implements ResourcePermission, Serializable {
172 private static final long serialVersionUID = 1L;
173
174 // permission data
175 private final long systemPermissionId;
176 private final String permissionName;
177 private final boolean withGrantOption;
178
179 private ResourcePermissionImpl(String permissionName,
180 boolean withGrantOption) {
181 assertPermissionNameSpecified(permissionName);
182
183 permissionName = permissionName.trim();
184
185 if (permissionName.startsWith("*")) {
186 SysPermission sysPermission = getSysPermission(permissionName);
187
188 this.systemPermissionId = sysPermission.getSystemPermissionId();
189 this.permissionName = sysPermission.getPermissionName();
190 }
191 else {
192 this.systemPermissionId = 0;
193 this.permissionName = permissionName.intern();
194 }
195
196 this.withGrantOption = withGrantOption;
197 }
198
199 @Override
200 public boolean isSystemPermission() {
201 return systemPermissionId != 0;
202 }
203
204 @Override
205 public String getPermissionName() {
206 return permissionName;
207 }
208
209 @Override
210 public long getSystemPermissionId() {
211 if (!isSystemPermission()) {
212 throw new IllegalArgumentException("No system permission ID may be retrieved for user permission: " + permissionName + ", please check your code");
213 }
214
215 return systemPermissionId;
216 }
217
218 @Override
219 public boolean isWithGrantOption() {
220 return withGrantOption;
221 }
222
223 @Override
224 @Deprecated
225 public boolean isWithGrant() {
226 return isWithGrantOption();
227 }
228
229 @Override
230 public boolean isGrantableFrom(ResourcePermission other) {
231 if (other == null) {
232 return false;
233 }
234
235 if (!other.isWithGrantOption()) {
236 return false;
237 }
238
239 return this.equalsIgnoreGrantOption(other);
240 }
241
242 @Override
243 public boolean equals(Object other) {
244 if (this == other) {
245 return true;
246 }
247 if (other == null || getClass() != other.getClass()) {
248 return false;
249 }
250
251 ResourcePermissionImpl otherResourcePermission = (ResourcePermissionImpl) other;
252
253 if (!permissionName.equals(otherResourcePermission.permissionName)) {
254 return false;
255 }
256 if (withGrantOption != otherResourcePermission.withGrantOption) {
257 return false;
258 }
259
260 return true;
261 }
262
263 @Override
264 public boolean equalsIgnoreGrantOption(Object other) {
265 if (this == other) {
266 return true;
267 }
268 if (other == null || getClass() != other.getClass()) {
269 return false;
270 }
271
272 ResourcePermissionImpl otherResourcePermission = (ResourcePermissionImpl) other;
273
274 if (!permissionName.equals(otherResourcePermission.permissionName)) {
275 return false;
276 }
277
278 return true;
279 }
280
281 @Override
282 @Deprecated
283 public boolean equalsIgnoreGrant(Object other) {
284 return equalsIgnoreGrantOption(other);
285 }
286
287 @Override
288 public int hashCode() {
289 int result = permissionName.hashCode();
290 result = 31 * result + (withGrantOption ? 1 : 0);
291 return result;
292 }
293
294 @Override
295 public String toString() {
296 return withGrantOption ? permissionName + " /G" : permissionName;
297 }
298
299 // private helper methods
300
301 private void assertPermissionNameSpecified(String permissionName) {
302 if (permissionName == null || permissionName.trim().isEmpty()) {
303 throw new IllegalArgumentException("A permission name is required");
304 }
305 }
306
307 // private static helper method to convert a sys permission name to a sys permission object
308
309 private static SysPermission getSysPermission(String permissionName) {
310 if (permissionName == null) {
311 throw new IllegalArgumentException("A system permission name is required");
312 }
313
314 final String trimmedPermissionName = permissionName.trim();
315
316 if (trimmedPermissionName.isEmpty()) {
317 throw new IllegalArgumentException("A system permission name is required");
318 }
319
320 final SysPermission sysPermission = sysPermissionsByName.get(trimmedPermissionName);
321
322 if (sysPermission == null) {
323 throw new IllegalArgumentException("Invalid system permission name: " + trimmedPermissionName);
324 }
325
326 return sysPermission;
327 }
328 }
329 }