Coverage Summary for Class: SQLAccessControlContext (com.acciente.oacc.sql.internal)
Class | Class, % | Method, % | Line, % |
---|---|---|---|
SQLAccessControlContext | 100% (1/ 1) | 98.8% (240/ 243) | 97.4% (2407/ 2472) |
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.sql.internal;
19
20 import com.acciente.oacc.AccessControlContext;
21 import com.acciente.oacc.AuthenticationProvider;
22 import com.acciente.oacc.Credentials;
23 import com.acciente.oacc.DomainCreatePermission;
24 import com.acciente.oacc.DomainCreatePermissions;
25 import com.acciente.oacc.DomainPermission;
26 import com.acciente.oacc.DomainPermissions;
27 import com.acciente.oacc.NotAuthenticatedException;
28 import com.acciente.oacc.NotAuthorizedException;
29 import com.acciente.oacc.OaccException;
30 import com.acciente.oacc.Resource;
31 import com.acciente.oacc.ResourceClassInfo;
32 import com.acciente.oacc.ResourceCreatePermission;
33 import com.acciente.oacc.ResourceCreatePermissions;
34 import com.acciente.oacc.ResourcePermission;
35 import com.acciente.oacc.ResourcePermissions;
36 import com.acciente.oacc.Resources;
37 import com.acciente.oacc.encryptor.PasswordEncryptor;
38 import com.acciente.oacc.sql.SQLProfile;
39 import com.acciente.oacc.sql.internal.persister.DomainPersister;
40 import com.acciente.oacc.sql.internal.persister.GrantDomainCreatePermissionPostCreateSysPersister;
41 import com.acciente.oacc.sql.internal.persister.GrantDomainCreatePermissionSysPersister;
42 import com.acciente.oacc.sql.internal.persister.GrantDomainPermissionSysPersister;
43 import com.acciente.oacc.sql.internal.persister.GrantGlobalResourcePermissionPersister;
44 import com.acciente.oacc.sql.internal.persister.GrantGlobalResourcePermissionSysPersister;
45 import com.acciente.oacc.sql.internal.persister.GrantResourceCreatePermissionPostCreatePersister;
46 import com.acciente.oacc.sql.internal.persister.GrantResourceCreatePermissionPostCreateSysPersister;
47 import com.acciente.oacc.sql.internal.persister.GrantResourceCreatePermissionSysPersister;
48 import com.acciente.oacc.sql.internal.persister.GrantResourcePermissionPersister;
49 import com.acciente.oacc.sql.internal.persister.GrantResourcePermissionSysPersister;
50 import com.acciente.oacc.sql.internal.persister.NonRecursiveDomainPersister;
51 import com.acciente.oacc.sql.internal.persister.NonRecursiveGrantDomainCreatePermissionPostCreateSysPersister;
52 import com.acciente.oacc.sql.internal.persister.NonRecursiveGrantDomainCreatePermissionSysPersister;
53 import com.acciente.oacc.sql.internal.persister.NonRecursiveGrantDomainPermissionSysPersister;
54 import com.acciente.oacc.sql.internal.persister.NonRecursiveGrantGlobalResourcePermissionPersister;
55 import com.acciente.oacc.sql.internal.persister.NonRecursiveGrantGlobalResourcePermissionSysPersister;
56 import com.acciente.oacc.sql.internal.persister.NonRecursiveGrantResourceCreatePermissionPostCreatePersister;
57 import com.acciente.oacc.sql.internal.persister.NonRecursiveGrantResourceCreatePermissionPostCreateSysPersister;
58 import com.acciente.oacc.sql.internal.persister.NonRecursiveGrantResourceCreatePermissionSysPersister;
59 import com.acciente.oacc.sql.internal.persister.NonRecursiveGrantResourcePermissionPersister;
60 import com.acciente.oacc.sql.internal.persister.NonRecursiveGrantResourcePermissionSysPersister;
61 import com.acciente.oacc.sql.internal.persister.NonRecursiveResourcePersister;
62 import com.acciente.oacc.sql.internal.persister.RecursiveDomainPersister;
63 import com.acciente.oacc.sql.internal.persister.RecursiveGrantDomainCreatePermissionPostCreateSysPersister;
64 import com.acciente.oacc.sql.internal.persister.RecursiveGrantDomainCreatePermissionSysPersister;
65 import com.acciente.oacc.sql.internal.persister.RecursiveGrantDomainPermissionSysPersister;
66 import com.acciente.oacc.sql.internal.persister.RecursiveGrantGlobalResourcePermissionPersister;
67 import com.acciente.oacc.sql.internal.persister.RecursiveGrantGlobalResourcePermissionSysPersister;
68 import com.acciente.oacc.sql.internal.persister.RecursiveGrantResourceCreatePermissionPostCreatePersister;
69 import com.acciente.oacc.sql.internal.persister.RecursiveGrantResourceCreatePermissionPostCreateSysPersister;
70 import com.acciente.oacc.sql.internal.persister.RecursiveGrantResourceCreatePermissionSysPersister;
71 import com.acciente.oacc.sql.internal.persister.RecursiveGrantResourcePermissionPersister;
72 import com.acciente.oacc.sql.internal.persister.RecursiveGrantResourcePermissionSysPersister;
73 import com.acciente.oacc.sql.internal.persister.RecursiveResourcePersister;
74 import com.acciente.oacc.sql.internal.persister.ResourceClassPermissionPersister;
75 import com.acciente.oacc.sql.internal.persister.ResourceClassPersister;
76 import com.acciente.oacc.sql.internal.persister.ResourcePersister;
77 import com.acciente.oacc.sql.internal.persister.SQLConnection;
78 import com.acciente.oacc.sql.internal.persister.SQLStrings;
79 import com.acciente.oacc.sql.internal.persister.id.DomainId;
80 import com.acciente.oacc.sql.internal.persister.id.Id;
81 import com.acciente.oacc.sql.internal.persister.id.ResourceClassId;
82 import com.acciente.oacc.sql.internal.persister.id.ResourceId;
83 import com.acciente.oacc.sql.internal.persister.id.ResourcePermissionId;
84
85 import javax.sql.DataSource;
86 import java.io.Serializable;
87 import java.sql.Connection;
88 import java.sql.SQLException;
89 import java.util.Arrays;
90 import java.util.Collections;
91 import java.util.HashMap;
92 import java.util.HashSet;
93 import java.util.List;
94 import java.util.Map;
95 import java.util.Set;
96
97 @SuppressWarnings({"UnusedAssignment", "ThrowFromFinallyBlock"})
98 public class SQLAccessControlContext implements AccessControlContext, Serializable {
99 private static final long serialVersionUID = 1L;
100
101 // services
102 private transient DataSource dataSource;
103 private transient Connection connection;
104
105 // state
106 private AuthenticationProvider authenticationProvider;
107 private boolean hasDefaultAuthenticationProvider;
108
109 // The resource that authenticated in this session with a call to one of the authenticate() methods
110 private Resource authenticatedResource;
111 private Resource defensiveCopyOfAuthenticatedResource;
112 private String authenticatedResourceDomainName;
113
114 // The resource as which the session's credentials are checked. This would be the same as the resource
115 // that initially authenticated - UNLESS a another resource is being IMPERSONATED
116 private Resource sessionResource;
117 private Resource defensiveCopyOfSessionResource;
118 private String sessionResourceDomainName;
119
120 // resource ID constants
121 private static final Long SYSTEM_RESOURCE_ID = Long.valueOf(0);
122
123 // domain permissions constants
124 private static final DomainPermission DomainPermission_CREATE_CHILD_DOMAIN
125 = DomainPermissions.getInstance(DomainPermissions.CREATE_CHILD_DOMAIN);
126 private static final DomainPermission DomainPermission_CREATE_CHILD_DOMAIN_GRANT
127 = DomainPermissions.getInstanceWithGrantOption(DomainPermissions.CREATE_CHILD_DOMAIN);
128 private static final DomainPermission DomainPermission_DELETE
129 = DomainPermissions.getInstance(DomainPermissions.DELETE);
130 private static final DomainPermission DomainPermission_DELETE_GRANT
131 = DomainPermissions.getInstanceWithGrantOption(DomainPermissions.DELETE);
132 private static final DomainPermission DomainPermission_SUPER_USER
133 = DomainPermissions.getInstance(DomainPermissions.SUPER_USER);
134 private static final DomainPermission DomainPermission_SUPER_USER_GRANT
135 = DomainPermissions.getInstanceWithGrantOption(DomainPermissions.SUPER_USER);
136
137 // resource permissions constants
138 private static final ResourcePermission ResourcePermission_INHERIT
139 = ResourcePermissions.getInstance(ResourcePermissions.INHERIT);
140 private static final ResourcePermission ResourcePermission_INHERIT_GRANT
141 = ResourcePermissions.getInstanceWithGrantOption(ResourcePermissions.INHERIT);
142 private static final ResourcePermission ResourcePermission_IMPERSONATE
143 = ResourcePermissions.getInstance(ResourcePermissions.IMPERSONATE);
144 private static final ResourcePermission ResourcePermission_IMPERSONATE_GRANT
145 = ResourcePermissions.getInstanceWithGrantOption(ResourcePermissions.IMPERSONATE);
146 private static final ResourcePermission ResourcePermission_RESET_CREDENTIALS
147 = ResourcePermissions.getInstance(ResourcePermissions.RESET_CREDENTIALS);
148 private static final ResourcePermission ResourcePermission_RESET_CREDENTIALS_GRANT
149 = ResourcePermissions.getInstanceWithGrantOption(ResourcePermissions.RESET_CREDENTIALS);
150 private static final ResourcePermission ResourcePermission_DELETE
151 = ResourcePermissions.getInstance(ResourcePermissions.DELETE);
152 private static final ResourcePermission ResourcePermission_DELETE_GRANT
153 = ResourcePermissions.getInstanceWithGrantOption(ResourcePermissions.DELETE);
154 private static final ResourcePermission ResourcePermission_QUERY
155 = ResourcePermissions.getInstance(ResourcePermissions.QUERY);
156 private static final ResourcePermission ResourcePermission_QUERY_GRANT
157 = ResourcePermissions.getInstanceWithGrantOption(ResourcePermissions.QUERY);
158
159 // persisters
160 private final ResourceClassPersister resourceClassPersister;
161 private final ResourceClassPermissionPersister resourceClassPermissionPersister;
162 private final DomainPersister domainPersister;
163 private final GrantDomainCreatePermissionSysPersister grantDomainCreatePermissionSysPersister;
164 private final GrantDomainCreatePermissionPostCreateSysPersister grantDomainCreatePermissionPostCreateSysPersister;
165 private final GrantDomainPermissionSysPersister grantDomainPermissionSysPersister;
166 private final ResourcePersister resourcePersister;
167 private final GrantResourceCreatePermissionSysPersister grantResourceCreatePermissionSysPersister;
168 private final GrantResourceCreatePermissionPostCreateSysPersister grantResourceCreatePermissionPostCreateSysPersister;
169 private final GrantResourceCreatePermissionPostCreatePersister grantResourceCreatePermissionPostCreatePersister;
170 private final GrantResourcePermissionSysPersister grantResourcePermissionSysPersister;
171 private final GrantGlobalResourcePermissionSysPersister grantGlobalResourcePermissionSysPersister;
172 private final GrantResourcePermissionPersister grantResourcePermissionPersister;
173 private final GrantGlobalResourcePermissionPersister grantGlobalResourcePermissionPersister;
174
175 public static AccessControlContext getAccessControlContext(Connection connection,
176 String schemaName,
177 SQLProfile sqlProfile,
178 PasswordEncryptor passwordEncryptor) {
179 __assertConnectionSpecified(connection);
180 return new SQLAccessControlContext(connection, schemaName, sqlProfile, passwordEncryptor);
181 }
182
183 public static AccessControlContext getAccessControlContext(DataSource dataSource,
184 String schemaName,
185 SQLProfile sqlProfile,
186 PasswordEncryptor passwordEncryptor) {
187 __assertDataSourceSpecified(dataSource);
188 return new SQLAccessControlContext(dataSource, schemaName, sqlProfile, passwordEncryptor);
189 }
190
191 public static AccessControlContext getAccessControlContext(Connection connection,
192 String schemaName,
193 SQLProfile sqlProfile,
194 AuthenticationProvider authenticationProvider) {
195 __assertConnectionSpecified(connection);
196 return new SQLAccessControlContext(connection, schemaName, sqlProfile, authenticationProvider);
197 }
198
199 public static AccessControlContext getAccessControlContext(DataSource dataSource,
200 String schemaName,
201 SQLProfile sqlProfile,
202 AuthenticationProvider authenticationProvider) {
203 __assertDataSourceSpecified(dataSource);
204 return new SQLAccessControlContext(dataSource, schemaName, sqlProfile, authenticationProvider);
205 }
206
207 /**
208 * @deprecated As of v2.0.0-rc.6; no replacement method necessary because unserializable fields are now marked as transient
209 */
210 @Deprecated
211 public static void preSerialize(AccessControlContext accessControlContext) {
212 }
213
214 public static void postDeserialize(AccessControlContext accessControlContext, Connection connection) {
215 if (accessControlContext instanceof SQLAccessControlContext) {
216 SQLAccessControlContext sqlAccessControlContext = (SQLAccessControlContext) accessControlContext;
217 sqlAccessControlContext.__postDeserialize(connection);
218 }
219 }
220
221 public static void postDeserialize(AccessControlContext accessControlContext, DataSource dataSource) {
222 if (accessControlContext instanceof SQLAccessControlContext) {
223 SQLAccessControlContext sqlAccessControlContext = (SQLAccessControlContext) accessControlContext;
224 sqlAccessControlContext.__postDeserialize(dataSource);
225 }
226 }
227
228 private SQLAccessControlContext(Connection connection,
229 String schemaName,
230 SQLProfile sqlProfile,
231 PasswordEncryptor passwordEncryptor) {
232 this(schemaName, sqlProfile);
233 this.connection = connection;
234 // use the built-in authentication provider when no custom implementation is provided
235 this.authenticationProvider
236 = new SQLPasswordAuthenticationProvider(connection, schemaName, passwordEncryptor);
237 this.hasDefaultAuthenticationProvider = true;
238 }
239
240 private SQLAccessControlContext(Connection connection,
241 String schemaName,
242 SQLProfile sqlProfile,
243 AuthenticationProvider authenticationProvider) {
244 this(schemaName, sqlProfile);
245 this.connection = connection;
246 this.authenticationProvider = authenticationProvider;
247 this.hasDefaultAuthenticationProvider = false;
248 }
249
250 private SQLAccessControlContext(DataSource dataSource,
251 String schemaName,
252 SQLProfile sqlProfile,
253 PasswordEncryptor passwordEncryptor) {
254 this(schemaName, sqlProfile);
255 this.dataSource = dataSource;
256 // use the built-in authentication provider when no custom implementation is provided
257 this.authenticationProvider
258 = new SQLPasswordAuthenticationProvider(dataSource, schemaName, passwordEncryptor);
259 this.hasDefaultAuthenticationProvider = true;
260 }
261
262 private SQLAccessControlContext(DataSource dataSource,
263 String schemaName,
264 SQLProfile sqlProfile,
265 AuthenticationProvider authenticationProvider) {
266 this(schemaName, sqlProfile);
267 this.dataSource = dataSource;
268 this.authenticationProvider = authenticationProvider;
269 this.hasDefaultAuthenticationProvider = false;
270 }
271
272 private SQLAccessControlContext(String schemaName,
273 SQLProfile sqlProfile) {
274 SchemaNameValidator.assertValid(schemaName);
275
276 // generate all the SQLs the persisters need based on the database dialect
277 SQLStrings sqlStrings = SQLStrings.getSQLStrings(schemaName, sqlProfile);
278
279 // setup persisters
280 resourceClassPersister
281 = new ResourceClassPersister(sqlProfile, sqlStrings);
282 resourceClassPermissionPersister
283 = new ResourceClassPermissionPersister(sqlProfile, sqlStrings);
284
285 if (sqlProfile.isRecursiveCTEEnabled()) {
286 grantDomainCreatePermissionSysPersister
287 = new RecursiveGrantDomainCreatePermissionSysPersister(sqlProfile, sqlStrings);
288 grantDomainCreatePermissionPostCreateSysPersister
289 = new RecursiveGrantDomainCreatePermissionPostCreateSysPersister(sqlProfile, sqlStrings);
290 grantDomainPermissionSysPersister
291 = new RecursiveGrantDomainPermissionSysPersister(sqlProfile, sqlStrings);
292 domainPersister
293 = new RecursiveDomainPersister(sqlProfile, sqlStrings);
294 resourcePersister
295 = new RecursiveResourcePersister(sqlProfile, sqlStrings);
296 grantResourceCreatePermissionSysPersister
297 = new RecursiveGrantResourceCreatePermissionSysPersister(sqlProfile, sqlStrings);
298 grantResourceCreatePermissionPostCreateSysPersister
299 = new RecursiveGrantResourceCreatePermissionPostCreateSysPersister(sqlProfile, sqlStrings);
300 grantResourceCreatePermissionPostCreatePersister
301 = new RecursiveGrantResourceCreatePermissionPostCreatePersister(sqlProfile, sqlStrings);
302 grantResourcePermissionSysPersister
303 = new RecursiveGrantResourcePermissionSysPersister(sqlProfile, sqlStrings);
304 grantGlobalResourcePermissionSysPersister
305 = new RecursiveGrantGlobalResourcePermissionSysPersister(sqlProfile, sqlStrings);
306 grantResourcePermissionPersister
307 = new RecursiveGrantResourcePermissionPersister(sqlProfile, sqlStrings);
308 grantGlobalResourcePermissionPersister
309 = new RecursiveGrantGlobalResourcePermissionPersister(sqlProfile, sqlStrings);
310 }
311 else {
312 grantDomainCreatePermissionSysPersister
313 = new NonRecursiveGrantDomainCreatePermissionSysPersister(sqlProfile, sqlStrings);
314 grantDomainCreatePermissionPostCreateSysPersister
315 = new NonRecursiveGrantDomainCreatePermissionPostCreateSysPersister(sqlProfile, sqlStrings);
316 grantDomainPermissionSysPersister
317 = new NonRecursiveGrantDomainPermissionSysPersister(sqlProfile, sqlStrings);
318 domainPersister
319 = new NonRecursiveDomainPersister(sqlProfile, sqlStrings);
320 resourcePersister
321 = new NonRecursiveResourcePersister(sqlProfile, sqlStrings);
322 grantResourceCreatePermissionSysPersister
323 = new NonRecursiveGrantResourceCreatePermissionSysPersister(sqlProfile, sqlStrings);
324 grantResourceCreatePermissionPostCreateSysPersister
325 = new NonRecursiveGrantResourceCreatePermissionPostCreateSysPersister(sqlProfile, sqlStrings);
326 grantResourceCreatePermissionPostCreatePersister
327 = new NonRecursiveGrantResourceCreatePermissionPostCreatePersister(sqlProfile, sqlStrings);
328 grantResourcePermissionSysPersister
329 = new NonRecursiveGrantResourcePermissionSysPersister(sqlProfile, sqlStrings);
330 grantGlobalResourcePermissionSysPersister
331 = new NonRecursiveGrantGlobalResourcePermissionSysPersister(sqlProfile, sqlStrings);
332 grantResourcePermissionPersister
333 = new NonRecursiveGrantResourcePermissionPersister(sqlProfile, sqlStrings);
334 grantGlobalResourcePermissionPersister
335 = new NonRecursiveGrantGlobalResourcePermissionPersister(sqlProfile, sqlStrings);
336 }
337 }
338
339 private void __postDeserialize(DataSource dataSource) {
340 if (this.dataSource != null || this.connection != null) {
341 throw new IllegalStateException("Cannot re-initialize an already initialized SQLAccessControlContext");
342 }
343 this.dataSource = dataSource;
344 this.connection = null;
345 if (hasDefaultAuthenticationProvider) {
346 ((SQLPasswordAuthenticationProvider) authenticationProvider).postDeserialize(dataSource);
347 }
348 }
349
350 private void __postDeserialize(Connection connection) {
351 if (this.dataSource != null || this.connection != null) {
352 throw new IllegalStateException("Cannot re-initialize an already initialized SQLAccessControlContext");
353 }
354 this.dataSource = null;
355 this.connection = connection;
356 if (hasDefaultAuthenticationProvider) {
357 ((SQLPasswordAuthenticationProvider) authenticationProvider).postDeserialize(connection);
358 }
359 }
360
361 @Override
362 public void authenticate(Resource resource, Credentials credentials) {
363 __assertResourceSpecified(resource);
364 __assertCredentialsSpecified(credentials);
365
366 // we deliberately don't resolve the resource before calling the common handler method, to avoid having
367 // to keep the connection open across a potentially long call to a third-party authenticationProvider or
368 // to avoid having to get a connection twice
369 __authenticate(resource, credentials);
370 }
371
372 @Override
373 public void authenticate(Resource resource) {
374 __assertResourceSpecified(resource);
375
376 // we deliberately don't resolve the resource before calling the common handler method, to avoid having
377 // to keep the connection open across a potentially long call to a third-party authenticationProvider or
378 // to avoid having to get a connection twice
379 __authenticate(resource, null);
380 }
381
382 private void __authenticate(Resource resource, Credentials credentials) {
383 // before delegating to the authentication provider we do some basic validation
384 SQLConnection connection = null;
385
386 final String resourceDomainForResource;
387 try {
388 connection = __getConnection();
389
390 // resolve the resource here - instead of outside this method - to avoid having
391 // to keep the connection open across a potentially long call to a third-party authenticationProvider or
392 // to avoid having to get a connection twice
393 resource = __resolveResource(connection, resource);
394
395 final ResourceClassInternalInfo resourceClassInternalInfo
396 = resourceClassPersister.getResourceClassInfoByResourceId(connection, resource);
397
398 // complain if the resource is not marked as supporting authentication
399 if (!resourceClassInternalInfo.isAuthenticatable()) {
400 throw new IllegalArgumentException("Resource " + resource
401 + " is not of an authenticatable resource class: "
402 + resourceClassInternalInfo.getResourceClassName());
403 }
404 resourceDomainForResource = domainPersister.getResourceDomainNameByResourceId(connection, resource);
405 }
406 finally {
407 __closeConnection(connection);
408 }
409
410 // now we delegate to the authentication provider
411 if (credentials != null) {
412 authenticationProvider.authenticate(resource, credentials);
413 }
414 else {
415 authenticationProvider.authenticate(resource);
416 }
417
418 authenticatedResource = resource;
419 defensiveCopyOfAuthenticatedResource = null;
420 authenticatedResourceDomainName = resourceDomainForResource;
421
422 sessionResource = authenticatedResource;
423 defensiveCopyOfSessionResource = null;
424 sessionResourceDomainName = authenticatedResourceDomainName;
425 }
426
427 @Override
428 public void unauthenticate() {
429 sessionResource = authenticatedResource = null;
430 defensiveCopyOfSessionResource = defensiveCopyOfAuthenticatedResource = null;
431 sessionResourceDomainName = authenticatedResourceDomainName = null;
432 }
433
434 @Override
435 public void impersonate(Resource resource) {
436 SQLConnection connection = null;
437
438 __assertAuthenticated();
439 __assertResourceSpecified(resource);
440
441 try {
442 connection = __getConnection();
443
444 resource = __resolveResource(connection, resource);
445 __assertImpersonatePermission(connection, resource);
446
447 // switch the session credentials to the new resource
448 sessionResource = resource;
449 defensiveCopyOfSessionResource = null;
450 sessionResourceDomainName = domainPersister.getResourceDomainNameByResourceId(connection, resource);
451 }
452 finally {
453 __closeConnection(connection);
454 }
455 }
456
457 private void __assertImpersonatePermission(SQLConnection connection, Resource resource) {
458 final ResourceClassInternalInfo resourceClassInternalInfo
459 = resourceClassPersister.getResourceClassInfoByResourceId(connection, resource);
460
461 // complain if the resource is not of an authenticatable resource-class
462 if (!resourceClassInternalInfo.isAuthenticatable()) {
463 throw new IllegalArgumentException("Resource " + resource
464 + " is not of an authenticatable resource class: "
465 + resourceClassInternalInfo.getResourceClassName());
466 }
467
468 boolean impersonatePermissionOK = false;
469
470 // first check direct permissions
471 final Set<ResourcePermission>
472 resourcePermissions = __getEffectiveResourcePermissions(connection, authenticatedResource, resource);
473
474 if (resourcePermissions.contains(ResourcePermission_IMPERSONATE)
475 || resourcePermissions.contains(ResourcePermission_IMPERSONATE_GRANT)) {
476 impersonatePermissionOK = true;
477 }
478
479 if (!impersonatePermissionOK) {
480 // next check global direct permissions
481 final String
482 domainName = domainPersister.getResourceDomainNameByResourceId(connection, resource);
483 final Set<ResourcePermission>
484 globalResourcePermissions = __getEffectiveGlobalResourcePermissions(connection,
485 authenticatedResource,
486 resourceClassInternalInfo.getResourceClassName(),
487 domainName);
488
489 if (globalResourcePermissions.contains(ResourcePermission_IMPERSONATE)
490 || globalResourcePermissions.contains(ResourcePermission_IMPERSONATE_GRANT)) {
491 impersonatePermissionOK = true;
492 }
493 }
494
495 if (!impersonatePermissionOK) {
496 // finally check for super user permissions
497 if (__isSuperUserOfResource(connection, authenticatedResource, resource)) {
498 impersonatePermissionOK = true;
499 }
500 }
501
502 if (!impersonatePermissionOK) {
503 throw NotAuthorizedException.newInstanceForActionOnResource(authenticatedResource, "impersonate", resource);
504 }
505 }
506
507 @Override
508 public void unimpersonate() {
509 sessionResource = authenticatedResource;
510 defensiveCopyOfSessionResource = defensiveCopyOfAuthenticatedResource;
511 sessionResourceDomainName = authenticatedResourceDomainName;
512 }
513
514 @Override
515 public void setCredentials(Resource resource, Credentials newCredentials) {
516 SQLConnection connection = null;
517
518 __assertAuthenticated();
519 __assertResourceSpecified(resource);
520
521 if (!authenticatedResource.equals(sessionResource)) {
522 throw new IllegalStateException("Calling setCredentials while impersonating another resource is not valid");
523 }
524
525 __assertCredentialsSpecified(newCredentials);
526
527 final ResourceClassInternalInfo resourceClassInfo;
528 final String domainName;
529 try {
530 connection = __getConnection();
531
532 resource = __resolveResource(connection, resource);
533 resourceClassInfo = resourceClassPersister.getResourceClassInfoByResourceId(connection, resource);
534
535 if (!resourceClassInfo.isAuthenticatable()) {
536 throw new IllegalArgumentException("Calling setCredentials for an unauthenticatable resource is not valid");
537 }
538
539 if (authenticatedResource.equals(resource)) {
540 domainName = authenticatedResourceDomainName;
541 // skip permission checks if the authenticated resource is trying to set its own credentials
542 }
543 else {
544 domainName = domainPersister.getResourceDomainNameByResourceId(connection, resource);
545 __assertResetCredentialsResourcePermission(connection,
546 resource,
547 resourceClassInfo.getResourceClassName(),
548 domainName);
549 }
550 }
551 finally {
552 __closeConnection(connection);
553 }
554
555 authenticationProvider.validateCredentials(resourceClassInfo.getResourceClassName(),
556 domainName,
557 newCredentials);
558
559 authenticationProvider.setCredentials(resource, newCredentials);
560 }
561
562 private void __assertResetCredentialsResourcePermission(SQLConnection connection,
563 Resource resource,
564 String resourceClassName,
565 String domainName) {
566 // first check direct permissions
567 boolean hasResetCredentialsPermission = false;
568
569 final Set<ResourcePermission>
570 resourcePermissions = __getEffectiveResourcePermissions(connection, authenticatedResource, resource);
571
572 if (resourcePermissions.contains(ResourcePermission_RESET_CREDENTIALS)
573 || resourcePermissions.contains(ResourcePermission_RESET_CREDENTIALS_GRANT)) {
574 hasResetCredentialsPermission = true;
575 }
576
577 if (!hasResetCredentialsPermission) {
578 // next check global direct permissions
579 final Set<ResourcePermission>
580 globalResourcePermissions = __getEffectiveGlobalResourcePermissions(connection,
581 authenticatedResource,
582 resourceClassName,
583 domainName);
584
585 if (globalResourcePermissions.contains(ResourcePermission_RESET_CREDENTIALS)
586 || globalResourcePermissions.contains(ResourcePermission_RESET_CREDENTIALS_GRANT)) {
587 hasResetCredentialsPermission = true;
588 }
589 }
590
591 if (!hasResetCredentialsPermission) {
592 // finally check for super user permissions
593 if (__isSuperUserOfResource(connection, authenticatedResource, resource)) {
594 hasResetCredentialsPermission = true;
595 }
596 }
597
598 if (!hasResetCredentialsPermission) {
599 throw NotAuthorizedException.newInstanceForActionOnResource(authenticatedResource,
600 "reset credentials",
601 resource);
602 }
603 }
604
605 @Override
606 public void createResourceClass(String resourceClassName,
607 boolean authenticatable,
608 boolean unauthenticatedCreateAllowed) {
609 SQLConnection connection = null;
610
611 __assertAuthenticated();
612 __assertAuthenticatedAsSystemResource(); // check if the auth resource is permitted to create resource classes
613 __assertResourceClassNameValid(resourceClassName);
614
615 try {
616 connection = __getConnection();
617
618 resourceClassName = resourceClassName.trim();
619
620 // check if this resource class already exists
621 if (resourceClassPersister.getResourceClassId(connection, resourceClassName) != null) {
622 throw new IllegalArgumentException("Duplicate resource class: " + resourceClassName);
623 }
624
625 resourceClassPersister.addResourceClass(connection,
626 resourceClassName,
627 authenticatable,
628 unauthenticatedCreateAllowed);
629 }
630 finally {
631 __closeConnection(connection);
632 }
633 }
634
635 @Override
636 public void createResourcePermission(String resourceClassName, String permissionName) {
637 SQLConnection connection = null;
638
639 __assertAuthenticated();
640 __assertAuthenticatedAsSystemResource(); // check if the auth resource is permitted to create resource classes
641 __assertResourceClassSpecified(resourceClassName);
642 __assertPermissionNameValid(permissionName);
643
644 try {
645 connection = __getConnection();
646
647 resourceClassName = resourceClassName.trim();
648 permissionName = permissionName.trim();
649
650 // first verify that resource class is defined
651 Id<ResourceClassId> resourceClassId = resourceClassPersister.getResourceClassId(connection, resourceClassName);
652
653 if (resourceClassId == null) {
654 throw new IllegalArgumentException("Could not find resource class: " + resourceClassName);
655 }
656
657 // check if the permission name is already defined!
658 Id<ResourcePermissionId> permissionId
659 = resourceClassPermissionPersister.getResourceClassPermissionId(connection, resourceClassId, permissionName);
660
661 if (permissionId != null) {
662 throw new IllegalArgumentException("Duplicate permission: " + permissionName + " for resource class: " + resourceClassName);
663 }
664
665 resourceClassPermissionPersister.addResourceClassPermission(connection, resourceClassId, permissionName);
666 }
667 finally {
668 __closeConnection(connection);
669 }
670 }
671
672 @Override
673 public void createDomain(String domainName) {
674 SQLConnection connection = null;
675
676 __assertAuthenticated();
677 __assertDomainSpecified(domainName);
678
679 try {
680 connection = __getConnection();
681 domainName = domainName.trim();
682
683 __createDomain(connection, domainName, null);
684 }
685 finally {
686 __closeConnection(connection);
687 }
688 }
689
690 @Override
691 public void createDomain(String domainName,
692 String parentDomainName) {
693 SQLConnection connection = null;
694
695 __assertAuthenticated();
696 __assertDomainSpecified(domainName);
697 __assertParentDomainSpecified(parentDomainName);
698
699 try {
700 connection = __getConnection();
701
702 domainName = domainName.trim();
703 parentDomainName = parentDomainName.trim();
704
705 __createDomain(connection, domainName, parentDomainName);
706 }
707 finally {
708 __closeConnection(connection);
709 }
710 }
711
712 private void __createDomain(SQLConnection connection,
713 String domainName,
714 String parentDomainName) {
715 // we need to check if the currently authenticated resource is allowed to create domains
716 final Set<DomainCreatePermission> domainCreatePermissions
717 = grantDomainCreatePermissionSysPersister.getDomainCreateSysPermissionsIncludeInherited(connection,
718 sessionResource);
719
720 // if there is at least one permission, then it implies that this resource is allowed to create domains
721 if (domainCreatePermissions.isEmpty()) {
722 throw NotAuthorizedException.newInstanceForAction(sessionResource, "create domain");
723 }
724
725 // determine the post create permissions on the new domain
726 final Set<DomainPermission> newDomainPermissions
727 = __getPostCreateDomainPermissions(grantDomainCreatePermissionPostCreateSysPersister
728 .getDomainCreatePostCreateSysPermissionsIncludeInherited(connection,
729 sessionResource));
730 // check to ensure that the requested domain name does not already exist
731 if (domainPersister.getResourceDomainId(connection, domainName) != null) {
732 throw new IllegalArgumentException("Duplicate domain: " + domainName);
733 }
734
735 if (parentDomainName == null) {
736 // create the new root domain
737 domainPersister.addResourceDomain(connection, domainName);
738 }
739 else {
740 // check to ensure that the parent domain name exists
741 Id<DomainId> parentDomainId = domainPersister.getResourceDomainId(connection, parentDomainName);
742
743 if (parentDomainId == null) {
744 throw new IllegalArgumentException("Parent domain: " + parentDomainName + " not found!");
745 }
746
747 // we need to check if the currently authenticated resource is allowed to create child domains in the parent
748 Set<DomainPermission> parentDomainPermissions;
749
750 parentDomainPermissions = __getEffectiveDomainPermissions(connection, sessionResource, parentDomainName);
751
752 if (!parentDomainPermissions.contains(DomainPermission_CREATE_CHILD_DOMAIN)
753 && !parentDomainPermissions.contains(DomainPermission_CREATE_CHILD_DOMAIN_GRANT)
754 && !parentDomainPermissions.contains(DomainPermission_SUPER_USER)
755 && !parentDomainPermissions.contains(DomainPermission_SUPER_USER_GRANT)) {
756 throw NotAuthorizedException.newInstanceForAction(sessionResource,
757 "create child domain in domain: " + parentDomainName);
758 }
759
760 // create the new child domain
761 domainPersister.addResourceDomain(connection, domainName, parentDomainId);
762 }
763
764 if (newDomainPermissions.size() > 0) {
765 // grant the currently authenticated resource the privileges to the new domain
766 __setDirectDomainPermissions(connection,
767 sessionResource,
768 domainName,
769 newDomainPermissions,
770 true);
771 }
772 }
773
774 @Override
775 public boolean deleteDomain(String domainName) {
776 SQLConnection connection = null;
777
778 __assertAuthenticated();
779 __assertDomainSpecified(domainName);
780
781 try {
782 connection = __getConnection();
783
784 return __deleteDomain(connection, domainName);
785 }
786 finally {
787 __closeConnection(connection);
788 }
789
790 }
791
792 private boolean __deleteDomain(SQLConnection connection, String domainName) {
793 // short-circuit out of this call if the specified resource does not exist
794 final Id<DomainId> domainId = domainPersister.getResourceDomainId(connection, domainName);
795 if (domainId == null) {
796 return false;
797 }
798
799 // check for authorization (using internal has-permission method is ok because querying for session resource)
800 if (!__hasDomainPermissions(connection,
801 sessionResource,
802 domainName,
803 Collections.singleton(DomainPermission_DELETE))) {
804 throw NotAuthorizedException.newInstanceForDomainPermissions(sessionResource,
805 domainName,
806 DomainPermission_DELETE);
807 }
808
809 // check if the domain is empty (=domain must not contain any resources, and none in any descendant domains)
810 if (!resourcePersister.isDomainEmpty(connection, domainId)) {
811 throw new IllegalArgumentException("Deleting a domain ("
812 + domainName
813 + ") that contains resources directly or in a descendant domain is invalid");
814 }
815
816 // remove any permissions the obsolete resource has as an accessor resource
817 grantDomainPermissionSysPersister.removeAllDomainSysPermissions(connection, domainId);
818 grantResourceCreatePermissionPostCreatePersister.removeAllResourceCreatePostCreatePermissions(connection, domainId);
819 grantResourceCreatePermissionPostCreateSysPersister.removeAllResourceCreatePostCreateSysPermissions(connection, domainId);
820 grantResourceCreatePermissionSysPersister.removeAllResourceCreateSysPermissions(connection, domainId);
821 grantGlobalResourcePermissionPersister.removeAllGlobalResourcePermissions(connection, domainId);
822 grantGlobalResourcePermissionSysPersister.removeAllGlobalSysPermissions(connection, domainId);
823
824 // remove the domain
825 domainPersister.deleteDomain(connection, domainId);
826
827 return true;
828 }
829
830 @Override
831 public Resource createResource(String resourceClassName, String domainName) {
832 SQLConnection connection = null;
833
834 try {
835 connection = __getConnection();
836
837 return __createResource(connection, resourceClassName, domainName, null, null);
838 }
839 finally {
840 __closeConnection(connection);
841 }
842 }
843
844 @Override
845 public Resource createResource(String resourceClassName,
846 String domainName,
847 Credentials credentials) {
848 SQLConnection connection = null;
849
850 __assertCredentialsSpecified(credentials);
851
852 try {
853 connection = __getConnection();
854
855 return __createResource(connection, resourceClassName, domainName, null, credentials);
856 }
857 finally {
858 __closeConnection(connection);
859 }
860 }
861
862 @Override
863 public Resource createResource(String resourceClassName,
864 String domainName,
865 String externalId) {
866 SQLConnection connection = null;
867
868 __assertExternalIdSpecified(externalId);
869
870 try {
871 connection = __getConnection();
872
873 return __createResource(connection, resourceClassName, domainName, externalId, null);
874 }
875 finally {
876 __closeConnection(connection);
877 }
878 }
879
880 @Override
881 public Resource createResource(String resourceClassName,
882 String domainName,
883 String externalId,
884 Credentials credentials) {
885 SQLConnection connection = null;
886
887 __assertExternalIdSpecified(externalId);
888 __assertCredentialsSpecified(credentials);
889
890 try {
891 connection = __getConnection();
892
893 return __createResource(connection, resourceClassName, domainName, externalId, credentials);
894 }
895 finally {
896 __closeConnection(connection);
897 }
898 }
899
900 private Resource __createResource(SQLConnection connection,
901 String resourceClassName,
902 String domainName,
903 String externalId,
904 Credentials credentials) {
905 __assertResourceClassSpecified(resourceClassName);
906 __assertDomainSpecified(domainName);
907
908 // validate the resource class
909 resourceClassName = resourceClassName.trim();
910 final ResourceClassInternalInfo resourceClassInternalInfo = __getResourceClassInternalInfo(connection,
911 resourceClassName);
912
913 if (!resourceClassInternalInfo.isUnauthenticatedCreateAllowed()) {
914 __assertAuthenticated();
915 }
916
917 if (resourceClassInternalInfo.isAuthenticatable()) {
918 // if this resource class is authenticatable, then validate the credentials
919 authenticationProvider.validateCredentials(resourceClassName, domainName, credentials);
920 }
921 else {
922 // if this resource class is NOT authenticatable, then specifying credentials is invalid
923 __assertCredentialsNotSpecified(credentials);
924 }
925
926 // validate the domain
927 final Id<DomainId> domainId = domainPersister.getResourceDomainId(connection, domainName);
928
929 if (domainId == null) {
930 throw new IllegalArgumentException("Could not find domain: " + domainName);
931 }
932
933 // check to ensure that the specified external id does not already exist
934 if (externalId != null && resourcePersister.resolveResourceByExternalId(connection, externalId) != null) {
935 throw new IllegalArgumentException("External id is not unique: " + externalId);
936 }
937
938 // we first check the create permissions
939 final Set<ResourcePermission> newResourcePermissions;
940
941 // the only way we can have come here with _sessionResource == null is
942 // when non-authenticated create is allowed for this resource class
943 if (sessionResource == null) {
944 // if this session is unauthenticated then give the new resource all available
945 // permissions to itself
946 newResourcePermissions = new HashSet<>();
947
948 for (String permissionName : resourceClassPermissionPersister.getPermissionNames(connection, resourceClassName)) {
949 newResourcePermissions.add(ResourcePermissions.getInstanceWithGrantOption(permissionName));
950 }
951
952 newResourcePermissions.add(ResourcePermission_DELETE_GRANT);
953 newResourcePermissions.add(ResourcePermission_QUERY_GRANT);
954
955 if (resourceClassInternalInfo.isAuthenticatable()) {
956 newResourcePermissions.add(ResourcePermission_RESET_CREDENTIALS_GRANT);
957 newResourcePermissions.add(ResourcePermission_IMPERSONATE_GRANT);
958 }
959 }
960 else {
961 final Set<ResourceCreatePermission> resourceCreatePermissions;
962 boolean createPermissionOK = false;
963
964 resourceCreatePermissions = __getEffectiveResourceCreatePermissionsIgnoringSuperUserPrivileges(connection,
965 sessionResource,
966 resourceClassName,
967 domainName);
968 newResourcePermissions = __getPostCreateResourcePermissions(resourceCreatePermissions);
969
970 if (resourceCreatePermissions.size() > 0) {
971 createPermissionOK = true;
972 }
973
974 // if that did not work, next we check the session resource has super user permissions
975 // to the domain of the new resource
976 if (!createPermissionOK) {
977 createPermissionOK = __isSuperUserOfDomain(connection, sessionResource, domainName);
978 }
979
980 if (!createPermissionOK) {
981 throw NotAuthorizedException.newInstanceForAction(sessionResource,
982 "create resource of resource class " + resourceClassName);
983 }
984 }
985
986 // create the new resource
987 final Resource newResource = resourcePersister.createResource(connection,
988 Id.<ResourceClassId>from(resourceClassInternalInfo
989 .getResourceClassId()),
990 domainId,
991 externalId);
992
993 // set permissions on the new resource, if applicable
994 if (newResourcePermissions != null && newResourcePermissions.size() > 0) {
995 if (sessionResource != null) {
996 __setDirectResourcePermissions(connection,
997 sessionResource,
998 newResource,
999 newResourcePermissions,
1000 sessionResource,
1001 true);
1002 }
1003 else {
1004 // if this session is unauthenticated the permissions are granted to the newly created resource
1005 __setDirectResourcePermissions(connection,
1006 newResource,
1007 newResource,
1008 newResourcePermissions,
1009 newResource,
1010 true);
1011 }
1012 }
1013
1014 if (credentials != null) {
1015 authenticationProvider.setCredentials(newResource, credentials);
1016 }
1017
1018 return newResource;
1019 }
1020
1021 @Override
1022 public Resource setExternalId(Resource resource, String externalId) {
1023 SQLConnection connection = null;
1024
1025 __assertAuthenticated();
1026 __assertResourceSpecified(resource);
1027 __assertExternalIdSpecified(externalId);
1028
1029 try {
1030 connection = __getConnection();
1031 resource = __resolveResource(connection, resource);
1032
1033 return __setExternalId(connection, resource, externalId);
1034 }
1035 finally {
1036 __closeConnection(connection);
1037 }
1038 }
1039
1040 private Resource __setExternalId(SQLConnection connection, Resource resource, String externalId) {
1041 final Resource resourceByExternalId = resourcePersister.resolveResourceByExternalId(connection, externalId);
1042
1043 if (resourceByExternalId == null) {
1044 // ok, that externalId is unused, we can go ahead and set it, unless the existing resource already has a different one set
1045 if (resource.getExternalId() != null){
1046 // setting external id is a one-time operation - resetting to a different value is not allowed
1047 throw new IllegalArgumentException("Could not reset the resource's external id to a different value");
1048 }
1049 }
1050 else {
1051 // the externalId is already used - let's check if it's on the same resource we're trying to set
1052 if (resource.getId().equals(resourceByExternalId.getId())) {
1053 // for idempotency - if externalId is already set to the specified value, do nothing
1054 return resource;
1055 }
1056 else {
1057 // the externalId has already been assigned to a different resource
1058 throw new IllegalArgumentException("External id is not unique: " + externalId);
1059 }
1060 }
1061
1062 // check create-permission on the resource's domain and resource class in order to set external id
1063 final Id<ResourceClassId> resourceClassId
1064 = Id.from(resourceClassPersister.getResourceClassInfoByResourceId(connection, resource).getResourceClassId());
1065 final Id<DomainId> domainId = resourcePersister.getDomainIdByResource(connection, resource);
1066 final Set<ResourceCreatePermission> resourceCreateSysPermissions
1067 = grantResourceCreatePermissionSysPersister.getResourceCreateSysPermissionsIncludeInherited(connection,
1068 sessionResource,
1069 resourceClassId,
1070 domainId);
1071
1072 boolean createPermissionOK = false;
1073 if (resourceCreateSysPermissions.size() > 0) {
1074 createPermissionOK = true;
1075 }
1076
1077 // check if the session resource has super user permissions to the resource's domain, if necessary
1078 if (!createPermissionOK) {
1079 createPermissionOK = __isSuperUserOfDomain(connection, sessionResource, domainId);
1080 }
1081
1082 if (!createPermissionOK) {
1083 throw NotAuthorizedException.newInstanceForAction(sessionResource, "set external id of resource " + resource);
1084 }
1085
1086 return resourcePersister.setExternalId(connection, Id.<ResourceId>from(resource.getId()), externalId);
1087 }
1088
1089 @Override
1090 public boolean deleteResource(Resource obsoleteResource) {
1091 SQLConnection connection = null;
1092
1093 __assertAuthenticated();
1094 __assertResourceSpecified(obsoleteResource);
1095
1096 try {
1097 connection = __getConnection();
1098
1099 // we deliberately don't resolve the resource before calling the handler method, because the
1100 // delete operation should be idempotent and return false if the resource does not resolve/exist
1101 return __deleteResource(connection, obsoleteResource);
1102 }
1103 finally {
1104 __closeConnection(connection);
1105 }
1106 }
1107
1108 private boolean __deleteResource(SQLConnection connection,
1109 Resource obsoleteResource) {
1110 try {
1111 obsoleteResource = __resolveResource(connection, obsoleteResource);
1112 }
1113 catch (IllegalArgumentException e) {
1114 // short-circuit out of this call if the specified resource does not exist/resolve
1115 // NOTE that this will still throw an exception if a resource does not match its
1116 // specified external id
1117 if (e.getMessage().toLowerCase().contains("not found")) {
1118 return false;
1119 }
1120 throw e;
1121 }
1122
1123 // check for authorization
1124 if (!__isSuperUserOfResource(connection, sessionResource, obsoleteResource)) {
1125 final Set<ResourcePermission> sessionResourcePermissions
1126 = __getEffectiveResourcePermissionsIgnoringSuperUserPrivileges(connection,
1127 sessionResource,
1128 obsoleteResource);
1129
1130 if (!sessionResourcePermissions.contains(ResourcePermission_DELETE) &&
1131 !sessionResourcePermissions.contains(ResourcePermission_DELETE_GRANT)) {
1132 throw NotAuthorizedException.newInstanceForActionOnResource(sessionResource, "delete", obsoleteResource);
1133 }
1134 }
1135
1136 // remove the resource's credentials, if necessary
1137 final ResourceClassInternalInfo resourceClassInternalInfo
1138 = resourceClassPersister.getResourceClassInfoByResourceId(connection, obsoleteResource);
1139
1140 if (resourceClassInternalInfo.isAuthenticatable()) {
1141 authenticationProvider.deleteCredentials(obsoleteResource);
1142 }
1143
1144 // remove any permissions the obsolete resource has as an accessor resource
1145 grantDomainCreatePermissionPostCreateSysPersister.removeDomainCreatePostCreateSysPermissions(connection, obsoleteResource);
1146 grantDomainCreatePermissionSysPersister.removeDomainCreateSysPermissions(connection, obsoleteResource);
1147 grantDomainPermissionSysPersister.removeAllDomainSysPermissions(connection, obsoleteResource);
1148 grantResourceCreatePermissionPostCreatePersister.removeAllResourceCreatePostCreatePermissions(connection, obsoleteResource);
1149 grantResourceCreatePermissionPostCreateSysPersister.removeAllResourceCreatePostCreateSysPermissions(connection, obsoleteResource);
1150 grantResourceCreatePermissionSysPersister.removeAllResourceCreateSysPermissions(connection, obsoleteResource);
1151 grantGlobalResourcePermissionPersister.removeAllGlobalResourcePermissions(connection, obsoleteResource);
1152 grantGlobalResourcePermissionSysPersister.removeAllGlobalSysPermissions(connection, obsoleteResource);
1153
1154 // remove any permissions the obsolete resource has as an accessor resource OR as an accessed resource
1155 grantResourcePermissionPersister.removeAllResourcePermissionsAsAccessorOrAccessed(connection, obsoleteResource);
1156 grantResourcePermissionSysPersister.removeAllResourceSysPermissionsAsAccessorOrAccessed(connection, obsoleteResource);
1157
1158 // remove the resource
1159 resourcePersister.deleteResource(connection, obsoleteResource);
1160
1161 // handle special case where deleted resource is the session or authenticated resource
1162 if (authenticatedResource.equals(obsoleteResource)) {
1163 unauthenticate();
1164 }
1165 else if (sessionResource.equals(obsoleteResource)) {
1166 unimpersonate();
1167 }
1168
1169 return true;
1170 }
1171
1172 @Override
1173 public void setDomainPermissions(Resource accessorResource,
1174 String domainName,
1175 Set<DomainPermission> permissions) {
1176 SQLConnection connection = null;
1177
1178 __assertAuthenticated();
1179 __assertResourceSpecified(accessorResource);
1180 __assertDomainSpecified(domainName);
1181 __assertPermissionsSpecified(permissions);
1182
1183 final Set<DomainPermission> normalizedDomainPermissions = __normalizeDomainPermissions(permissions);
1184
1185 try {
1186 connection = __getConnection();
1187 accessorResource = __resolveResource(connection, accessorResource);
1188
1189 __setDirectDomainPermissions(connection, accessorResource, domainName, normalizedDomainPermissions, false);
1190 }
1191 finally {
1192 __closeConnection(connection);
1193 }
1194 }
1195 private void __setDirectDomainPermissions(SQLConnection connection,
1196 Resource accessorResource,
1197 String domainName,
1198 Set<DomainPermission> requestedDomainPermissions,
1199 boolean newDomainMode) {
1200 // determine the domain ID of the domain, for use in the grant below
1201 Id<DomainId> domainId = domainPersister.getResourceDomainId(connection, domainName);
1202
1203 if (domainId == null) {
1204 throw new IllegalArgumentException("Could not find domain: " + domainName);
1205 }
1206
1207 // validate requested set is not null; empty set is valid and would remove any direct domain permissions
1208 if (requestedDomainPermissions == null) {
1209 throw new IllegalArgumentException("Set of requested domain permissions may not be null");
1210 }
1211
1212 if (!newDomainMode) {
1213 // check if the grantor (=session resource) has permissions to grant the requested permissions
1214 final Set<DomainPermission>
1215 grantorPermissions
1216 = __getEffectiveDomainPermissions(connection,
1217 sessionResource,
1218 domainName);
1219
1220 // check if the grantor (=session resource) has super user permissions to the target domain
1221 if (!grantorPermissions.contains(DomainPermission_SUPER_USER)
1222 && !grantorPermissions.contains(DomainPermission_SUPER_USER_GRANT)) {
1223
1224 final Set<DomainPermission>
1225 directAccessorPermissions
1226 = __getDirectDomainPermissions(connection, accessorResource, domainId);
1227
1228 final Set<DomainPermission>
1229 requestedAddPermissions
1230 = __subtract(requestedDomainPermissions, directAccessorPermissions);
1231
1232 if (!requestedAddPermissions.isEmpty()) {
1233 final Set<DomainPermission> unauthorizedAddPermissions;
1234 unauthorizedAddPermissions
1235 = __subtractDomainPermissionsIfGrantableFrom(requestedAddPermissions, grantorPermissions);
1236
1237 if (unauthorizedAddPermissions.size() > 0) {
1238 throw NotAuthorizedException.newInstanceForAction(sessionResource,
1239 "add the following domain permission(s): " + unauthorizedAddPermissions);
1240 }
1241 }
1242
1243 final Set<DomainPermission>
1244 requestedRemovePermissions
1245 = __subtract(directAccessorPermissions, requestedDomainPermissions);
1246
1247 if (!requestedRemovePermissions.isEmpty()) {
1248 final Set<DomainPermission> unauthorizedRemovePermissions;
1249 unauthorizedRemovePermissions
1250 = __subtractDomainPermissionsIfGrantableFrom(requestedRemovePermissions, grantorPermissions);
1251
1252 if (unauthorizedRemovePermissions.size() > 0) {
1253 throw NotAuthorizedException.newInstanceForAction(sessionResource,
1254 "remove the following domain permission(s): " + unauthorizedRemovePermissions);
1255 }
1256 }
1257 }
1258
1259 // revoke any existing permissions that accessor to has to this domain directly
1260 grantDomainPermissionSysPersister.removeDomainSysPermissions(connection, accessorResource, domainId);
1261 }
1262
1263 // add the new permissions
1264 grantDomainPermissionSysPersister.addDomainSysPermissions(connection,
1265 accessorResource,
1266 sessionResource,
1267 domainId,
1268 requestedDomainPermissions);
1269 }
1270
1271 private Set<DomainPermission> __getDirectDomainPermissions(SQLConnection connection,
1272 Resource accessorResource,
1273 Id<DomainId> domainId) {
1274 // only system permissions are possible on a domain
1275 return grantDomainPermissionSysPersister.getDomainSysPermissions(connection, accessorResource, domainId);
1276 }
1277
1278 private Set<DomainPermission> __subtractDomainPermissionsIfGrantableFrom(Set<DomainPermission> candidatePermissionSet,
1279 Set<DomainPermission> grantorPermissionSet) {
1280 Set<DomainPermission> differenceSet = new HashSet<>(candidatePermissionSet);
1281
1282 for (DomainPermission candidatePermission : candidatePermissionSet) {
1283 for (DomainPermission grantorPermission : grantorPermissionSet) {
1284 if (candidatePermission.isGrantableFrom(grantorPermission)) {
1285 differenceSet.remove(candidatePermission);
1286 break;
1287 }
1288 }
1289 }
1290
1291 return differenceSet;
1292 }
1293
1294 @Override
1295 public void grantDomainPermissions(Resource accessorResource,
1296 String domainName,
1297 Set<DomainPermission> domainPermissions) {
1298 SQLConnection connection = null;
1299
1300 __assertAuthenticated();
1301 __assertResourceSpecified(accessorResource);
1302 __assertDomainSpecified(domainName);
1303 __assertPermissionsSpecified(domainPermissions);
1304 __assertPermissionsSetNotEmpty(domainPermissions);
1305
1306 final Set<DomainPermission> normalizedDomainPermissions = __normalizeDomainPermissions(domainPermissions);
1307
1308 try {
1309 connection = __getConnection();
1310 accessorResource = __resolveResource(connection, accessorResource);
1311
1312 __grantDirectDomainPermissions(connection, accessorResource, domainName, normalizedDomainPermissions);
1313 }
1314 finally {
1315 __closeConnection(connection);
1316 }
1317 }
1318
1319 @Override
1320 public void grantDomainPermissions(Resource accessorResource,
1321 String domainName,
1322 DomainPermission domainPermission,
1323 DomainPermission... domainPermissions) {
1324 SQLConnection connection = null;
1325
1326 __assertAuthenticated();
1327 __assertResourceSpecified(accessorResource);
1328 __assertDomainSpecified(domainName);
1329 __assertPermissionSpecified(domainPermission);
1330 __assertVarargPermissionsSpecified(domainPermissions);
1331
1332 final Set<DomainPermission> normalizedDomainPermissions
1333 = __normalizeDomainPermissions(__getSetWithoutNullsOrDuplicates(domainPermission, domainPermissions));
1334
1335 try {
1336 connection = __getConnection();
1337 accessorResource = __resolveResource(connection, accessorResource);
1338
1339 __grantDirectDomainPermissions(connection, accessorResource, domainName, normalizedDomainPermissions);
1340 }
1341 finally {
1342 __closeConnection(connection);
1343 }
1344 }
1345
1346 private void __grantDirectDomainPermissions(SQLConnection connection,
1347 Resource accessorResource,
1348 String domainName,
1349 Set<DomainPermission> requestedDomainPermissions) {
1350 __assertUniqueDomainPermissionsNames(requestedDomainPermissions);
1351
1352 // determine the domain ID of the domain, for use in the grant below
1353 Id<DomainId> domainId = domainPersister.getResourceDomainId(connection, domainName);
1354
1355 if (domainId == null) {
1356 throw new IllegalArgumentException("Could not find domain: " + domainName);
1357 }
1358
1359 // validate requested set is not null; empty set is valid and would remove any direct domain permissions
1360 if (requestedDomainPermissions == null) {
1361 throw new IllegalArgumentException("Set of requested domain permissions may not be null");
1362 }
1363
1364 // check if the grantor (=session resource) has permissions to grant the requested permissions
1365 final Set<DomainPermission>
1366 grantorPermissions
1367 = __getEffectiveDomainPermissions(connection,
1368 sessionResource,
1369 domainName);
1370
1371 // check if the grantor (=session resource) has super user permissions to the target domain
1372 if (!grantorPermissions.contains(DomainPermission_SUPER_USER)
1373 && !grantorPermissions.contains(DomainPermission_SUPER_USER_GRANT)) {
1374
1375 final Set<DomainPermission> unauthorizedPermissions
1376 = __subtractDomainPermissionsIfGrantableFrom(requestedDomainPermissions, grantorPermissions);
1377
1378 if (unauthorizedPermissions.size() > 0) {
1379 throw NotAuthorizedException.newInstanceForAction(sessionResource,
1380 "grant the following domain permission(s): " + unauthorizedPermissions);
1381 }
1382 }
1383
1384 final Set<DomainPermission> directAccessorPermissions
1385 = __getDirectDomainPermissions(connection, accessorResource, domainId);
1386
1387 final Set<DomainPermission> addPermissions = new HashSet<>(requestedDomainPermissions.size());
1388 final Set<DomainPermission> updatePermissions = new HashSet<>(requestedDomainPermissions.size());
1389
1390 for (DomainPermission requestedPermission : requestedDomainPermissions) {
1391 boolean existingPermission = false;
1392
1393 for (DomainPermission existingDirectPermission : directAccessorPermissions) {
1394 if (requestedPermission.equalsIgnoreGrantOption(existingDirectPermission)) {
1395 // we found a match by permission name - now let's see if we need to update existing or leave it unchanged
1396 if (!requestedPermission.equals(existingDirectPermission) &&
1397 !requestedPermission.isGrantableFrom(existingDirectPermission)) {
1398 // requested permission has higher granting rights than the already existing direct permission,
1399 // so we need to update it
1400 updatePermissions.add(requestedPermission);
1401 }
1402
1403 existingPermission = true;
1404 break;
1405 }
1406 }
1407
1408 if (!existingPermission) {
1409 // couldn't find requested permission in set of already existing direct permissions, by name, so we need to add it
1410 addPermissions.add(requestedPermission);
1411 }
1412 }
1413
1414 // update any existing permissions that accessor to has to this domain directly
1415 grantDomainPermissionSysPersister.updateDomainSysPermissions(connection,
1416 accessorResource,
1417 sessionResource,
1418 domainId,
1419 updatePermissions);
1420
1421 // add the new permissions
1422 grantDomainPermissionSysPersister.addDomainSysPermissions(connection,
1423 accessorResource,
1424 sessionResource,
1425 domainId,
1426 addPermissions);
1427 }
1428
1429 private void __assertUniqueDomainPermissionsNames(Set<DomainPermission> domainPermissions) {
1430 final Set<String> uniquePermissionNames = new HashSet<>(domainPermissions.size());
1431
1432 for (final DomainPermission domainPermissionPermission : domainPermissions) {
1433 if (uniquePermissionNames.contains(domainPermissionPermission.getPermissionName())) {
1434 throw new IllegalArgumentException("Duplicate permission: " + domainPermissionPermission.getPermissionName()
1435 + " that only differs in 'withGrant' option");
1436 }
1437 else {
1438 uniquePermissionNames.add(domainPermissionPermission.getPermissionName());
1439 }
1440 }
1441 }
1442
1443 @Override
1444 public void revokeDomainPermissions(Resource accessorResource,
1445 String domainName,
1446 Set<DomainPermission> domainPermissions) {
1447 SQLConnection connection = null;
1448
1449 __assertAuthenticated();
1450 __assertResourceSpecified(accessorResource);
1451 __assertDomainSpecified(domainName);
1452 __assertPermissionsSpecified(domainPermissions);
1453 __assertPermissionsSetNotEmpty(domainPermissions);
1454
1455 final Set<DomainPermission> normalizedDomainPermissions = __normalizeDomainPermissions(domainPermissions);
1456
1457 try {
1458 connection = __getConnection();
1459 accessorResource = __resolveResource(connection, accessorResource);
1460
1461 __revokeDirectDomainPermissions(connection, accessorResource, domainName, normalizedDomainPermissions);
1462 }
1463 finally {
1464 __closeConnection(connection);
1465 }
1466 }
1467
1468 @Override
1469 public void revokeDomainPermissions(Resource accessorResource,
1470 String domainName,
1471 DomainPermission domainPermission,
1472 DomainPermission... domainPermissions) {
1473 SQLConnection connection = null;
1474
1475 __assertAuthenticated();
1476 __assertResourceSpecified(accessorResource);
1477 __assertDomainSpecified(domainName);
1478 __assertPermissionSpecified(domainPermission);
1479 __assertVarargPermissionsSpecified(domainPermissions);
1480
1481 final Set<DomainPermission> normalizedDomainPermissions
1482 = __normalizeDomainPermissions(__getSetWithoutNullsOrDuplicates(domainPermission, domainPermissions));
1483
1484 try {
1485 connection = __getConnection();
1486 accessorResource = __resolveResource(connection, accessorResource);
1487
1488 __revokeDirectDomainPermissions(connection, accessorResource, domainName, normalizedDomainPermissions);
1489 }
1490 finally {
1491 __closeConnection(connection);
1492 }
1493 }
1494
1495 private void __revokeDirectDomainPermissions(SQLConnection connection,
1496 Resource accessorResource,
1497 String domainName,
1498 Set<DomainPermission> requestedDomainPermissions) {
1499 __assertUniqueDomainPermissionsNames(requestedDomainPermissions);
1500
1501 // determine the domain ID of the domain, for use in the revocation below
1502 Id<DomainId> domainId = domainPersister.getResourceDomainId(connection, domainName);
1503
1504 if (domainId == null) {
1505 throw new IllegalArgumentException("Could not find domain: " + domainName);
1506 }
1507
1508 // validate requested set is not null
1509 if (requestedDomainPermissions == null) {
1510 throw new IllegalArgumentException("Set of requested domain permissions to be revoked may not be null");
1511 }
1512
1513 final Set<DomainPermission>
1514 grantorPermissions
1515 = __getEffectiveDomainPermissions(connection,
1516 sessionResource,
1517 domainName);
1518
1519 // check if the grantor (=session resource) has super user permissions to the target domain or
1520 // has permissions to grant the requested permissions
1521 if (!grantorPermissions.contains(DomainPermission_SUPER_USER)
1522 && !grantorPermissions.contains(DomainPermission_SUPER_USER_GRANT)) {
1523
1524 final Set<DomainPermission> unauthorizedPermissions
1525 = __subtractDomainPermissionsIfGrantableFrom(requestedDomainPermissions, grantorPermissions);
1526
1527 if (unauthorizedPermissions.size() > 0) {
1528 throw NotAuthorizedException.newInstanceForAction(sessionResource,
1529 "revoke the following domain permission(s): " + unauthorizedPermissions);
1530 }
1531 }
1532
1533 final Set<DomainPermission> directAccessorPermissions
1534 = __getDirectDomainPermissions(connection, accessorResource, domainId);
1535
1536 final Set<DomainPermission> removePermissions = new HashSet<>(requestedDomainPermissions.size());
1537
1538 for (DomainPermission requestedPermission : requestedDomainPermissions) {
1539 for (DomainPermission existingDirectPermission : directAccessorPermissions) {
1540 if (requestedPermission.equalsIgnoreGrantOption(existingDirectPermission)) {
1541 // requested permission has same name and regardless of granting rights we need to remove it
1542 removePermissions.add(requestedPermission);
1543 break;
1544 }
1545 }
1546 }
1547
1548 // remove any existing permissions that accessor has to this domain directly
1549 grantDomainPermissionSysPersister.removeDomainSysPermissions(connection,
1550 accessorResource,
1551 domainId,
1552 removePermissions);
1553 }
1554
1555 @Override
1556 public Set<DomainPermission> getDomainPermissions(Resource accessorResource,
1557 String domainName) {
1558 SQLConnection connection = null;
1559
1560 __assertAuthenticated();
1561 __assertResourceSpecified(accessorResource);
1562 __assertDomainSpecified(domainName);
1563
1564 try {
1565 connection = __getConnection();
1566 accessorResource = __resolveResource(connection, accessorResource);
1567 __assertQueryAuthorization(connection, accessorResource);
1568
1569 Id<DomainId> domainId = domainPersister.getResourceDomainId(connection, domainName);
1570
1571 if (domainId == null) {
1572 throw new IllegalArgumentException("Could not find domain: " + domainName);
1573 }
1574
1575 return __getDirectDomainPermissions(connection, accessorResource, domainId);
1576 }
1577 finally {
1578 __closeConnection(connection);
1579 }
1580 }
1581
1582 @Override
1583 public Map<String, Set<DomainPermission>> getDomainPermissionsMap(Resource accessorResource) {
1584 SQLConnection connection = null;
1585
1586 __assertAuthenticated();
1587 __assertResourceSpecified(accessorResource);
1588
1589 try {
1590 connection = __getConnection();
1591 accessorResource = __resolveResource(connection, accessorResource);
1592 __assertQueryAuthorization(connection, accessorResource);
1593
1594 return __collapseDomainPermissions(grantDomainPermissionSysPersister.getDomainSysPermissions(connection,
1595 accessorResource));
1596 }
1597 finally {
1598 __closeConnection(connection);
1599 }
1600
1601 }
1602
1603 @Override
1604 public Set<DomainPermission> getEffectiveDomainPermissions(Resource accessorResource,
1605 String domainName) {
1606 SQLConnection connection = null;
1607
1608 __assertAuthenticated();
1609 __assertResourceSpecified(accessorResource);
1610 __assertDomainSpecified(domainName);
1611
1612 try {
1613 connection = __getConnection();
1614 accessorResource = __resolveResource(connection, accessorResource);
1615 __assertQueryAuthorization(connection, accessorResource);
1616
1617 return __getEffectiveDomainPermissions(connection, accessorResource, domainName);
1618 }
1619 finally {
1620 __closeConnection(connection);
1621 }
1622 }
1623
1624 private Set<DomainPermission> __getEffectiveDomainPermissions(SQLConnection connection,
1625 Resource accessorResource,
1626 String domainName) {
1627 Id<DomainId> domainId = domainPersister.getResourceDomainId(connection, domainName);
1628
1629 if (domainId == null) {
1630 throw new IllegalArgumentException("Could not find domain: " + domainName);
1631 }
1632
1633 return __getEffectiveDomainPermissions(connection, accessorResource, domainId);
1634 }
1635
1636 private Set<DomainPermission> __getEffectiveDomainPermissions(SQLConnection connection,
1637 Resource accessorResource,
1638 Id<DomainId> domainId) {
1639 // only system permissions are possible on a domain
1640 final Set<DomainPermission> domainSysPermissionsIncludingInherited
1641 = grantDomainPermissionSysPersister.getDomainSysPermissionsIncludeInherited(connection,
1642 accessorResource,
1643 domainId);
1644 for (DomainPermission permission : domainSysPermissionsIncludingInherited) {
1645 // check if super-user privileges apply and construct set of all possible permissions, if necessary
1646 if (DomainPermissions.SUPER_USER.equals(permission.getPermissionName())) {
1647 return __getApplicableDomainPermissions();
1648 }
1649 }
1650
1651 return __collapseDomainPermissions(domainSysPermissionsIncludingInherited);
1652 }
1653
1654 private Set<DomainPermission> __collapseDomainPermissions(Set<DomainPermission> domainPermissions) {
1655 final Set<DomainPermission> collapsedPermissions = new HashSet<>(domainPermissions);
1656
1657 for (DomainPermission permission : domainPermissions) {
1658 for (DomainPermission grantEquivalentPermission : domainPermissions) {
1659 if (permission.isGrantableFrom(grantEquivalentPermission) && !permission.equals(grantEquivalentPermission)) {
1660 collapsedPermissions.remove(permission);
1661 break;
1662 }
1663 }
1664 }
1665
1666 return collapsedPermissions;
1667 }
1668
1669 @Override
1670 public Map<String, Set<DomainPermission>> getEffectiveDomainPermissionsMap(Resource accessorResource) {
1671 SQLConnection connection = null;
1672
1673 __assertAuthenticated();
1674 __assertResourceSpecified(accessorResource);
1675
1676 try {
1677 connection = __getConnection();
1678 accessorResource = __resolveResource(connection, accessorResource);
1679 __assertQueryAuthorization(connection, accessorResource);
1680
1681 return __getEffectiveDomainPermissionsMap(connection, accessorResource);
1682 }
1683 finally {
1684 __closeConnection(connection);
1685 }
1686 }
1687
1688 private Map<String, Set<DomainPermission>> __getEffectiveDomainPermissionsMap(SQLConnection connection,
1689 Resource accessorResource) {
1690 final Map<String, Set<DomainPermission>> domainSysPermissionsIncludingInherited
1691 = grantDomainPermissionSysPersister.getDomainSysPermissionsIncludeInherited(connection,
1692 accessorResource);
1693
1694 for (Map.Entry<String, Set<DomainPermission>>
1695 domainPermissionsByDomainEntry : domainSysPermissionsIncludingInherited.entrySet()) {
1696 final Set<DomainPermission> domainPermissions = domainPermissionsByDomainEntry.getValue();
1697
1698 if (domainPermissions.contains(DomainPermission_SUPER_USER)
1699 || domainPermissions.contains(DomainPermission_SUPER_USER_GRANT)) {
1700 domainSysPermissionsIncludingInherited.put(domainPermissionsByDomainEntry.getKey(),
1701 __getApplicableDomainPermissions());
1702 }
1703 }
1704
1705 return __collapseDomainPermissions(domainSysPermissionsIncludingInherited);
1706 }
1707
1708 private static Set<DomainPermission> __getApplicableDomainPermissions() {
1709 Set<DomainPermission> superDomainPermissions = new HashSet<>(3);
1710 superDomainPermissions.add(DomainPermission_SUPER_USER_GRANT);
1711 superDomainPermissions.add(DomainPermission_CREATE_CHILD_DOMAIN_GRANT);
1712 superDomainPermissions.add(DomainPermission_DELETE_GRANT);
1713
1714 return superDomainPermissions;
1715 }
1716
1717 private Map<String, Set<DomainPermission>> __collapseDomainPermissions(Map<String, Set<DomainPermission>> domainPermissionsMap) {
1718 Map<String, Set<DomainPermission>> collapsedDomainPermissionsMap = new HashMap<>(domainPermissionsMap.size());
1719
1720 for (Map.Entry<String, Set<DomainPermission>> domainPermissionsByDomainEntry : domainPermissionsMap.entrySet()) {
1721 collapsedDomainPermissionsMap.put(domainPermissionsByDomainEntry.getKey(),
1722 __collapseDomainPermissions(domainPermissionsByDomainEntry.getValue()));
1723 }
1724
1725 return collapsedDomainPermissionsMap;
1726 }
1727
1728 @Override
1729 public void setDomainCreatePermissions(Resource accessorResource,
1730 Set<DomainCreatePermission> domainCreatePermissions) {
1731 SQLConnection connection = null;
1732
1733 __assertAuthenticated();
1734 __assertResourceSpecified(accessorResource);
1735 __assertPermissionsSpecified(domainCreatePermissions);
1736
1737 final Set<DomainCreatePermission> normalizedDomainCreatePermissions
1738 = __normalizeDomainCreatePermissions(domainCreatePermissions);
1739
1740 try {
1741 connection = __getConnection();
1742 accessorResource = __resolveResource(connection, accessorResource);
1743
1744 __setDirectDomainCreatePermissions(connection, accessorResource, normalizedDomainCreatePermissions);
1745 }
1746 finally {
1747 __closeConnection(connection);
1748 }
1749 }
1750
1751 private void __setDirectDomainCreatePermissions(SQLConnection connection,
1752 Resource accessorResource,
1753 Set<DomainCreatePermission> requestedDomainCreatePermissions) {
1754 __assertSetContainsDomainCreateSystemPermission(requestedDomainCreatePermissions);
1755 __assertUniqueSystemOrPostCreateDomainPermissionNames(requestedDomainCreatePermissions);
1756
1757 // check if grantor (=session resource) is authorized to add/remove requested permissions
1758 final Set<DomainCreatePermission>
1759 grantorPermissions
1760 = __getEffectiveDomainCreatePermissions(connection, sessionResource);
1761
1762 final Set<DomainCreatePermission>
1763 directAccessorPermissions
1764 = __getDirectDomainCreatePermissions(connection, accessorResource);
1765
1766 final Set<DomainCreatePermission>
1767 requestedAddPermissions
1768 = __subtract(requestedDomainCreatePermissions, directAccessorPermissions);
1769
1770 if (!requestedAddPermissions.isEmpty()) {
1771 final Set<DomainCreatePermission>
1772 unauthorizedAddPermissions
1773 = __subtractDomainCreatePermissionsIfGrantableFrom(requestedAddPermissions, grantorPermissions);
1774
1775 if (unauthorizedAddPermissions.size() > 0) {
1776 throw NotAuthorizedException.newInstanceForAction(sessionResource,
1777 "add the following domain create permission(s): " + unauthorizedAddPermissions);
1778 }
1779 }
1780
1781 final Set<DomainCreatePermission>
1782 requestedRemovePermissions
1783 = __subtract(directAccessorPermissions, requestedDomainCreatePermissions);
1784
1785 if (!requestedRemovePermissions.isEmpty()) {
1786 final Set<DomainCreatePermission>
1787 unauthorizedRemovePermissions
1788 = __subtractDomainCreatePermissionsIfGrantableFrom(requestedRemovePermissions, grantorPermissions);
1789
1790 if (unauthorizedRemovePermissions.size() > 0) {
1791 throw NotAuthorizedException.newInstanceForAction(sessionResource,
1792 "remove the following domain create permission(s): " + unauthorizedRemovePermissions);
1793 }
1794 }
1795
1796 // NOTE: our current data model only support system permissions for domains
1797
1798 // revoke any existing domain system permission (*CREATE) this accessor has to this domain
1799 grantDomainCreatePermissionSysPersister.removeDomainCreateSysPermissions(connection, accessorResource);
1800 // revoke any existing domain post create system permissions this accessor has to this domain
1801 grantDomainCreatePermissionPostCreateSysPersister.removeDomainCreatePostCreateSysPermissions(connection,
1802 accessorResource);
1803
1804 // add the domain system permissions (*CREATE)
1805 grantDomainCreatePermissionSysPersister.addDomainCreateSysPermissions(connection,
1806 accessorResource,
1807 sessionResource,
1808 requestedDomainCreatePermissions);
1809 // add the domain post create system permissions
1810 grantDomainCreatePermissionPostCreateSysPersister
1811 .addDomainCreatePostCreateSysPermissions(connection,
1812 accessorResource,
1813 sessionResource,
1814 requestedDomainCreatePermissions);
1815 }
1816
1817 private void __assertSetContainsDomainCreateSystemPermission(Set<DomainCreatePermission> domainCreatePermissions) {
1818 if (!domainCreatePermissions.isEmpty()) {
1819 // if at least one permission is specified, then there must be a *CREATE permission in the set
1820 if (!__setContainsDomainCreateSystemPermission(domainCreatePermissions)) {
1821 throw new IllegalArgumentException("Domain create permission *CREATE must be specified");
1822 }
1823 }
1824 }
1825
1826 private boolean __setContainsDomainCreateSystemPermission(Set<DomainCreatePermission> domainCreatePermissions) {
1827 for (final DomainCreatePermission domainCreatePermission : domainCreatePermissions) {
1828 if (domainCreatePermission.isSystemPermission()
1829 && DomainCreatePermissions.CREATE.equals(domainCreatePermission.getPermissionName())) {
1830 return true;
1831 }
1832 }
1833 return false;
1834 }
1835
1836 private Set<DomainCreatePermission> __getDirectDomainCreatePermissions(SQLConnection connection,
1837 Resource accessorResource) {
1838 final Set<DomainCreatePermission> domainCreatePermissions = new HashSet<>();
1839 domainCreatePermissions
1840 .addAll(grantDomainCreatePermissionSysPersister.getDomainCreateSysPermissions(connection,
1841 accessorResource));
1842 domainCreatePermissions
1843 .addAll(grantDomainCreatePermissionPostCreateSysPersister.getDomainCreatePostCreateSysPermissions(
1844 connection,
1845 accessorResource));
1846 return domainCreatePermissions;
1847 }
1848
1849 private Set<DomainCreatePermission> __subtractDomainCreatePermissionsIfGrantableFrom(Set<DomainCreatePermission> candidatePermissionSet,
1850 Set<DomainCreatePermission> grantorPermissionSet) {
1851 Set<DomainCreatePermission> differenceSet = new HashSet<>(candidatePermissionSet);
1852
1853 for (DomainCreatePermission candidatePermission : candidatePermissionSet) {
1854 for (DomainCreatePermission grantorPermission : grantorPermissionSet) {
1855 if (candidatePermission.isGrantableFrom(grantorPermission)) {
1856 differenceSet.remove(candidatePermission);
1857 break;
1858 }
1859 }
1860 }
1861
1862 return differenceSet;
1863 }
1864
1865 @Override
1866 public void grantDomainCreatePermissions(Resource accessorResource,
1867 Set<DomainCreatePermission> domainCreatePermissions) {
1868 SQLConnection connection = null;
1869
1870 __assertAuthenticated();
1871 __assertResourceSpecified(accessorResource);
1872 __assertPermissionsSpecified(domainCreatePermissions);
1873 __assertPermissionsSetNotEmpty(domainCreatePermissions);
1874
1875 final Set<DomainCreatePermission> normalizedDomainCreatePermissions
1876 = __normalizeDomainCreatePermissions(domainCreatePermissions);
1877
1878 try {
1879 connection = __getConnection();
1880 accessorResource = __resolveResource(connection, accessorResource);
1881
1882 __grantDirectDomainCreatePermissions(connection, accessorResource, normalizedDomainCreatePermissions);
1883 }
1884 finally {
1885 __closeConnection(connection);
1886 }
1887 }
1888
1889 @Override
1890 public void grantDomainCreatePermissions(Resource accessorResource,
1891 DomainCreatePermission domainCreatePermission,
1892 DomainCreatePermission... domainCreatePermissions) {
1893 SQLConnection connection = null;
1894
1895 __assertAuthenticated();
1896 __assertResourceSpecified(accessorResource);
1897 __assertPermissionSpecified(domainCreatePermission);
1898 __assertVarargPermissionsSpecified(domainCreatePermissions);
1899
1900 final Set<DomainCreatePermission> normalizedDomainCreatePermissions
1901 = __normalizeDomainCreatePermissions(__getSetWithoutNullsOrDuplicates(domainCreatePermission, domainCreatePermissions));
1902
1903 try {
1904 connection = __getConnection();
1905 accessorResource = __resolveResource(connection, accessorResource);
1906
1907 __grantDirectDomainCreatePermissions(connection, accessorResource, normalizedDomainCreatePermissions);
1908 }
1909 finally {
1910 __closeConnection(connection);
1911 }
1912 }
1913
1914 private void __grantDirectDomainCreatePermissions(SQLConnection connection,
1915 Resource accessorResource,
1916 Set<DomainCreatePermission> requestedDomainCreatePermissions) {
1917 __assertUniqueSystemOrPostCreateDomainPermissionNames(requestedDomainCreatePermissions);
1918
1919 // check if grantor (=session resource) is authorized to add requested permissions
1920 final Set<DomainCreatePermission>
1921 grantorPermissions
1922 = __getEffectiveDomainCreatePermissions(connection, sessionResource);
1923
1924 final Set<DomainCreatePermission>
1925 unauthorizedPermissions
1926 = __subtractDomainCreatePermissionsIfGrantableFrom(requestedDomainCreatePermissions, grantorPermissions);
1927
1928 if (unauthorizedPermissions.size() > 0) {
1929 throw NotAuthorizedException.newInstanceForAction(sessionResource,
1930 "grant the following domain create permission(s): " + unauthorizedPermissions);
1931 }
1932
1933 final Set<DomainCreatePermission> directAccessorPermissions
1934 = __getDirectDomainCreatePermissions(connection, accessorResource);
1935
1936 if (directAccessorPermissions.isEmpty()) {
1937 // our invariant is that a resource's direct create permissions must include the *CREATE system permission;
1938 // if there are no direct create permissions, then the requested permissions to be granted need to include *CREATE
1939 __assertSetContainsDomainCreateSystemPermission(requestedDomainCreatePermissions);
1940 }
1941
1942 final Set<DomainCreatePermission> addPermissions = new HashSet<>(requestedDomainCreatePermissions.size());
1943 final Set<DomainCreatePermission> updatePermissions = new HashSet<>(requestedDomainCreatePermissions.size());
1944
1945 for (DomainCreatePermission requestedPermission : requestedDomainCreatePermissions) {
1946 boolean existingPermission = false;
1947
1948 if (requestedPermission.isSystemPermission()) {
1949 for (DomainCreatePermission existingDirectPermission : directAccessorPermissions) {
1950
1951 if (existingDirectPermission.isSystemPermission() &&
1952 requestedPermission.getSystemPermissionId() == existingDirectPermission.getSystemPermissionId()) {
1953 // we found a match by sysId - now let's see if we need to update existing or leave it unchanged
1954 if (!requestedPermission.equals(existingDirectPermission) &&
1955 !requestedPermission.isGrantableFrom(existingDirectPermission)) {
1956 // requested permission has higher granting rights than
1957 // the already existing direct permission, so we need to update it
1958 updatePermissions.add(requestedPermission);
1959 }
1960
1961 existingPermission = true;
1962 break;
1963 }
1964 }
1965 }
1966 else {
1967 final DomainPermission requestedPostCreateDomainPermission = requestedPermission.getPostCreateDomainPermission();
1968 for (DomainCreatePermission existingDirectPermission : directAccessorPermissions) {
1969 if (!existingDirectPermission.isSystemPermission()) {
1970 final DomainPermission existingPostCreateDomainPermission
1971 = existingDirectPermission.getPostCreateDomainPermission();
1972
1973 if (requestedPostCreateDomainPermission.equalsIgnoreGrantOption(existingPostCreateDomainPermission)) {
1974 // found a match in name - let's check compatibility first
1975 if (requestedPermission.isWithGrantOption() != requestedPostCreateDomainPermission.isWithGrantOption()
1976 && existingDirectPermission.isWithGrantOption() != existingPostCreateDomainPermission.isWithGrantOption()
1977 && requestedPermission.isWithGrantOption() != existingDirectPermission.isWithGrantOption()) {
1978 // the requested permission is incompatible to the existing permission because we can't
1979 // perform grant operations (a)/G -> (a/G) or (a/G) -> (a)/G without removing either the
1980 // create or post-create granting option
1981 throw new IllegalArgumentException("Requested create permissions "
1982 + requestedDomainCreatePermissions
1983 + " are incompatible with existing create permissions "
1984 + directAccessorPermissions);
1985 }
1986
1987 // now let's see if we need to update existing permission or leave it unchanged
1988 if (!requestedPermission.equals(existingDirectPermission)
1989 && ((requestedPermission.isWithGrantOption() && requestedPostCreateDomainPermission.isWithGrantOption())
1990 || (!existingDirectPermission.isWithGrantOption() && !existingPostCreateDomainPermission.isWithGrantOption()))) {
1991 // the two permissions match in name, but the requested has higher granting rights,
1992 // so we need to update
1993 updatePermissions.add(requestedPermission);
1994 }
1995 // because we found a match in name, we can skip comparing requested against other existing permissions
1996 existingPermission = true;
1997 break;
1998 }
1999 }
2000 }
2001 }
2002
2003 if (!existingPermission) {
2004 // couldn't find requested permission in set of already existing direct permissions, by name, so we need to add it
2005 addPermissions.add(requestedPermission);
2006 }
2007 }
2008
2009 // update the domain system permissions (*CREATE), if necessary
2010 grantDomainCreatePermissionSysPersister.updateDomainCreateSysPermissions(connection,
2011 accessorResource,
2012 sessionResource,
2013 updatePermissions);
2014 // update the domain post create system permissions, if necessary
2015 grantDomainCreatePermissionPostCreateSysPersister
2016 .updateDomainCreatePostCreateSysPermissions(connection,
2017 accessorResource,
2018 sessionResource,
2019 updatePermissions);
2020
2021 // add any new domain system permissions (*CREATE)
2022 grantDomainCreatePermissionSysPersister.addDomainCreateSysPermissions(connection,
2023 accessorResource,
2024 sessionResource,
2025 addPermissions);
2026 // add any new domain post create system permissions
2027 grantDomainCreatePermissionPostCreateSysPersister
2028 .addDomainCreatePostCreateSysPermissions(connection,
2029 accessorResource,
2030 sessionResource,
2031 addPermissions);
2032 }
2033
2034 private void __assertUniqueSystemOrPostCreateDomainPermissionNames(Set<DomainCreatePermission> domainCreatePermissions) {
2035 final Set<String> uniqueSystemPermissionNames = new HashSet<>(domainCreatePermissions.size());
2036 final Set<String> uniquePostCreatePermissionNames = new HashSet<>(domainCreatePermissions.size());
2037
2038 for (final DomainCreatePermission domainCreatePermission : domainCreatePermissions) {
2039 if (domainCreatePermission.isSystemPermission()) {
2040 if (uniqueSystemPermissionNames.contains(domainCreatePermission.getPermissionName())) {
2041 throw new IllegalArgumentException("Duplicate permission: "
2042 + domainCreatePermission.getPermissionName()
2043 + " that only differs in 'withGrant' option");
2044 }
2045 else {
2046 uniqueSystemPermissionNames.add(domainCreatePermission.getPermissionName());
2047 }
2048 }
2049 else {
2050 final DomainPermission postCreateDomainPermission = domainCreatePermission.getPostCreateDomainPermission();
2051
2052 if (uniquePostCreatePermissionNames.contains(postCreateDomainPermission.getPermissionName())) {
2053 throw new IllegalArgumentException("Duplicate permission: "
2054 + postCreateDomainPermission.getPermissionName()
2055 + " that only differs in 'withGrant' option");
2056 }
2057 else {
2058 uniquePostCreatePermissionNames.add(postCreateDomainPermission.getPermissionName());
2059 }
2060 }
2061 }
2062 }
2063
2064 @Override
2065 public void revokeDomainCreatePermissions(Resource accessorResource,
2066 Set<DomainCreatePermission> domainCreatePermissions) {
2067 SQLConnection connection = null;
2068
2069 __assertAuthenticated();
2070 __assertResourceSpecified(accessorResource);
2071 __assertPermissionsSpecified(domainCreatePermissions);
2072 __assertPermissionsSetNotEmpty(domainCreatePermissions);
2073
2074 final Set<DomainCreatePermission> normalizedDomainCreatePermissions
2075 = __normalizeDomainCreatePermissions(domainCreatePermissions);
2076
2077 try {
2078 connection = __getConnection();
2079 accessorResource = __resolveResource(connection, accessorResource);
2080
2081 __revokeDirectDomainCreatePermissions(connection, accessorResource, normalizedDomainCreatePermissions);
2082 }
2083 finally {
2084 __closeConnection(connection);
2085 }
2086 }
2087
2088 @Override
2089 public void revokeDomainCreatePermissions(Resource accessorResource,
2090 DomainCreatePermission domainCreatePermission,
2091 DomainCreatePermission... domainCreatePermissions) {
2092 SQLConnection connection = null;
2093
2094 __assertAuthenticated();
2095 __assertResourceSpecified(accessorResource);
2096 __assertPermissionSpecified(domainCreatePermission);
2097 __assertVarargPermissionsSpecified(domainCreatePermissions);
2098
2099 final Set<DomainCreatePermission> normalizedDomainCreatePermissions
2100 = __normalizeDomainCreatePermissions(__getSetWithoutNullsOrDuplicates(domainCreatePermission, domainCreatePermissions));
2101
2102 try {
2103 connection = __getConnection();
2104 accessorResource = __resolveResource(connection, accessorResource);
2105
2106 __revokeDirectDomainCreatePermissions(connection, accessorResource, normalizedDomainCreatePermissions);
2107 }
2108 finally {
2109 __closeConnection(connection);
2110 }
2111 }
2112
2113 private void __revokeDirectDomainCreatePermissions(SQLConnection connection,
2114 Resource accessorResource,
2115 Set<DomainCreatePermission> requestedDomainCreatePermissions) {
2116 __assertUniqueSystemOrPostCreateDomainPermissionNames(requestedDomainCreatePermissions);
2117
2118 // check if grantor (=session resource) is authorized to revoke requested permissions
2119 final Set<DomainCreatePermission>
2120 grantorPermissions
2121 = __getEffectiveDomainCreatePermissions(connection, sessionResource);
2122
2123 final Set<DomainCreatePermission>
2124 unauthorizedPermissions
2125 = __subtractDomainCreatePermissionsIfGrantableFrom(requestedDomainCreatePermissions, grantorPermissions);
2126
2127 if (unauthorizedPermissions.size() > 0) {
2128 throw NotAuthorizedException.newInstanceForAction(sessionResource,
2129 "revoke the following domain create permission(s): " + unauthorizedPermissions);
2130 }
2131
2132 final Set<DomainCreatePermission> directAccessorPermissions
2133 = __getDirectDomainCreatePermissions(connection, accessorResource);
2134
2135 if ((directAccessorPermissions.size() > requestedDomainCreatePermissions.size()) &&
2136 __setContainsDomainCreateSystemPermission(requestedDomainCreatePermissions)) {
2137 // our invariant is that a resource's direct create permissions must include the *CREATE system permission;
2138 // if after revoking the requested permissions, the remaining set wouldn't include the *CREATE, we'd have a problem
2139 throw new IllegalArgumentException(
2140 "Attempt to revoke a subset of domain create permissions that includes the *CREATE system permission: "
2141 + requestedDomainCreatePermissions);
2142 }
2143
2144 final Set<DomainCreatePermission> removePermissions = new HashSet<>(requestedDomainCreatePermissions.size());
2145
2146 for (DomainCreatePermission requestedPermission : requestedDomainCreatePermissions) {
2147 if (requestedPermission.isSystemPermission()) {
2148 for (DomainCreatePermission existingDirectPermission : directAccessorPermissions) {
2149 if (existingDirectPermission.isSystemPermission() &&
2150 requestedPermission.getSystemPermissionId() == existingDirectPermission.getSystemPermissionId()) {
2151 // requested permission has same system Id as an already existing direct permission, so remove it
2152 removePermissions.add(requestedPermission);
2153 break;
2154 }
2155 }
2156 }
2157 else {
2158 final DomainPermission requestedPostCreateDomainPermission = requestedPermission.getPostCreateDomainPermission();
2159 for (DomainCreatePermission existingDirectPermission : directAccessorPermissions) {
2160 if (!existingDirectPermission.isSystemPermission()) {
2161 // now let's look at the post-create permissions
2162 if (requestedPostCreateDomainPermission.equalsIgnoreGrantOption(existingDirectPermission.getPostCreateDomainPermission())) {
2163 // requested post-create permission has same name as an already existing direct permission, so remove it
2164 removePermissions.add(requestedPermission);
2165 break;
2166 }
2167 }
2168 }
2169 }
2170 }
2171
2172 // remove the domain system permissions (*CREATE), if necessary
2173 grantDomainCreatePermissionSysPersister.removeDomainCreateSysPermissions(connection,
2174 accessorResource,
2175 removePermissions);
2176 // remove the domain post create system permissions, if necessary
2177 grantDomainCreatePermissionPostCreateSysPersister.removeDomainCreatePostCreateSysPermissions(connection,
2178 accessorResource,
2179 removePermissions);
2180 }
2181
2182 @Override
2183 public Set<DomainCreatePermission> getDomainCreatePermissions(Resource accessorResource) {
2184 SQLConnection connection = null;
2185
2186 __assertAuthenticated();
2187 __assertResourceSpecified(accessorResource);
2188
2189 try {
2190 connection = __getConnection();
2191 accessorResource = __resolveResource(connection, accessorResource);
2192 __assertQueryAuthorization(connection, accessorResource);
2193
2194 return __getDirectDomainCreatePermissions(connection, accessorResource);
2195 }
2196 finally {
2197 __closeConnection(connection);
2198 }
2199 }
2200
2201 @Override
2202 public Set<DomainCreatePermission> getEffectiveDomainCreatePermissions(Resource accessorResource) {
2203 SQLConnection connection = null;
2204
2205 __assertAuthenticated();
2206 __assertResourceSpecified(accessorResource);
2207
2208 try {
2209 connection = __getConnection();
2210 accessorResource = __resolveResource(connection, accessorResource);
2211 __assertQueryAuthorization(connection, accessorResource);
2212
2213 return __getEffectiveDomainCreatePermissions(connection, accessorResource);
2214 }
2215 finally {
2216 __closeConnection(connection);
2217 }
2218 }
2219
2220 private Set<DomainCreatePermission> __getEffectiveDomainCreatePermissions(SQLConnection connection,
2221 Resource accessorResource) {
2222 final Set<DomainCreatePermission> domainCreatePermissions = new HashSet<>();
2223 domainCreatePermissions
2224 .addAll(grantDomainCreatePermissionSysPersister.getDomainCreateSysPermissionsIncludeInherited(connection,
2225 accessorResource));
2226 domainCreatePermissions
2227 .addAll(grantDomainCreatePermissionPostCreateSysPersister
2228 .getDomainCreatePostCreateSysPermissionsIncludeInherited(connection,
2229 accessorResource));
2230 return __collapseDomainCreatePermissions(domainCreatePermissions);
2231 }
2232
2233 private Set<DomainCreatePermission> __collapseDomainCreatePermissions(Set<DomainCreatePermission> domainCreatePermissions) {
2234 final Set<DomainCreatePermission> collapsedPermissions = new HashSet<>(domainCreatePermissions);
2235
2236 for (DomainCreatePermission permission : domainCreatePermissions) {
2237 for (DomainCreatePermission grantEquivalentPermission : domainCreatePermissions) {
2238 if (permission.isGrantableFrom(grantEquivalentPermission) && !permission.equals(grantEquivalentPermission)) {
2239 collapsedPermissions.remove(permission);
2240 break;
2241 }
2242 }
2243 }
2244
2245 return collapsedPermissions;
2246 }
2247
2248 @Override
2249 public void setResourceCreatePermissions(Resource accessorResource,
2250 String resourceClassName,
2251 String domainName,
2252 Set<ResourceCreatePermission> resourceCreatePermissions) {
2253 SQLConnection connection = null;
2254
2255 __assertAuthenticated();
2256 __assertResourceSpecified(accessorResource);
2257 __assertResourceClassSpecified(resourceClassName);
2258 __assertDomainSpecified(domainName);
2259 __assertPermissionsSpecified(resourceCreatePermissions);
2260
2261 final Set<ResourceCreatePermission> normalizedResourceCreatePermissions
2262 = __normalizeResourceCreatePermission(resourceCreatePermissions);
2263
2264 try {
2265 connection = __getConnection();
2266 accessorResource = __resolveResource(connection, accessorResource);
2267
2268 __setDirectResourceCreatePermissions(connection,
2269 accessorResource,
2270 resourceClassName,
2271 domainName,
2272 normalizedResourceCreatePermissions);
2273 }
2274 finally {
2275 __closeConnection(connection);
2276 }
2277 }
2278
2279 private void __setDirectResourceCreatePermissions(SQLConnection connection,
2280 Resource accessorResource,
2281 String resourceClassName,
2282 String domainName,
2283 Set<ResourceCreatePermission> requestedResourceCreatePermissions) {
2284 // verify that resource class is defined and get its metadata
2285 final ResourceClassInternalInfo resourceClassInfo = __getResourceClassInternalInfo(connection,
2286 resourceClassName);
2287
2288 final Id<ResourceClassId> resourceClassId = Id.from(resourceClassInfo.getResourceClassId());
2289
2290 // verify that domain is defined
2291 final Id<DomainId> domainId = domainPersister.getResourceDomainId(connection, domainName);
2292
2293 if (domainId == null) {
2294 throw new IllegalArgumentException("Could not find domain: " + domainName);
2295 }
2296
2297 // ensure that the *CREATE system permissions was specified
2298 __assertSetContainsResourceCreateSystemPermission(requestedResourceCreatePermissions);
2299
2300 // ensure that the post create permissions are all in the correct resource class
2301 __assertUniquePostCreatePermissionsNamesForResourceClass(connection, requestedResourceCreatePermissions, resourceClassInfo);
2302
2303 // check if the grantor (=session resource) is authorized to grant the requested permissions
2304 if (!__isSuperUserOfDomain(connection, sessionResource, domainName)) {
2305 final Set<ResourceCreatePermission>
2306 grantorPermissions
2307 = __getEffectiveResourceCreatePermissionsIgnoringSuperUserPrivileges(connection,
2308 sessionResource,
2309 resourceClassName,
2310 domainName);
2311
2312 final Set<ResourceCreatePermission>
2313 directAccessorPermissions
2314 = __getDirectResourceCreatePermissions(connection,
2315 accessorResource,
2316 resourceClassId,
2317 domainId);
2318
2319 final Set<ResourceCreatePermission>
2320 requestedAddPermissions
2321 = __subtract(requestedResourceCreatePermissions, directAccessorPermissions);
2322
2323 if (!requestedAddPermissions.isEmpty()) {
2324 final Set<ResourceCreatePermission>
2325 unauthorizedAddPermissions
2326 = __subtractResourceCreatePermissionsIfGrantableFrom(requestedAddPermissions, grantorPermissions);
2327
2328 if (unauthorizedAddPermissions.size() > 0) {
2329 throw NotAuthorizedException.newInstanceForAction(sessionResource,
2330 "add the following permission(s): " + unauthorizedAddPermissions);
2331 }
2332 }
2333
2334 final Set<ResourceCreatePermission>
2335 requestedRemovePermissions
2336 = __subtract(directAccessorPermissions, requestedResourceCreatePermissions);
2337
2338 if (!requestedRemovePermissions.isEmpty()) {
2339 final Set<ResourceCreatePermission>
2340 unauthorizedRemovePermissions
2341 = __subtractResourceCreatePermissionsIfGrantableFrom(requestedRemovePermissions, grantorPermissions);
2342
2343 if (unauthorizedRemovePermissions.size() > 0) {
2344 throw NotAuthorizedException.newInstanceForAction(sessionResource,
2345 "remove the following permission(s): " + unauthorizedRemovePermissions);
2346 }
2347 }
2348 }
2349
2350 // revoke any existing *CREATE system permissions this accessor has to this resource class
2351 grantResourceCreatePermissionSysPersister.removeResourceCreateSysPermissions(connection,
2352 accessorResource,
2353 resourceClassId,
2354 domainId);
2355
2356
2357 // revoke any existing post create system permissions this accessor has to this resource class
2358 grantResourceCreatePermissionPostCreateSysPersister.removeResourceCreatePostCreateSysPermissions(connection,
2359 accessorResource,
2360 resourceClassId,
2361 domainId);
2362
2363 // revoke any existing post create non-system permissions this accessor has to this resource class
2364 grantResourceCreatePermissionPostCreatePersister.removeResourceCreatePostCreatePermissions(connection,
2365 accessorResource,
2366 resourceClassId,
2367 domainId);
2368
2369 // grant the *CREATE system permissions
2370 grantResourceCreatePermissionSysPersister.addResourceCreateSysPermissions(connection,
2371 accessorResource,
2372 resourceClassId,
2373 domainId,
2374 requestedResourceCreatePermissions,
2375 sessionResource);
2376
2377 // grant the post create system permissions
2378 grantResourceCreatePermissionPostCreateSysPersister.addResourceCreatePostCreateSysPermissions(connection,
2379 accessorResource,
2380 resourceClassId,
2381 domainId,
2382 requestedResourceCreatePermissions,
2383 sessionResource);
2384
2385 // grant the post create non-system permissions
2386 grantResourceCreatePermissionPostCreatePersister.addResourceCreatePostCreatePermissions(connection,
2387 accessorResource,
2388 resourceClassId,
2389 domainId,
2390 requestedResourceCreatePermissions,
2391 sessionResource);
2392 }
2393
2394 private void __assertSetContainsResourceCreateSystemPermission(Set<ResourceCreatePermission> resourceCreatePermissions) {
2395 if (!resourceCreatePermissions.isEmpty()) {
2396 boolean createSysPermissionFound = false;
2397 for (final ResourceCreatePermission resourceCreatePermission : resourceCreatePermissions) {
2398 if (resourceCreatePermission.isSystemPermission()
2399 && ResourceCreatePermissions.CREATE.equals(resourceCreatePermission.getPermissionName())) {
2400 createSysPermissionFound = true;
2401 break;
2402 }
2403 }
2404 // if at least one permission is specified, then there must be a *CREATE permission in the set
2405 if (!createSysPermissionFound) {
2406 throw new IllegalArgumentException("Permission: *CREATE must be specified");
2407 }
2408 }
2409 }
2410
2411 private void __assertUniquePostCreatePermissionsNamesForResourceClass(SQLConnection connection,
2412 Set<ResourceCreatePermission> resourceCreatePermissions,
2413 ResourceClassInternalInfo resourceClassInternalInfo) {
2414 final List<String> validPermissionNames =
2415 __getApplicableResourcePermissionNames(connection, resourceClassInternalInfo);
2416 final Set<String> uniqueSystemPermissionNames = new HashSet<>(resourceCreatePermissions.size());
2417 final Set<String> uniquePostCreatePermissionNames = new HashSet<>(resourceCreatePermissions.size());
2418
2419 for (final ResourceCreatePermission resourceCreatePermission : resourceCreatePermissions) {
2420 if (resourceCreatePermission.isSystemPermission()) {
2421 if (uniqueSystemPermissionNames.contains(resourceCreatePermission.getPermissionName())) {
2422 throw new IllegalArgumentException("Duplicate permission: "
2423 + resourceCreatePermission.getPermissionName()
2424 + " that only differs in 'withGrant' option");
2425 }
2426 else {
2427 uniqueSystemPermissionNames.add(resourceCreatePermission.getPermissionName());
2428 }
2429 }
2430 else {
2431 final ResourcePermission postCreateResourcePermission = resourceCreatePermission.getPostCreateResourcePermission();
2432
2433 if (!validPermissionNames.contains(postCreateResourcePermission.getPermissionName())) {
2434 if (postCreateResourcePermission.isSystemPermission()) {
2435 // currently the only invalid system permissions are for unauthenticatable resource classes
2436 throw new IllegalArgumentException("Permission: "
2437 + postCreateResourcePermission.getPermissionName()
2438 + ", not valid for unauthenticatable resource");
2439 }
2440 else {
2441 throw new IllegalArgumentException("Permission: "
2442 + postCreateResourcePermission.getPermissionName()
2443 + " is not defined for resource class: "
2444 + resourceClassInternalInfo.getResourceClassName());
2445 }
2446 }
2447
2448 if (uniquePostCreatePermissionNames.contains(postCreateResourcePermission.getPermissionName())) {
2449 throw new IllegalArgumentException("Duplicate permission: "
2450 + postCreateResourcePermission.getPermissionName()
2451 + " that only differs in 'withGrant' option");
2452 }
2453 else {
2454 uniquePostCreatePermissionNames.add(postCreateResourcePermission.getPermissionName());
2455 }
2456 }
2457 }
2458 }
2459
2460 private Set<ResourceCreatePermission> __subtractResourceCreatePermissionsIfGrantableFrom(Set<ResourceCreatePermission> candidatePermissionSet,
2461 Set<ResourceCreatePermission> grantorPermissionSet) {
2462 Set<ResourceCreatePermission> differenceSet = new HashSet<>(candidatePermissionSet);
2463
2464 for (ResourceCreatePermission candidatePermission : candidatePermissionSet) {
2465 for (ResourceCreatePermission grantorPermission : grantorPermissionSet) {
2466 if (candidatePermission.isGrantableFrom(grantorPermission)) {
2467 differenceSet.remove(candidatePermission);
2468 break;
2469 }
2470 }
2471 }
2472
2473 return differenceSet;
2474 }
2475
2476 private <T> Set<T> __subtract(Set<T> minuendSet, Set<T> subtrahendSet) {
2477 Set<T> differenceSet = new HashSet<>(minuendSet);
2478
2479 differenceSet.removeAll(subtrahendSet);
2480
2481 return differenceSet;
2482 }
2483
2484 private Set<ResourceCreatePermission> __getDirectResourceCreatePermissions(SQLConnection connection,
2485 Resource accessorResource,
2486 Id<ResourceClassId> resourceClassId,
2487 Id<DomainId> domainId) {
2488 Set<ResourceCreatePermission> resourceCreatePermissions = new HashSet<>();
2489
2490 // first get the *CREATE system permission the accessor has directly to the specified resource class
2491 resourceCreatePermissions
2492 .addAll(grantResourceCreatePermissionSysPersister.getResourceCreateSysPermissions(connection,
2493 accessorResource,
2494 resourceClassId,
2495 domainId));
2496
2497 // next get the post create system permissions the accessor has directly to the specified resource class
2498 resourceCreatePermissions
2499 .addAll(grantResourceCreatePermissionPostCreateSysPersister.getResourceCreatePostCreateSysPermissions(
2500 connection,
2501 accessorResource,
2502 resourceClassId,
2503 domainId));
2504
2505 // next get the post create non-system permissions the accessor has directly to the specified resource class
2506 resourceCreatePermissions
2507 .addAll(grantResourceCreatePermissionPostCreatePersister.getResourceCreatePostCreatePermissions(
2508 connection,
2509 accessorResource,
2510 resourceClassId,
2511 domainId));
2512
2513 return resourceCreatePermissions;
2514 }
2515
2516 @Override
2517 public void grantResourceCreatePermissions(Resource accessorResource,
2518 String resourceClassName,
2519 String domainName,
2520 Set<ResourceCreatePermission> resourceCreatePermissions) {
2521 SQLConnection connection = null;
2522
2523 __assertAuthenticated();
2524 __assertResourceSpecified(accessorResource);
2525 __assertResourceClassSpecified(resourceClassName);
2526 __assertDomainSpecified(domainName);
2527 __assertPermissionsSpecified(resourceCreatePermissions);
2528 __assertPermissionsSetNotEmpty(resourceCreatePermissions);
2529
2530 final Set<ResourceCreatePermission> normalizedResourceCreatePermissions
2531 = __normalizeResourceCreatePermission(resourceCreatePermissions);
2532
2533 try {
2534 connection = __getConnection();
2535 accessorResource = __resolveResource(connection, accessorResource);
2536
2537 __grantDirectResourceCreatePermissions(connection,
2538 accessorResource,
2539 resourceClassName,
2540 domainName,
2541 normalizedResourceCreatePermissions);
2542 }
2543 finally {
2544 __closeConnection(connection);
2545 }
2546 }
2547
2548 @Override
2549 public void grantResourceCreatePermissions(Resource accessorResource,
2550 String resourceClassName,
2551 String domainName,
2552 ResourceCreatePermission resourceCreatePermission,
2553 ResourceCreatePermission... resourceCreatePermissions) {
2554 SQLConnection connection = null;
2555
2556 __assertAuthenticated();
2557 __assertResourceSpecified(accessorResource);
2558 __assertResourceClassSpecified(resourceClassName);
2559 __assertDomainSpecified(domainName);
2560 __assertPermissionSpecified(resourceCreatePermission);
2561 __assertVarargPermissionsSpecified(resourceCreatePermissions);
2562
2563 final Set<ResourceCreatePermission> normalizedResourceCreatePermissions
2564 = __normalizeResourceCreatePermission(__getSetWithoutNullsOrDuplicates(resourceCreatePermission,
2565 resourceCreatePermissions));
2566 try {
2567 connection = __getConnection();
2568 accessorResource = __resolveResource(connection, accessorResource);
2569
2570 __grantDirectResourceCreatePermissions(connection,
2571 accessorResource,
2572 resourceClassName,
2573 domainName,
2574 normalizedResourceCreatePermissions);
2575 }
2576 finally {
2577 __closeConnection(connection);
2578 }
2579 }
2580
2581 private void __grantDirectResourceCreatePermissions(SQLConnection connection,
2582 Resource accessorResource,
2583 String resourceClassName,
2584 String domainName,
2585 Set<ResourceCreatePermission> requestedResourceCreatePermissions) {
2586 // verify that resource class is defined and get its metadata
2587 final ResourceClassInternalInfo resourceClassInfo = __getResourceClassInternalInfo(connection,
2588 resourceClassName);
2589
2590 final Id<ResourceClassId> resourceClassId = Id.from(resourceClassInfo.getResourceClassId());
2591
2592 // verify that domain is defined
2593 final Id<DomainId> domainId = domainPersister.getResourceDomainId(connection, domainName);
2594
2595 if (domainId == null) {
2596 throw new IllegalArgumentException("Could not find domain: " + domainName);
2597 }
2598
2599 // ensure that the post create permissions are all in the correct resource class
2600 __assertUniquePostCreatePermissionsNamesForResourceClass(connection, requestedResourceCreatePermissions, resourceClassInfo);
2601
2602 // check if the grantor (=session resource) is authorized to grant the requested permissions
2603 if (!__isSuperUserOfDomain(connection, sessionResource, domainName)) {
2604 final Set<ResourceCreatePermission> grantorPermissions
2605 = __getEffectiveResourceCreatePermissionsIgnoringSuperUserPrivileges(connection,
2606 sessionResource,
2607 resourceClassName,
2608 domainName);
2609
2610 final Set<ResourceCreatePermission> unauthorizedAddPermissions
2611 = __subtractResourceCreatePermissionsIfGrantableFrom(requestedResourceCreatePermissions, grantorPermissions);
2612
2613 if (unauthorizedAddPermissions.size() > 0) {
2614 throw NotAuthorizedException.newInstanceForAction(sessionResource,
2615 "grant the following permission(s): " + unauthorizedAddPermissions);
2616 }
2617 }
2618
2619 // ensure that the *CREATE system permissions was specified
2620 final Set<ResourceCreatePermission>
2621 directAccessorPermissions
2622 = __getDirectResourceCreatePermissions(connection,
2623 accessorResource,
2624 resourceClassId,
2625 domainId);
2626
2627 if (directAccessorPermissions.isEmpty()) {
2628 // our invariant is that a resource's direct create permissions must include the *CREATE system permission;
2629 // if there are no direct create permissions, then the requested permissions to be granted needs to include *CREATE
2630 __assertSetContainsResourceCreateSystemPermission(requestedResourceCreatePermissions);
2631 }
2632
2633 final Set<ResourceCreatePermission> addPermissions = new HashSet<>(requestedResourceCreatePermissions.size());
2634 final Set<ResourceCreatePermission> updatePermissions = new HashSet<>(requestedResourceCreatePermissions.size());
2635
2636 for (ResourceCreatePermission requestedPermission : requestedResourceCreatePermissions) {
2637 boolean existingPermission = false;
2638
2639 if (requestedPermission.isSystemPermission()) {
2640 for (ResourceCreatePermission existingDirectPermission : directAccessorPermissions) {
2641 if (existingDirectPermission.isSystemPermission() &&
2642 requestedPermission.getSystemPermissionId() == existingDirectPermission.getSystemPermissionId()) {
2643 // we found a match by sysId - now let's see if we need to update existing or leave it unchanged
2644 if (!requestedPermission.equals(existingDirectPermission) &&
2645 !requestedPermission.isGrantableFrom(existingDirectPermission)) {
2646 // requested permission has higher granting rights than
2647 // the already existing direct permission, so we need to update it
2648 updatePermissions.add(requestedPermission);
2649 }
2650
2651 existingPermission = true;
2652 break;
2653 }
2654 }
2655 }
2656 else {
2657 final ResourcePermission requestedPostCreateResourcePermission
2658 = requestedPermission.getPostCreateResourcePermission();
2659 for (ResourceCreatePermission existingDirectPermission : directAccessorPermissions) {
2660 if (!existingDirectPermission.isSystemPermission()) {
2661 final ResourcePermission existingPostCreateResourcePermission
2662 = existingDirectPermission.getPostCreateResourcePermission();
2663
2664 if (requestedPostCreateResourcePermission.equalsIgnoreGrantOption(existingPostCreateResourcePermission)) {
2665 // found a match in name - let's check compatibility first
2666 if (requestedPermission.isWithGrantOption() != requestedPostCreateResourcePermission.isWithGrantOption()
2667 && existingDirectPermission.isWithGrantOption() != existingPostCreateResourcePermission.isWithGrantOption()
2668 && requestedPermission.isWithGrantOption() != existingDirectPermission.isWithGrantOption()) {
2669 // the requested permission is incompatible to the existing permission because we can't
2670 // perform grant operations (a)/G -> (a/G) or (a/G) -> (a)/G without removing either the
2671 // create or post-create granting option
2672 throw new IllegalArgumentException("Requested create permissions "
2673 + requestedResourceCreatePermissions
2674 + " are incompatible with existing create permissions "
2675 + directAccessorPermissions);
2676 }
2677
2678 // now let's see if we need to update existing permission or leave it unchanged
2679 if (!requestedPermission.equals(existingDirectPermission)
2680 && ((requestedPermission.isWithGrantOption() && requestedPostCreateResourcePermission.isWithGrantOption())
2681 || (!existingDirectPermission.isWithGrantOption() && !existingPostCreateResourcePermission.isWithGrantOption()))) {
2682 // the two permissions match in name, but the requested has higher granting rights,
2683 // so we need to update
2684 updatePermissions.add(requestedPermission);
2685 }
2686
2687 // because we found a match in name, we can skip comparing requested against other existing permissions
2688 existingPermission = true;
2689 break;
2690 }
2691 }
2692 }
2693 }
2694
2695 if (!existingPermission) {
2696 // couldn't find requested permission in set of already existing direct permissions, by name, so we need to add it
2697 addPermissions.add(requestedPermission);
2698 }
2699 }
2700
2701 // update *CREATE system permission, if necessary
2702 grantResourceCreatePermissionSysPersister.updateResourceCreateSysPermissions(connection,
2703 accessorResource,
2704 resourceClassId,
2705 domainId,
2706 updatePermissions,
2707 sessionResource);
2708
2709 // update any post create system permissions, if necessary
2710 grantResourceCreatePermissionPostCreateSysPersister.updateResourceCreatePostCreateSysPermissions(connection,
2711 accessorResource,
2712 resourceClassId,
2713 domainId,
2714 updatePermissions,
2715 sessionResource);
2716
2717 // update any post create non-system permissions, if necessary
2718 grantResourceCreatePermissionPostCreatePersister.updateResourceCreatePostCreatePermissions(connection,
2719 accessorResource,
2720 resourceClassId,
2721 domainId,
2722 updatePermissions,
2723 sessionResource);
2724 // grant the *CREATE system permissions, if necessary
2725 grantResourceCreatePermissionSysPersister.addResourceCreateSysPermissions(connection,
2726 accessorResource,
2727 resourceClassId,
2728 domainId,
2729 addPermissions,
2730 sessionResource);
2731
2732 // grant any post create system permissions, if necessary
2733 grantResourceCreatePermissionPostCreateSysPersister.addResourceCreatePostCreateSysPermissions(connection,
2734 accessorResource,
2735 resourceClassId,
2736 domainId,
2737 addPermissions,
2738 sessionResource);
2739
2740 // grant any post create non-system permissions, if necessary
2741 grantResourceCreatePermissionPostCreatePersister.addResourceCreatePostCreatePermissions(connection,
2742 accessorResource,
2743 resourceClassId,
2744 domainId,
2745 addPermissions,
2746 sessionResource);
2747 }
2748
2749 @Override
2750 public void revokeResourceCreatePermissions(Resource accessorResource,
2751 String resourceClassName,
2752 String domainName,
2753 Set<ResourceCreatePermission> resourceCreatePermissions) {
2754 SQLConnection connection = null;
2755
2756 __assertAuthenticated();
2757 __assertResourceSpecified(accessorResource);
2758 __assertResourceClassSpecified(resourceClassName);
2759 __assertDomainSpecified(domainName);
2760 __assertPermissionsSpecified(resourceCreatePermissions);
2761 __assertPermissionsSetNotEmpty(resourceCreatePermissions);
2762
2763 final Set<ResourceCreatePermission> normalizedResourceCreatePermissions
2764 = __normalizeResourceCreatePermission(resourceCreatePermissions);
2765
2766 try {
2767 connection = __getConnection();
2768 accessorResource = __resolveResource(connection, accessorResource);
2769
2770 __revokeDirectResourceCreatePermissions(connection,
2771 accessorResource,
2772 resourceClassName,
2773 domainName,
2774 normalizedResourceCreatePermissions);
2775 }
2776 finally {
2777 __closeConnection(connection);
2778 }
2779 }
2780
2781 @Override
2782 public void revokeResourceCreatePermissions(Resource accessorResource,
2783 String resourceClassName,
2784 String domainName,
2785 ResourceCreatePermission resourceCreatePermission,
2786 ResourceCreatePermission... resourceCreatePermissions) {
2787 SQLConnection connection = null;
2788
2789 __assertAuthenticated();
2790 __assertResourceSpecified(accessorResource);
2791 __assertResourceClassSpecified(resourceClassName);
2792 __assertDomainSpecified(domainName);
2793 __assertPermissionSpecified(resourceCreatePermission);
2794 __assertVarargPermissionsSpecified(resourceCreatePermissions);
2795
2796 final Set<ResourceCreatePermission> normalizedResourceCreatePermissions
2797 = __normalizeResourceCreatePermission(__getSetWithoutNullsOrDuplicates(resourceCreatePermission,
2798 resourceCreatePermissions));
2799
2800 try {
2801 connection = __getConnection();
2802 accessorResource = __resolveResource(connection, accessorResource);
2803
2804 __revokeDirectResourceCreatePermissions(connection,
2805 accessorResource,
2806 resourceClassName,
2807 domainName,
2808 normalizedResourceCreatePermissions);
2809 }
2810 finally {
2811 __closeConnection(connection);
2812 }
2813 }
2814
2815 private void __revokeDirectResourceCreatePermissions(SQLConnection connection,
2816 Resource accessorResource,
2817 String resourceClassName,
2818 String domainName,
2819 Set<ResourceCreatePermission> requestedResourceCreatePermissions) {
2820 // verify that resource class is defined and get its metadata
2821 final ResourceClassInternalInfo resourceClassInfo = __getResourceClassInternalInfo(connection,
2822 resourceClassName);
2823
2824 final Id<ResourceClassId> resourceClassId = Id.from(resourceClassInfo.getResourceClassId());
2825
2826 // verify that domain is defined
2827 final Id<DomainId> domainId = domainPersister.getResourceDomainId(connection, domainName);
2828
2829 if (domainId == null) {
2830 throw new IllegalArgumentException("Could not find domain: " + domainName);
2831 }
2832
2833 __assertUniquePostCreatePermissionsNamesForResourceClass(connection,
2834 requestedResourceCreatePermissions,
2835 resourceClassInfo);
2836
2837 // check if the grantor (=session resource) is authorized to grant the requested permissions
2838 if (!__isSuperUserOfDomain(connection, sessionResource, domainName)) {
2839 final Set<ResourceCreatePermission> grantorPermissions
2840 = __getEffectiveResourceCreatePermissionsIgnoringSuperUserPrivileges(connection,
2841 sessionResource,
2842 resourceClassName,
2843 domainName);
2844
2845 final Set<ResourceCreatePermission> unauthorizedPermissions
2846 = __subtractResourceCreatePermissionsIfGrantableFrom(requestedResourceCreatePermissions,
2847 grantorPermissions);
2848
2849 if (unauthorizedPermissions.size() > 0) {
2850 throw NotAuthorizedException.newInstanceForAction(sessionResource,
2851 "revoke the following permission(s): " + unauthorizedPermissions);
2852 }
2853 }
2854
2855 // ensure that the *CREATE system permissions will remain if not all are cleared
2856 final Set<ResourceCreatePermission>
2857 directAccessorPermissions
2858 = __getDirectResourceCreatePermissions(connection,
2859 accessorResource,
2860 resourceClassId,
2861 domainId);
2862
2863 if ((directAccessorPermissions.size() > requestedResourceCreatePermissions.size()) &&
2864 __setContainsResourceCreateSystemPermission(requestedResourceCreatePermissions)) {
2865 // our invariant is that a resource's direct create permissions must include the *CREATE system permission;
2866 // if after revoking the requested permissions, the remaining set wouldn't include the *CREATE, we'd have a problem
2867 throw new IllegalArgumentException(
2868 "Attempt to revoke a subset of resource create permissions that includes the *CREATE system permission: "
2869 + requestedResourceCreatePermissions);
2870 }
2871
2872 final Set<ResourceCreatePermission> removePermissions = new HashSet<>(requestedResourceCreatePermissions.size());
2873
2874 for (ResourceCreatePermission requestedPermission : requestedResourceCreatePermissions) {
2875 if (requestedPermission.isSystemPermission()) {
2876 for (ResourceCreatePermission existingDirectPermission : directAccessorPermissions) {
2877 if (existingDirectPermission.isSystemPermission() &&
2878 requestedPermission.getSystemPermissionId() == existingDirectPermission.getSystemPermissionId()) {
2879 // requested permission has same system Id as an already existing direct permission, so remove it
2880 removePermissions.add(requestedPermission);
2881 break;
2882 }
2883 }
2884 }
2885 else {
2886 final ResourcePermission requestedPostCreateResourcePermission
2887 = requestedPermission.getPostCreateResourcePermission();
2888 for (ResourceCreatePermission existingDirectPermission : directAccessorPermissions) {
2889 if (!existingDirectPermission.isSystemPermission()) {
2890 // now let's look at the post-create permissions
2891 if (requestedPostCreateResourcePermission
2892 .equalsIgnoreGrantOption(existingDirectPermission.getPostCreateResourcePermission())) {
2893 // requested post-create permission has same name as an already existing direct permission, so remove it
2894 removePermissions.add(requestedPermission);
2895 break;
2896 }
2897 }
2898 }
2899 }
2900 }
2901
2902 // remove *CREATE system permission, if necessary
2903 grantResourceCreatePermissionSysPersister.removeResourceCreateSysPermissions(connection,
2904 accessorResource,
2905 resourceClassId,
2906 domainId,
2907 removePermissions);
2908
2909 // remove any post create system permissions, if necessary
2910 grantResourceCreatePermissionPostCreateSysPersister.removeResourceCreatePostCreateSysPermissions(connection,
2911 accessorResource,
2912 resourceClassId,
2913 domainId,
2914 removePermissions);
2915
2916 // remove any post create non-system permissions, if necessary
2917 grantResourceCreatePermissionPostCreatePersister.removeResourceCreatePostCreatePermissions(connection,
2918 accessorResource,
2919 resourceClassId,
2920 domainId,
2921 removePermissions);
2922 }
2923
2924 private boolean __setContainsResourceCreateSystemPermission(Set<ResourceCreatePermission> resourceCreatePermissions) {
2925 for (final ResourceCreatePermission resourceCreatePermission : resourceCreatePermissions) {
2926 if (resourceCreatePermission.isSystemPermission()
2927 && ResourceCreatePermissions.CREATE.equals(resourceCreatePermission.getPermissionName())) {
2928 return true;
2929 }
2930 }
2931 return false;
2932 }
2933
2934 @Override
2935 public Set<ResourceCreatePermission> getResourceCreatePermissions(Resource accessorResource,
2936 String resourceClassName,
2937 String domainName) {
2938 SQLConnection connection = null;
2939
2940 __assertAuthenticated();
2941 __assertResourceSpecified(accessorResource);
2942 __assertResourceClassSpecified(resourceClassName);
2943 __assertDomainSpecified(domainName);
2944
2945 try {
2946 connection = __getConnection();
2947 accessorResource = __resolveResource(connection, accessorResource);
2948 __assertQueryAuthorization(connection, accessorResource);
2949
2950 resourceClassName = resourceClassName.trim();
2951 domainName = domainName.trim();
2952
2953 return __getDirectResourceCreatePermissions(connection,
2954 accessorResource,
2955 resourceClassName,
2956 domainName);
2957 }
2958 finally {
2959 __closeConnection(connection);
2960 }
2961 }
2962
2963 private Set<ResourceCreatePermission> __getDirectResourceCreatePermissions(SQLConnection connection,
2964 Resource accessorResource,
2965 String resourceClassName,
2966 String domainName) {
2967 // verify that resource class is defined
2968 Id<ResourceClassId> resourceClassId = resourceClassPersister.getResourceClassId(connection, resourceClassName);
2969
2970 if (resourceClassId == null) {
2971 throw new IllegalArgumentException("Could not find resource class: " + resourceClassName);
2972 }
2973
2974 // verify that domain is defined
2975 final Id<DomainId> domainId = domainPersister.getResourceDomainId(connection, domainName);
2976
2977 if (domainId == null) {
2978 throw new IllegalArgumentException("Could not find domain: " + domainName);
2979 }
2980
2981 return __getDirectResourceCreatePermissions(connection,
2982 accessorResource,
2983 resourceClassId,
2984 domainId);
2985 }
2986
2987 @Override
2988 public Map<String, Map<String, Set<ResourceCreatePermission>>> getResourceCreatePermissionsMap(Resource accessorResource) {
2989 SQLConnection connection = null;
2990
2991 __assertAuthenticated();
2992 __assertResourceSpecified(accessorResource);
2993
2994 try {
2995 connection = __getConnection();
2996 accessorResource = __resolveResource(connection, accessorResource);
2997 __assertQueryAuthorization(connection, accessorResource);
2998
2999 return __getDirectResourceCreatePermissionsMap(connection, accessorResource);
3000 }
3001 finally {
3002 __closeConnection(connection);
3003 }
3004 }
3005
3006 private Map<String, Map<String, Set<ResourceCreatePermission>>> __getDirectResourceCreatePermissionsMap(SQLConnection connection,
3007 Resource accessorResource) {
3008 // collect all the create permissions that the accessor has
3009 Map<String, Map<String, Set<ResourceCreatePermission>>> allResourceCreatePermissionsMap = new HashMap<>();
3010
3011 // read the *CREATE system permissions and add to allResourceCreatePermissionsMap
3012 allResourceCreatePermissionsMap
3013 .putAll(grantResourceCreatePermissionSysPersister.getResourceCreateSysPermissions(connection,
3014 accessorResource));
3015
3016 // read the post create system permissions and add to allResourceCreatePermissionsMap
3017 __mergeSourceCreatePermissionsMapIntoTargetCreatePermissionsMap(
3018 grantResourceCreatePermissionPostCreateSysPersister
3019 .getResourceCreatePostCreateSysPermissions(connection, accessorResource),
3020 allResourceCreatePermissionsMap);
3021
3022 // read the post create non-system permissions and add to allResourceCreatePermissionsMap
3023 __mergeSourceCreatePermissionsMapIntoTargetCreatePermissionsMap(
3024 grantResourceCreatePermissionPostCreatePersister
3025 .getResourceCreatePostCreatePermissions(connection, accessorResource),
3026 allResourceCreatePermissionsMap);
3027
3028 return __collapseResourceCreatePermissions(allResourceCreatePermissionsMap);
3029 }
3030
3031 @Override
3032 public Set<ResourceCreatePermission> getEffectiveResourceCreatePermissions(Resource accessorResource,
3033 String resourceClassName,
3034 String domainName) {
3035 SQLConnection connection = null;
3036
3037 __assertAuthenticated();
3038 __assertResourceSpecified(accessorResource);
3039 __assertResourceClassSpecified(resourceClassName);
3040 __assertDomainSpecified(domainName);
3041
3042 try {
3043 connection = __getConnection();
3044 accessorResource = __resolveResource(connection, accessorResource);
3045 __assertQueryAuthorization(connection, accessorResource);
3046
3047 resourceClassName = resourceClassName.trim();
3048 domainName = domainName.trim();
3049
3050 return __getEffectiveResourceCreatePermissions(connection,
3051 accessorResource,
3052 resourceClassName,
3053 domainName);
3054 }
3055 finally {
3056 __closeConnection(connection);
3057 }
3058 }
3059
3060 private Set<ResourceCreatePermission> __getEffectiveResourceCreatePermissionsIgnoringSuperUserPrivileges(SQLConnection connection,
3061 Resource accessorResource,
3062 String resourceClassName,
3063 String domainName) {
3064 // verify that resource class is defined
3065 Id<ResourceClassId> resourceClassId = resourceClassPersister.getResourceClassId(connection, resourceClassName);
3066
3067 if (resourceClassId == null) {
3068 throw new IllegalArgumentException("Could not find resource class: " + resourceClassName);
3069 }
3070
3071 // verify that domain is defined
3072 final Id<DomainId> domainId = domainPersister.getResourceDomainId(connection, domainName);
3073
3074 if (domainId == null) {
3075 throw new IllegalArgumentException("Could not find domain: " + domainName);
3076 }
3077
3078 // collect the create permissions that this resource has to this resource class
3079 Set<ResourceCreatePermission> resourceCreatePermissions = new HashSet<>();
3080
3081 // first read the *CREATE system permission the accessor has to the specified resource class
3082 resourceCreatePermissions.addAll(
3083 grantResourceCreatePermissionSysPersister.getResourceCreateSysPermissionsIncludeInherited(connection,
3084 accessorResource,
3085 resourceClassId,
3086 domainId));
3087
3088 // next read the post create system permissions the accessor has to the specified resource class
3089 resourceCreatePermissions
3090 .addAll(grantResourceCreatePermissionPostCreateSysPersister
3091 .getResourceCreatePostCreateSysPermissionsIncludeInherited(connection,
3092 accessorResource,
3093 resourceClassId,
3094 domainId));
3095
3096 // next read the post create non-system permissions the accessor has to the specified resource class
3097 resourceCreatePermissions
3098 .addAll(grantResourceCreatePermissionPostCreatePersister
3099 .getResourceCreatePostCreatePermissionsIncludeInherited(connection,
3100 accessorResource,
3101 resourceClassId,
3102 domainId));
3103 return __collapseResourceCreatePermissions(resourceCreatePermissions);
3104 }
3105
3106 private Set<ResourceCreatePermission> __getEffectiveResourceCreatePermissions(SQLConnection connection,
3107 Resource accessorResource,
3108 String resourceClassName,
3109 String domainName) {
3110 // verify that resource class is defined
3111 final ResourceClassInternalInfo resourceClassInternalInfo
3112 = __getResourceClassInternalInfo(connection, resourceClassName);
3113
3114 // verify that domain is defined
3115 final Id<DomainId> domainId = domainPersister.getResourceDomainId(connection, domainName);
3116
3117 if (domainId == null) {
3118 throw new IllegalArgumentException("Could not find domain: " + domainName);
3119 }
3120
3121 if (__isSuperUserOfDomain(connection, accessorResource, domainName)) {
3122 return __getApplicableResourceCreatePermissions(connection, resourceClassInternalInfo);
3123 }
3124
3125 Id<ResourceClassId> resourceClassId = Id.from(resourceClassInternalInfo.getResourceClassId());
3126
3127 // collect the create permissions that this resource has to this resource class
3128 Set<ResourceCreatePermission> resourceCreatePermissions = new HashSet<>();
3129
3130 // first read the *CREATE system permission the accessor has to the specified resource class
3131 resourceCreatePermissions.addAll(
3132 grantResourceCreatePermissionSysPersister.getResourceCreateSysPermissionsIncludeInherited(connection,
3133 accessorResource,
3134 resourceClassId,
3135 domainId));
3136
3137 // next read the post create system permissions the accessor has to the specified resource class
3138 resourceCreatePermissions
3139 .addAll(grantResourceCreatePermissionPostCreateSysPersister
3140 .getResourceCreatePostCreateSysPermissionsIncludeInherited(connection,
3141 accessorResource,
3142 resourceClassId,
3143 domainId));
3144
3145 // next read the post create non-system permissions the accessor has to the specified resource class
3146 resourceCreatePermissions
3147 .addAll(grantResourceCreatePermissionPostCreatePersister
3148 .getResourceCreatePostCreatePermissionsIncludeInherited(connection,
3149 accessorResource,
3150 resourceClassId,
3151 domainId));
3152 return __collapseResourceCreatePermissions(resourceCreatePermissions);
3153 }
3154
3155 private Set<ResourceCreatePermission> __collapseResourceCreatePermissions(Set<ResourceCreatePermission> resourceCreatePermissions) {
3156 final Set<ResourceCreatePermission> collapsedPermissions = new HashSet<>(resourceCreatePermissions);
3157
3158 for (ResourceCreatePermission permission : resourceCreatePermissions) {
3159 for (ResourceCreatePermission grantEquivalentPermission : resourceCreatePermissions) {
3160 if (permission.isGrantableFrom(grantEquivalentPermission) && !permission.equals(grantEquivalentPermission)) {
3161 collapsedPermissions.remove(permission);
3162 break;
3163 }
3164 }
3165 }
3166
3167 return collapsedPermissions;
3168 }
3169
3170 @Override
3171 public Map<String, Map<String, Set<ResourceCreatePermission>>> getEffectiveResourceCreatePermissionsMap(Resource accessorResource) {
3172 SQLConnection connection = null;
3173
3174 __assertAuthenticated();
3175 __assertResourceSpecified(accessorResource);
3176
3177 try {
3178 connection = __getConnection();
3179 accessorResource = __resolveResource(connection, accessorResource);
3180 __assertQueryAuthorization(connection, accessorResource);
3181
3182 return __getEffectiveResourceCreatePermissionsMap(connection,
3183 accessorResource);
3184 }
3185 finally {
3186 __closeConnection(connection);
3187 }
3188 }
3189
3190 private Map<String, Map<String, Set<ResourceCreatePermission>>> __getEffectiveResourceCreatePermissionsMap(
3191 SQLConnection connection,
3192 Resource accessorResource) {
3193 // collect all the create permissions that the accessor has
3194 Map<String, Map<String, Set<ResourceCreatePermission>>> allResourceCreatePermissionsMap = new HashMap<>();
3195
3196 // read the *CREATE system permissions and add to allResourceCreatePermissionsMap
3197 allResourceCreatePermissionsMap
3198 .putAll(grantResourceCreatePermissionSysPersister
3199 .getResourceCreateSysPermissionsIncludeInherited(connection, accessorResource));
3200
3201 // read the post create system permissions and add to allResourceCreatePermissionsMap
3202 __mergeSourceCreatePermissionsMapIntoTargetCreatePermissionsMap(
3203 grantResourceCreatePermissionPostCreateSysPersister
3204 .getResourceCreatePostCreateSysPermissionsIncludeInherited(connection, accessorResource),
3205 allResourceCreatePermissionsMap);
3206
3207 // read the post create non-system permissions and add to allResourceCreatePermissionsMap
3208 __mergeSourceCreatePermissionsMapIntoTargetCreatePermissionsMap(
3209 grantResourceCreatePermissionPostCreatePersister
3210 .getResourceCreatePostCreatePermissionsIncludeInherited(connection, accessorResource),
3211 allResourceCreatePermissionsMap);
3212
3213 // finally, collect all applicable create permissions when accessor has super-user privileges to any domain
3214 // and add them into the globalALLPermissionsMap
3215 final Map<String, Map<String, Set<ResourceCreatePermission>>> allSuperResourceCreatePermissionsMap = new HashMap<>();
3216 Map<String, Set<ResourceCreatePermission>> superResourceCreatePermissionsMap = null;
3217
3218 final Map<String, Set<DomainPermission>> effectiveDomainPermissionsMap
3219 = __getEffectiveDomainPermissionsMap(connection, accessorResource);
3220
3221 for (Map.Entry<String, Set<DomainPermission>>
3222 effectiveDomainPermissionsByDomainEntry : effectiveDomainPermissionsMap.entrySet()) {
3223 final Set<DomainPermission> effectiveDomainPermissions = effectiveDomainPermissionsByDomainEntry.getValue();
3224 if (effectiveDomainPermissions.contains(DomainPermission_SUPER_USER)
3225 || effectiveDomainPermissions.contains(DomainPermission_SUPER_USER_GRANT)) {
3226
3227 if (superResourceCreatePermissionsMap == null) {
3228 // lazy-construct super-user-privileged resource-permissions map by resource classes
3229 final List<String> resourceClassNames = resourceClassPersister.getResourceClassNames(connection);
3230 superResourceCreatePermissionsMap = new HashMap<>(resourceClassNames.size());
3231 for (String resourceClassName : resourceClassNames) {
3232 final Set<ResourceCreatePermission> applicableResourceCreatePermissions
3233 = __getApplicableResourceCreatePermissions(connection,
3234 __getResourceClassInternalInfo(connection,
3235 resourceClassName));
3236
3237 superResourceCreatePermissionsMap.put(resourceClassName, applicableResourceCreatePermissions);
3238 }
3239 }
3240 allSuperResourceCreatePermissionsMap.put(effectiveDomainPermissionsByDomainEntry.getKey(),
3241 superResourceCreatePermissionsMap);
3242 }
3243 }
3244
3245 __mergeSourceCreatePermissionsMapIntoTargetCreatePermissionsMap(allSuperResourceCreatePermissionsMap,
3246 allResourceCreatePermissionsMap);
3247
3248 return __collapseResourceCreatePermissions(allResourceCreatePermissionsMap);
3249 }
3250
3251 private void __mergeSourceCreatePermissionsMapIntoTargetCreatePermissionsMap(Map<String, Map<String, Set<ResourceCreatePermission>>> sourceCreatePermissionsMap,
3252 Map<String, Map<String, Set<ResourceCreatePermission>>> targetCreatePermissionsMap) {
3253 for (Map.Entry<String, Map<String, Set<ResourceCreatePermission>>>
3254 sourcePermissionsMapByDomainEntry : sourceCreatePermissionsMap.entrySet()) {
3255 final String domainName = sourcePermissionsMapByDomainEntry.getKey();
3256
3257 Map<String, Set<ResourceCreatePermission>> targetCreatePermsForDomainMap
3258 = targetCreatePermissionsMap.get(domainName);
3259 // does the target map have domain?
3260 if (targetCreatePermsForDomainMap == null) {
3261 // no, add the domain
3262 targetCreatePermsForDomainMap = new HashMap<>();
3263 targetCreatePermissionsMap.put(domainName, targetCreatePermsForDomainMap);
3264 }
3265 for (Map.Entry<String, Set<ResourceCreatePermission>>
3266 sourcePermissionsByResourceClassEntry : sourcePermissionsMapByDomainEntry.getValue().entrySet()) {
3267 final String resourceClassName = sourcePermissionsByResourceClassEntry.getKey();
3268
3269 Set<ResourceCreatePermission> targetCreatePermsForClassSet = targetCreatePermsForDomainMap.get(resourceClassName);
3270 // does the target map have the resource class?
3271 if (targetCreatePermsForClassSet == null) {
3272 // no, add the resource class
3273 targetCreatePermsForClassSet = new HashSet<>();
3274 targetCreatePermsForDomainMap.put(resourceClassName, targetCreatePermsForClassSet);
3275 }
3276
3277 // add the source permissions above to the target for the respective domain + resource class
3278 targetCreatePermsForClassSet.addAll(sourcePermissionsByResourceClassEntry.getValue());
3279 }
3280 }
3281 }
3282
3283 private Map<String, Map<String, Set<ResourceCreatePermission>>> __collapseResourceCreatePermissions(Map<String, Map<String, Set<ResourceCreatePermission>>> resourceCreatePermissionsMap) {
3284 for (Map.Entry<String, Map<String, Set<ResourceCreatePermission>>>
3285 createPermissionsByDomainEntry : resourceCreatePermissionsMap.entrySet()) {
3286 final Map<String, Set<ResourceCreatePermission>>
3287 createPermissionsByResourceClassMap = createPermissionsByDomainEntry.getValue();
3288
3289 for (Map.Entry<String, Set<ResourceCreatePermission>>
3290 createPermissionsByResourceClassEntry : createPermissionsByResourceClassMap.entrySet()) {
3291 createPermissionsByResourceClassMap.put(createPermissionsByResourceClassEntry.getKey(),
3292 __collapseResourceCreatePermissions(createPermissionsByResourceClassEntry
3293 .getValue()));
3294 }
3295 }
3296
3297 return resourceCreatePermissionsMap;
3298 }
3299
3300 @Override
3301 public void setResourcePermissions(Resource accessorResource,
3302 Resource accessedResource,
3303 Set<ResourcePermission> resourcePermissions) {
3304 SQLConnection connection = null;
3305
3306 __assertAuthenticated();
3307 __assertResourceSpecified(accessorResource);
3308 __assertResourceSpecified(accessedResource);
3309 __assertPermissionsSpecified(resourcePermissions);
3310
3311 final Set<ResourcePermission> normalizedResourcePermissions = __normalizeResourcePermission(resourcePermissions);
3312
3313 try {
3314 connection = __getConnection();
3315 accessorResource = __resolveResource(connection, accessorResource);
3316 accessedResource = __resolveResource(connection, accessedResource);
3317
3318 __setDirectResourcePermissions(connection,
3319 accessorResource,
3320 accessedResource,
3321 normalizedResourcePermissions,
3322 sessionResource,
3323 false);
3324 }
3325 finally {
3326 __closeConnection(connection);
3327 }
3328 }
3329
3330 private void __setDirectResourcePermissions(SQLConnection connection,
3331 Resource accessorResource,
3332 Resource accessedResource,
3333 Set<ResourcePermission> requestedResourcePermissions,
3334 Resource grantorResource,
3335 boolean newResourceMode) {
3336 final ResourceClassInternalInfo accessedResourceClassInternalInfo
3337 = resourceClassPersister.getResourceClassInfoByResourceId(connection, accessedResource);
3338
3339 // next ensure that the requested permissions are all in the correct resource class
3340 __assertUniqueResourcePermissionsNamesForResourceClass(connection,
3341 requestedResourcePermissions,
3342 accessedResourceClassInternalInfo);
3343
3344 // if this method is being called to set the post create permissions on a newly created resource
3345 // we do not perform the security checks below, since it would be incorrect
3346 if (!newResourceMode) {
3347 if (!__isSuperUserOfResource(connection, grantorResource, accessedResource)) {
3348 // next check if the grantor (i.e. session resource) has permissions to grant the requested permissions
3349 final Set<ResourcePermission>
3350 grantorResourcePermissions
3351 = __getEffectiveResourcePermissionsIgnoringSuperUserPrivileges(connection,
3352 grantorResource,
3353 accessedResource);
3354
3355 final Set<ResourcePermission>
3356 directAccessorResourcePermissions
3357 = __getDirectResourcePermissions(connection,
3358 accessorResource,
3359 accessedResource);
3360
3361 final Set<ResourcePermission>
3362 requestedAddPermissions
3363 = __subtract(requestedResourcePermissions, directAccessorResourcePermissions);
3364
3365 if (requestedAddPermissions.size() > 0) {
3366 final Set<ResourcePermission>
3367 unauthorizedAddPermissions
3368 = __subtractResourcePermissionsIfGrantableFrom(requestedAddPermissions, grantorResourcePermissions);
3369
3370 if (unauthorizedAddPermissions.size() > 0) {
3371 throw NotAuthorizedException.newInstanceForAction(grantorResource,
3372 "add the following permission(s): " + unauthorizedAddPermissions);
3373 }
3374 }
3375
3376 final Set<ResourcePermission>
3377 requestedRemovePermissions
3378 = __subtract(directAccessorResourcePermissions, requestedResourcePermissions);
3379
3380 if (requestedRemovePermissions.size() > 0) {
3381 final Set<ResourcePermission>
3382 unauthorizedRemovePermissions
3383 = __subtractResourcePermissionsIfGrantableFrom(requestedRemovePermissions, grantorResourcePermissions);
3384
3385 if (unauthorizedRemovePermissions.size() > 0) {
3386 throw NotAuthorizedException.newInstanceForAction(grantorResource,
3387 "remove the following permission(s): " + unauthorizedRemovePermissions);
3388 }
3389 }
3390 }
3391
3392 // if inherit permissions are about to be granted, first check for cycles
3393 if (requestedResourcePermissions.contains(ResourcePermission_INHERIT)
3394 || requestedResourcePermissions.contains(ResourcePermission_INHERIT_GRANT)) {
3395 Set<ResourcePermission> reversePathResourcePermissions
3396 = __getEffectiveResourcePermissionsIgnoringSuperUserPrivileges(connection,
3397 accessedResource,
3398 accessorResource);
3399
3400 if (reversePathResourcePermissions.contains(ResourcePermission_INHERIT)
3401 || reversePathResourcePermissions.contains(ResourcePermission_INHERIT_GRANT)
3402 || accessorResource.equals(accessedResource)) {
3403 throw new OaccException("Granting the requested permission(s): "
3404 + requestedResourcePermissions
3405 + " will cause a cycle between: "
3406 + accessorResource
3407 + " and: "
3408 + accessedResource);
3409 }
3410 }
3411
3412 // revoke any existing direct system permissions between the accessor and the accessed resource
3413 grantResourcePermissionSysPersister.removeResourceSysPermissions(connection,
3414 accessorResource,
3415 accessedResource);
3416
3417 // revoke any existing direct non-system permissions between the accessor and the accessed resource
3418 grantResourcePermissionPersister.removeResourcePermissions(connection, accessorResource, accessedResource);
3419 }
3420
3421 // add the new direct system permissions
3422 grantResourcePermissionSysPersister.addResourceSysPermissions(connection,
3423 accessorResource,
3424 accessedResource,
3425 Id.<ResourceClassId>from(
3426 accessedResourceClassInternalInfo
3427 .getResourceClassId()),
3428 requestedResourcePermissions,
3429 grantorResource);
3430
3431 // add the new direct non-system permissions
3432 grantResourcePermissionPersister.addResourcePermissions(connection,
3433 accessorResource,
3434 accessedResource,
3435 Id.<ResourceClassId>from(accessedResourceClassInternalInfo
3436 .getResourceClassId()),
3437 requestedResourcePermissions,
3438 grantorResource);
3439 }
3440
3441 private void __assertUniqueResourcePermissionsNamesForResourceClass(SQLConnection connection,
3442 Set<ResourcePermission> resourcePermissions,
3443 ResourceClassInternalInfo resourceClassInternalInfo) {
3444 final List<String> validPermissionNames
3445 = __getApplicableResourcePermissionNames(connection, resourceClassInternalInfo);
3446 final Set<String> uniquePermissionNames = new HashSet<>(resourcePermissions.size());
3447
3448 for (final ResourcePermission resourcePermission : resourcePermissions) {
3449 if (!validPermissionNames.contains(resourcePermission.getPermissionName())) {
3450 if (resourcePermission.isSystemPermission()) {
3451 // currently the only invalid system permissions are for unauthenticatable resource classes
3452 throw new IllegalArgumentException("Permission: "
3453 + resourcePermission.getPermissionName()
3454 + ", not valid for unauthenticatable resource");
3455 }
3456 else {
3457 throw new IllegalArgumentException("Permission: "
3458 + resourcePermission.getPermissionName()
3459 + " is not defined for resource class: "
3460 + resourceClassInternalInfo.getResourceClassName());
3461 }
3462 }
3463
3464 if (uniquePermissionNames.contains(resourcePermission.getPermissionName())) {
3465 throw new IllegalArgumentException("Duplicate permission: "
3466 + resourcePermission.getPermissionName()
3467 + " that only differs in 'withGrant' option");
3468 }
3469 else {
3470 uniquePermissionNames.add(resourcePermission.getPermissionName());
3471 }
3472 }
3473 }
3474
3475 private Set<ResourcePermission> __subtractResourcePermissionsIfGrantableFrom(Set<ResourcePermission> candidatePermissionSet,
3476 Set<ResourcePermission> grantorPermissionSet) {
3477 Set<ResourcePermission> differenceSet = new HashSet<>(candidatePermissionSet);
3478
3479 for (ResourcePermission candidatePermission : candidatePermissionSet) {
3480 for (ResourcePermission grantorPermission : grantorPermissionSet) {
3481 if (candidatePermission.isGrantableFrom(grantorPermission)) {
3482 differenceSet.remove(candidatePermission);
3483 break;
3484 }
3485 }
3486 }
3487
3488 return differenceSet;
3489 }
3490
3491 @Override
3492 public void grantResourcePermissions(Resource accessorResource,
3493 Resource accessedResource,
3494 Set<ResourcePermission> resourcePermissions) {
3495 SQLConnection connection = null;
3496
3497 __assertAuthenticated();
3498 __assertResourceSpecified(accessorResource);
3499 __assertResourceSpecified(accessedResource);
3500 __assertPermissionsSpecified(resourcePermissions);
3501 __assertPermissionsSetNotEmpty(resourcePermissions);
3502
3503 final Set<ResourcePermission> normalizedResourcePermissions = __normalizeResourcePermission(resourcePermissions);
3504
3505 try {
3506 connection = __getConnection();
3507 accessorResource = __resolveResource(connection, accessorResource);
3508 accessedResource = __resolveResource(connection, accessedResource);
3509
3510 __grantDirectResourcePermissions(connection, accessorResource, accessedResource, normalizedResourcePermissions);
3511 }
3512 finally {
3513 __closeConnection(connection);
3514 }
3515 }
3516
3517 @Override
3518 public void grantResourcePermissions(Resource accessorResource,
3519 Resource accessedResource,
3520 ResourcePermission resourcePermission,
3521 ResourcePermission... resourcePermissions) {
3522 SQLConnection connection = null;
3523
3524 __assertAuthenticated();
3525 __assertResourceSpecified(accessorResource);
3526 __assertResourceSpecified(accessedResource);
3527 __assertPermissionSpecified(resourcePermission);
3528 __assertVarargPermissionsSpecified(resourcePermissions);
3529
3530 final Set<ResourcePermission> normalizedResourcePermissions
3531 = __normalizeResourcePermission(__getSetWithoutNullsOrDuplicates(resourcePermission, resourcePermissions));
3532
3533 try {
3534 connection = __getConnection();
3535 accessorResource = __resolveResource(connection, accessorResource);
3536 accessedResource = __resolveResource(connection, accessedResource);
3537
3538 __grantDirectResourcePermissions(connection, accessorResource, accessedResource, normalizedResourcePermissions);
3539 }
3540 finally {
3541 __closeConnection(connection);
3542 }
3543 }
3544
3545 private void __grantDirectResourcePermissions(SQLConnection connection,
3546 Resource accessorResource,
3547 Resource accessedResource,
3548 Set<ResourcePermission> requestedResourcePermissions) {
3549 final ResourceClassInternalInfo accessedResourceClassInternalInfo
3550 = resourceClassPersister.getResourceClassInfoByResourceId(connection, accessedResource);
3551
3552 // next ensure that the requested permissions are all in the correct resource class
3553 __assertUniqueResourcePermissionsNamesForResourceClass(connection,
3554 requestedResourcePermissions,
3555 accessedResourceClassInternalInfo);
3556
3557 // check for authorization
3558 if (!__isSuperUserOfResource(connection, sessionResource, accessedResource)) {
3559 final Set<ResourcePermission>
3560 grantorResourcePermissions
3561 = __getEffectiveResourcePermissionsIgnoringSuperUserPrivileges(connection,
3562 sessionResource,
3563 accessedResource);
3564
3565 final Set<ResourcePermission>
3566 unauthorizedPermissions
3567 = __subtractResourcePermissionsIfGrantableFrom(requestedResourcePermissions, grantorResourcePermissions);
3568
3569 if (unauthorizedPermissions.size() > 0) {
3570 throw NotAuthorizedException.newInstanceForAction(sessionResource,
3571 "grant the following permission(s): " + unauthorizedPermissions);
3572 }
3573 }
3574
3575 final Set<ResourcePermission> directAccessorResourcePermissions
3576 = __getDirectResourcePermissions(connection, accessorResource, accessedResource);
3577
3578 final Set<ResourcePermission> addPermissions = new HashSet<>(requestedResourcePermissions.size());
3579 final Set<ResourcePermission> updatePermissions = new HashSet<>(requestedResourcePermissions.size());
3580
3581 for (ResourcePermission requestedPermission : requestedResourcePermissions) {
3582 boolean existingPermission = false;
3583
3584 for (ResourcePermission existingDirectPermission : directAccessorResourcePermissions) {
3585 if (requestedPermission.equalsIgnoreGrantOption(existingDirectPermission)) {
3586 // found a match by name - now let's see if we need to update existing or leave it unchanged
3587 if (!requestedPermission.equals(existingDirectPermission) &&
3588 !requestedPermission.isGrantableFrom(existingDirectPermission)) {
3589 // requested permission has higher granting rights than the already existing direct permission,
3590 // so we need to update it
3591 updatePermissions.add(requestedPermission);
3592 }
3593
3594 existingPermission = true;
3595 break;
3596 }
3597 }
3598
3599 if (!existingPermission) {
3600 // couldn't find requested permission in set of already existing direct permissions, by name, so we need to add it
3601 addPermissions.add(requestedPermission);
3602 }
3603 }
3604
3605 // if inherit permissions are about to be granted, first check for cycles
3606 if (addPermissions.contains(ResourcePermission_INHERIT)
3607 || addPermissions.contains(ResourcePermission_INHERIT_GRANT)) {
3608 Set<ResourcePermission> reversePathResourcePermissions
3609 = __getEffectiveResourcePermissionsIgnoringSuperUserPrivileges(connection,
3610 accessedResource,
3611 accessorResource);
3612
3613 if (reversePathResourcePermissions.contains(ResourcePermission_INHERIT)
3614 || reversePathResourcePermissions.contains(ResourcePermission_INHERIT_GRANT)
3615 || accessorResource.equals(accessedResource)) {
3616 throw new OaccException("Granting the requested permission(s): "
3617 + requestedResourcePermissions
3618 + " will cause a cycle between: "
3619 + accessorResource
3620 + " and: "
3621 + accessedResource);
3622 }
3623 }
3624
3625 // update any necessary direct system permissions between the accessor and the accessed resource
3626 grantResourcePermissionSysPersister.updateResourceSysPermissions(connection,
3627 accessorResource,
3628 accessedResource,
3629 Id.<ResourceClassId>from(
3630 accessedResourceClassInternalInfo.getResourceClassId()),
3631 updatePermissions,
3632 sessionResource);
3633
3634 // update any necessary direct non-system permissions between the accessor and the accessed resource
3635 grantResourcePermissionPersister.updateResourcePermissions(connection,
3636 accessorResource,
3637 accessedResource,
3638 Id.<ResourceClassId>from(
3639 accessedResourceClassInternalInfo.getResourceClassId()),
3640 updatePermissions,
3641 sessionResource);
3642
3643 // add the new direct system permissions
3644 grantResourcePermissionSysPersister.addResourceSysPermissions(connection,
3645 accessorResource,
3646 accessedResource,
3647 Id.<ResourceClassId>from(
3648 accessedResourceClassInternalInfo.getResourceClassId()),
3649 addPermissions,
3650 sessionResource);
3651
3652 // add the new direct non-system permissions
3653 grantResourcePermissionPersister.addResourcePermissions(connection,
3654 accessorResource,
3655 accessedResource,
3656 Id.<ResourceClassId>from(accessedResourceClassInternalInfo.getResourceClassId()),
3657 addPermissions,
3658 sessionResource);
3659 }
3660
3661 @Override
3662 public void revokeResourcePermissions(Resource accessorResource,
3663 Resource accessedResource,
3664 Set<ResourcePermission> resourcePermissions) {
3665 SQLConnection connection = null;
3666
3667 __assertAuthenticated();
3668 __assertResourceSpecified(accessorResource);
3669 __assertResourceSpecified(accessedResource);
3670 __assertPermissionsSpecified(resourcePermissions);
3671 __assertPermissionsSetNotEmpty(resourcePermissions);
3672
3673 final Set<ResourcePermission> normalizedResourcePermissions = __normalizeResourcePermission(resourcePermissions);
3674
3675 try {
3676 connection = __getConnection();
3677 accessorResource = __resolveResource(connection, accessorResource);
3678 accessedResource = __resolveResource(connection, accessedResource);
3679
3680 __revokeDirectResourcePermissions(connection, accessorResource, accessedResource, normalizedResourcePermissions);
3681 }
3682 finally {
3683 __closeConnection(connection);
3684 }
3685 }
3686
3687 @Override
3688 public void revokeResourcePermissions(Resource accessorResource,
3689 Resource accessedResource,
3690 ResourcePermission resourcePermission,
3691 ResourcePermission... resourcePermissions) {
3692 SQLConnection connection = null;
3693
3694 __assertAuthenticated();
3695 __assertResourceSpecified(accessorResource);
3696 __assertResourceSpecified(accessedResource);
3697 __assertPermissionSpecified(resourcePermission);
3698 __assertVarargPermissionsSpecified(resourcePermissions);
3699
3700 final Set<ResourcePermission> normalizedResourcePermissions
3701 = __normalizeResourcePermission(__getSetWithoutNullsOrDuplicates(resourcePermission, resourcePermissions));
3702
3703 try {
3704 connection = __getConnection();
3705 accessorResource = __resolveResource(connection, accessorResource);
3706 accessedResource = __resolveResource(connection, accessedResource);
3707
3708 __revokeDirectResourcePermissions(connection, accessorResource, accessedResource, normalizedResourcePermissions);
3709 }
3710 finally {
3711 __closeConnection(connection);
3712 }
3713 }
3714
3715 private void __revokeDirectResourcePermissions(SQLConnection connection,
3716 Resource accessorResource,
3717 Resource accessedResource,
3718 Set<ResourcePermission> obsoleteResourcePermissions) {
3719 final ResourceClassInternalInfo accessedResourceClassInternalInfo
3720 = resourceClassPersister.getResourceClassInfoByResourceId(connection, accessedResource);
3721
3722 // next ensure that the requested permissions are unique in name
3723 __assertUniqueResourcePermissionsNamesForResourceClass(connection,
3724 obsoleteResourcePermissions,
3725 accessedResourceClassInternalInfo);
3726
3727 // check for authorization
3728 if (!__isSuperUserOfResource(connection, sessionResource, accessedResource)) {
3729 final Set<ResourcePermission>
3730 grantorResourcePermissions
3731 = __getEffectiveResourcePermissionsIgnoringSuperUserPrivileges(connection,
3732 sessionResource,
3733 accessedResource);
3734
3735 final Set<ResourcePermission>
3736 unauthorizedPermissions
3737 = __subtractResourcePermissionsIfGrantableFrom(obsoleteResourcePermissions, grantorResourcePermissions);
3738
3739 if (unauthorizedPermissions.size() > 0) {
3740 throw NotAuthorizedException.newInstanceForAction(sessionResource,
3741 "revoke the following permission(s): " + unauthorizedPermissions);
3742 }
3743 }
3744
3745 final Set<ResourcePermission> directAccessorResourcePermissions
3746 = __getDirectResourcePermissions(connection, accessorResource, accessedResource);
3747
3748 final Set<ResourcePermission> removePermissions = new HashSet<>(obsoleteResourcePermissions.size());
3749
3750 for (ResourcePermission requestedPermission : obsoleteResourcePermissions) {
3751 for (ResourcePermission existingDirectPermission : directAccessorResourcePermissions) {
3752 if (requestedPermission.equalsIgnoreGrantOption(existingDirectPermission)) {
3753 // requested permission has same name and regardless of granting rights we need to remove it
3754 removePermissions.add(requestedPermission);
3755 break;
3756 }
3757 }
3758 }
3759
3760 // update any necessary direct system permissions between the accessor and the accessed resource
3761 grantResourcePermissionSysPersister.removeResourceSysPermissions(connection,
3762 accessorResource,
3763 accessedResource,
3764 Id.<ResourceClassId>from(
3765 accessedResourceClassInternalInfo
3766 .getResourceClassId()),
3767 removePermissions);
3768
3769 // update any necessary direct non-system permissions between the accessor and the accessed resource
3770 grantResourcePermissionPersister.removeResourcePermissions(connection,
3771 accessorResource,
3772 accessedResource,
3773 Id.<ResourceClassId>from(
3774 accessedResourceClassInternalInfo
3775 .getResourceClassId()),
3776 removePermissions);
3777 }
3778
3779 @Override
3780 public Set<ResourcePermission> getResourcePermissions(Resource accessorResource,
3781 Resource accessedResource) {
3782 SQLConnection connection = null;
3783
3784 __assertAuthenticated();
3785 __assertResourceSpecified(accessorResource);
3786 __assertResourceSpecified(accessedResource);
3787
3788 try {
3789 connection = __getConnection();
3790 accessorResource = __resolveResource(connection, accessorResource);
3791 accessedResource = __resolveResource(connection, accessedResource);
3792 __assertQueryAuthorization(connection, accessorResource);
3793
3794 return __getDirectResourcePermissions(connection, accessorResource, accessedResource);
3795 }
3796 finally {
3797 __closeConnection(connection);
3798 }
3799 }
3800
3801 private Set<ResourcePermission> __getDirectResourcePermissions(SQLConnection connection,
3802 Resource accessorResource,
3803 Resource accessedResource) {
3804 Set<ResourcePermission> resourcePermissions = new HashSet<>();
3805
3806 // collect the system permissions that the accessor resource has to the accessed resource
3807 resourcePermissions.addAll(grantResourcePermissionSysPersister.getResourceSysPermissions(connection,
3808 accessorResource,
3809 accessedResource));
3810
3811 // collect the non-system permissions that the accessor has to the accessed resource
3812 resourcePermissions.addAll(grantResourcePermissionPersister.getResourcePermissions(connection,
3813 accessorResource,
3814 accessedResource));
3815
3816 return resourcePermissions;
3817 }
3818
3819 @Override
3820 public Set<ResourcePermission> getEffectiveResourcePermissions(Resource accessorResource, Resource accessedResource) {
3821 SQLConnection connection = null;
3822
3823 __assertAuthenticated();
3824 __assertResourceSpecified(accessorResource);
3825 __assertResourceSpecified(accessedResource);
3826
3827 try {
3828 connection = __getConnection();
3829 accessorResource = __resolveResource(connection, accessorResource);
3830 accessedResource = __resolveResource(connection, accessedResource);
3831 __assertQueryAuthorization(connection, accessorResource);
3832
3833 return __getEffectiveResourcePermissions(connection, accessorResource, accessedResource);
3834 }
3835 finally {
3836 __closeConnection(connection);
3837 }
3838 }
3839
3840 private Set<ResourcePermission> __getEffectiveResourcePermissions(SQLConnection connection,
3841 Resource accessorResource,
3842 Resource accessedResource) {
3843 Set<ResourcePermission> resourcePermissions = new HashSet<>();
3844
3845 final Id<DomainId> accessedDomainId = resourcePersister.getDomainIdByResource(connection, accessedResource);
3846 final ResourceClassInternalInfo resourceClassInternalInfo
3847 = resourceClassPersister.getResourceClassInfoByResourceId(connection, accessedResource);
3848
3849 if (__isSuperUserOfDomain(connection, accessorResource, accessedDomainId)) {
3850 return __getApplicableResourcePermissions(connection, resourceClassInternalInfo);
3851 }
3852
3853 // collect the system permissions that the accessor resource has to the accessed resource
3854 resourcePermissions.addAll(grantResourcePermissionSysPersister
3855 .getResourceSysPermissionsIncludeInherited(connection,
3856 accessorResource,
3857 accessedResource));
3858
3859 // collect the non-system permissions that the accessor has to the accessed resource
3860 resourcePermissions.addAll(grantResourcePermissionPersister.getResourcePermissionsIncludeInherited(connection,
3861 accessorResource,
3862 accessedResource));
3863
3864 final Id<ResourceClassId> accessedResourceClassId = Id.from(resourceClassInternalInfo.getResourceClassId());
3865
3866 // collect the global system permissions that the accessor has to the accessed resource's domain
3867 resourcePermissions
3868 .addAll(grantGlobalResourcePermissionSysPersister.getGlobalSysPermissionsIncludeInherited(connection,
3869 accessorResource,
3870 accessedResourceClassId,
3871 accessedDomainId));
3872
3873 // first collect the global non-system permissions that the accessor this resource has to the accessed resource's domain
3874 resourcePermissions
3875 .addAll(grantGlobalResourcePermissionPersister.getGlobalResourcePermissionsIncludeInherited(connection,
3876 accessorResource,
3877 accessedResourceClassId,
3878 accessedDomainId));
3879 return __collapseResourcePermissions(resourcePermissions);
3880 }
3881
3882 private Set<ResourcePermission> __getEffectiveResourcePermissionsIgnoringSuperUserPrivileges(SQLConnection connection,
3883 Resource accessorResource,
3884 Resource accessedResource) {
3885 Set<ResourcePermission> resourcePermissions = new HashSet<>();
3886
3887 // collect the system permissions that the accessor resource has to the accessed resource
3888 resourcePermissions.addAll(grantResourcePermissionSysPersister
3889 .getResourceSysPermissionsIncludeInherited(connection,
3890 accessorResource,
3891 accessedResource));
3892
3893 // collect the non-system permissions that the accessor has to the accessed resource
3894 resourcePermissions.addAll(grantResourcePermissionPersister.getResourcePermissionsIncludeInherited(connection,
3895 accessorResource,
3896 accessedResource));
3897
3898 final Id<DomainId> accessedDomainId = resourcePersister.getDomainIdByResource(connection, accessedResource);
3899 final Id<ResourceClassId> accessedResourceClassId
3900 = Id.from(resourceClassPersister
3901 .getResourceClassInfoByResourceId(connection, accessedResource)
3902 .getResourceClassId());
3903
3904 // collect the global system permissions that the accessor has to the accessed resource's domain
3905 resourcePermissions
3906 .addAll(grantGlobalResourcePermissionSysPersister.getGlobalSysPermissionsIncludeInherited(connection,
3907 accessorResource,
3908 accessedResourceClassId,
3909 accessedDomainId));
3910
3911 // first collect the global non-system permissions that the accessor this resource has to the accessed resource's domain
3912 resourcePermissions
3913 .addAll(grantGlobalResourcePermissionPersister.getGlobalResourcePermissionsIncludeInherited(connection,
3914 accessorResource,
3915 accessedResourceClassId,
3916 accessedDomainId));
3917 return __collapseResourcePermissions(resourcePermissions);
3918 }
3919
3920 @Override
3921 public void setGlobalResourcePermissions(Resource accessorResource,
3922 String resourceClassName,
3923 String domainName,
3924 Set<ResourcePermission> resourcePermissions) {
3925 SQLConnection connection = null;
3926
3927 __assertAuthenticated();
3928 __assertResourceSpecified(accessorResource);
3929 __assertResourceClassSpecified(resourceClassName);
3930 __assertDomainSpecified(domainName);
3931 __assertPermissionsSpecified(resourcePermissions);
3932
3933 final Set<ResourcePermission> normalizedResourcePermissions = __normalizeResourcePermission(resourcePermissions);
3934
3935 try {
3936 connection = __getConnection();
3937 accessorResource = __resolveResource(connection, accessorResource);
3938 resourceClassName = resourceClassName.trim();
3939 domainName = domainName.trim();
3940
3941 __setDirectGlobalPermissions(connection,
3942 accessorResource,
3943 resourceClassName,
3944 domainName,
3945 normalizedResourcePermissions);
3946 }
3947 finally {
3948 __closeConnection(connection);
3949 }
3950 }
3951
3952 private void __setDirectGlobalPermissions(SQLConnection connection,
3953 Resource accessorResource,
3954 String resourceClassName,
3955 String domainName,
3956 Set<ResourcePermission> requestedResourcePermissions) {
3957 // verify that resource class is defined
3958 final Id<ResourceClassId> resourceClassId = resourceClassPersister.getResourceClassId(connection, resourceClassName);
3959
3960 if (resourceClassId == null) {
3961 throw new IllegalArgumentException("Could not find resource class: " + resourceClassName);
3962 }
3963
3964 final ResourceClassInternalInfo resourceClassInternalInfo = resourceClassPersister.getResourceClassInfo(connection, resourceClassName);
3965
3966 // verify the domain
3967 final Id<DomainId> domainId = domainPersister.getResourceDomainId(connection, domainName);
3968
3969 if (domainId == null) {
3970 throw new IllegalArgumentException("Could not find domain: " + domainName);
3971 }
3972
3973 // next ensure that the requested permissions are all in the correct resource class
3974 __assertUniqueGlobalResourcePermissionNamesForResourceClass(connection, requestedResourcePermissions, resourceClassInternalInfo);
3975
3976 if (!__isSuperUserOfDomain(connection, sessionResource, domainName)) {
3977 // check if the grantor (=session resource) is authorized to grant the requested permissions
3978 final Set<ResourcePermission>
3979 grantorPermissions
3980 = __getEffectiveGlobalResourcePermissionsIgnoringSuperUserPrivileges(connection,
3981 sessionResource,
3982 resourceClassName,
3983 domainName);
3984 final Set<ResourcePermission>
3985 directAccessorPermissions
3986 = __getDirectGlobalResourcePermissions(connection,
3987 accessorResource,
3988 resourceClassId,
3989 domainId);
3990
3991 final Set<ResourcePermission>
3992 requestedAddPermissions
3993 = __subtract(requestedResourcePermissions, directAccessorPermissions);
3994
3995 if (!requestedAddPermissions.isEmpty()) {
3996 final Set<ResourcePermission>
3997 unauthorizedAddPermissions
3998 = __subtractResourcePermissionsIfGrantableFrom(requestedAddPermissions, grantorPermissions);
3999
4000 if (unauthorizedAddPermissions.size() > 0) {
4001 throw NotAuthorizedException.newInstanceForAction(sessionResource,
4002 "add the following global permission(s): " + unauthorizedAddPermissions);
4003 }
4004 }
4005
4006 final Set<ResourcePermission>
4007 requestedRemovePermissions
4008 = __subtract(directAccessorPermissions, requestedResourcePermissions);
4009
4010 if (!requestedRemovePermissions.isEmpty()) {
4011 final Set<ResourcePermission>
4012 unauthorizedRemovePermissions
4013 = __subtractResourcePermissionsIfGrantableFrom(requestedRemovePermissions, grantorPermissions);
4014
4015 if (unauthorizedRemovePermissions.size() > 0) {
4016 throw NotAuthorizedException.newInstanceForAction(sessionResource,
4017 "remove the following global permission(s): " + unauthorizedRemovePermissions);
4018 }
4019 }
4020 }
4021
4022 // revoke any existing system permissions this accessor has to this domain + resource class
4023 grantGlobalResourcePermissionSysPersister.removeGlobalSysPermissions(connection,
4024 accessorResource,
4025 resourceClassId,
4026 domainId);
4027
4028 // revoke any existing non-system permissions that this grantor gave this accessor to this domain to the resource class
4029 grantGlobalResourcePermissionPersister.removeGlobalResourcePermissions(connection,
4030 accessorResource,
4031 resourceClassId,
4032 domainId);
4033
4034 // add the new system permissions
4035 grantGlobalResourcePermissionSysPersister.addGlobalSysPermissions(connection,
4036 accessorResource,
4037 resourceClassId,
4038 domainId,
4039 requestedResourcePermissions,
4040 sessionResource);
4041
4042 // add the new non-system permissions
4043 grantGlobalResourcePermissionPersister.addGlobalResourcePermissions(connection,
4044 accessorResource,
4045 resourceClassId,
4046 domainId,
4047 requestedResourcePermissions,
4048 sessionResource);
4049 }
4050
4051 private Set<ResourcePermission> __getDirectGlobalResourcePermissions(SQLConnection connection,
4052 Resource accessorResource,
4053 Id<ResourceClassId> resourceClassId,
4054 Id<DomainId> domainId) {
4055 Set<ResourcePermission> resourcePermissions = new HashSet<>();
4056
4057 // collect the global system permissions that the accessor resource has to the accessed resource class & domain directly
4058 resourcePermissions.addAll(grantGlobalResourcePermissionSysPersister.getGlobalSysPermissions(connection,
4059 accessorResource,
4060 resourceClassId,
4061 domainId));
4062
4063 // collect the global non-system permissions that the accessor has to the accessed resource class & domain directly
4064 resourcePermissions.addAll(grantGlobalResourcePermissionPersister.getGlobalResourcePermissions(connection,
4065 accessorResource,
4066 resourceClassId,
4067 domainId));
4068
4069 return resourcePermissions;
4070 }
4071
4072 private void __assertUniqueGlobalResourcePermissionNamesForResourceClass(SQLConnection connection,
4073 Set<ResourcePermission> requestedResourcePermissions,
4074 ResourceClassInternalInfo resourceClassInternalInfo) {
4075 final List<String> validPermissionNames = __getApplicableResourcePermissionNames(connection,
4076 resourceClassInternalInfo);
4077 final HashSet<String> uniquePermissionNames = new HashSet<>(requestedResourcePermissions.size());
4078
4079 for (ResourcePermission resourcePermission : requestedResourcePermissions) {
4080 if (resourcePermission.isSystemPermission() && ResourcePermission_INHERIT.equals(resourcePermission)) {
4081 // we prohibit granting the system INHERIT permission, since cycle checking may be prohibitively compute intensive
4082 throw new IllegalArgumentException("Permission: "
4083 + String.valueOf(resourcePermission)
4084 + ", not valid in this context");
4085 }
4086
4087 if (!validPermissionNames.contains(resourcePermission.getPermissionName())) {
4088 if (resourcePermission.isSystemPermission()) {
4089 // currently the only invalid system permissions are for unauthenticatable resource classes
4090 throw new IllegalArgumentException("Permission "
4091 + resourcePermission.getPermissionName()
4092 + " not valid for unauthenticatable resource of class "
4093 + resourceClassInternalInfo.getResourceClassName());
4094 }
4095 else {
4096 throw new IllegalArgumentException("Permission: "
4097 + resourcePermission.getPermissionName()
4098 + " is not defined for resource class: "
4099 + resourceClassInternalInfo.getResourceClassName());
4100 }
4101 }
4102
4103 if (uniquePermissionNames.contains(resourcePermission.getPermissionName())) {
4104 throw new IllegalArgumentException("Duplicate permission: "
4105 + resourcePermission.getPermissionName()
4106 + " that only differs in 'withGrant' option");
4107 }
4108 else {
4109 uniquePermissionNames.add(resourcePermission.getPermissionName());
4110 }
4111 }
4112 }
4113
4114
4115 @Override
4116 public void grantGlobalResourcePermissions(Resource accessorResource,
4117 String resourceClassName,
4118 String domainName,
4119 Set<ResourcePermission> resourcePermissions) {
4120 SQLConnection connection = null;
4121
4122 __assertAuthenticated();
4123 __assertResourceSpecified(accessorResource);
4124 __assertResourceClassSpecified(resourceClassName);
4125 __assertDomainSpecified(domainName);
4126 __assertPermissionsSpecified(resourcePermissions);
4127 __assertPermissionsSetNotEmpty(resourcePermissions);
4128
4129 final Set<ResourcePermission> normalizedResourcePermissions = __normalizeResourcePermission(resourcePermissions);
4130
4131 try {
4132 connection = __getConnection();
4133 accessorResource = __resolveResource(connection, accessorResource);
4134 resourceClassName = resourceClassName.trim();
4135 domainName = domainName.trim();
4136
4137 __grantDirectGlobalPermissions(connection,
4138 accessorResource,
4139 resourceClassName,
4140 domainName,
4141 normalizedResourcePermissions);
4142 }
4143 finally {
4144 __closeConnection(connection);
4145 }
4146 }
4147
4148 @Override
4149 public void grantGlobalResourcePermissions(Resource accessorResource,
4150 String resourceClassName,
4151 String domainName,
4152 ResourcePermission resourcePermission,
4153 ResourcePermission... resourcePermissions) {
4154 SQLConnection connection = null;
4155
4156 __assertAuthenticated();
4157 __assertResourceSpecified(accessorResource);
4158 __assertResourceClassSpecified(resourceClassName);
4159 __assertDomainSpecified(domainName);
4160 __assertPermissionSpecified(resourcePermission);
4161 __assertVarargPermissionsSpecified(resourcePermissions);
4162
4163 final Set<ResourcePermission> normalizedResourcePermissions
4164 = __normalizeResourcePermission(__getSetWithoutNullsOrDuplicates(resourcePermission, resourcePermissions));
4165
4166 try {
4167 connection = __getConnection();
4168 accessorResource = __resolveResource(connection, accessorResource);
4169 resourceClassName = resourceClassName.trim();
4170 domainName = domainName.trim();
4171
4172 __grantDirectGlobalPermissions(connection,
4173 accessorResource,
4174 resourceClassName,
4175 domainName,
4176 normalizedResourcePermissions);
4177 }
4178 finally {
4179 __closeConnection(connection);
4180 }
4181 }
4182
4183 private void __grantDirectGlobalPermissions(SQLConnection connection,
4184 Resource accessorResource,
4185 String resourceClassName,
4186 String domainName,
4187 Set<ResourcePermission> requestedResourcePermissions) {
4188 // verify that resource class is defined
4189 final Id<ResourceClassId> resourceClassId = resourceClassPersister.getResourceClassId(connection, resourceClassName);
4190
4191 if (resourceClassId == null) {
4192 throw new IllegalArgumentException("Could not find resource class: " + resourceClassName);
4193 }
4194
4195 final ResourceClassInternalInfo resourceClassInternalInfo
4196 = resourceClassPersister.getResourceClassInfo(connection, resourceClassName);
4197
4198 // verify the domain
4199 final Id<DomainId> domainId = domainPersister.getResourceDomainId(connection, domainName);
4200
4201 if (domainId == null) {
4202 throw new IllegalArgumentException("Could not find domain: " + domainName);
4203 }
4204
4205 // next ensure that the requested permissions are all in the correct resource class
4206 __assertUniqueGlobalResourcePermissionNamesForResourceClass(connection, requestedResourcePermissions, resourceClassInternalInfo);
4207
4208 // check for authorization
4209 if (!__isSuperUserOfDomain(connection, sessionResource, domainName)) {
4210 final Set<ResourcePermission> grantorPermissions
4211 = __getEffectiveGlobalResourcePermissionsIgnoringSuperUserPrivileges(connection,
4212 sessionResource,
4213 resourceClassName,
4214 domainName);
4215
4216 final Set<ResourcePermission> unauthorizedPermissions
4217 = __subtractResourcePermissionsIfGrantableFrom(requestedResourcePermissions, grantorPermissions);
4218
4219 if (unauthorizedPermissions.size() > 0) {
4220 throw NotAuthorizedException.newInstanceForAction(sessionResource,
4221 "grant the following global permission(s): " + unauthorizedPermissions);
4222 }
4223 }
4224
4225 final Set<ResourcePermission> directAccessorPermissions
4226 = __getDirectGlobalResourcePermissions(connection, accessorResource, resourceClassId, domainId);
4227
4228 final Set<ResourcePermission> addPermissions = new HashSet<>(requestedResourcePermissions.size());
4229 final Set<ResourcePermission> updatePermissions = new HashSet<>(requestedResourcePermissions.size());
4230
4231 for (ResourcePermission requestedPermission : requestedResourcePermissions) {
4232 boolean existingPermission = false;
4233
4234 for (ResourcePermission existingDirectPermission : directAccessorPermissions) {
4235 if (requestedPermission.equalsIgnoreGrantOption(existingDirectPermission)) {
4236 // found a match by name - now let's check if we need to update existing or leave it unchanged
4237 if (!requestedPermission.equals(existingDirectPermission) &&
4238 !requestedPermission.isGrantableFrom(existingDirectPermission)) {
4239 // requested permission has higher granting rights than the already existing direct permission,
4240 // so we need to update it
4241 updatePermissions.add(requestedPermission);
4242 }
4243
4244 existingPermission = true;
4245 break;
4246 }
4247 }
4248
4249 if (!existingPermission) {
4250 // couldn't find requested permission in set of already existing direct permissions, by name, so we need to add it
4251 addPermissions.add(requestedPermission);
4252 }
4253 }
4254
4255 // update any necessary direct system permissions between the accessor and the accessed resource
4256 grantGlobalResourcePermissionSysPersister.updateGlobalSysPermissions(connection,
4257 accessorResource,
4258 resourceClassId,
4259 domainId,
4260 updatePermissions,
4261 sessionResource);
4262
4263 // update any necessary direct non-system permissions between the accessor and the accessed resource
4264 grantGlobalResourcePermissionPersister.updateGlobalResourcePermissions(connection,
4265 accessorResource,
4266 resourceClassId,
4267 domainId,
4268 updatePermissions,
4269 sessionResource);
4270
4271 // add the new system permissions
4272 grantGlobalResourcePermissionSysPersister.addGlobalSysPermissions(connection,
4273 accessorResource,
4274 resourceClassId,
4275 domainId,
4276 addPermissions,
4277 sessionResource);
4278
4279 // add the new non-system permissions
4280 grantGlobalResourcePermissionPersister.addGlobalResourcePermissions(connection,
4281 accessorResource,
4282 resourceClassId,
4283 domainId,
4284 addPermissions,
4285 sessionResource);
4286 }
4287
4288 @Override
4289 public void revokeGlobalResourcePermissions(Resource accessorResource,
4290 String resourceClassName,
4291 String domainName,
4292 Set<ResourcePermission> resourcePermissions) {
4293 SQLConnection connection = null;
4294
4295 __assertAuthenticated();
4296 __assertResourceSpecified(accessorResource);
4297 __assertResourceClassSpecified(resourceClassName);
4298 __assertDomainSpecified(domainName);
4299 __assertPermissionsSpecified(resourcePermissions);
4300 __assertPermissionsSetNotEmpty(resourcePermissions);
4301
4302 final Set<ResourcePermission> normalizedResourcePermissions = __normalizeResourcePermission(resourcePermissions);
4303
4304 try {
4305 connection = __getConnection();
4306 accessorResource = __resolveResource(connection, accessorResource);
4307 resourceClassName = resourceClassName.trim();
4308 domainName = domainName.trim();
4309
4310 __revokeDirectGlobalPermissions(connection,
4311 accessorResource,
4312 resourceClassName,
4313 domainName,
4314 normalizedResourcePermissions);
4315 }
4316 finally {
4317 __closeConnection(connection);
4318 }
4319 }
4320
4321 @Override
4322 public void revokeGlobalResourcePermissions(Resource accessorResource,
4323 String resourceClassName,
4324 String domainName,
4325 ResourcePermission resourcePermission,
4326 ResourcePermission... resourcePermissions) {
4327 SQLConnection connection = null;
4328
4329 __assertAuthenticated();
4330 __assertResourceSpecified(accessorResource);
4331 __assertResourceClassSpecified(resourceClassName);
4332 __assertDomainSpecified(domainName);
4333 __assertPermissionSpecified(resourcePermission);
4334 __assertVarargPermissionsSpecified(resourcePermissions);
4335
4336 final Set<ResourcePermission> normalizedResourcePermissions
4337 = __normalizeResourcePermission(__getSetWithoutNullsOrDuplicates(resourcePermission, resourcePermissions));
4338
4339 try {
4340 connection = __getConnection();
4341 accessorResource = __resolveResource(connection, accessorResource);
4342 resourceClassName = resourceClassName.trim();
4343 domainName = domainName.trim();
4344
4345 __revokeDirectGlobalPermissions(connection,
4346 accessorResource,
4347 resourceClassName,
4348 domainName,
4349 normalizedResourcePermissions);
4350 }
4351 finally {
4352 __closeConnection(connection);
4353 }
4354 }
4355
4356 private void __revokeDirectGlobalPermissions(SQLConnection connection,
4357 Resource accessorResource,
4358 String resourceClassName,
4359 String domainName,
4360 Set<ResourcePermission> requestedResourcePermissions) {
4361 // verify that resource class is defined
4362 final ResourceClassInternalInfo resourceClassInfo = __getResourceClassInternalInfo(connection,
4363 resourceClassName);
4364
4365 final Id<ResourceClassId> resourceClassId = resourceClassPersister.getResourceClassId(connection, resourceClassName);
4366
4367 // next ensure that the requested permissions are valid and unique in name
4368 __assertUniqueResourcePermissionsNamesForResourceClass(connection,
4369 requestedResourcePermissions,
4370 resourceClassInfo);
4371
4372 // verify the domain
4373 final Id<DomainId> domainId = domainPersister.getResourceDomainId(connection, domainName);
4374
4375 if (domainId == null) {
4376 throw new IllegalArgumentException("Could not find domain: " + domainName);
4377 }
4378
4379 // check for authorization
4380 if (!__isSuperUserOfDomain(connection, sessionResource, domainName)) {
4381 final Set<ResourcePermission> grantorPermissions
4382 = __getEffectiveGlobalResourcePermissionsIgnoringSuperUserPrivileges(connection,
4383 sessionResource,
4384 resourceClassName,
4385 domainName);
4386
4387 final Set<ResourcePermission> unauthorizedPermissions
4388 = __subtractResourcePermissionsIfGrantableFrom(requestedResourcePermissions, grantorPermissions);
4389
4390 if (unauthorizedPermissions.size() > 0) {
4391 throw NotAuthorizedException.newInstanceForAction(sessionResource,
4392 "revoke the following global permission(s): " + unauthorizedPermissions);
4393 }
4394 }
4395
4396 final Set<ResourcePermission> directAccessorPermissions
4397 = __getDirectGlobalResourcePermissions(connection, accessorResource, resourceClassId, domainId);
4398
4399 final Set<ResourcePermission> removePermissions = new HashSet<>(requestedResourcePermissions.size());
4400
4401 for (ResourcePermission requestedPermission : requestedResourcePermissions) {
4402 for (ResourcePermission existingDirectPermission : directAccessorPermissions) {
4403 if (requestedPermission.equalsIgnoreGrantOption(existingDirectPermission)) {
4404 // requested permission has same name and regardless of granting rights we need to remove it
4405 removePermissions.add(requestedPermission);
4406 break;
4407 }
4408 }
4409 }
4410
4411 // remove any necessary direct system permissions
4412 grantGlobalResourcePermissionSysPersister.removeGlobalSysPermissions(connection,
4413 accessorResource,
4414 resourceClassId,
4415 domainId,
4416 removePermissions);
4417
4418 // remove any necessary direct non-system permissions
4419 grantGlobalResourcePermissionPersister.removeGlobalResourcePermissions(connection,
4420 accessorResource,
4421 resourceClassId,
4422 domainId,
4423 removePermissions);
4424 }
4425
4426 @Override
4427 public Set<ResourcePermission> getGlobalResourcePermissions(Resource accessorResource,
4428 String resourceClassName,
4429 String domainName) {
4430 SQLConnection connection = null;
4431
4432 __assertAuthenticated();
4433 __assertResourceSpecified(accessorResource);
4434 __assertResourceClassSpecified(resourceClassName);
4435 __assertDomainSpecified(domainName);
4436
4437 try {
4438 connection = __getConnection();
4439 accessorResource = __resolveResource(connection, accessorResource);
4440 __assertQueryAuthorization(connection, accessorResource);
4441
4442 resourceClassName = resourceClassName.trim();
4443 domainName = domainName.trim();
4444
4445 return __getDirectGlobalResourcePermissions(connection,
4446 accessorResource,
4447 resourceClassName,
4448 domainName);
4449 }
4450 finally {
4451 __closeConnection(connection);
4452 }
4453 }
4454
4455 private Set<ResourcePermission> __getDirectGlobalResourcePermissions(SQLConnection connection,
4456 Resource accessorResource,
4457 String resourceClassName,
4458 String domainName) {
4459 // verify that resource class is defined
4460 final Id<ResourceClassId> resourceClassId = resourceClassPersister.getResourceClassId(connection, resourceClassName);
4461
4462 if (resourceClassId == null) {
4463 throw new IllegalArgumentException("Could not find resource class: " + resourceClassName);
4464 }
4465
4466 // verify the domain
4467 final Id<DomainId> domainId = domainPersister.getResourceDomainId(connection, domainName);
4468
4469 if (domainId == null) {
4470 throw new IllegalArgumentException("Could not find domain: " + domainName);
4471 }
4472
4473 return __getDirectGlobalResourcePermissions(connection,
4474 accessorResource,
4475 resourceClassId,
4476 domainId);
4477 }
4478
4479 @Override
4480 public Set<ResourcePermission> getEffectiveGlobalResourcePermissions(Resource accessorResource,
4481 String resourceClassName,
4482 String domainName) {
4483 SQLConnection connection = null;
4484
4485 __assertAuthenticated();
4486 __assertResourceSpecified(accessorResource);
4487 __assertResourceClassSpecified(resourceClassName);
4488 __assertDomainSpecified(domainName);
4489
4490 try {
4491 connection = __getConnection();
4492 accessorResource = __resolveResource(connection, accessorResource);
4493 __assertQueryAuthorization(connection, accessorResource);
4494
4495 resourceClassName = resourceClassName.trim();
4496 domainName = domainName.trim();
4497
4498 return __getEffectiveGlobalResourcePermissions(connection,
4499 accessorResource,
4500 resourceClassName,
4501 domainName);
4502 }
4503 finally {
4504 __closeConnection(connection);
4505 }
4506 }
4507
4508 private Set<ResourcePermission> __getEffectiveGlobalResourcePermissionsIgnoringSuperUserPrivileges(SQLConnection connection,
4509 Resource accessorResource,
4510 String resourceClassName,
4511 String domainName) {
4512 // verify that resource class is defined
4513 final Id<ResourceClassId> resourceClassId = resourceClassPersister.getResourceClassId(connection, resourceClassName);
4514
4515 if (resourceClassId == null) {
4516 throw new IllegalArgumentException("Could not find resource class: " + resourceClassName);
4517 }
4518
4519 // verify the domain
4520 final Id<DomainId> domainId = domainPersister.getResourceDomainId(connection, domainName);
4521
4522 if (domainId == null) {
4523 throw new IllegalArgumentException("Could not find domain: " + domainName);
4524 }
4525
4526 Set<ResourcePermission> resourcePermissions = new HashSet<>();
4527
4528 // first collect the system permissions that the accessor has to the accessed resource
4529 resourcePermissions.addAll(grantGlobalResourcePermissionSysPersister
4530 .getGlobalSysPermissionsIncludeInherited(connection,
4531 accessorResource,
4532 resourceClassId,
4533 domainId));
4534
4535 // first collect the non-system permissions that the accessor this resource has to the accessor resource
4536 resourcePermissions.addAll(grantGlobalResourcePermissionPersister
4537 .getGlobalResourcePermissionsIncludeInherited(connection,
4538 accessorResource,
4539 resourceClassId,
4540 domainId));
4541 return __collapseResourcePermissions(resourcePermissions);
4542 }
4543
4544 private Set<ResourcePermission> __getEffectiveGlobalResourcePermissions(SQLConnection connection,
4545 Resource accessorResource,
4546 String resourceClassName,
4547 String domainName) {
4548 // verify that resource class is defined
4549 final ResourceClassInternalInfo resourceClassInternalInfo = __getResourceClassInternalInfo(connection,
4550 resourceClassName);
4551
4552 // verify the domain
4553 final Id<DomainId> domainId = domainPersister.getResourceDomainId(connection, domainName);
4554
4555 if (domainId == null) {
4556 throw new IllegalArgumentException("Could not find domain: " + domainName);
4557 }
4558
4559 if (__isSuperUserOfDomain(connection, accessorResource, domainName)) {
4560 return __getApplicableResourcePermissions(connection, resourceClassInternalInfo);
4561 }
4562
4563 final Id<ResourceClassId> resourceClassId = Id.from(resourceClassInternalInfo.getResourceClassId());
4564 Set<ResourcePermission> resourcePermissions = new HashSet<>();
4565
4566 // first collect the system permissions that the accessor has to the accessed resource
4567 resourcePermissions.addAll(grantGlobalResourcePermissionSysPersister
4568 .getGlobalSysPermissionsIncludeInherited(connection,
4569 accessorResource,
4570 resourceClassId,
4571 domainId));
4572
4573 // first collect the non-system permissions that the accessor this resource has to the accessor resource
4574 resourcePermissions.addAll(grantGlobalResourcePermissionPersister
4575 .getGlobalResourcePermissionsIncludeInherited(connection,
4576 accessorResource,
4577 resourceClassId,
4578 domainId));
4579 return __collapseResourcePermissions(resourcePermissions);
4580 }
4581
4582 private Set<ResourcePermission> __getApplicableResourcePermissions(SQLConnection connection,
4583 ResourceClassInternalInfo resourceClassInternalInfo) {
4584 final List<String> resourcePermissionNames
4585 = __getApplicableResourcePermissionNames(connection, resourceClassInternalInfo);
4586
4587 Set<ResourcePermission> superResourcePermissions = new HashSet<>(resourcePermissionNames.size());
4588
4589 for (String permissionName : resourcePermissionNames) {
4590 superResourcePermissions.add(ResourcePermissions.getInstanceWithGrantOption(permissionName));
4591 }
4592
4593 return superResourcePermissions;
4594 }
4595
4596 private Set<ResourceCreatePermission> __getApplicableResourceCreatePermissions(SQLConnection connection,
4597 ResourceClassInternalInfo resourceClassInternalInfo) {
4598
4599 final List<String> resourcePermissionNames
4600 = __getApplicableResourcePermissionNames(connection, resourceClassInternalInfo);
4601
4602 Set<ResourceCreatePermission> superResourceCreatePermissions = new HashSet<>(resourcePermissionNames.size()+1);
4603
4604 superResourceCreatePermissions.add(ResourceCreatePermissions.getInstanceWithGrantOption(ResourceCreatePermissions.CREATE));
4605
4606 for (String permissionName : resourcePermissionNames) {
4607 superResourceCreatePermissions
4608 .add(ResourceCreatePermissions
4609 .getInstanceWithGrantOption(ResourcePermissions.getInstanceWithGrantOption(permissionName)));
4610 }
4611
4612 return superResourceCreatePermissions;
4613 }
4614
4615 private Set<ResourcePermission> __collapseResourcePermissions(Set<ResourcePermission> resourcePermissions) {
4616 final Set<ResourcePermission> collapsedPermissions = new HashSet<>(resourcePermissions);
4617
4618 for (ResourcePermission permission : resourcePermissions) {
4619 for (ResourcePermission grantEquivalentPermission : resourcePermissions) {
4620 if (permission.isGrantableFrom(grantEquivalentPermission) && !permission.equals(grantEquivalentPermission)) {
4621 collapsedPermissions.remove(permission);
4622 break;
4623 }
4624 }
4625 }
4626
4627 return collapsedPermissions;
4628 }
4629
4630 @Override
4631 public Map<String, Map<String, Set<ResourcePermission>>> getGlobalResourcePermissionsMap(Resource accessorResource) {
4632 SQLConnection connection = null;
4633
4634 __assertAuthenticated();
4635 __assertResourceSpecified(accessorResource);
4636
4637 try {
4638 connection = __getConnection();
4639 accessorResource = __resolveResource(connection, accessorResource);
4640 __assertQueryAuthorization(connection, accessorResource);
4641
4642 return __getDirectGlobalResourcePermissionsMap(connection, accessorResource);
4643 }
4644 finally {
4645 __closeConnection(connection);
4646 }
4647 }
4648
4649 private Map<String, Map<String, Set<ResourcePermission>>> __getDirectGlobalResourcePermissionsMap(SQLConnection connection,
4650 Resource accessorResource) {
4651 final Map<String, Map<String, Set<ResourcePermission>>> globalALLPermissionsMap = new HashMap<>();
4652
4653 // collect the system permissions that the accessor has and add it into the globalALLPermissionsMap
4654 globalALLPermissionsMap
4655 .putAll(grantGlobalResourcePermissionSysPersister.getGlobalSysPermissions(connection, accessorResource));
4656
4657 // next collect the non-system permissions that the accessor has and add it into the globalALLPermissionsMap
4658 __mergeSourcePermissionsMapIntoTargetPermissionsMap(grantGlobalResourcePermissionPersister
4659 .getGlobalResourcePermissions(connection,
4660 accessorResource),
4661 globalALLPermissionsMap);
4662
4663 return __collapseResourcePermissions(globalALLPermissionsMap);
4664 }
4665
4666 @Override
4667 public Map<String, Map<String, Set<ResourcePermission>>> getEffectiveGlobalResourcePermissionsMap(Resource accessorResource) {
4668 SQLConnection connection = null;
4669
4670 __assertAuthenticated();
4671 __assertResourceSpecified(accessorResource);
4672
4673 try {
4674 connection = __getConnection();
4675 accessorResource = __resolveResource(connection, accessorResource);
4676 __assertQueryAuthorization(connection, accessorResource);
4677
4678 return __getEffectiveGlobalResourcePermissionsMap(connection, accessorResource);
4679 }
4680 finally {
4681 __closeConnection(connection);
4682 }
4683 }
4684
4685 private Map<String, Map<String, Set<ResourcePermission>>> __getEffectiveGlobalResourcePermissionsMap(SQLConnection connection,
4686 Resource accessorResource) {
4687 final Map<String, Map<String, Set<ResourcePermission>>> globalALLPermissionsMap = new HashMap<>();
4688
4689 // collect the system permissions that the accessor has and add it into the globalALLPermissionsMap
4690 globalALLPermissionsMap
4691 .putAll(grantGlobalResourcePermissionSysPersister
4692 .getGlobalSysPermissionsIncludeInherited(connection, accessorResource));
4693
4694 // next collect the non-system permissions that the accessor has and add it into the globalALLPermissionsMap
4695 __mergeSourcePermissionsMapIntoTargetPermissionsMap(
4696 grantGlobalResourcePermissionPersister.getGlobalResourcePermissionsIncludeInherited(connection,
4697 accessorResource),
4698 globalALLPermissionsMap);
4699
4700 // finally, collect all applicable permissions when accessor has super-user privileges to any domain
4701 // and add them into the globalALLPermissionsMap
4702 final Map<String, Map<String, Set<ResourcePermission>>> superGlobalResourcePermissionsMap = new HashMap<>();
4703 Map<String, Set<ResourcePermission>> superResourcePermissionsMap = null;
4704
4705 final Map<String, Set<DomainPermission>> effectiveDomainPermissionsMap
4706 = __getEffectiveDomainPermissionsMap(connection, accessorResource);
4707
4708 for (Map.Entry<String, Set<DomainPermission>>
4709 effectiveDomainPermissionsByDomainEntry : effectiveDomainPermissionsMap.entrySet()) {
4710 final Set<DomainPermission> effectiveDomainPermissions = effectiveDomainPermissionsByDomainEntry.getValue();
4711 if (effectiveDomainPermissions.contains(DomainPermission_SUPER_USER)
4712 || effectiveDomainPermissions.contains(DomainPermission_SUPER_USER_GRANT)) {
4713
4714 if (superResourcePermissionsMap == null) {
4715 // lazy-construct super-user-privileged resource-permissions map by resource classes
4716 final List<String> resourceClassNames = resourceClassPersister.getResourceClassNames(connection);
4717 superResourcePermissionsMap = new HashMap<>(resourceClassNames.size());
4718 for (String resourceClassName : resourceClassNames) {
4719 final Set<ResourcePermission> applicableResourcePermissions
4720 = __getApplicableResourcePermissions(connection,
4721 __getResourceClassInternalInfo(connection,
4722 resourceClassName));
4723
4724 superResourcePermissionsMap.put(resourceClassName, applicableResourcePermissions);
4725 }
4726 }
4727 superGlobalResourcePermissionsMap.put(effectiveDomainPermissionsByDomainEntry.getKey(),
4728 superResourcePermissionsMap);
4729 }
4730 }
4731
4732 __mergeSourcePermissionsMapIntoTargetPermissionsMap(superGlobalResourcePermissionsMap, globalALLPermissionsMap);
4733
4734 return __collapseResourcePermissions(globalALLPermissionsMap);
4735 }
4736
4737 private void __mergeSourcePermissionsMapIntoTargetPermissionsMap(Map<String, Map<String, Set<ResourcePermission>>> sourcePermissionsMap,
4738 Map<String, Map<String, Set<ResourcePermission>>> targetPermissionsMap) {
4739 for (Map.Entry<String, Map<String, Set<ResourcePermission>>>
4740 sourcePermissionsMapByDomainEntry : sourcePermissionsMap.entrySet()) {
4741 final String domainName = sourcePermissionsMapByDomainEntry.getKey();
4742
4743 Map<String, Set<ResourcePermission>> targetPermsForDomainMap = targetPermissionsMap.get(domainName);
4744 // does the target map have domain?
4745 if (targetPermsForDomainMap == null) {
4746 // no, add the domain
4747 targetPermsForDomainMap = new HashMap<>();
4748 targetPermissionsMap.put(domainName, targetPermsForDomainMap);
4749 }
4750
4751 for (Map.Entry<String, Set<ResourcePermission>>
4752 sourcePermissionsByResourceClassEntry : sourcePermissionsMapByDomainEntry.getValue().entrySet()) {
4753 final String resourceClassName = sourcePermissionsByResourceClassEntry.getKey();
4754
4755 Set<ResourcePermission> targetPermsForClassSet = targetPermsForDomainMap.get(resourceClassName);
4756 // does the target map have the resource class?
4757 if (targetPermsForClassSet == null) {
4758 // no, add the resource class
4759 targetPermsForClassSet = new HashSet<>();
4760 targetPermsForDomainMap.put(resourceClassName, targetPermsForClassSet);
4761 }
4762
4763 // add the source permissions above to the target for the respective domain + resource class
4764 targetPermsForClassSet.addAll(sourcePermissionsByResourceClassEntry.getValue());
4765 }
4766 }
4767 }
4768
4769 private Map<String, Map<String, Set<ResourcePermission>>> __collapseResourcePermissions(Map<String, Map<String, Set<ResourcePermission>>> resourcePermissionsMap) {
4770 for (Map.Entry<String, Map<String, Set<ResourcePermission>>>
4771 resourcePermissionsMapByDomainEntry : resourcePermissionsMap.entrySet()) {
4772 final Map<String, Set<ResourcePermission>> resourcePermissionsByResourceClassMap
4773 = resourcePermissionsMapByDomainEntry.getValue();
4774
4775 for (Map.Entry<String, Set<ResourcePermission>>
4776 resourcePermissionsByResourceClassEntry : resourcePermissionsByResourceClassMap.entrySet()) {
4777 resourcePermissionsByResourceClassMap.put(resourcePermissionsByResourceClassEntry.getKey(),
4778 __collapseResourcePermissions(resourcePermissionsByResourceClassEntry
4779 .getValue()));
4780 }
4781 }
4782
4783 return resourcePermissionsMap;
4784 }
4785
4786 @Override
4787 public String getDomainNameByResource(Resource resource) {
4788 SQLConnection connection = null;
4789
4790 __assertAuthenticated();
4791 __assertResourceSpecified(resource);
4792
4793 try {
4794 connection = __getConnection();
4795 resource = __resolveResource(connection, resource);
4796
4797 if (sessionResource.equals(resource)) {
4798 return sessionResourceDomainName;
4799 }
4800 else if (authenticatedResource.equals(resource)) {
4801 return authenticatedResourceDomainName;
4802 }
4803
4804 return domainPersister.getResourceDomainNameByResourceId(connection, resource);
4805 }
4806 finally {
4807 __closeConnection(connection);
4808 }
4809 }
4810
4811 @Override
4812 public Set<String> getDomainDescendants(String domainName) {
4813 SQLConnection connection = null;
4814
4815 __assertAuthenticated();
4816 __assertDomainSpecified(domainName);
4817
4818 try {
4819 connection = __getConnection();
4820 domainName = domainName.trim();
4821
4822 return domainPersister.getResourceDomainNameDescendants(connection, domainName);
4823 }
4824 finally {
4825 __closeConnection(connection);
4826 }
4827 }
4828
4829 @Override
4830 public ResourceClassInfo getResourceClassInfo(String resourceClassName) {
4831 SQLConnection connection = null;
4832
4833 __assertAuthenticated();
4834 __assertResourceClassSpecified(resourceClassName);
4835
4836 try {
4837 connection = __getConnection();
4838
4839 final ResourceClassInternalInfo resourceClassInternalInfo = __getResourceClassInternalInfo(connection,
4840 resourceClassName);
4841
4842 return new ResourceClassInfo(resourceClassInternalInfo.getResourceClassName(),
4843 resourceClassInternalInfo.isAuthenticatable(),
4844 resourceClassInternalInfo.isUnauthenticatedCreateAllowed());
4845 }
4846 finally {
4847 __closeConnection(connection);
4848 }
4849 }
4850
4851 @Override
4852 public ResourceClassInfo getResourceClassInfoByResource(Resource resource) {
4853 SQLConnection connection = null;
4854
4855 __assertAuthenticated();
4856 __assertResourceSpecified(resource);
4857
4858 try {
4859 connection = __getConnection();
4860
4861 resource = __resolveResource(connection, resource);
4862 final ResourceClassInternalInfo resourceClassInternalInfo
4863 = resourceClassPersister.getResourceClassInfoByResourceId(connection, resource);
4864 return new ResourceClassInfo(resourceClassInternalInfo.getResourceClassName(),
4865 resourceClassInternalInfo.isAuthenticatable(),
4866 resourceClassInternalInfo.isUnauthenticatedCreateAllowed());
4867 }
4868 finally {
4869 __closeConnection(connection);
4870 }
4871 }
4872
4873 @Override
4874 public Resource getAuthenticatedResource() {
4875 __assertAuthenticated();
4876
4877 if (defensiveCopyOfAuthenticatedResource == null ||
4878 !__isEqual(defensiveCopyOfAuthenticatedResource, authenticatedResource)) {
4879 defensiveCopyOfAuthenticatedResource = Resources.getInstance(authenticatedResource.getId(),
4880 authenticatedResource.getExternalId());
4881 }
4882
4883 return defensiveCopyOfAuthenticatedResource;
4884 }
4885
4886 @Override
4887 public Resource getSessionResource() {
4888 __assertAuthenticated();
4889
4890 if (defensiveCopyOfSessionResource == null ||
4891 !__isEqual(defensiveCopyOfSessionResource, sessionResource)) {
4892 defensiveCopyOfSessionResource = Resources.getInstance(sessionResource.getId(),
4893 sessionResource.getExternalId());
4894 }
4895
4896 return defensiveCopyOfSessionResource;
4897 }
4898
4899 @Override
4900 public void assertPostCreateDomainPermissions(Resource accessorResource,
4901 Set<DomainPermission> domainPermissions) {
4902 if (!hasPostCreateDomainPermissions(accessorResource, domainPermissions)) {
4903 throw NotAuthorizedException.newInstanceForPostCreateDomainPermissions(accessorResource,
4904 domainPermissions);
4905 }
4906 }
4907
4908 @Override
4909 public void assertPostCreateDomainPermissions(Resource accessorResource,
4910 DomainPermission domainPermission,
4911 DomainPermission... domainPermissions) {
4912 if (!hasPostCreateDomainPermissions(accessorResource, domainPermission, domainPermissions)) {
4913 throw NotAuthorizedException.newInstanceForPostCreateDomainPermissions(accessorResource,
4914 domainPermission,
4915 domainPermissions);
4916 }
4917 }
4918
4919 @Override
4920 public boolean hasPostCreateDomainPermissions(Resource accessorResource,
4921 Set<DomainPermission> domainPermissions) {
4922 SQLConnection connection = null;
4923
4924 __assertAuthenticated();
4925 __assertResourceSpecified(accessorResource);
4926 __assertPermissionsSpecified(domainPermissions);
4927 __assertPermissionsSetNotEmpty(domainPermissions);
4928
4929 final Set<DomainPermission> normalizedDomainPermissions = __normalizeDomainPermissions(domainPermissions);
4930
4931 try {
4932 connection = __getConnection();
4933 accessorResource = __resolveResource(connection, accessorResource);
4934
4935 return __hasPostCreateDomainPermissions(connection, accessorResource, normalizedDomainPermissions);
4936 }
4937 finally {
4938 __closeConnection(connection);
4939 }
4940 }
4941
4942 @Override
4943 public boolean hasPostCreateDomainPermissions(Resource accessorResource,
4944 DomainPermission domainPermission,
4945 DomainPermission... domainPermissions) {
4946 SQLConnection connection = null;
4947
4948 __assertAuthenticated();
4949 __assertResourceSpecified(accessorResource);
4950 __assertPermissionSpecified(domainPermission);
4951 __assertVarargPermissionsSpecified(domainPermissions);
4952
4953 final Set<DomainPermission> normalizedDomainPermissions
4954 = __normalizeDomainPermissions(__getSetWithoutNullsOrDuplicates(domainPermission, domainPermissions));
4955
4956 try {
4957 connection = __getConnection();
4958 accessorResource = __resolveResource(connection, accessorResource);
4959
4960 return __hasPostCreateDomainPermissions(connection,
4961 accessorResource,
4962 normalizedDomainPermissions);
4963 }
4964 finally {
4965 __closeConnection(connection);
4966 }
4967 }
4968
4969 private boolean __hasPostCreateDomainPermissions(SQLConnection connection,
4970 Resource accessorResource,
4971 Set<DomainPermission> requestedDomainPermissions) {
4972 __assertQueryAuthorization(connection, accessorResource);
4973
4974 boolean hasPermission = false;
4975
4976 // first check if the accessor even has *CREATE permission for domains
4977 final Set<DomainCreatePermission> effectiveDomainCreatePermissions
4978 = __getEffectiveDomainCreatePermissions(connection, accessorResource);
4979
4980 for (DomainCreatePermission domainCreatePermission : effectiveDomainCreatePermissions) {
4981 if (domainCreatePermission.isSystemPermission()
4982 && DomainCreatePermissions.CREATE.equals(domainCreatePermission.getPermissionName())) {
4983 hasPermission = true;
4984 break;
4985 }
4986 }
4987
4988 if (hasPermission) {
4989 // check if the requested permissions are permissible from the set of effective post-create permissions
4990 final Set<DomainPermission> postCreateDomainPermissions
4991 = __getPostCreateDomainPermissions(effectiveDomainCreatePermissions);
4992
4993 for (DomainPermission requestedDomainPermission : requestedDomainPermissions) {
4994 if (!__isPermissible(requestedDomainPermission, postCreateDomainPermissions)) {
4995 hasPermission = false;
4996 break;
4997 }
4998 }
4999
5000 if (!hasPermission) {
5001 hasPermission = postCreateDomainPermissions.contains(DomainPermission_SUPER_USER)
5002 || postCreateDomainPermissions.contains(DomainPermission_SUPER_USER_GRANT);
5003 }
5004 }
5005 return hasPermission;
5006 }
5007
5008 private boolean __isPermissible(DomainPermission queriedDomainPermission,
5009 Set<DomainPermission> domainPermissions) {
5010 for (DomainPermission domainPermission : domainPermissions) {
5011 if (queriedDomainPermission.equals(domainPermission)
5012 || queriedDomainPermission.isGrantableFrom(domainPermission)) {
5013 return true;
5014 }
5015 }
5016 return false;
5017 }
5018
5019 @Override
5020 public void assertDomainPermissions(Resource accessorResource,
5021 String domainName,
5022 Set<DomainPermission> domainPermissions) {
5023 if (!hasDomainPermissions(accessorResource, domainName, domainPermissions)) {
5024 throw NotAuthorizedException.newInstanceForDomainPermissions(accessorResource,
5025 domainName,
5026 domainPermissions);
5027 }
5028 }
5029
5030 @Override
5031 public void assertDomainPermissions(Resource accessorResource,
5032 String domainName,
5033 DomainPermission domainPermission,
5034 DomainPermission... domainPermissions) {
5035 if (!hasDomainPermissions(accessorResource, domainName, domainPermission, domainPermissions)) {
5036 throw NotAuthorizedException.newInstanceForDomainPermissions(accessorResource,
5037 domainName,
5038 domainPermission,
5039 domainPermissions);
5040 }
5041 }
5042
5043 @Override
5044 public boolean hasDomainPermissions(Resource accessorResource,
5045 String domainName,
5046 Set<DomainPermission> domainPermissions) {
5047 SQLConnection connection = null;
5048
5049 __assertAuthenticated();
5050 __assertResourceSpecified(accessorResource);
5051 __assertDomainSpecified(domainName);
5052 __assertPermissionsSpecified(domainPermissions);
5053 __assertPermissionsSetNotEmpty(domainPermissions);
5054
5055 final Set<DomainPermission> normalizedDomainPermissions = __normalizeDomainPermissions(domainPermissions);
5056
5057 try {
5058 connection = __getConnection();
5059 accessorResource = __resolveResource(connection, accessorResource);
5060
5061 return __hasDomainPermissions(connection, accessorResource, domainName, normalizedDomainPermissions);
5062 }
5063 finally {
5064 __closeConnection(connection);
5065 }
5066 }
5067
5068 @Override
5069 public boolean hasDomainPermissions(Resource accessorResource,
5070 String domainName,
5071 DomainPermission domainPermission,
5072 DomainPermission... domainPermissions) {
5073 SQLConnection connection = null;
5074
5075 __assertAuthenticated();
5076 __assertResourceSpecified(accessorResource);
5077 __assertDomainSpecified(domainName);
5078 __assertPermissionSpecified(domainPermission);
5079 __assertVarargPermissionsSpecified(domainPermissions);
5080
5081 final Set<DomainPermission> normalizedDomainPermissions
5082 = __normalizeDomainPermissions(__getSetWithoutNullsOrDuplicates(domainPermission, domainPermissions));
5083
5084 try {
5085 connection = __getConnection();
5086 accessorResource = __resolveResource(connection, accessorResource);
5087
5088 return __hasDomainPermissions(connection, accessorResource, domainName, normalizedDomainPermissions);
5089 }
5090 finally {
5091 __closeConnection(connection);
5092 }
5093 }
5094
5095 private boolean __hasDomainPermissions(SQLConnection connection,
5096 Resource accessorResource,
5097 String domainName,
5098 Set<DomainPermission> requestedDomainPermissions) {
5099 __assertQueryAuthorization(connection, accessorResource);
5100
5101 // first check for effective permissions
5102 final Set<DomainPermission> effectiveDomainPermissions = __getEffectiveDomainPermissions(connection,
5103 accessorResource,
5104 domainName);
5105 boolean hasPermission = true;
5106
5107 for (DomainPermission domainPermission : requestedDomainPermissions) {
5108 if (!__isPermissible(domainPermission, effectiveDomainPermissions)) {
5109 hasPermission = false;
5110 break;
5111 }
5112 }
5113
5114 // next check super-user permissions to the domain of the accessed resource
5115 if (!hasPermission) {
5116 hasPermission = __isSuperUserOfDomain(connection, accessorResource, domainName);
5117 }
5118
5119 return hasPermission;
5120 }
5121
5122 @Override
5123 public void assertDomainCreatePermissions(Resource accessorResource,
5124 Set<DomainCreatePermission> domainCreatePermissions) {
5125 if (!hasDomainCreatePermissions(accessorResource, domainCreatePermissions)) {
5126 throw NotAuthorizedException.newInstanceForDomainCreatePermissions(accessorResource,
5127 domainCreatePermissions);
5128 }
5129 }
5130
5131 @Override
5132 public void assertDomainCreatePermissions(Resource accessorResource,
5133 DomainCreatePermission domainCreatePermission,
5134 DomainCreatePermission... domainCreatePermissions) {
5135 if (!hasDomainCreatePermissions(accessorResource, domainCreatePermission, domainCreatePermissions)) {
5136 throw NotAuthorizedException.newInstanceForDomainCreatePermissions(accessorResource,
5137 domainCreatePermission,
5138 domainCreatePermissions);
5139 }
5140 }
5141
5142 @Override
5143 public boolean hasDomainCreatePermissions(Resource accessorResource,
5144 Set<DomainCreatePermission> domainCreatePermissions) {
5145 SQLConnection connection = null;
5146
5147 __assertAuthenticated();
5148 __assertResourceSpecified(accessorResource);
5149 __assertPermissionsSpecified(domainCreatePermissions);
5150 __assertPermissionsSetNotEmpty(domainCreatePermissions);
5151
5152 final Set<DomainCreatePermission> normalizedDomainCreatePermissions
5153 = __normalizeDomainCreatePermissions(domainCreatePermissions);
5154
5155 try {
5156 connection = __getConnection();
5157 accessorResource = __resolveResource(connection, accessorResource);
5158
5159 return __hasDomainCreatePermissions(connection, accessorResource, normalizedDomainCreatePermissions);
5160 }
5161 finally {
5162 __closeConnection(connection);
5163 }
5164 }
5165
5166 @Override
5167 public boolean hasDomainCreatePermissions(Resource accessorResource,
5168 DomainCreatePermission domainCreatePermission,
5169 DomainCreatePermission... domainCreatePermissions) {
5170 SQLConnection connection = null;
5171
5172 __assertAuthenticated();
5173 __assertResourceSpecified(accessorResource);
5174 __assertPermissionSpecified(domainCreatePermission);
5175 __assertVarargPermissionsSpecified(domainCreatePermissions);
5176
5177 final Set<DomainCreatePermission> normalizedDomainCreatePermissions
5178 = __normalizeDomainCreatePermissions(__getSetWithoutNullsOrDuplicates(domainCreatePermission,
5179 domainCreatePermissions));
5180
5181 try {
5182 connection = __getConnection();
5183 accessorResource = __resolveResource(connection, accessorResource);
5184
5185 return __hasDomainCreatePermissions(connection, accessorResource, normalizedDomainCreatePermissions);
5186 }
5187 finally {
5188 __closeConnection(connection);
5189 }
5190 }
5191
5192 private boolean __hasDomainCreatePermissions(SQLConnection connection,
5193 Resource accessorResource,
5194 Set<DomainCreatePermission> queriedDomainCreatePermissions) {
5195 __assertQueryAuthorization(connection, accessorResource);
5196
5197 final Set<DomainCreatePermission> effectiveDomainCreatePermissions
5198 = __getEffectiveDomainCreatePermissions(connection, accessorResource);
5199
5200 for (DomainCreatePermission domainCreatePermission : queriedDomainCreatePermissions) {
5201 if (!__isPermissible(domainCreatePermission, effectiveDomainCreatePermissions)) {
5202 return false;
5203 }
5204 }
5205
5206 return true;
5207 }
5208
5209 private boolean __isPermissible(DomainCreatePermission queriedDomainCreatePermission,
5210 Set<DomainCreatePermission> domainCreatePermissions) {
5211 for (DomainCreatePermission domainCreatePermission : domainCreatePermissions) {
5212 if (queriedDomainCreatePermission.equals(domainCreatePermission)
5213 || queriedDomainCreatePermission.isGrantableFrom(domainCreatePermission)) {
5214 return true;
5215 }
5216 }
5217 return false;
5218 }
5219
5220 @Override
5221 public void assertPostCreateResourcePermissions(Resource accessorResource,
5222 String resourceClassName,
5223 String domainName,
5224 Set<ResourcePermission> resourcePermissions) {
5225 if (!hasPostCreateResourcePermissions(accessorResource,
5226 resourceClassName,
5227 domainName,
5228 resourcePermissions)) {
5229 throw NotAuthorizedException.newInstanceForPostCreateResourcePermissions(accessorResource,
5230 resourceClassName,
5231 domainName,
5232 resourcePermissions);
5233 }
5234 }
5235
5236 @Override
5237 public void assertPostCreateResourcePermissions(Resource accessorResource,
5238 String resourceClassName,
5239 String domainName,
5240 ResourcePermission resourcePermission,
5241 ResourcePermission... resourcePermissions) {
5242 if (!hasPostCreateResourcePermissions(accessorResource,
5243 resourceClassName,
5244 domainName,
5245 resourcePermission,
5246 resourcePermissions)) {
5247 throw NotAuthorizedException.newInstanceForPostCreateResourcePermissions(accessorResource,
5248 resourceClassName,
5249 domainName,
5250 resourcePermission,
5251 resourcePermissions);
5252 }
5253 }
5254
5255 @Override
5256 public boolean hasPostCreateResourcePermissions(Resource accessorResource,
5257 String resourceClassName,
5258 String domainName,
5259 Set<ResourcePermission> resourcePermissions) {
5260 SQLConnection connection = null;
5261
5262 __assertAuthenticated();
5263 __assertResourceSpecified(accessorResource);
5264 __assertResourceClassSpecified(resourceClassName);
5265 __assertDomainSpecified(domainName);
5266 __assertPermissionsSpecified(resourcePermissions);
5267 __assertPermissionsSetNotEmpty(resourcePermissions);
5268
5269 final Set<ResourcePermission> normalizedResourcePermissions = __normalizeResourcePermission(resourcePermissions);
5270
5271 try {
5272 connection = __getConnection();
5273 accessorResource = __resolveResource(connection, accessorResource);
5274 resourceClassName = resourceClassName.trim();
5275 domainName = domainName.trim();
5276
5277 return __hasPostCreateResourcePermissions(connection,
5278 accessorResource,
5279 resourceClassName,
5280 domainName,
5281 normalizedResourcePermissions);
5282 }
5283 finally {
5284 __closeConnection(connection);
5285 }
5286 }
5287
5288 @Override
5289 public boolean hasPostCreateResourcePermissions(Resource accessorResource,
5290 String resourceClassName,
5291 String domainName,
5292 ResourcePermission resourcePermission,
5293 ResourcePermission... resourcePermissions) {
5294 SQLConnection connection = null;
5295
5296 __assertAuthenticated();
5297 __assertResourceSpecified(accessorResource);
5298 __assertResourceClassSpecified(resourceClassName);
5299 __assertDomainSpecified(domainName);
5300 __assertPermissionSpecified(resourcePermission);
5301 __assertVarargPermissionsSpecified(resourcePermissions);
5302
5303 final Set<ResourcePermission> normalizedResourcePermissions
5304 = __normalizeResourcePermission(__getSetWithoutNullsOrDuplicates(resourcePermission, resourcePermissions));
5305
5306 try {
5307 connection = __getConnection();
5308 accessorResource = __resolveResource(connection, accessorResource);
5309 resourceClassName = resourceClassName.trim();
5310 domainName = domainName.trim();
5311
5312 return __hasPostCreateResourcePermissions(connection,
5313 accessorResource,
5314 resourceClassName,
5315 domainName,
5316 normalizedResourcePermissions);
5317 }
5318 finally {
5319 __closeConnection(connection);
5320 }
5321 }
5322
5323 private boolean __hasPostCreateResourcePermissions(SQLConnection connection,
5324 Resource accessorResource,
5325 String resourceClassName,
5326 String domainName,
5327 Set<ResourcePermission> requestedResourcePermissions) {
5328 __assertPermissionsValid(connection, resourceClassName, requestedResourcePermissions);
5329 __assertQueryAuthorization(connection, accessorResource);
5330
5331 boolean hasPermission = false;
5332
5333 // first check if the accessor even has *CREATE permission for the resource class and domain
5334 final Set<ResourceCreatePermission> effectiveResourceCreatePermissions
5335 = __getEffectiveResourceCreatePermissions(connection,
5336 accessorResource,
5337 resourceClassName,
5338 domainName);
5339
5340 for (ResourceCreatePermission resourceCreatePermission : effectiveResourceCreatePermissions) {
5341 if (resourceCreatePermission.isSystemPermission()
5342 && ResourceCreatePermissions.CREATE.equals(resourceCreatePermission.getPermissionName())) {
5343 hasPermission = true;
5344 break;
5345 }
5346 }
5347
5348 if (hasPermission) {
5349 // check if the requested permission is permissible from the set of effective post-create permissions
5350 final Set<ResourcePermission> postCreateResourcePermissions
5351 = __getPostCreateResourcePermissions(effectiveResourceCreatePermissions);
5352
5353 final Set<ResourcePermission> nonPostCreateResourcePermissions
5354 = new HashSet<>(requestedResourcePermissions.size());
5355
5356 for (ResourcePermission requestedResourcePermission : requestedResourcePermissions) {
5357 if (!__isPermissible(requestedResourcePermission, postCreateResourcePermissions)) {
5358 nonPostCreateResourcePermissions.add(requestedResourcePermission);
5359 }
5360 }
5361
5362 if (!nonPostCreateResourcePermissions.isEmpty()) {
5363 // check if the requested permission is permissible from the set of effective global permissions
5364 final Set<ResourcePermission> globalResourcePermissions
5365 = __getEffectiveGlobalResourcePermissions(connection,
5366 accessorResource,
5367 resourceClassName,
5368 domainName);
5369
5370 for (ResourcePermission requestedResourcePermission : nonPostCreateResourcePermissions) {
5371 if (!__isPermissible(requestedResourcePermission, globalResourcePermissions)) {
5372 hasPermission = false;
5373 break;
5374 }
5375 }
5376 }
5377 }
5378
5379 if (!hasPermission) {
5380 hasPermission = __isSuperUserOfDomain(connection, accessorResource, domainName);
5381 }
5382
5383 return hasPermission;
5384 }
5385
5386 private boolean __isPermissible(ResourcePermission queriedResourcePermission,
5387 Set<ResourcePermission> resourcePermissions) {
5388 for (ResourcePermission resourcePermission : resourcePermissions) {
5389 if (queriedResourcePermission.equals(resourcePermission)
5390 || queriedResourcePermission.isGrantableFrom(resourcePermission)) {
5391 return true;
5392 }
5393 }
5394 return false;
5395 }
5396
5397 @Override
5398 public void assertGlobalResourcePermissions(Resource accessorResource,
5399 String resourceClassName,
5400 String domainName,
5401 Set<ResourcePermission> resourcePermissions) {
5402 if (!hasGlobalResourcePermissions(accessorResource,
5403 resourceClassName,
5404 domainName,
5405 resourcePermissions)) {
5406 throw NotAuthorizedException.newInstanceForGlobalResourcePermissions(accessorResource,
5407 resourceClassName,
5408 domainName,
5409 resourcePermissions);
5410 }
5411 }
5412
5413 @Override
5414 public void assertGlobalResourcePermissions(Resource accessorResource,
5415 String resourceClassName,
5416 String domainName,
5417 ResourcePermission resourcePermission,
5418 ResourcePermission... resourcePermissions) {
5419 if (!hasGlobalResourcePermissions(accessorResource,
5420 resourceClassName,
5421 domainName,
5422 resourcePermission,
5423 resourcePermissions)) {
5424 throw NotAuthorizedException.newInstanceForGlobalResourcePermissions(accessorResource,
5425 resourceClassName,
5426 domainName,
5427 resourcePermission,
5428 resourcePermissions);
5429 }
5430 }
5431
5432 @Override
5433 public boolean hasGlobalResourcePermissions(Resource accessorResource,
5434 String resourceClassName,
5435 String domainName,
5436 Set<ResourcePermission> resourcePermissions) {
5437 SQLConnection connection = null;
5438
5439 __assertAuthenticated();
5440 __assertResourceSpecified(accessorResource);
5441 __assertResourceClassSpecified(resourceClassName);
5442 __assertDomainSpecified(domainName);
5443 __assertPermissionsSpecified(resourcePermissions);
5444 __assertPermissionsSetNotEmpty(resourcePermissions);
5445
5446 final Set<ResourcePermission> normalizedResourcePermissions = __normalizeResourcePermission(resourcePermissions);
5447
5448 try {
5449 connection = __getConnection();
5450 accessorResource = __resolveResource(connection, accessorResource);
5451 resourceClassName = resourceClassName.trim();
5452 domainName = domainName.trim();
5453
5454 return __hasGlobalResourcePermissions(connection,
5455 accessorResource,
5456 resourceClassName,
5457 domainName,
5458 normalizedResourcePermissions);
5459 }
5460 finally {
5461 __closeConnection(connection);
5462 }
5463 }
5464
5465 @Override
5466 public boolean hasGlobalResourcePermissions(Resource accessorResource,
5467 String resourceClassName,
5468 String domainName,
5469 ResourcePermission resourcePermission,
5470 ResourcePermission... resourcePermissions) {
5471 SQLConnection connection = null;
5472
5473 __assertAuthenticated();
5474 __assertResourceSpecified(accessorResource);
5475 __assertResourceClassSpecified(resourceClassName);
5476 __assertDomainSpecified(domainName);
5477 __assertPermissionSpecified(resourcePermission);
5478 __assertVarargPermissionsSpecified(resourcePermissions);
5479
5480 final Set<ResourcePermission> normalizedResourcePermissions
5481 = __normalizeResourcePermission(__getSetWithoutNullsOrDuplicates(resourcePermission, resourcePermissions));
5482
5483 try {
5484 connection = __getConnection();
5485 accessorResource = __resolveResource(connection, accessorResource);
5486 resourceClassName = resourceClassName.trim();
5487 domainName = domainName.trim();
5488
5489 return __hasGlobalResourcePermissions(connection,
5490 accessorResource,
5491 resourceClassName,
5492 domainName,
5493 normalizedResourcePermissions);
5494 }
5495 finally {
5496 __closeConnection(connection);
5497 }
5498 }
5499
5500 private boolean __hasGlobalResourcePermissions(SQLConnection connection,
5501 Resource accessorResource,
5502 String resourceClassName,
5503 String domainName,
5504 Set<ResourcePermission> requestedResourcePermissions) {
5505 __assertPermissionsValid(connection, resourceClassName, requestedResourcePermissions);
5506 __assertQueryAuthorization(connection, accessorResource);
5507
5508 final Set<ResourcePermission>
5509 globalResourcePermissions = __getEffectiveGlobalResourcePermissions(connection,
5510 accessorResource,
5511 resourceClassName,
5512 domainName);
5513 boolean hasPermission = true;
5514
5515 for (ResourcePermission requestedResourcePermission : requestedResourcePermissions) {
5516 if (!__isPermissible(requestedResourcePermission, globalResourcePermissions)) {
5517 hasPermission = false;
5518 break;
5519 }
5520 }
5521
5522 if (!hasPermission) {
5523 hasPermission = __isSuperUserOfDomain(connection, accessorResource, domainName);
5524 }
5525 return hasPermission;
5526 }
5527
5528 @Override
5529 public void assertResourcePermissions(Resource accessorResource,
5530 Resource accessedResource,
5531 Set<ResourcePermission> resourcePermissions) {
5532 if (!hasResourcePermissions(accessorResource, accessedResource, resourcePermissions)) {
5533 throw NotAuthorizedException.newInstanceForResourcePermissions(accessorResource,
5534 accessedResource,
5535 resourcePermissions);
5536 }
5537 }
5538
5539 @Override
5540 public void assertResourcePermissions(Resource accessorResource,
5541 Resource accessedResource,
5542 ResourcePermission resourcePermission,
5543 ResourcePermission... resourcePermissions) {
5544 if (!hasResourcePermissions(accessorResource, accessedResource, resourcePermission, resourcePermissions)) {
5545 throw NotAuthorizedException.newInstanceForResourcePermissions(accessorResource,
5546 accessedResource,
5547 resourcePermission,
5548 resourcePermissions);
5549 }
5550 }
5551
5552 @Override
5553 public boolean hasResourcePermissions(Resource accessorResource,
5554 Resource accessedResource,
5555 Set<ResourcePermission> resourcePermissions) {
5556 SQLConnection connection = null;
5557
5558 __assertAuthenticated();
5559 __assertResourceSpecified(accessorResource);
5560 __assertResourceSpecified(accessedResource);
5561 __assertPermissionsSpecified(resourcePermissions);
5562 __assertPermissionsSetNotEmpty(resourcePermissions);
5563
5564 final Set<ResourcePermission> normalizedResourcePermissions = __normalizeResourcePermission(resourcePermissions);
5565
5566 try {
5567 connection = __getConnection();
5568 accessorResource = __resolveResource(connection, accessorResource);
5569 accessedResource = __resolveResource(connection, accessedResource);
5570
5571 return __hasResourcePermissions(connection, accessorResource, accessedResource, normalizedResourcePermissions);
5572 }
5573 finally {
5574 __closeConnection(connection);
5575 }
5576 }
5577
5578 @Override
5579 public boolean hasResourcePermissions(Resource accessorResource,
5580 Resource accessedResource,
5581 ResourcePermission resourcePermission,
5582 ResourcePermission... resourcePermissions) {
5583 SQLConnection connection = null;
5584
5585 __assertAuthenticated();
5586 __assertResourceSpecified(accessorResource);
5587 __assertResourceSpecified(accessedResource);
5588 __assertPermissionSpecified(resourcePermission);
5589 __assertVarargPermissionsSpecified(resourcePermissions);
5590
5591 final Set<ResourcePermission> normalizedResourcePermissions
5592 = __normalizeResourcePermission(__getSetWithoutNullsOrDuplicates(resourcePermission, resourcePermissions));
5593
5594 try {
5595 connection = __getConnection();
5596 accessorResource = __resolveResource(connection, accessorResource);
5597 accessedResource = __resolveResource(connection, accessedResource);
5598
5599 return __hasResourcePermissions(connection, accessorResource, accessedResource, normalizedResourcePermissions);
5600 }
5601 finally {
5602 __closeConnection(connection);
5603 }
5604 }
5605
5606 private boolean __hasResourcePermissions(SQLConnection connection,
5607 Resource accessorResource,
5608 Resource accessedResource,
5609 Set<ResourcePermission> requestedResourcePermissions) {
5610 __assertQueryAuthorization(connection, accessorResource);
5611
5612 final ResourceClassInternalInfo resourceClassInternalInfo
5613 = resourceClassPersister.getResourceClassInfoByResourceId(connection, accessedResource);
5614 __assertPermissionsValid(connection,
5615 resourceClassInternalInfo.getResourceClassName(),
5616 requestedResourcePermissions);
5617
5618 // first check for effective permissions
5619 final Set<ResourcePermission> effectiveResourcePermissions
5620 = __getEffectiveResourcePermissions(connection,
5621 accessorResource,
5622 accessedResource);
5623
5624 boolean hasPermission = true;
5625
5626 for (ResourcePermission requestedResourcePermission : requestedResourcePermissions) {
5627 if (!__isPermissible(requestedResourcePermission, effectiveResourcePermissions)) {
5628 hasPermission = false;
5629 break;
5630 }
5631 }
5632
5633 // next check super-user permissions to the domain of the accessed resource
5634 if (!hasPermission) {
5635 final String domainName
5636 = domainPersister.getResourceDomainNameByResourceId(connection, accessedResource);
5637
5638 hasPermission = __isSuperUserOfDomain(connection, accessorResource, domainName);
5639 }
5640
5641 return hasPermission;
5642 }
5643
5644 @Override
5645 public void assertResourceCreatePermissions(Resource accessorResource,
5646 String resourceClassName,
5647 String domainName,
5648 Set<ResourceCreatePermission> resourceCreatePermissions) {
5649 if (!hasResourceCreatePermissions(accessorResource,
5650 resourceClassName,
5651 domainName,
5652 resourceCreatePermissions)) {
5653 throw NotAuthorizedException.newInstanceForResourceCreatePermissions(accessorResource,
5654 resourceCreatePermissions);
5655 }
5656 }
5657
5658 @Override
5659 public void assertResourceCreatePermissions(Resource accessorResource,
5660 String resourceClassName,
5661 String domainName,
5662 ResourceCreatePermission resourceCreatePermission,
5663 ResourceCreatePermission... resourceCreatePermissions) {
5664 if (!hasResourceCreatePermissions(accessorResource,
5665 resourceClassName,
5666 domainName,
5667 resourceCreatePermission,
5668 resourceCreatePermissions)) {
5669 throw NotAuthorizedException.newInstanceForResourceCreatePermissions(accessorResource,
5670 resourceCreatePermission,
5671 resourceCreatePermissions);
5672 }
5673 }
5674
5675 @Override
5676 public boolean hasResourceCreatePermissions(Resource accessorResource,
5677 String resourceClassName,
5678 String domainName,
5679 Set<ResourceCreatePermission> resourceCreatePermissions) {
5680 SQLConnection connection = null;
5681
5682 __assertAuthenticated();
5683 __assertResourceSpecified(accessorResource);
5684 __assertResourceClassSpecified(resourceClassName);
5685 __assertDomainSpecified(domainName);
5686 __assertPermissionsSpecified(resourceCreatePermissions);
5687 __assertPermissionsSetNotEmpty(resourceCreatePermissions);
5688
5689 final Set<ResourceCreatePermission> normalizedResourceCreatePermissions
5690 = __normalizeResourceCreatePermission(resourceCreatePermissions);
5691
5692 try {
5693 connection = __getConnection();
5694 accessorResource = __resolveResource(connection, accessorResource);
5695 resourceClassName = resourceClassName.trim();
5696 domainName = domainName.trim();
5697
5698 return __hasResourceCreatePermissions(connection,
5699 accessorResource,
5700 resourceClassName,
5701 domainName,
5702 normalizedResourceCreatePermissions);
5703 }
5704 finally {
5705 __closeConnection(connection);
5706 }
5707 }
5708
5709 @Override
5710 public boolean hasResourceCreatePermissions(Resource accessorResource,
5711 String resourceClassName,
5712 String domainName,
5713 ResourceCreatePermission resourceCreatePermission,
5714 ResourceCreatePermission... resourceCreatePermissions) {
5715 SQLConnection connection = null;
5716
5717 __assertAuthenticated();
5718 __assertResourceSpecified(accessorResource);
5719 __assertResourceClassSpecified(resourceClassName);
5720 __assertDomainSpecified(domainName);
5721 __assertPermissionSpecified(resourceCreatePermission);
5722 __assertVarargPermissionsSpecified(resourceCreatePermissions);
5723
5724 final Set<ResourceCreatePermission> normalizedResourceCreatePermissions
5725 = __normalizeResourceCreatePermission(__getSetWithoutNullsOrDuplicates(resourceCreatePermission,
5726 resourceCreatePermissions));
5727
5728 try {
5729 connection = __getConnection();
5730 accessorResource = __resolveResource(connection, accessorResource);
5731 resourceClassName = resourceClassName.trim();
5732 domainName = domainName.trim();
5733
5734 return __hasResourceCreatePermissions(connection,
5735 accessorResource,
5736 resourceClassName,
5737 domainName,
5738 normalizedResourceCreatePermissions);
5739 }
5740 finally {
5741 __closeConnection(connection);
5742 }
5743 }
5744
5745 private boolean __hasResourceCreatePermissions(SQLConnection connection,
5746 Resource accessorResource,
5747 String resourceClassName,
5748 String domainName,
5749 Set<ResourceCreatePermission> requestedResourceCreatePermissions) {
5750 __assertPermissionsValid(connection,
5751 resourceClassName,
5752 __getPostCreateResourcePermissions(requestedResourceCreatePermissions));
5753 __assertQueryAuthorization(connection, accessorResource);
5754
5755 final Set<ResourceCreatePermission> effectiveResourceCreatePermissions
5756 = __getEffectiveResourceCreatePermissions(connection,
5757 accessorResource,
5758 resourceClassName,
5759 domainName);
5760 boolean hasPermission = true;
5761
5762 // first check for effective create permissions
5763 for (ResourceCreatePermission resourceCreatePermission : requestedResourceCreatePermissions) {
5764 if (!__isPermissible(resourceCreatePermission, effectiveResourceCreatePermissions)) {
5765 hasPermission = false;
5766 break;
5767 }
5768 }
5769
5770 // next check super-user permissions to the domain
5771 if (!hasPermission) {
5772 hasPermission = __isSuperUserOfDomain(connection, accessorResource, domainName);
5773 }
5774
5775 return hasPermission;
5776 }
5777
5778 private boolean __isPermissible(ResourceCreatePermission queriedResourceCreatePermission,
5779 Set<ResourceCreatePermission> resourceCreatePermissions) {
5780 for (ResourceCreatePermission resourceCreatePermission : resourceCreatePermissions) {
5781 if (queriedResourceCreatePermission.equals(resourceCreatePermission)
5782 || queriedResourceCreatePermission.isGrantableFrom(resourceCreatePermission)) {
5783 return true;
5784 }
5785 }
5786 return false;
5787 }
5788
5789 @Override
5790 public Set<Resource> getResourcesByResourcePermissions(Resource accessorResource,
5791 String resourceClassName,
5792 Set<ResourcePermission> resourcePermissions) {
5793 SQLConnection connection = null;
5794
5795 __assertAuthenticated();
5796 __assertResourceSpecified(accessorResource);
5797 __assertResourceClassSpecified(resourceClassName);
5798 __assertPermissionsSpecified(resourcePermissions);
5799 __assertPermissionsSetNotEmpty(resourcePermissions);
5800
5801 final Set<ResourcePermission> normalizedResourcePermissions = __normalizeResourcePermission(resourcePermissions);
5802
5803 try {
5804 connection = __getConnection();
5805
5806 accessorResource = __resolveResource(connection, accessorResource);
5807 __assertQueryAuthorization(connection, accessorResource);
5808
5809 resourceClassName = resourceClassName.trim();
5810
5811 return __getResourcesByPermissions(connection,
5812 accessorResource,
5813 resourceClassName,
5814 normalizedResourcePermissions);
5815 }
5816 finally {
5817 __closeConnection(connection);
5818 }
5819 }
5820
5821 @Override
5822 public Set<Resource> getResourcesByResourcePermissions(Resource accessorResource,
5823 String resourceClassName,
5824 ResourcePermission resourcePermission,
5825 ResourcePermission... resourcePermissions) {
5826 SQLConnection connection = null;
5827
5828 __assertAuthenticated();
5829 __assertResourceSpecified(accessorResource);
5830 __assertResourceClassSpecified(resourceClassName);
5831 __assertPermissionSpecified(resourcePermission);
5832 __assertVarargPermissionsSpecified(resourcePermissions);
5833
5834 final Set<ResourcePermission> normalizedResourcePermissions
5835 = __normalizeResourcePermission(__getSetWithoutNullsOrDuplicates(resourcePermission, resourcePermissions));
5836
5837 try {
5838 connection = __getConnection();
5839
5840 accessorResource = __resolveResource(connection, accessorResource);
5841 __assertQueryAuthorization(connection, accessorResource);
5842
5843 resourceClassName = resourceClassName.trim();
5844
5845 return __getResourcesByPermissions(connection,
5846 accessorResource,
5847 resourceClassName,
5848 normalizedResourcePermissions);
5849 }
5850 finally {
5851 __closeConnection(connection);
5852 }
5853 }
5854
5855 private Set<Resource> __getResourcesByPermissions(SQLConnection connection,
5856 Resource accessorResource,
5857 String resourceClassName,
5858 Set<ResourcePermission> requestedResourcePermissions) {
5859 // first verify that resource class is defined
5860 Id<ResourceClassId> resourceClassId;
5861 Id<ResourcePermissionId> permissionId;
5862
5863 resourceClassId = resourceClassPersister.getResourceClassId(connection, resourceClassName);
5864
5865 if (resourceClassId == null) {
5866 throw new IllegalArgumentException("Could not find resource class: " + resourceClassName);
5867 }
5868
5869 // verify permissions are valid for resource class
5870 __assertPermissionsValid(connection, resourceClassName, requestedResourcePermissions);
5871
5872 Set<Resource> resources = new HashSet<>();
5873
5874 for (ResourcePermission resourcePermission : requestedResourcePermissions) {
5875 Set<Resource> currentResources = new HashSet<>();
5876
5877 if (resourcePermission.isSystemPermission()) {
5878 // get the list of objects of the specified type that the session has access to via direct permissions
5879 currentResources.addAll(grantResourcePermissionSysPersister
5880 .getResourcesByResourceSysPermission(connection,
5881 accessorResource,
5882 resourceClassId,
5883 resourcePermission));
5884
5885 // get the list of objects of the specified type that the session has access to via global permissions
5886 currentResources.addAll(grantGlobalResourcePermissionSysPersister
5887 .getResourcesByGlobalSysPermission(connection,
5888 accessorResource,
5889 resourceClassId,
5890 resourcePermission));
5891 }
5892 else {
5893 // check if the non-system permission name is valid
5894 permissionId = resourceClassPermissionPersister.getResourceClassPermissionId(connection,
5895 resourceClassId,
5896 resourcePermission
5897 .getPermissionName());
5898
5899 if (permissionId == null) {
5900 throw new IllegalArgumentException("Permission: " + resourcePermission + " is not defined for resource class: " + resourceClassName);
5901 }
5902
5903 // get the list of objects of the specified type that the session has access to via direct permissions
5904 currentResources.addAll(grantResourcePermissionPersister
5905 .getResourcesByResourcePermission(connection,
5906 accessorResource,
5907 resourceClassId,
5908 resourcePermission,
5909 permissionId));
5910
5911 // get the list of objects of the specified type that the session has access to via global permissions
5912 currentResources.addAll(grantGlobalResourcePermissionPersister
5913 .getResourcesByGlobalResourcePermission(connection,
5914 accessorResource,
5915 resourceClassId,
5916 resourcePermission,
5917 permissionId));
5918 }
5919
5920 if (currentResources.isEmpty()) {
5921 // we got an empty set for a permission, we are done since this and all future intersects will be empty
5922 resources = currentResources;
5923 break;
5924 }
5925 else {
5926 // the only way resources will be empty below is if we never entered this else clause before
5927 if (resources.isEmpty()) {
5928 resources = currentResources;
5929 }
5930 else {
5931 // compute the intersection of previous iterations and the current resources
5932 resources.retainAll(currentResources);
5933 if (resources.isEmpty()) {
5934 // if intersection with previous results is empty, then all future intersections will be empty, as well
5935 break;
5936 }
5937 }
5938 }
5939 }
5940
5941 // finally get the list of objects of the specified type that the session has access to via super user permissions
5942 resources.addAll(grantDomainPermissionSysPersister.getResourcesByDomainSuperUserPermission(connection,
5943 accessorResource,
5944 resourceClassId));
5945 return resources;
5946 }
5947
5948 @Override
5949 public Set<Resource> getResourcesByResourcePermissionsAndDomain(Resource accessorResource,
5950 String resourceClassName,
5951 String domainName,
5952 Set<ResourcePermission> resourcePermissions) {
5953 SQLConnection connection = null;
5954
5955 __assertAuthenticated();
5956 __assertResourceSpecified(accessorResource);
5957 __assertResourceClassSpecified(resourceClassName);
5958 __assertDomainSpecified(domainName);
5959 __assertPermissionsSpecified(resourcePermissions);
5960 __assertPermissionsSetNotEmpty(resourcePermissions);
5961
5962 final Set<ResourcePermission> normalizedResourcePermissions = __normalizeResourcePermission(resourcePermissions);
5963
5964 try {
5965 connection = __getConnection();
5966
5967 accessorResource = __resolveResource(connection, accessorResource);
5968 __assertQueryAuthorization(connection, accessorResource);
5969
5970 resourceClassName = resourceClassName.trim();
5971
5972 return __getResourcesByPermissionsAndDomain(connection,
5973 accessorResource,
5974 resourceClassName,
5975 domainName,
5976 normalizedResourcePermissions);
5977 }
5978 finally {
5979 __closeConnection(connection);
5980 }
5981 }
5982
5983 @Override
5984 public Set<Resource> getResourcesByResourcePermissionsAndDomain(Resource accessorResource,
5985 String resourceClassName,
5986 String domainName,
5987 ResourcePermission resourcePermission,
5988 ResourcePermission... resourcePermissions) {
5989 SQLConnection connection = null;
5990
5991 __assertAuthenticated();
5992 __assertResourceSpecified(accessorResource);
5993 __assertResourceClassSpecified(resourceClassName);
5994 __assertDomainSpecified(domainName);
5995 __assertPermissionSpecified(resourcePermission);
5996 __assertVarargPermissionsSpecified(resourcePermissions);
5997
5998 final Set<ResourcePermission> normalizedResourcePermissions
5999 = __normalizeResourcePermission(__getSetWithoutNullsOrDuplicates(resourcePermission, resourcePermissions));
6000
6001 try {
6002 connection = __getConnection();
6003
6004 accessorResource = __resolveResource(connection, accessorResource);
6005 __assertQueryAuthorization(connection, accessorResource);
6006
6007 resourceClassName = resourceClassName.trim();
6008
6009 return __getResourcesByPermissionsAndDomain(connection,
6010 accessorResource,
6011 resourceClassName,
6012 domainName,
6013 normalizedResourcePermissions);
6014 }
6015 finally {
6016 __closeConnection(connection);
6017 }
6018 }
6019
6020 private Set<Resource> __getResourcesByPermissionsAndDomain(SQLConnection connection,
6021 Resource accessorResource,
6022 String resourceClassName,
6023 String domainName,
6024 Set<ResourcePermission> requestedResourcePermissions) {
6025 // first verify that resource class and domain is defined
6026 Id<ResourceClassId> resourceClassId;
6027 Id<DomainId> domainId;
6028 Id<ResourcePermissionId> permissionId;
6029
6030 resourceClassId = resourceClassPersister.getResourceClassId(connection, resourceClassName);
6031
6032 if (resourceClassId == null) {
6033 throw new IllegalArgumentException("Could not find resource class: " + resourceClassName);
6034 }
6035
6036 domainId = domainPersister.getResourceDomainId(connection, domainName);
6037
6038 if (domainId == null) {
6039 throw new IllegalArgumentException("Could not find domain: " + domainName);
6040 }
6041
6042 // verify permissions are valid for resource class
6043 __assertPermissionsValid(connection, resourceClassName, requestedResourcePermissions);
6044
6045 Set<Resource> resources = new HashSet<>();
6046
6047 for (ResourcePermission resourcePermission : requestedResourcePermissions) {
6048 Set<Resource> currentResources = new HashSet<>();
6049
6050 if (resourcePermission.isSystemPermission()) {
6051 // get the list of objects of the specified type that the session has access to via direct permissions
6052 currentResources.addAll(grantResourcePermissionSysPersister
6053 .getResourcesByResourceSysPermission(connection,
6054 accessorResource,
6055 resourceClassId,
6056 domainId,
6057 resourcePermission));
6058
6059 // get the list of objects of the specified type that the session has access to via global permissions
6060 currentResources.addAll(grantGlobalResourcePermissionSysPersister
6061 .getResourcesByGlobalSysPermission(connection,
6062 accessorResource,
6063 resourceClassId,
6064 domainId,
6065 resourcePermission));
6066 }
6067 else {
6068 // check if the non-system permission name is valid
6069 permissionId = resourceClassPermissionPersister.getResourceClassPermissionId(connection,
6070 resourceClassId,
6071 resourcePermission
6072 .getPermissionName());
6073
6074 if (permissionId == null) {
6075 throw new IllegalArgumentException("Permission: " + resourcePermission + " is not defined for resource class: " + resourceClassName);
6076 }
6077
6078 // get the list of objects of the specified type that the session has access to via direct permissions
6079 currentResources.addAll(grantResourcePermissionPersister
6080 .getResourcesByResourcePermission(connection,
6081 accessorResource,
6082 resourceClassId,
6083 domainId,
6084 resourcePermission,
6085 permissionId));
6086
6087 // get the list of objects of the specified type that the session has access to via global permissions
6088 currentResources.addAll(grantGlobalResourcePermissionPersister
6089 .getResourcesByGlobalResourcePermission(connection,
6090 accessorResource,
6091 resourceClassId,
6092 domainId,
6093 resourcePermission,
6094 permissionId));
6095 }
6096 if (currentResources.isEmpty()) {
6097 // we got an empty set for a permission, we are done since this and all future intersects will be empty
6098 resources = currentResources;
6099 break;
6100 }
6101 else {
6102 // the only way resources will be empty below is if we never entered this else clause before
6103 if (resources.isEmpty()) {
6104 resources = currentResources;
6105 }
6106 else {
6107 // compute the intersection of previous iterations and the current resources
6108 resources.retainAll(currentResources);
6109 if (resources.isEmpty()) {
6110 // if intersection with previous results is empty, then all future intersections will be empty, as well
6111 break;
6112 }
6113 }
6114 }
6115 }
6116
6117 // finally get the list of objects of the specified type that the session has access to via super user permissions
6118 resources.addAll(grantDomainPermissionSysPersister.getResourcesByDomainSuperUserPermission(connection,
6119 accessorResource,
6120 resourceClassId,
6121 domainId));
6122 return resources;
6123 }
6124
6125 @Override
6126 public Set<Resource> getAccessorResourcesByResourcePermissions(Resource accessedResource,
6127 String resourceClassName,
6128 Set<ResourcePermission> resourcePermissions) {
6129 SQLConnection connection = null;
6130
6131 __assertAuthenticated();
6132 __assertResourceSpecified(accessedResource);
6133 __assertResourceClassSpecified(resourceClassName);
6134 __assertPermissionsSpecified(resourcePermissions);
6135 __assertPermissionsSetNotEmpty(resourcePermissions);
6136
6137 final Set<ResourcePermission> normalizedResourcePermissions = __normalizeResourcePermission(resourcePermissions);
6138
6139 try {
6140 connection = __getConnection();
6141
6142 accessedResource = __resolveResource(connection, accessedResource);
6143 __assertQueryAuthorization(connection, accessedResource);
6144
6145 resourceClassName = resourceClassName.trim();
6146
6147 return __getAccessorResourcesByResourcePermissions(connection,
6148 accessedResource,
6149 resourceClassName,
6150 normalizedResourcePermissions);
6151 }
6152 finally {
6153 __closeConnection(connection);
6154 }
6155 }
6156
6157 @Override
6158 public Set<Resource> getAccessorResourcesByResourcePermissions(Resource accessedResource,
6159 String resourceClassName,
6160 ResourcePermission resourcePermission,
6161 ResourcePermission... resourcePermissions) {
6162 SQLConnection connection = null;
6163
6164 __assertAuthenticated();
6165 __assertResourceSpecified(accessedResource);
6166 __assertResourceClassSpecified(resourceClassName);
6167 __assertPermissionSpecified(resourcePermission);
6168 __assertVarargPermissionsSpecified(resourcePermissions);
6169
6170 final Set<ResourcePermission> normalizedResourcePermissions
6171 = __normalizeResourcePermission(__getSetWithoutNullsOrDuplicates(resourcePermission, resourcePermissions));
6172
6173 try {
6174 connection = __getConnection();
6175
6176 accessedResource = __resolveResource(connection, accessedResource);
6177 __assertQueryAuthorization(connection, accessedResource);
6178
6179 resourceClassName = resourceClassName.trim();
6180
6181 return __getAccessorResourcesByResourcePermissions(connection,
6182 accessedResource,
6183 resourceClassName,
6184 normalizedResourcePermissions);
6185 }
6186 finally {
6187 __closeConnection(connection);
6188 }
6189 }
6190
6191 private Set<Resource> __getAccessorResourcesByResourcePermissions(SQLConnection connection,
6192 Resource accessedResource,
6193 String resourceClassName,
6194 Set<ResourcePermission> requestedResourcePermissions) {
6195 // first verify that resource class is defined
6196 Id<ResourceClassId> resourceClassId;
6197 Id<ResourcePermissionId> permissionId;
6198
6199 resourceClassId = resourceClassPersister.getResourceClassId(connection, resourceClassName);
6200
6201 if (resourceClassId == null) {
6202 throw new IllegalArgumentException("Could not find resource class: " + resourceClassName);
6203 }
6204
6205 // verify permissions are valid for the resource class
6206 __assertPermissionsValid(connection, resourceClassName, requestedResourcePermissions);
6207
6208 Set<Resource> resources = new HashSet<>();
6209
6210 for (ResourcePermission resourcePermission : requestedResourcePermissions) {
6211 Set<Resource> currentResources = new HashSet<>();
6212
6213 if (resourcePermission.isSystemPermission()) {
6214 // get the list of objects of the specified type that the session has access to via direct permissions
6215 currentResources.addAll(grantResourcePermissionSysPersister
6216 .getAccessorResourcesByResourceSysPermission(connection,
6217 accessedResource,
6218 resourceClassId,
6219 resourcePermission));
6220 }
6221 else {
6222 // check if the non-system permission name is valid
6223 permissionId = resourceClassPermissionPersister.getResourceClassPermissionId(connection,
6224 resourceClassId,
6225 resourcePermission
6226 .getPermissionName());
6227
6228 if (permissionId == null) {
6229 throw new IllegalArgumentException("Permission: " + resourcePermission + " is not defined for resource class: " + resourceClassName);
6230 }
6231
6232 // get the list of objects of the specified type that the session has access to via direct permissions
6233 currentResources.addAll(grantResourcePermissionPersister
6234 .getAccessorResourcesByResourcePermission(connection,
6235 accessedResource,
6236 resourceClassId,
6237 resourcePermission,
6238 permissionId));
6239 }
6240 if (currentResources.isEmpty()) {
6241 // we got an empty set for a permission, we are done since this and all future intersects will be empty
6242 resources = currentResources;
6243 break;
6244 }
6245 else {
6246 // the only way resources will be empty below is if we never entered this else clause before
6247 if (resources.isEmpty()) {
6248 resources = currentResources;
6249 }
6250 else {
6251 // compute the intersection of previous iterations and the current resources
6252 resources.retainAll(currentResources);
6253 if (resources.isEmpty()) {
6254 // if intersection with previous results is empty, then all future intersections will be empty, as well
6255 break;
6256 }
6257 }
6258 }
6259 }
6260
6261 return resources;
6262 }
6263
6264 @Override
6265 public List<String> getResourceClassNames() {
6266 SQLConnection connection = null;
6267
6268 __assertAuthenticated();
6269
6270 try {
6271 connection = __getConnection();
6272
6273 return resourceClassPersister.getResourceClassNames(connection);
6274 }
6275 finally {
6276 __closeConnection(connection);
6277 }
6278 }
6279
6280 @Override
6281 public List<String> getResourcePermissionNames(String resourceClassName) {
6282 SQLConnection connection = null;
6283
6284 __assertAuthenticated();
6285 __assertResourceClassSpecified(resourceClassName);
6286
6287 try {
6288 connection = __getConnection();
6289 resourceClassName = resourceClassName.trim();
6290
6291 return __getApplicableResourcePermissionNames(connection, resourceClassName);
6292 }
6293 finally {
6294 __closeConnection(connection);
6295 }
6296 }
6297
6298 // private shared helper methods
6299
6300 private static Set<DomainPermission> __normalizeDomainPermissions(Set<DomainPermission> domainPermissions) {
6301 Set<DomainPermission> normalizedPermissions = new HashSet<>(domainPermissions.size());
6302 for (DomainPermission domainPermission : domainPermissions) {
6303 normalizedPermissions.add(DomainPermissions.getInstance(domainPermission));
6304 }
6305 return normalizedPermissions;
6306 }
6307
6308 private static Set<DomainCreatePermission> __normalizeDomainCreatePermissions(Set<DomainCreatePermission> domainCreatePermissions) {
6309 Set<DomainCreatePermission> normalizedPermissions = new HashSet<>(domainCreatePermissions.size());
6310 for (DomainCreatePermission permission : domainCreatePermissions) {
6311 normalizedPermissions.add(DomainCreatePermissions.getInstance(permission));
6312 }
6313 return normalizedPermissions;
6314 }
6315
6316 private static Set<ResourcePermission> __normalizeResourcePermission(Set<ResourcePermission> resourcePermissions) {
6317 Set<ResourcePermission> normalizedPermissions = new HashSet<>(resourcePermissions.size());
6318 for (ResourcePermission resourcePermission : resourcePermissions) {
6319 normalizedPermissions.add(ResourcePermissions.getInstance(resourcePermission));
6320 }
6321 return normalizedPermissions;
6322 }
6323
6324 private static Set<ResourceCreatePermission> __normalizeResourceCreatePermission(Set<ResourceCreatePermission> resourceCreatePermissions) {
6325 Set<ResourceCreatePermission> normalizedPermissions = new HashSet<>(resourceCreatePermissions.size());
6326 for (ResourceCreatePermission resourceCreatePermission : resourceCreatePermissions) {
6327 normalizedPermissions.add(ResourceCreatePermissions.getInstance(resourceCreatePermission));
6328 }
6329 return normalizedPermissions;
6330 }
6331
6332 private Resource __resolveResource(SQLConnection connection,
6333 Resource resource) {
6334 if (__isEqual(sessionResource, resource)) {
6335 return sessionResource;
6336 }
6337
6338 if (__isEqual(authenticatedResource, resource)) {
6339 return authenticatedResource;
6340 }
6341
6342 final Resource resolvedResource;
6343
6344 if (resource.getId() != null) {
6345 if (resource.getExternalId() != null) {
6346 // the resource has both internal and external Ids, so let's see if they match
6347 resolvedResource = resourcePersister.resolveResourceByExternalId(connection, resource.getExternalId());
6348 if (resolvedResource == null || !resource.equals(resolvedResource)) {
6349 throw new IllegalArgumentException("Resource " + resource + "'s id does not resolve to the specified externalId!");
6350 }
6351 }
6352 else {
6353 // ensure that we have a valid internal resource id, so we might as well also fully resolve it
6354 resolvedResource = resourcePersister.resolveResourceByResourceId(connection, resource);
6355
6356 if (resolvedResource == null) {
6357 throw new IllegalArgumentException("Resource " + resource + " not found!");
6358 }
6359 }
6360 }
6361 else if (resource.getExternalId() != null) {
6362 // there is no internal resource Id, so we need to look it up
6363 resolvedResource = resourcePersister.resolveResourceByExternalId(connection, resource.getExternalId());
6364
6365 if (resolvedResource == null) {
6366 throw new IllegalArgumentException("Resource " + resource + " not found!");
6367 }
6368 }
6369 else {
6370 throw new IllegalArgumentException("A resource id and/or external id is required, but neither was specified");
6371 }
6372
6373 return resolvedResource;
6374 }
6375
6376 private static boolean __isEqual(Resource resource1, Resource resource2) {
6377 if (resource1 == resource2) {
6378 return true;
6379 }
6380 if (resource1 == null) {
6381 return false;
6382 }
6383 return __isEqual(resource1.getId(), resource2.getId())
6384 && __isEqual(resource1.getExternalId(), resource2.getExternalId());
6385 }
6386
6387 private static boolean __isEqual(Long long1, Long long2) {
6388 if (long1 == long2) {
6389 return true;
6390 }
6391 if (long1 == null) {
6392 return false;
6393 }
6394 return long1.equals(long2);
6395 }
6396
6397 private static boolean __isEqual(String s1, String s2) {
6398 if (s1 == s2) {
6399 return true;
6400 }
6401 if (s1 == null) {
6402 return false;
6403 }
6404 return s1.equals(s2);
6405 }
6406
6407 private List<String> __getApplicableResourcePermissionNames(SQLConnection connection,
6408 String resourceClassName) {
6409 return __getApplicableResourcePermissionNames(connection,
6410 __getResourceClassInternalInfo(connection, resourceClassName));
6411 }
6412
6413 private List<String> __getApplicableResourcePermissionNames(SQLConnection connection,
6414 ResourceClassInternalInfo resourceClassInternalInfo) {
6415 final List<String> permissionNames
6416 = resourceClassPermissionPersister.getPermissionNames(connection,
6417 resourceClassInternalInfo.getResourceClassName());
6418 permissionNames.add(ResourcePermissions.INHERIT);
6419 permissionNames.add(ResourcePermissions.DELETE);
6420 permissionNames.add(ResourcePermissions.QUERY);
6421
6422 if (resourceClassInternalInfo.isAuthenticatable()) {
6423 permissionNames.add(ResourcePermissions.IMPERSONATE);
6424 permissionNames.add(ResourcePermissions.RESET_CREDENTIALS);
6425 }
6426 return permissionNames;
6427 }
6428
6429 private ResourceClassInternalInfo __getResourceClassInternalInfo(SQLConnection connection,
6430 String resourceClassName) {
6431 final ResourceClassInternalInfo resourceClassInternalInfo
6432 = resourceClassPersister.getResourceClassInfo(connection, resourceClassName);
6433
6434 // check if the resource class is valid
6435 if (resourceClassInternalInfo == null) {
6436 throw new IllegalArgumentException("Could not find resource class: " + resourceClassName);
6437 }
6438
6439 return resourceClassInternalInfo;
6440 }
6441
6442 private boolean __isSuperUserOfResource(SQLConnection connection,
6443 Resource accessorResource,
6444 Resource accessedResource) {
6445 return __isSuperUserOfDomain(connection,
6446 accessorResource,
6447 domainPersister.getResourceDomainNameByResourceId(connection, accessedResource));
6448 }
6449
6450
6451 private boolean __isSuperUserOfDomain(SQLConnection connection,
6452 Resource accessorResource,
6453 String queriedDomain) {
6454 Set<DomainPermission> domainPermissions = __getEffectiveDomainPermissions(connection, accessorResource, queriedDomain);
6455
6456 return domainPermissions.contains(DomainPermission_SUPER_USER)
6457 || domainPermissions.contains(DomainPermission_SUPER_USER_GRANT);
6458 }
6459
6460 private boolean __isSuperUserOfDomain(SQLConnection connection,
6461 Resource accessorResource,
6462 Id<DomainId> queriedDomainId) {
6463 Set<DomainPermission> domainPermissions = __getEffectiveDomainPermissions(connection,
6464 accessorResource,
6465 queriedDomainId);
6466
6467 return domainPermissions.contains(DomainPermission_SUPER_USER)
6468 || domainPermissions.contains(DomainPermission_SUPER_USER_GRANT);
6469 }
6470
6471 private Set<DomainPermission> __getPostCreateDomainPermissions(Set<DomainCreatePermission> domainCreatePermissions) {
6472 Set<DomainPermission> domainPermissions = new HashSet<>();
6473
6474 for (DomainCreatePermission domainCreatePermission : domainCreatePermissions) {
6475 if (!domainCreatePermission.isSystemPermission()) {
6476 domainPermissions.add(domainCreatePermission.getPostCreateDomainPermission());
6477 }
6478 }
6479 return domainPermissions;
6480 }
6481
6482 private Set<ResourcePermission> __getPostCreateResourcePermissions(Set<ResourceCreatePermission> resourceCreatePermissions) {
6483 Set<ResourcePermission> resourcePermissions = new HashSet<>();
6484
6485 for (ResourceCreatePermission resourceCreatePermission : resourceCreatePermissions) {
6486 if (!resourceCreatePermission.isSystemPermission()) {
6487 resourcePermissions.add(resourceCreatePermission.getPostCreateResourcePermission());
6488 }
6489 }
6490 return resourcePermissions;
6491 }
6492
6493 // helper methods
6494
6495 private static void __assertConnectionSpecified(Connection connection) {
6496 if (connection == null) {
6497 throw new IllegalArgumentException("Connection required, none specified");
6498 }
6499 }
6500
6501 private static void __assertDataSourceSpecified(DataSource dataSource) {
6502 if (dataSource == null) {
6503 throw new IllegalArgumentException("DataSource required, none specified");
6504 }
6505 }
6506
6507 private void __assertResourceSpecified(Resource resource) {
6508 if (resource == null) {
6509 throw new NullPointerException("Resource required, none specified");
6510 }
6511 }
6512
6513 private void __assertCredentialsSpecified(Credentials credentials) {
6514 if (credentials == null) {
6515 throw new NullPointerException("Credentials required, none specified");
6516 }
6517 }
6518
6519 private void __assertCredentialsNotSpecified(Credentials credentials) {
6520 if (credentials != null) {
6521 throw new IllegalArgumentException("Credentials not supported, but specified for unauthenticatable resource class");
6522 }
6523 }
6524
6525 private void __assertExternalIdSpecified(String externalId) {
6526 if (externalId == null) {
6527 throw new NullPointerException("External id required, none specified");
6528 }
6529 else if (externalId.trim().isEmpty()) {
6530 throw new IllegalArgumentException("External id required, none specified");
6531 }
6532 }
6533
6534 private void __assertDomainSpecified(String domainName) {
6535 if (domainName == null) {
6536 throw new NullPointerException("Domain required, none specified");
6537 }
6538 else if (domainName.trim().isEmpty()) {
6539 throw new IllegalArgumentException("Domain required, none specified");
6540 }
6541 }
6542
6543 private void __assertParentDomainSpecified(String domainName) {
6544 if (domainName == null) {
6545 throw new NullPointerException("Parent domain required, none specified");
6546 }
6547 else if (domainName.trim().isEmpty()) {
6548 throw new IllegalArgumentException("Parent domain required, none specified");
6549 }
6550 }
6551
6552 private void __assertAuthenticatedAsSystemResource() {
6553 if (sessionResource == null || !SYSTEM_RESOURCE_ID.equals(sessionResource.getId())) {
6554 throw NotAuthorizedException.newInstanceForAction(sessionResource,
6555 "perform operation reserved for the system resource");
6556 }
6557 }
6558
6559 private void __assertAuthenticated() {
6560 if (sessionResource == null) {
6561 throw new NotAuthenticatedException("Session not authenticated");
6562 }
6563 }
6564
6565 private void __assertResourceClassSpecified(String resourceClassName) {
6566 if (resourceClassName == null) {
6567 throw new NullPointerException("Resource class required, none specified");
6568 }
6569 else if (resourceClassName.trim().isEmpty()) {
6570 throw new IllegalArgumentException("Resource class required, none specified");
6571 }
6572 }
6573
6574 private void __assertPermissionSpecified(ResourcePermission resourcePermission) {
6575 if (resourcePermission == null) {
6576 throw new NullPointerException("Resource permission required, none specified");
6577 }
6578 }
6579
6580 private void __assertVarargPermissionsSpecified(ResourcePermission... resourcePermissions) {
6581 if (resourcePermissions == null) {
6582 throw new NullPointerException("An array or a sequence of resource permissions are required, but the null value was specified");
6583 }
6584 }
6585
6586 private void __assertPermissionSpecified(ResourceCreatePermission resourceCreatePermission) {
6587 if (resourceCreatePermission == null) {
6588 throw new NullPointerException("Resource create permission required, none specified");
6589 }
6590 }
6591
6592 private void __assertVarargPermissionsSpecified(ResourceCreatePermission... resourceCreatePermissions) {
6593 if (resourceCreatePermissions == null) {
6594 throw new NullPointerException("An array or a sequence of resource create permissions are required, but the null value was specified");
6595 }
6596 }
6597
6598 private void __assertPermissionSpecified(DomainCreatePermission domainCreatePermission) {
6599 if (domainCreatePermission == null) {
6600 throw new NullPointerException("Domain create permission required, none specified");
6601 }
6602 }
6603
6604 private void __assertVarargPermissionsSpecified(DomainCreatePermission... domainCreatePermissions) {
6605 if (domainCreatePermissions == null) {
6606 throw new NullPointerException("An array or a sequence of domain create permissions are required, but the null value was specified");
6607 }
6608 }
6609
6610 private void __assertPermissionSpecified(DomainPermission domainPermission) {
6611 if (domainPermission == null) {
6612 throw new NullPointerException("Domain permission required, none specified");
6613 }
6614 }
6615
6616 private void __assertVarargPermissionsSpecified(DomainPermission... domainPermissions) {
6617 if (domainPermissions == null) {
6618 throw new NullPointerException("An array or a sequence of domain permissions are required, but the null value was specified");
6619 }
6620 }
6621
6622 private void __assertPermissionsSpecified(Set permissionSet) {
6623 if (permissionSet == null) {
6624 throw new NullPointerException("Set of permissions required, none specified");
6625 }
6626
6627 if (permissionSet.contains(null)) {
6628 throw new NullPointerException("Set of permissions contains null element");
6629 }
6630 }
6631
6632 private void __assertPermissionsSetNotEmpty(Set permissionSet) {
6633 if (permissionSet.isEmpty()) {
6634 throw new IllegalArgumentException("Set of permissions required, empty set specified");
6635 }
6636 }
6637
6638 private void __assertPermissionNameValid(String permissionName) {
6639 if (permissionName == null) {
6640 throw new NullPointerException("Permission name may not be null");
6641 }
6642 else if (permissionName.trim().isEmpty()) {
6643 throw new IllegalArgumentException("Permission name may not be blank");
6644 }
6645
6646 if (permissionName.trim().startsWith("*")) {
6647 throw new IllegalArgumentException("Permission name may not start with asterisk '*'");
6648 }
6649 }
6650
6651 private void __assertResourceClassNameValid(String resourceClassName) {
6652 if (resourceClassName == null) {
6653 throw new NullPointerException("Resource class name may not be null");
6654 }
6655 else if (resourceClassName.trim().isEmpty()) {
6656 throw new IllegalArgumentException("Resource class name may not be blank");
6657 }
6658 }
6659
6660 private void __assertPermissionsValid(SQLConnection connection,
6661 String resourceClassName,
6662 Set<ResourcePermission> resourcePermissions) {
6663 final List<String> permissionNames = __getApplicableResourcePermissionNames(connection, resourceClassName);
6664
6665 for (ResourcePermission resourcePermission : resourcePermissions) {
6666 if (!permissionNames.contains(resourcePermission.getPermissionName())) {
6667 if (resourcePermission.isSystemPermission()) {
6668 // currently the only invalid system permissions are for unauthenticatable resource classes
6669 throw new IllegalArgumentException("Permission "
6670 + resourcePermission.getPermissionName()
6671 + " not valid for unauthenticatable resource class "
6672 + resourceClassName);
6673 }
6674 else {
6675 throw new IllegalArgumentException("Permission: "
6676 + resourcePermission.getPermissionName()
6677 + " is not defined for resource class: "
6678 + resourceClassName);
6679 }
6680 }
6681 }
6682 }
6683
6684 private void __assertQueryAuthorization(SQLConnection connection,
6685 Resource accessorResource) {
6686 if (!sessionResource.equals(accessorResource)) {
6687 final Set<ResourcePermission> effectiveResourcePermissions = __getEffectiveResourcePermissions(connection,
6688 sessionResource,
6689 accessorResource);
6690 if (!effectiveResourcePermissions.contains(ResourcePermission_QUERY)
6691 && !effectiveResourcePermissions.contains(ResourcePermission_QUERY_GRANT)
6692 && !effectiveResourcePermissions.contains(ResourcePermission_IMPERSONATE)
6693 && !effectiveResourcePermissions.contains(ResourcePermission_IMPERSONATE_GRANT)) {
6694 throw NotAuthorizedException.newInstanceForActionOnResource(sessionResource,
6695 "query",
6696 accessorResource);
6697 }
6698 }
6699 }
6700
6701 @SafeVarargs
6702 private static <T> Set<T> __getSetWithoutNullsOrDuplicates(T firstElement, T... elements) {
6703 // not null constraint
6704 if (elements == null) {
6705 throw new NullPointerException("An array or a sequence of arguments are required, but none were specified");
6706 }
6707
6708 final HashSet<T> resultSet = new HashSet<>(elements.length + 1);
6709 resultSet.add(firstElement);
6710
6711 for (T element : elements) {
6712 // non-null elements constraint
6713 if (element == null) {
6714 throw new NullPointerException("A " + elements.getClass().getSimpleName()
6715 + " argument (or sequence of varargs) without null elements is required, but received: "
6716 + Arrays.asList(elements));
6717 }
6718
6719 // duplicate elements get ignored silently
6720 if (!resultSet.add(element)) {
6721 throw new IllegalArgumentException("Duplicate element: " + element);
6722 }
6723 }
6724
6725 return resultSet;
6726 }
6727
6728 // private connection management helper methods
6729
6730 private SQLConnection __getConnection() {
6731 if (dataSource != null) {
6732 try {
6733 return new SQLConnection(dataSource.getConnection());
6734 }
6735 catch (SQLException e) {
6736 throw new RuntimeException(e);
6737 }
6738 }
6739 else if (connection != null) {
6740 return new SQLConnection(connection);
6741 }
6742 else {
6743 throw new IllegalStateException("Not initialized! No data source or connection, perhaps missing call to postDeserialize()?");
6744 }
6745 }
6746
6747 private void __closeConnection(SQLConnection connection) {
6748 // only close the connection if we got it from a pool, otherwise just leave the connection open
6749 if (dataSource != null) {
6750 if (connection != null) {
6751 try {
6752 connection.close();
6753 }
6754 catch (SQLException e) {
6755 throw new RuntimeException(e);
6756 }
6757 }
6758 }
6759 }
6760 }