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

Class Class, % Method, % Line, %
NonRecursiveGrantGlobalResourcePermissionPersister 100% (1/ 1) 100% (6/ 6) 88.7% (141/ 159)


1 /* 2  * Copyright 2009-2018, Acciente LLC 3  * 4  * Acciente LLC licenses this file to you under the 5  * Apache License, Version 2.0 (the "License"); you 6  * may not use this file except in compliance with the 7  * License. You may obtain a copy of the License at 8  * 9  * http://www.apache.org/licenses/LICENSE-2.0 10  * 11  * Unless required by applicable law or agreed to in 12  * writing, software distributed under the License is 13  * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14  * OR CONDITIONS OF ANY KIND, either express or implied. 15  * See the License for the specific language governing 16  * permissions and limitations under the License. 17  */ 18 package com.acciente.oacc.sql.internal.persister; 19  20 import com.acciente.oacc.Resource; 21 import com.acciente.oacc.ResourcePermission; 22 import com.acciente.oacc.sql.SQLProfile; 23 import com.acciente.oacc.sql.internal.persister.id.DomainId; 24 import com.acciente.oacc.sql.internal.persister.id.Id; 25 import com.acciente.oacc.sql.internal.persister.id.ResourceClassId; 26 import com.acciente.oacc.sql.internal.persister.id.ResourceId; 27 import com.acciente.oacc.sql.internal.persister.id.ResourcePermissionId; 28  29 import java.io.Serializable; 30 import java.sql.SQLException; 31 import java.util.ArrayList; 32 import java.util.Collections; 33 import java.util.HashMap; 34 import java.util.HashSet; 35 import java.util.List; 36 import java.util.Map; 37 import java.util.Set; 38  39 public class NonRecursiveGrantGlobalResourcePermissionPersister extends CommonGrantGlobalResourcePermissionPersister implements Serializable { 40  private static final long serialVersionUID = 1L; 41  42  public NonRecursiveGrantGlobalResourcePermissionPersister(SQLProfile sqlProfile, 43  SQLStrings sqlStrings) { 44  super(sqlProfile, sqlStrings); 45  } 46  47  @Override 48  public Set<Resource> getResourcesByGlobalResourcePermission(SQLConnection connection, 49  Resource accessorResource, 50  Id<ResourceClassId> resourceClassId, 51  ResourcePermission resourcePermission, 52  Id<ResourcePermissionId> resourcePermissionId) { 53  if (resourcePermission.isSystemPermission()) { 54  throw new IllegalArgumentException("Permission: " + resourcePermission + " is not a non-system permission"); 55  } 56  57  SQLStatement statement = null; 58  try { 59  // first get all the resources from which the accessor inherits any permissions 60  final Set<Id<ResourceId>> accessorResourceIds 61  = NonRecursivePersisterHelper.getInheritedAccessorResourceIds(sqlStrings, connection, accessorResource); 62  63  // second, get all the domains the accessors directly have the specified global permission to 64  SQLResult resultSet; 65  Set<Id<DomainId>> directGlobalDomains = new HashSet<>(); 66  statement = connection.prepareStatement(sqlStrings.SQL_findInGrantGlobalResourcePermission_withoutInheritance_ResourceDomainID_BY_AccessorID_ResourceClassID_PermissionID_IsWithGrant); 67  68  for (Id<ResourceId> accessorResourceId : accessorResourceIds) { 69  statement.setResourceId(1, accessorResourceId); 70  statement.setResourceClassId(2, resourceClassId); 71  statement.setResourcePermissionId(3, resourcePermissionId); 72  statement.setBoolean(4, resourcePermission.isWithGrantOption()); 73  resultSet = statement.executeQuery(); 74  75  while (resultSet.next()) { 76  directGlobalDomains.add(resultSet.getResourceDomainId("DomainId")); 77  } 78  resultSet.close(); 79  } 80  closeStatement(statement); 81  82  // then get all resources of the specified class for each of the direct domain's descendants 83  Set<Resource> resources = new HashSet<>(); 84  statement = connection.prepareStatement(sqlStrings.SQL_findInResource_withoutInheritance_ResourceId_ExternalId_BY_ResourceClassID_DomainID); 85  86  for (Id<DomainId> directDomainId: directGlobalDomains) { 87  Set<Id<DomainId>> descendentDomainIds 88  = NonRecursivePersisterHelper.getDescendantDomainIdsOrderedByAscendingLevel(sqlStrings, 89  connection, 90  directDomainId); 91  for (Id<DomainId> descendentDomainId : descendentDomainIds) { 92  statement.setResourceClassId(1, resourceClassId); 93  statement.setResourceDomainId(2, descendentDomainId); 94  resultSet = statement.executeQuery(); 95  96  while (resultSet.next()) { 97  resources.add(resultSet.getResource("ResourceId", "ExternalId")); 98  } 99  resultSet.close(); 100  } 101  } 102  103  return resources; 104  } 105  catch (SQLException e) { 106  throw new RuntimeException(e); 107  } 108  finally { 109  closeStatement(statement); 110  } 111  } 112  113  @Override 114  public Set<Resource> getResourcesByGlobalResourcePermission(SQLConnection connection, 115  Resource accessorResource, 116  Id<ResourceClassId> resourceClassId, 117  Id<DomainId> resourceDomainId, 118  ResourcePermission resourcePermission, 119  Id<ResourcePermissionId> resourcePermissionId) { 120  if (resourcePermission.isSystemPermission()) { 121  throw new IllegalArgumentException("Permission: " + resourcePermission + " is not a non-system permission"); 122  } 123  124  SQLStatement statement = null; 125  try { 126  // first get all the resources from which the accessor inherits any permissions 127  final Set<Id<ResourceId>> accessorResourceIds 128  = NonRecursivePersisterHelper.getInheritedAccessorResourceIds(sqlStrings, connection, accessorResource); 129  130  // second, get all the domains the accessors directly have the specified global permission to 131  SQLResult resultSet; 132  Set<Id<DomainId>> directGlobalDomains = new HashSet<>(); 133  statement = connection.prepareStatement(sqlStrings.SQL_findInGrantGlobalResourcePermission_withoutInheritance_ResourceDomainID_BY_AccessorID_ResourceClassID_PermissionID_IsWithGrant); 134  135  for (Id<ResourceId> accessorResourceId : accessorResourceIds) { 136  statement.setResourceId(1, accessorResourceId); 137  statement.setResourceClassId(2, resourceClassId); 138  statement.setResourcePermissionId(3, resourcePermissionId); 139  statement.setBoolean(4, resourcePermission.isWithGrantOption()); 140  resultSet = statement.executeQuery(); 141  142  while (resultSet.next()) { 143  directGlobalDomains.add(resultSet.getResourceDomainId("DomainId")); 144  } 145  resultSet.close(); 146  } 147  closeStatement(statement); 148  149  Set<Id<DomainId>> requestedAncestorDomainIds 150  = NonRecursivePersisterHelper.getAncestorDomainIds(sqlStrings, connection, resourceDomainId); 151  Set<Id<DomainId>> requestedDescendentDomainIds 152  = NonRecursivePersisterHelper.getDescendantDomainIdsOrderedByAscendingLevel(sqlStrings, 153  connection, 154  resourceDomainId); 155  Set<Id<DomainId>> effectiveDomainIds = Collections.emptySet(); 156  157  // let's see if we have global permissions on an ancestor of the requested domain, first 158  for (Id<DomainId> directDomainId: directGlobalDomains) { 159  if (requestedAncestorDomainIds.contains(directDomainId)) { 160  // because we have global permissions on an ancestor of the requested domain, 161  // we have access to all resources of any sub-domain of the requested domain 162  effectiveDomainIds = requestedDescendentDomainIds; 163  break; 164  } 165  } 166  167  if (effectiveDomainIds.isEmpty()){ 168  // we did not have global permission on an ancestor of the requested domain, so let's 169  // find the highest level sub-domain of the requested domain to which we have global permission 170  for (Id<DomainId> requestedDescendentDomainId : requestedDescendentDomainIds) { 171  if (directGlobalDomains.contains(requestedDescendentDomainId)) { 172  effectiveDomainIds 173  = NonRecursivePersisterHelper.getDescendantDomainIdsOrderedByAscendingLevel(sqlStrings, 174  connection, 175  requestedDescendentDomainId); 176  break; 177  } 178  } 179  } 180  181  // now let's collect all the resources for those sub-domains to which we effectively have global permissions 182  Set<Resource> resources = new HashSet<>(); 183  statement = connection.prepareStatement(sqlStrings.SQL_findInResource_withoutInheritance_ResourceId_ExternalId_BY_ResourceClassID_DomainID); 184  for (Id<DomainId> effectiveDomainId : effectiveDomainIds) { 185  statement.setResourceClassId(1, resourceClassId); 186  statement.setResourceDomainId(2, effectiveDomainId); 187  resultSet = statement.executeQuery(); 188  189  while (resultSet.next()) { 190  resources.add(resultSet.getResource("ResourceId", "ExternalId")); 191  } 192  resultSet.close(); 193  } 194  195  return resources; 196  } 197  catch (SQLException e) { 198  throw new RuntimeException(e); 199  } 200  finally { 201  closeStatement(statement); 202  } 203  } 204  205  @Override 206  public Set<ResourcePermission> getGlobalResourcePermissionsIncludeInherited(SQLConnection connection, 207  Resource accessorResource, 208  Id<ResourceClassId> resourceClassId, 209  Id<DomainId> resourceDomainId) { 210  SQLStatement statement = null; 211  try { 212  // first get all the resources from which the accessor inherits any permissions 213  final Set<Id<ResourceId>> accessorResourceIds 214  = NonRecursivePersisterHelper.getInheritedAccessorResourceIds(sqlStrings, connection, accessorResource); 215  216  // get the ancestors of the specified domain, to which the accessors could also have permissions 217  final Set<Id<DomainId>> ancestorDomainIds 218  = NonRecursivePersisterHelper.getAncestorDomainIds(sqlStrings, connection, resourceDomainId); 219  220  // now collect the global permissions any accessor resource has to the specified domain or its ancestors 221  SQLResult resultSet; 222  Set<ResourcePermission> resourcePermissions = new HashSet<>(); 223  statement = connection.prepareStatement(sqlStrings.SQL_findInGrantGlobalResourcePermission_withoutInheritance_PermissionName_IsWithGrant_BY_AccessorID_AccessedDomainID_ResourceClassID); 224  225  for (Id<ResourceId> accessorResourceId : accessorResourceIds) { 226  for (Id<DomainId> domainId : ancestorDomainIds) { 227  statement.setResourceId(1, accessorResourceId); 228  statement.setResourceDomainId(2, domainId); 229  statement.setResourceClassId(3, resourceClassId); 230  resultSet = statement.executeQuery(); 231  232  while (resultSet.next()) { 233  resourcePermissions.add(getResourcePermission(resultSet)); 234  } 235  resultSet.close(); 236  } 237  } 238  239  return resourcePermissions; 240  } 241  catch (SQLException e) { 242  throw new RuntimeException(e); 243  } 244  finally { 245  closeStatement(statement); 246  } 247  } 248  249  @Override 250  public Map<String, Map<String, Set<ResourcePermission>>> getGlobalResourcePermissionsIncludeInherited(SQLConnection connection, 251  Resource accessorResource) { 252  SQLStatement statement = null; 253  try { 254  // first get all the resources from which the accessor inherits any permissions 255  final Set<Id<ResourceId>> accessorResourceIds 256  = NonRecursivePersisterHelper.getInheritedAccessorResourceIds(sqlStrings, connection, accessorResource); 257  258  // second, get all the global resource permissions the accessors directly have access to 259  SQLResult resultSet; 260  Map<String, Map<String, Set<ResourcePermission>>> globalPermissionsMap = new HashMap<>(); 261  262  statement = connection.prepareStatement(sqlStrings.SQL_findInGrantGlobalResourcePermission_withoutInheritance_ResourceDomainName_ResourceClassName_PermissionName_IsWithGrant_BY_AccessorID); 263  264  for (Id<ResourceId> accessorResourceId : accessorResourceIds) { 265  statement.setResourceId(1, accessorResourceId); 266  resultSet = statement.executeQuery(); 267  268  while (resultSet.next()) { 269  final String resourceDomainName = resultSet.getString("DomainName"); 270  final String resourceClassName = resultSet.getString("ResourceClassName"); 271  272  Map<String, Set<ResourcePermission>> permissionsForResourceDomain 273  = globalPermissionsMap.get(resourceDomainName); 274  if (permissionsForResourceDomain == null) { 275  permissionsForResourceDomain = new HashMap<>(); 276  globalPermissionsMap.put(resourceDomainName, permissionsForResourceDomain); 277  } 278  279  Set<ResourcePermission> permissionsForResourceClass 280  = permissionsForResourceDomain.get(resourceClassName); 281  if (permissionsForResourceClass == null) { 282  permissionsForResourceClass = new HashSet<>(); 283  permissionsForResourceDomain.put(resourceClassName, permissionsForResourceClass); 284  } 285  286  permissionsForResourceClass.add(getResourcePermission(resultSet)); 287  } 288  resultSet.close(); 289  } 290  closeStatement(statement); 291  statement = null; 292  293  // then apply each domain's direct permissions to all its descendants 294  // !! DON'T UPDATE THE PERMISSION-MAP WHILE ITERATING OVER ITS KEY-SET !! (get a copy of the key-set instead) 295  Set<String> directDomainNames = new HashSet<>(globalPermissionsMap.keySet()); 296  for (String directDomainName : directDomainNames) { 297  Set<String> descendentDomains = NonRecursivePersisterHelper.getDescendantDomainNames(sqlStrings, 298  connection, 299  directDomainName); 300  301  for (String descendentDomain : descendentDomains) { 302  Map<String, Set<ResourcePermission>> permissionsForResourceDomain 303  = globalPermissionsMap.get(descendentDomain); 304  if (permissionsForResourceDomain == null) { 305  permissionsForResourceDomain = new HashMap<>(); 306  globalPermissionsMap.put(descendentDomain, permissionsForResourceDomain); 307  } 308  309  if (!descendentDomain.equals(directDomainName)) { 310  final Map<String, Set<ResourcePermission>> sourceResourceClassPermissionsMap 311  = globalPermissionsMap.get(directDomainName); 312  313  for (String resourceClassName : sourceResourceClassPermissionsMap.keySet()) { 314  Set<ResourcePermission> permissionsForResourceClass 315  = permissionsForResourceDomain.get(resourceClassName); 316  if (permissionsForResourceClass == null) { 317  permissionsForResourceClass = new HashSet<>(); 318  permissionsForResourceDomain.put(resourceClassName, permissionsForResourceClass); 319  } 320  321  permissionsForResourceClass.addAll(sourceResourceClassPermissionsMap.get(resourceClassName)); 322  } 323  } 324  } 325  } 326  327  return globalPermissionsMap; 328  } 329  catch (SQLException e) { 330  throw new RuntimeException(e); 331  } 332  finally { 333  closeStatement(statement); 334  } 335  } 336  337  @Override 338  public void removeAllGlobalResourcePermissions(SQLConnection connection, 339  Id<DomainId> accessedDomainId) { 340  SQLStatement statement = null; 341  try { 342  // get descendant domain Ids 343  List<Id<DomainId>> descendantDomainIds 344  = new ArrayList<>(NonRecursivePersisterHelper.getDescendantDomainIdsOrderedByAscendingLevel(sqlStrings, 345  connection, 346  accessedDomainId)); 347  348  // delete domains' accessors (in reverse order of domainLevel, to preserve FK constraints) 349  statement = connection.prepareStatement(sqlStrings.SQL_removeInGrantGlobalResourcePermission_BY_AccessedDomainId); 350  351  for (int i=descendantDomainIds.size()-1; i >= 0; i--) { 352  statement.setResourceDomainId(1, descendantDomainIds.get(i)); 353  statement.executeUpdate(); 354  } 355  } 356  catch (SQLException e) { 357  throw new RuntimeException(e); 358  } 359  finally { 360  closeStatement(statement); 361  } 362  } 363 }