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

Class Method, % Line, %
ResourcePermissions 88.9% (8/ 9) 91.9% (57/ 62)
ResourcePermissions$ResourcePermissionImpl 86.7% (13/ 15) 83.3% (50/ 60)
total 87.5% (21/ 24) 87.7% (107/ 122)


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 java.io.Serializable; 21 import java.util.ArrayList; 22 import java.util.Collections; 23 import java.util.HashMap; 24 import java.util.List; 25 import java.util.Map; 26 import java.util.concurrent.ConcurrentHashMap; 27 import java.util.concurrent.ConcurrentMap; 28  29 public class ResourcePermissions { 30  // constants for the important system permissions with pre-defined semantics 31  private static final SysPermission SYSPERMISSION_INHERIT = new SysPermission(-101, "*INHERIT"); 32  public static final String INHERIT = SYSPERMISSION_INHERIT.getPermissionName(); 33  private static final SysPermission SYSPERMISSION_IMPERSONATE = new SysPermission(-102, "*IMPERSONATE"); 34  public static final String IMPERSONATE = SYSPERMISSION_IMPERSONATE.getPermissionName(); 35  private static final SysPermission SYSPERMISSION_RESET_CREDENTIALS = new SysPermission(-103, "*RESET-CREDENTIALS"); 36  public static final String RESET_CREDENTIALS = SYSPERMISSION_RESET_CREDENTIALS.getPermissionName(); 37  private static final SysPermission SYSPERMISSION_DELETE = new SysPermission(-104, "*DELETE"); 38  public static final String DELETE = SYSPERMISSION_DELETE.getPermissionName(); 39  private static final SysPermission SYSPERMISSION_QUERY = new SysPermission(-105, "*QUERY"); 40  public static final String QUERY = SYSPERMISSION_QUERY.getPermissionName(); 41  42  private static final Map<String, SysPermission> sysPermissionsByName; 43  private static final Map<Long, String> sysPermissionNamesById; 44  private static final List<String> sysPermissionNames; 45  private static final ConcurrentMap<String, ResourcePermission> ungrantablePermissionByName; 46  private static final ConcurrentMap<String, ResourcePermission> grantablePermissionByName; 47  48  static { 49  sysPermissionsByName = new HashMap<>(); 50  sysPermissionsByName.put(INHERIT, SYSPERMISSION_INHERIT); 51  sysPermissionsByName.put(IMPERSONATE, SYSPERMISSION_IMPERSONATE); 52  sysPermissionsByName.put(RESET_CREDENTIALS, SYSPERMISSION_RESET_CREDENTIALS); 53  sysPermissionsByName.put(DELETE, SYSPERMISSION_DELETE); 54  sysPermissionsByName.put(QUERY, SYSPERMISSION_QUERY); 55  56  sysPermissionNamesById = new HashMap<>(sysPermissionsByName.size()); 57  for (SysPermission sysPermission : sysPermissionsByName.values()) { 58  sysPermissionNamesById.put(sysPermission.getSystemPermissionId(), sysPermission.getPermissionName()); 59  } 60  61  sysPermissionNames = Collections.unmodifiableList(new ArrayList<>(sysPermissionNamesById.values())); 62  63  ungrantablePermissionByName = new ConcurrentHashMap<>(); 64  grantablePermissionByName = new ConcurrentHashMap<>(); 65  } 66  67  public static List<String> getSysPermissionNames() { 68  return sysPermissionNames; 69  } 70  71  public static String getSysPermissionName(long systemPermissionId) { 72  final String sysPermissionName = sysPermissionNamesById.get(systemPermissionId); 73  74  if (sysPermissionName == null) { 75  throw new IllegalArgumentException("Invalid system permission ID: " + systemPermissionId); 76  } 77  78  return sysPermissionName; 79  } 80  81  /** 82  * Creates a new resource permission of the specified name without 83  * the option to grant the permission to another resource 84  * 85  * @param permissionName the name of the permission 86  * @return a resource permission 87  */ 88  public static ResourcePermission getInstance(String permissionName) { 89  permissionName = getCanonicalPermissionName(permissionName); 90  91  ResourcePermission resourcePermission = ungrantablePermissionByName.get(permissionName); 92  93  if (resourcePermission == null) { 94  resourcePermission = new ResourcePermissionImpl(permissionName, false); 95  final ResourcePermission cachedInstance = ungrantablePermissionByName.putIfAbsent(permissionName, resourcePermission); 96  if (cachedInstance != null) { 97  resourcePermission = cachedInstance; 98  } 99  } 100  101  return resourcePermission; 102  } 103  104  /** 105  * Creates a new resource permission of the specified name, but 106  * with the option to grant the permission to another resource 107  * 108  * @param permissionName the name of the permission 109  * @return a resource permission 110  */ 111  public static ResourcePermission getInstanceWithGrantOption(String permissionName) { 112  permissionName = getCanonicalPermissionName(permissionName); 113  114  ResourcePermission resourcePermission = grantablePermissionByName.get(permissionName); 115  116  if (resourcePermission == null) { 117  resourcePermission = new ResourcePermissionImpl(permissionName, true); 118  final ResourcePermission cachedInstance = grantablePermissionByName.putIfAbsent(permissionName, resourcePermission); 119  if (cachedInstance != null) { 120  resourcePermission = cachedInstance; 121  } 122  } 123  124  return resourcePermission; 125  } 126  127  /** 128  * @deprecated as of v2.0.0-rc.5; use {@link #getInstanceWithGrantOption(String)} or {@link #getInstance(String)} instead. 129  */ 130  @Deprecated 131  public static ResourcePermission getInstance(String permissionName, boolean withGrant) { 132  return new ResourcePermissionImpl(permissionName, withGrant); 133  } 134  135  public static ResourcePermission getInstance(ResourcePermission resourcePermission) { 136  if (resourcePermission instanceof ResourcePermissions.ResourcePermissionImpl) { 137  return resourcePermission; 138  } 139  140  final ResourcePermission verifiedPermission; 141  142  if (resourcePermission.isWithGrantOption()) { 143  verifiedPermission = getInstanceWithGrantOption(resourcePermission.getPermissionName()); 144  } 145  else { 146  verifiedPermission = getInstance(resourcePermission.getPermissionName()); 147  } 148  149  // validate system permission name and id matched 150  if (resourcePermission.isSystemPermission() && 151  verifiedPermission.getSystemPermissionId() != resourcePermission.getSystemPermissionId()){ 152  throw new IllegalArgumentException("Invalid system permission id for resource permission: " + resourcePermission); 153  } 154  155  return verifiedPermission; 156  } 157  158  private static String getCanonicalPermissionName(String permissionName) { 159  if (permissionName == null) { 160  throw new IllegalArgumentException("A permission name is required"); 161  } 162  163  permissionName = permissionName.trim(); 164  165  if (permissionName.isEmpty()) { 166  throw new IllegalArgumentException("A permission name is required"); 167  } 168  return permissionName; 169  } 170  171  static class ResourcePermissionImpl implements ResourcePermission, Serializable { 172  private static final long serialVersionUID = 1L; 173  174  // permission data 175  private final long systemPermissionId; 176  private final String permissionName; 177  private final boolean withGrantOption; 178  179  private ResourcePermissionImpl(String permissionName, 180  boolean withGrantOption) { 181  assertPermissionNameSpecified(permissionName); 182  183  permissionName = permissionName.trim(); 184  185  if (permissionName.startsWith("*")) { 186  SysPermission sysPermission = getSysPermission(permissionName); 187  188  this.systemPermissionId = sysPermission.getSystemPermissionId(); 189  this.permissionName = sysPermission.getPermissionName(); 190  } 191  else { 192  this.systemPermissionId = 0; 193  this.permissionName = permissionName.intern(); 194  } 195  196  this.withGrantOption = withGrantOption; 197  } 198  199  @Override 200  public boolean isSystemPermission() { 201  return systemPermissionId != 0; 202  } 203  204  @Override 205  public String getPermissionName() { 206  return permissionName; 207  } 208  209  @Override 210  public long getSystemPermissionId() { 211  if (!isSystemPermission()) { 212  throw new IllegalArgumentException("No system permission ID may be retrieved for user permission: " + permissionName + ", please check your code"); 213  } 214  215  return systemPermissionId; 216  } 217  218  @Override 219  public boolean isWithGrantOption() { 220  return withGrantOption; 221  } 222  223  @Override 224  @Deprecated 225  public boolean isWithGrant() { 226  return isWithGrantOption(); 227  } 228  229  @Override 230  public boolean isGrantableFrom(ResourcePermission other) { 231  if (other == null) { 232  return false; 233  } 234  235  if (!other.isWithGrantOption()) { 236  return false; 237  } 238  239  return this.equalsIgnoreGrantOption(other); 240  } 241  242  @Override 243  public boolean equals(Object other) { 244  if (this == other) { 245  return true; 246  } 247  if (other == null || getClass() != other.getClass()) { 248  return false; 249  } 250  251  ResourcePermissionImpl otherResourcePermission = (ResourcePermissionImpl) other; 252  253  if (!permissionName.equals(otherResourcePermission.permissionName)) { 254  return false; 255  } 256  if (withGrantOption != otherResourcePermission.withGrantOption) { 257  return false; 258  } 259  260  return true; 261  } 262  263  @Override 264  public boolean equalsIgnoreGrantOption(Object other) { 265  if (this == other) { 266  return true; 267  } 268  if (other == null || getClass() != other.getClass()) { 269  return false; 270  } 271  272  ResourcePermissionImpl otherResourcePermission = (ResourcePermissionImpl) other; 273  274  if (!permissionName.equals(otherResourcePermission.permissionName)) { 275  return false; 276  } 277  278  return true; 279  } 280  281  @Override 282  @Deprecated 283  public boolean equalsIgnoreGrant(Object other) { 284  return equalsIgnoreGrantOption(other); 285  } 286  287  @Override 288  public int hashCode() { 289  int result = permissionName.hashCode(); 290  result = 31 * result + (withGrantOption ? 1 : 0); 291  return result; 292  } 293  294  @Override 295  public String toString() { 296  return withGrantOption ? permissionName + " /G" : permissionName; 297  } 298  299  // private helper methods 300  301  private void assertPermissionNameSpecified(String permissionName) { 302  if (permissionName == null || permissionName.trim().isEmpty()) { 303  throw new IllegalArgumentException("A permission name is required"); 304  } 305  } 306  307  // private static helper method to convert a sys permission name to a sys permission object 308  309  private static SysPermission getSysPermission(String permissionName) { 310  if (permissionName == null) { 311  throw new IllegalArgumentException("A system permission name is required"); 312  } 313  314  final String trimmedPermissionName = permissionName.trim(); 315  316  if (trimmedPermissionName.isEmpty()) { 317  throw new IllegalArgumentException("A system permission name is required"); 318  } 319  320  final SysPermission sysPermission = sysPermissionsByName.get(trimmedPermissionName); 321  322  if (sysPermission == null) { 323  throw new IllegalArgumentException("Invalid system permission name: " + trimmedPermissionName); 324  } 325  326  return sysPermission; 327  } 328  } 329 }