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

Class Method, % Line, %
ResourceCreatePermissions 100% (11/ 11) 78.9% (60/ 76)
ResourceCreatePermissions$ResourceCreatePermissionImpl 92.9% (13/ 14) 73.4% (58/ 79)
total 96% (24/ 25) 76.1% (118/ 155)


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; 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  /** 101  * Creates a new resource create permission with no post-create permissions (i.e. only resource creation) 102  * without the option to grant the create-permission to another resource 103  * 104  * @param sysPermissionName the name of the system permission 105  * @return a resource create permission 106  */ 107  public static ResourceCreatePermission getInstance(String sysPermissionName) { 108  sysPermissionName = getCanonicalSysPermissionName(sysPermissionName); 109  110  ResourceCreatePermission resourceCreatePermission = ungrantableCreatePermissionsByName.get(sysPermissionName); 111  112  if (resourceCreatePermission == null) { 113  resourceCreatePermission = new ResourceCreatePermissionImpl(sysPermissionName, false); 114  final ResourceCreatePermission cachedInstance 115  = ungrantableCreatePermissionsByName.putIfAbsent(sysPermissionName, resourceCreatePermission); 116  if (cachedInstance != null) { 117  resourceCreatePermission = cachedInstance; 118  } 119  } 120  121  return resourceCreatePermission; 122  } 123  124  /** 125  * Creates a new resource create permission with the specified post-create permission 126  * without the option to grant the create-permission to another resource 127  * 128  * @param postCreateResourcePermission the post-create resource permission 129  * @return a resource create permission 130  */ 131  public static ResourceCreatePermission getInstance(ResourcePermission postCreateResourcePermission) { 132  assertPostCreatePermissionSpecified(postCreateResourcePermission); 133  // normalize post create permission before cache lookup, to prevent hash collisions from rogue implementations 134  postCreateResourcePermission = ResourcePermissions.getInstance(postCreateResourcePermission); 135  136  ResourceCreatePermission resourceCreatePermission 137  = ungrantableCreatePermissionsByPostCreatePermission.get(postCreateResourcePermission); 138  139  if (resourceCreatePermission == null) { 140  resourceCreatePermission = new ResourceCreatePermissionImpl((ResourcePermissionImpl) postCreateResourcePermission, false); 141  final ResourceCreatePermission cachedInstance 142  = ungrantableCreatePermissionsByPostCreatePermission.putIfAbsent(postCreateResourcePermission, resourceCreatePermission); 143  if (cachedInstance != null) { 144  resourceCreatePermission = cachedInstance; 145  } 146  } 147  148  return resourceCreatePermission; 149  } 150  151  /** 152  * Creates a new resource create permission with the specified post-create permission, 153  * but with the option to grant the create-permission to another resource 154  * 155  * @param postCreateResourcePermission the post-create resource permission 156  * @return a resource create permission 157  */ 158  public static ResourceCreatePermission getInstanceWithGrantOption(ResourcePermission postCreateResourcePermission) { 159  assertPostCreatePermissionSpecified(postCreateResourcePermission); 160  // normalize post create permission before cache lookup, to prevent hash collisions from rogue implementations 161  postCreateResourcePermission = ResourcePermissions.getInstance(postCreateResourcePermission); 162  163  ResourceCreatePermission resourceCreatePermission 164  = grantableCreatePermissionsByPostCreatePermission.get(postCreateResourcePermission); 165  166  if (resourceCreatePermission == null) { 167  resourceCreatePermission = new ResourceCreatePermissionImpl((ResourcePermissionImpl) postCreateResourcePermission, true); 168  final ResourceCreatePermission cachedInstance 169  = grantableCreatePermissionsByPostCreatePermission.putIfAbsent(postCreateResourcePermission, resourceCreatePermission); 170  if (cachedInstance != null) { 171  resourceCreatePermission = cachedInstance; 172  } 173  } 174  175  return resourceCreatePermission; 176  } 177  178  public static ResourceCreatePermission getInstance(ResourceCreatePermission resourceCreatePermission) { 179  if (resourceCreatePermission instanceof ResourceCreatePermissions.ResourceCreatePermissionImpl) { 180  return resourceCreatePermission; 181  } 182  183  final ResourceCreatePermission verifiedPermission; 184  185  if (resourceCreatePermission.isSystemPermission()) { 186  if (resourceCreatePermission.isWithGrantOption()) { 187  verifiedPermission = getInstanceWithGrantOption(resourceCreatePermission.getPermissionName()); 188  } 189  else { 190  verifiedPermission = getInstance(resourceCreatePermission.getPermissionName()); 191  } 192  193  // validate system permission name and id matched 194  if (verifiedPermission.getSystemPermissionId() != resourceCreatePermission.getSystemPermissionId()) { 195  throw new IllegalArgumentException("Invalid system permission id for resource create permission: " 196  + resourceCreatePermission); 197  } 198  } 199  else { 200  if (resourceCreatePermission.isWithGrantOption()) { 201  verifiedPermission = getInstanceWithGrantOption(ResourcePermissions.getInstance(resourceCreatePermission 202  .getPostCreateResourcePermission())); 203  } 204  else { 205  verifiedPermission = getInstance(ResourcePermissions.getInstance(resourceCreatePermission 206  .getPostCreateResourcePermission())); 207  } 208  } 209  210  return verifiedPermission; 211  } 212  213  private static String getCanonicalSysPermissionName(String permissionName) { 214  if (permissionName == null) { 215  throw new IllegalArgumentException("A system permission name is required"); 216  } 217  218  permissionName = permissionName.trim(); 219  220  if (permissionName.isEmpty()) { 221  throw new IllegalArgumentException("A system permission name is required"); 222  } 223  return permissionName; 224  } 225  226  private static void assertPostCreatePermissionSpecified(ResourcePermission postCreateResourcePermission) { 227  if (postCreateResourcePermission == null) { 228  throw new IllegalArgumentException("A post create resource permission is required"); 229  } 230  } 231  232  static class ResourceCreatePermissionImpl implements ResourceCreatePermission, Serializable { 233  private static final long serialVersionUID = 2L; 234  235  // permission data 236  private final long systemPermissionId; 237  private final String sysPermissionName; 238  private final ResourcePermissionImpl postCreateResourcePermission; 239  private final boolean withGrantOption; 240  241  private ResourceCreatePermissionImpl(String sysPermissionName, 242  boolean withGrantOption) { 243  SysPermission sysPermission = getSysPermission(sysPermissionName); 244  245  this.systemPermissionId = sysPermission.getSystemPermissionId(); 246  this.sysPermissionName = sysPermission.getPermissionName(); 247  this.postCreateResourcePermission = null; 248  this.withGrantOption = withGrantOption; 249  } 250  251  private ResourceCreatePermissionImpl(ResourcePermissionImpl postCreateResourcePermission, 252  boolean withGrantOption) { 253  this.systemPermissionId = 0; 254  this.sysPermissionName = null; 255  this.postCreateResourcePermission = postCreateResourcePermission; 256  this.withGrantOption = withGrantOption; 257  } 258  259  @Override 260  public boolean isSystemPermission() { 261  return systemPermissionId != 0; 262  } 263  264  @Override 265  public String getPermissionName() { 266  if (!isSystemPermission()) { 267  throw new IllegalArgumentException( 268  "No system permission name may be retrieved for non-system resource create permission: " + this + ", please check your code"); 269  } 270  return sysPermissionName; 271  } 272  273  @Override 274  public long getSystemPermissionId() { 275  if (!isSystemPermission()) { 276  throw new IllegalArgumentException( 277  "No system permission ID may be retrieved for non-system resource create permission: " + this + ", please check your code"); 278  } 279  return systemPermissionId; 280  } 281  282  @Override 283  public ResourcePermission getPostCreateResourcePermission() { 284  if (isSystemPermission()) { 285  throw new IllegalArgumentException( 286  "No post create resource permission may be retrieved for system resource create permission: " + this + ", please check your code"); 287  } 288  return postCreateResourcePermission; 289  } 290  291  @Override 292  public boolean isWithGrantOption() { 293  return withGrantOption; 294  } 295  296  @Override 297  public boolean isGrantableFrom(ResourceCreatePermission other) { 298  if (other == null) { 299  return false; 300  } 301  302  if (!other.isWithGrantOption()) { 303  return false; 304  } 305  306  if (this.isSystemPermission() != other.isSystemPermission()) { 307  return false; 308  } 309  310  if (this.isSystemPermission()) { 311  return this.systemPermissionId == other.getSystemPermissionId(); 312  } 313  314  if (this.postCreateResourcePermission.isWithGrantOption() && !other.getPostCreateResourcePermission().isWithGrantOption()) { 315  return false; 316  } 317  318  return this.postCreateResourcePermission.equalsIgnoreGrantOption(other.getPostCreateResourcePermission()); 319  } 320  321  @Override 322  public boolean equals(Object other) { 323  if (this == other) { 324  return true; 325  } 326  if (other == null || getClass() != other.getClass()) { 327  return false; 328  } 329  330  ResourceCreatePermissionImpl otherResourceCreatePermission = (ResourceCreatePermissionImpl) other; 331  332  if (systemPermissionId != otherResourceCreatePermission.systemPermissionId) { 333  return false; 334  } 335  if (sysPermissionName != null 336  ? !sysPermissionName.equals(otherResourceCreatePermission.sysPermissionName) 337  : otherResourceCreatePermission.sysPermissionName != null) { 338  return false; 339  } 340  if (postCreateResourcePermission != null 341  ? !postCreateResourcePermission.equals(otherResourceCreatePermission.postCreateResourcePermission) 342  : otherResourceCreatePermission.postCreateResourcePermission != null) { 343  return false; 344  } 345  if (withGrantOption != otherResourceCreatePermission.withGrantOption) { 346  return false; 347  } 348  349  return true; 350  } 351  352  @Override 353  public boolean equalsIgnoreGrantOption(Object other) { 354  if (this == other) { 355  return true; 356  } 357  if (other == null || getClass() != other.getClass()) { 358  return false; 359  } 360  361  ResourceCreatePermissionImpl otherResourceCreatePermission = (ResourceCreatePermissionImpl) other; 362  363  if (systemPermissionId != otherResourceCreatePermission.systemPermissionId) { 364  return false; 365  } 366  if (sysPermissionName != null 367  ? !sysPermissionName.equals(otherResourceCreatePermission.sysPermissionName) 368  : otherResourceCreatePermission.sysPermissionName != null) { 369  return false; 370  } 371  if (postCreateResourcePermission != null 372  ? !postCreateResourcePermission.equals(otherResourceCreatePermission.postCreateResourcePermission) 373  : otherResourceCreatePermission.postCreateResourcePermission != null) { 374  return false; 375  } 376  377  return true; 378  } 379  380  @Override 381  public int hashCode() { 382  int result = (int) (systemPermissionId ^ (systemPermissionId >>> 32)); 383  result = 31 * result + (sysPermissionName != null ? sysPermissionName.hashCode() : 0); 384  result = 31 * result + (postCreateResourcePermission != null ? postCreateResourcePermission.hashCode() : 0); 385  result = 31 * result + (withGrantOption ? 1 : 0); 386  return result; 387  } 388  389  @Override 390  public String toString() { 391  if (postCreateResourcePermission == null) { 392  return withGrantOption ? sysPermissionName + " /G" : sysPermissionName; 393  } 394  else { 395  return "[" + postCreateResourcePermission.toString() + "]" + (withGrantOption ? " /G" : ""); 396  } 397  } 398  399  // private static helper method to convert a sys permission name to a sys permission object 400  401  private static SysPermission getSysPermission(String permissionName) { 402  if (permissionName == null) { 403  throw new IllegalArgumentException("A system permission name is required"); 404  } 405  406  final String trimmedPermissionName = permissionName.trim(); 407  408  if (trimmedPermissionName.isEmpty()) { 409  throw new IllegalArgumentException("A system permission name is required"); 410  } 411  412  final SysPermission sysPermission = sysPermissionsByName.get(trimmedPermissionName); 413  414  if (sysPermission == null) { 415  throw new IllegalArgumentException("Invalid system permission name: " + trimmedPermissionName); 416  } 417  418  return sysPermission; 419  } 420  } 421 }