Coverage Summary for Class: ResourceCreatePermissions (com.acciente.oacc)

Class Method, % Line, %
ResourceCreatePermissions 84.6% (11/ 13) 75.9% (60/ 79)
ResourceCreatePermissions$ResourceCreatePermissionImpl 81.2% (13/ 16) 71.6% (58/ 81)
total 82.8% (24/ 29) 73.8% (118/ 160)


1 /* 2  * Copyright 2009-2017, Acciente LLC 3  * 4  * Acciente LLC licenses this file to you under the 5  * Apache License, Version 2.0 (the "License"); you 6  * may not use this file except in compliance with the 7  * License. You may obtain a copy of the License at 8  * 9  * http://www.apache.org/licenses/LICENSE-2.0 10  * 11  * Unless required by applicable law or agreed to in 12  * writing, software distributed under the License is 13  * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14  * OR CONDITIONS OF ANY KIND, either express or implied. 15  * See the License for the specific language governing 16  * permissions and limitations under the License. 17  */ 18 package com.acciente.oacc; 19  20 import com.acciente.oacc.ResourcePermissions.ResourcePermissionImpl; 21  22 import java.io.Serializable; 23 import java.util.ArrayList; 24 import java.util.Collections; 25 import java.util.HashMap; 26 import java.util.List; 27 import java.util.Map; 28 import java.util.concurrent.ConcurrentHashMap; 29 import java.util.concurrent.ConcurrentMap; 30  31 public class ResourceCreatePermissions { 32  // constants for the important system permissions with pre-defined semantics 33  private static final SysPermission SYSPERMISSION_CREATE = new SysPermission(-100, "*CREATE"); 34  public static final String CREATE = SYSPERMISSION_CREATE.getPermissionName(); 35  36  private static final Map<String, SysPermission> sysPermissionsByName; 37  private static final Map<Long, String> sysPermissionNamesById; 38  private static final List<String> sysPermissionNames; 39  private static final ConcurrentMap<String, ResourceCreatePermission> grantableCreatePermissionsByName; 40  private static final ConcurrentMap<String, ResourceCreatePermission> ungrantableCreatePermissionsByName; 41  private static final ConcurrentMap<ResourcePermission, ResourceCreatePermission> grantableCreatePermissionsByPostCreatePermission; 42  private static final ConcurrentMap<ResourcePermission, ResourceCreatePermission> ungrantableCreatePermissionsByPostCreatePermission; 43  44  static { 45  sysPermissionsByName = new HashMap<>(); 46  sysPermissionsByName.put(CREATE, SYSPERMISSION_CREATE); 47  48  sysPermissionNamesById = new HashMap<>(sysPermissionsByName.size()); 49  for (SysPermission sysPermission : sysPermissionsByName.values()) { 50  sysPermissionNamesById.put(sysPermission.getSystemPermissionId(), sysPermission.getPermissionName()); 51  } 52  53  sysPermissionNames = Collections.unmodifiableList(new ArrayList<>(sysPermissionNamesById.values())); 54  55  grantableCreatePermissionsByName = new ConcurrentHashMap<>(sysPermissionsByName.size()); 56  ungrantableCreatePermissionsByName = new ConcurrentHashMap<>(sysPermissionsByName.size()); 57  grantableCreatePermissionsByPostCreatePermission = new ConcurrentHashMap<>(); 58  ungrantableCreatePermissionsByPostCreatePermission = new ConcurrentHashMap<>(); 59  } 60  61  public static List<String> getSysPermissionNames() { 62  return sysPermissionNames; 63  } 64  65  public static String getSysPermissionName(long systemPermissionId) { 66  final String sysPermissionName = sysPermissionNamesById.get(systemPermissionId); 67  68  if (sysPermissionName == null) { 69  throw new IllegalArgumentException("Invalid system permission ID: " + systemPermissionId); 70  } 71  72  return sysPermissionName; 73  } 74  75  /** 76  * Creates a new resource create permission with no post-create permissions (i.e. only resource creation), 77  * but with the option to grant the create-permission to another resource 78  * 79  * @param sysPermissionName the name of the system permission 80  * @return a resource create permission 81  */ 82  public static ResourceCreatePermission getInstanceWithGrantOption(String sysPermissionName) { 83  sysPermissionName = getCanonicalSysPermissionName(sysPermissionName); 84  85  ResourceCreatePermission resourceCreatePermission = grantableCreatePermissionsByName.get(sysPermissionName); 86  87  if (resourceCreatePermission == null) { 88  resourceCreatePermission = new ResourceCreatePermissionImpl(sysPermissionName, true); 89  final ResourceCreatePermission cachedInstance 90  = grantableCreatePermissionsByName.putIfAbsent(sysPermissionName, resourceCreatePermission); 91  if (cachedInstance != null) { 92  resourceCreatePermission = cachedInstance; 93  } 94  } 95  96  return resourceCreatePermission; 97  } 98  99  /** 100  * Creates a new resource create permission with no post-create permissions (i.e. only resource creation) 101  * 102  * @param sysPermissionName 103  * @param withGrant true if the permission should have the grant privilege, false otherwise 104  * @return a resource create permission 105  * @deprecated as of v2.0.0-rc.5; use {@link #getInstanceWithGrantOption(String)} or {@link #getInstance(String)} instead. 106  */ 107  @Deprecated 108  public static ResourceCreatePermission getInstance(String sysPermissionName, boolean withGrant) { 109  return new ResourceCreatePermissionImpl(sysPermissionName, withGrant); 110  } 111  112  113  /** 114  * Creates a new resource create permission with no post-create permissions (i.e. only resource creation) 115  * without the option to grant the create-permission to another resource 116  * 117  * @param sysPermissionName the name of the system permission 118  * @return a resource create permission 119  */ 120  public static ResourceCreatePermission getInstance(String sysPermissionName) { 121  sysPermissionName = getCanonicalSysPermissionName(sysPermissionName); 122  123  ResourceCreatePermission resourceCreatePermission = ungrantableCreatePermissionsByName.get(sysPermissionName); 124  125  if (resourceCreatePermission == null) { 126  resourceCreatePermission = new ResourceCreatePermissionImpl(sysPermissionName, false); 127  final ResourceCreatePermission cachedInstance 128  = ungrantableCreatePermissionsByName.putIfAbsent(sysPermissionName, resourceCreatePermission); 129  if (cachedInstance != null) { 130  resourceCreatePermission = cachedInstance; 131  } 132  } 133  134  return resourceCreatePermission; 135  } 136  137  /** 138  * Creates a new resource create permission with the specified post-create permission 139  * without the option to grant the create-permission to another resource 140  * 141  * @param postCreateResourcePermission the post-create resource permission 142  * @return a resource create permission 143  */ 144  public static ResourceCreatePermission getInstance(ResourcePermission postCreateResourcePermission) { 145  assertPostCreatePermissionSpecified(postCreateResourcePermission); 146  // normalize post create permission before cache lookup, to prevent hash collisions from rogue implementations 147  postCreateResourcePermission = ResourcePermissions.getInstance(postCreateResourcePermission); 148  149  ResourceCreatePermission resourceCreatePermission 150  = ungrantableCreatePermissionsByPostCreatePermission.get(postCreateResourcePermission); 151  152  if (resourceCreatePermission == null) { 153  resourceCreatePermission = new ResourceCreatePermissionImpl((ResourcePermissionImpl) postCreateResourcePermission, false); 154  final ResourceCreatePermission cachedInstance 155  = ungrantableCreatePermissionsByPostCreatePermission.putIfAbsent(postCreateResourcePermission, resourceCreatePermission); 156  if (cachedInstance != null) { 157  resourceCreatePermission = cachedInstance; 158  } 159  } 160  161  return resourceCreatePermission; 162  } 163  164  /** 165  * Creates a new resource create permission with the specified post-create permission, 166  * but with the option to grant the create-permission to another resource 167  * 168  * @param postCreateResourcePermission the post-create resource permission 169  * @return a resource create permission 170  */ 171  public static ResourceCreatePermission getInstanceWithGrantOption(ResourcePermission postCreateResourcePermission) { 172  assertPostCreatePermissionSpecified(postCreateResourcePermission); 173  // normalize post create permission before cache lookup, to prevent hash collisions from rogue implementations 174  postCreateResourcePermission = ResourcePermissions.getInstance(postCreateResourcePermission); 175  176  ResourceCreatePermission resourceCreatePermission 177  = grantableCreatePermissionsByPostCreatePermission.get(postCreateResourcePermission); 178  179  if (resourceCreatePermission == null) { 180  resourceCreatePermission = new ResourceCreatePermissionImpl((ResourcePermissionImpl) postCreateResourcePermission, true); 181  final ResourceCreatePermission cachedInstance 182  = grantableCreatePermissionsByPostCreatePermission.putIfAbsent(postCreateResourcePermission, resourceCreatePermission); 183  if (cachedInstance != null) { 184  resourceCreatePermission = cachedInstance; 185  } 186  } 187  188  return resourceCreatePermission; 189  } 190  191  /** 192  * @deprecated as of v2.0.0-rc.5; use {@link #getInstanceWithGrantOption(ResourcePermission)} or 193  * {@link #getInstance(ResourcePermission)} instead. 194  */ 195  @Deprecated 196  public static ResourceCreatePermission getInstance(ResourcePermission postCreateResourcePermission, 197  boolean withGrant) { 198  postCreateResourcePermission = ResourcePermissions.getInstance(postCreateResourcePermission); 199  return new ResourceCreatePermissionImpl((ResourcePermissionImpl) postCreateResourcePermission, withGrant); 200  } 201  202  public static ResourceCreatePermission getInstance(ResourceCreatePermission resourceCreatePermission) { 203  if (resourceCreatePermission instanceof ResourceCreatePermissions.ResourceCreatePermissionImpl) { 204  return resourceCreatePermission; 205  } 206  207  final ResourceCreatePermission verifiedPermission; 208  209  if (resourceCreatePermission.isSystemPermission()) { 210  if (resourceCreatePermission.isWithGrantOption()) { 211  verifiedPermission = getInstanceWithGrantOption(resourceCreatePermission.getPermissionName()); 212  } 213  else { 214  verifiedPermission = getInstance(resourceCreatePermission.getPermissionName()); 215  } 216  217  // validate system permission name and id matched 218  if (verifiedPermission.getSystemPermissionId() != resourceCreatePermission.getSystemPermissionId()) { 219  throw new IllegalArgumentException("Invalid system permission id for resource create permission: " 220  + resourceCreatePermission); 221  } 222  } 223  else { 224  if (resourceCreatePermission.isWithGrantOption()) { 225  verifiedPermission = getInstanceWithGrantOption(ResourcePermissions.getInstance(resourceCreatePermission 226  .getPostCreateResourcePermission())); 227  } 228  else { 229  verifiedPermission = getInstance(ResourcePermissions.getInstance(resourceCreatePermission 230  .getPostCreateResourcePermission())); 231  } 232  } 233  234  return verifiedPermission; 235  } 236  237  private static String getCanonicalSysPermissionName(String permissionName) { 238  if (permissionName == null) { 239  throw new IllegalArgumentException("A system permission name is required"); 240  } 241  242  permissionName = permissionName.trim(); 243  244  if (permissionName.isEmpty()) { 245  throw new IllegalArgumentException("A system permission name is required"); 246  } 247  return permissionName; 248  } 249  250  private static void assertPostCreatePermissionSpecified(ResourcePermission postCreateResourcePermission) { 251  if (postCreateResourcePermission == null) { 252  throw new IllegalArgumentException("A post create resource permission is required"); 253  } 254  } 255  256  static class ResourceCreatePermissionImpl implements ResourceCreatePermission, Serializable { 257  private static final long serialVersionUID = 2L; 258  259  // permission data 260  private final long systemPermissionId; 261  private final String sysPermissionName; 262  private final ResourcePermissionImpl postCreateResourcePermission; 263  private final boolean withGrantOption; 264  265  private ResourceCreatePermissionImpl(String sysPermissionName, 266  boolean withGrantOption) { 267  SysPermission sysPermission = getSysPermission(sysPermissionName); 268  269  this.systemPermissionId = sysPermission.getSystemPermissionId(); 270  this.sysPermissionName = sysPermission.getPermissionName(); 271  this.postCreateResourcePermission = null; 272  this.withGrantOption = withGrantOption; 273  } 274  275  private ResourceCreatePermissionImpl(ResourcePermissionImpl postCreateResourcePermission, 276  boolean withGrantOption) { 277  this.systemPermissionId = 0; 278  this.sysPermissionName = null; 279  this.postCreateResourcePermission = postCreateResourcePermission; 280  this.withGrantOption = withGrantOption; 281  } 282  283  @Override 284  public boolean isSystemPermission() { 285  return systemPermissionId != 0; 286  } 287  288  @Override 289  public String getPermissionName() { 290  if (!isSystemPermission()) { 291  throw new IllegalArgumentException( 292  "No system permission name may be retrieved for non-system resource create permission: " + this + ", please check your code"); 293  } 294  return sysPermissionName; 295  } 296  297  @Override 298  public long getSystemPermissionId() { 299  if (!isSystemPermission()) { 300  throw new IllegalArgumentException( 301  "No system permission ID may be retrieved for non-system resource create permission: " + this + ", please check your code"); 302  } 303  return systemPermissionId; 304  } 305  306  @Override 307  public ResourcePermission getPostCreateResourcePermission() { 308  if (isSystemPermission()) { 309  throw new IllegalArgumentException( 310  "No post create resource permission may be retrieved for system resource create permission: " + this + ", please check your code"); 311  } 312  return postCreateResourcePermission; 313  } 314  315  @Override 316  public boolean isWithGrantOption() { 317  return withGrantOption; 318  } 319  320  @Override 321  @Deprecated 322  public boolean isWithGrant() { 323  return isWithGrantOption(); 324  } 325  326  @Override 327  public boolean isGrantableFrom(ResourceCreatePermission other) { 328  if (other == null) { 329  return false; 330  } 331  332  if (!other.isWithGrantOption()) { 333  return false; 334  } 335  336  if (this.isSystemPermission() != other.isSystemPermission()) { 337  return false; 338  } 339  340  if (this.isSystemPermission()) { 341  return this.systemPermissionId == other.getSystemPermissionId(); 342  } 343  344  if (this.postCreateResourcePermission.isWithGrantOption() && !other.getPostCreateResourcePermission().isWithGrantOption()) { 345  return false; 346  } 347  348  return this.postCreateResourcePermission.equalsIgnoreGrantOption(other.getPostCreateResourcePermission()); 349  } 350  351  @Override 352  public boolean equals(Object other) { 353  if (this == other) { 354  return true; 355  } 356  if (other == null || getClass() != other.getClass()) { 357  return false; 358  } 359  360  ResourceCreatePermissionImpl otherResourceCreatePermission = (ResourceCreatePermissionImpl) other; 361  362  if (systemPermissionId != otherResourceCreatePermission.systemPermissionId) { 363  return false; 364  } 365  if (sysPermissionName != null 366  ? !sysPermissionName.equals(otherResourceCreatePermission.sysPermissionName) 367  : otherResourceCreatePermission.sysPermissionName != null) { 368  return false; 369  } 370  if (postCreateResourcePermission != null 371  ? !postCreateResourcePermission.equals(otherResourceCreatePermission.postCreateResourcePermission) 372  : otherResourceCreatePermission.postCreateResourcePermission != null) { 373  return false; 374  } 375  if (withGrantOption != otherResourceCreatePermission.withGrantOption) { 376  return false; 377  } 378  379  return true; 380  } 381  382  @Override 383  public boolean equalsIgnoreGrantOption(Object other) { 384  if (this == other) { 385  return true; 386  } 387  if (other == null || getClass() != other.getClass()) { 388  return false; 389  } 390  391  ResourceCreatePermissionImpl otherResourceCreatePermission = (ResourceCreatePermissionImpl) other; 392  393  if (systemPermissionId != otherResourceCreatePermission.systemPermissionId) { 394  return false; 395  } 396  if (sysPermissionName != null 397  ? !sysPermissionName.equals(otherResourceCreatePermission.sysPermissionName) 398  : otherResourceCreatePermission.sysPermissionName != null) { 399  return false; 400  } 401  if (postCreateResourcePermission != null 402  ? !postCreateResourcePermission.equals(otherResourceCreatePermission.postCreateResourcePermission) 403  : otherResourceCreatePermission.postCreateResourcePermission != null) { 404  return false; 405  } 406  407  return true; 408  } 409  410  @Override 411  @Deprecated 412  public boolean equalsIgnoreGrant(Object other) { 413  return equalsIgnoreGrantOption(other); 414  } 415  416  @Override 417  public int hashCode() { 418  int result = (int) (systemPermissionId ^ (systemPermissionId >>> 32)); 419  result = 31 * result + (sysPermissionName != null ? sysPermissionName.hashCode() : 0); 420  result = 31 * result + (postCreateResourcePermission != null ? postCreateResourcePermission.hashCode() : 0); 421  result = 31 * result + (withGrantOption ? 1 : 0); 422  return result; 423  } 424  425  @Override 426  public String toString() { 427  if (postCreateResourcePermission == null) { 428  return withGrantOption ? sysPermissionName + " /G" : sysPermissionName; 429  } 430  else { 431  return "[" + postCreateResourcePermission.toString() + "]" + (withGrantOption ? " /G" : ""); 432  } 433  } 434  435  // private static helper method to convert a sys permission name to a sys permission object 436  437  private static SysPermission getSysPermission(String permissionName) { 438  if (permissionName == null) { 439  throw new IllegalArgumentException("A system permission name is required"); 440  } 441  442  final String trimmedPermissionName = permissionName.trim(); 443  444  if (trimmedPermissionName.isEmpty()) { 445  throw new IllegalArgumentException("A system permission name is required"); 446  } 447  448  final SysPermission sysPermission = sysPermissionsByName.get(trimmedPermissionName); 449  450  if (sysPermission == null) { 451  throw new IllegalArgumentException("Invalid system permission name: " + trimmedPermissionName); 452  } 453  454  return sysPermission; 455  } 456  } 457 }