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