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

Class Method, % Line, %
ResourcePermissions 100% (8/ 8) 93.4% (57/ 61)
ResourcePermissions$ResourcePermissionImpl 100% (13/ 13) 86.2% (50/ 58)
total 100% (21/ 21) 89.9% (107/ 119)


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 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  public static ResourcePermission getInstance(ResourcePermission resourcePermission) { 128  if (resourcePermission instanceof ResourcePermissions.ResourcePermissionImpl) { 129  return resourcePermission; 130  } 131  132  final ResourcePermission verifiedPermission; 133  134  if (resourcePermission.isWithGrantOption()) { 135  verifiedPermission = getInstanceWithGrantOption(resourcePermission.getPermissionName()); 136  } 137  else { 138  verifiedPermission = getInstance(resourcePermission.getPermissionName()); 139  } 140  141  // validate system permission name and id matched 142  if (resourcePermission.isSystemPermission() && 143  verifiedPermission.getSystemPermissionId() != resourcePermission.getSystemPermissionId()){ 144  throw new IllegalArgumentException("Invalid system permission id for resource permission: " + resourcePermission); 145  } 146  147  return verifiedPermission; 148  } 149  150  private static String getCanonicalPermissionName(String permissionName) { 151  if (permissionName == null) { 152  throw new IllegalArgumentException("A permission name is required"); 153  } 154  155  permissionName = permissionName.trim(); 156  157  if (permissionName.isEmpty()) { 158  throw new IllegalArgumentException("A permission name is required"); 159  } 160  return permissionName; 161  } 162  163  static class ResourcePermissionImpl implements ResourcePermission, Serializable { 164  private static final long serialVersionUID = 1L; 165  166  // permission data 167  private final long systemPermissionId; 168  private final String permissionName; 169  private final boolean withGrantOption; 170  171  private ResourcePermissionImpl(String permissionName, 172  boolean withGrantOption) { 173  assertPermissionNameSpecified(permissionName); 174  175  permissionName = permissionName.trim(); 176  177  if (permissionName.startsWith("*")) { 178  SysPermission sysPermission = getSysPermission(permissionName); 179  180  this.systemPermissionId = sysPermission.getSystemPermissionId(); 181  this.permissionName = sysPermission.getPermissionName(); 182  } 183  else { 184  this.systemPermissionId = 0; 185  this.permissionName = permissionName.intern(); 186  } 187  188  this.withGrantOption = withGrantOption; 189  } 190  191  @Override 192  public boolean isSystemPermission() { 193  return systemPermissionId != 0; 194  } 195  196  @Override 197  public String getPermissionName() { 198  return permissionName; 199  } 200  201  @Override 202  public long getSystemPermissionId() { 203  if (!isSystemPermission()) { 204  throw new IllegalArgumentException("No system permission ID may be retrieved for user permission: " + permissionName + ", please check your code"); 205  } 206  207  return systemPermissionId; 208  } 209  210  @Override 211  public boolean isWithGrantOption() { 212  return withGrantOption; 213  } 214  215  @Override 216  public boolean isGrantableFrom(ResourcePermission other) { 217  if (other == null) { 218  return false; 219  } 220  221  if (!other.isWithGrantOption()) { 222  return false; 223  } 224  225  return this.equalsIgnoreGrantOption(other); 226  } 227  228  @Override 229  public boolean equals(Object other) { 230  if (this == other) { 231  return true; 232  } 233  if (other == null || getClass() != other.getClass()) { 234  return false; 235  } 236  237  ResourcePermissionImpl otherResourcePermission = (ResourcePermissionImpl) other; 238  239  if (!permissionName.equals(otherResourcePermission.permissionName)) { 240  return false; 241  } 242  if (withGrantOption != otherResourcePermission.withGrantOption) { 243  return false; 244  } 245  246  return true; 247  } 248  249  @Override 250  public boolean equalsIgnoreGrantOption(Object other) { 251  if (this == other) { 252  return true; 253  } 254  if (other == null || getClass() != other.getClass()) { 255  return false; 256  } 257  258  ResourcePermissionImpl otherResourcePermission = (ResourcePermissionImpl) other; 259  260  if (!permissionName.equals(otherResourcePermission.permissionName)) { 261  return false; 262  } 263  264  return true; 265  } 266  267  @Override 268  public int hashCode() { 269  int result = permissionName.hashCode(); 270  result = 31 * result + (withGrantOption ? 1 : 0); 271  return result; 272  } 273  274  @Override 275  public String toString() { 276  return withGrantOption ? permissionName + " /G" : permissionName; 277  } 278  279  // private helper methods 280  281  private void assertPermissionNameSpecified(String permissionName) { 282  if (permissionName == null || permissionName.trim().isEmpty()) { 283  throw new IllegalArgumentException("A permission name is required"); 284  } 285  } 286  287  // private static helper method to convert a sys permission name to a sys permission object 288  289  private static SysPermission getSysPermission(String permissionName) { 290  if (permissionName == null) { 291  throw new IllegalArgumentException("A system permission name is required"); 292  } 293  294  final String trimmedPermissionName = permissionName.trim(); 295  296  if (trimmedPermissionName.isEmpty()) { 297  throw new IllegalArgumentException("A system permission name is required"); 298  } 299  300  final SysPermission sysPermission = sysPermissionsByName.get(trimmedPermissionName); 301  302  if (sysPermission == null) { 303  throw new IllegalArgumentException("Invalid system permission name: " + trimmedPermissionName); 304  } 305  306  return sysPermission; 307  } 308  } 309 }