Coverage Summary for Class: SQLAccessControlContext (com.acciente.oacc.sql.internal)

Class Class, % Method, % Line, %
SQLAccessControlContext 100% (1/ 1) 98.8% (240/ 243) 97.4% (2407/ 2472)


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