1 module hunt.security.Permission; 2 3 import hunt.security.Guard; 4 import hunt.security.PermissionCollection; 5 6 import hunt.Exceptions; 7 /** 8 * Abstract class for representing access to a system resource. 9 * All permissions have a name (whose interpretation depends on the subclass), 10 * as well as abstract functions for defining the semantics of the 11 * particular Permission subclass. 12 * 13 * <p>Most Permission objects also include an "actions" list that tells the actions 14 * that are permitted for the object. For example, 15 * for a {@code java.io.FilePermission} object, the permission name is 16 * the pathname of a file (or directory), and the actions list 17 * (such as "read, write") specifies which actions are granted for the 18 * specified file (or for files in the specified directory). 19 * The actions list is optional for Permission objects, such as 20 * {@code java.lang.RuntimePermission}, 21 * that don't need such a list; you either have the named permission (such 22 * as "system.exit") or you don't. 23 * 24 * <p>An important method that must be implemented by each subclass is 25 * the {@code implies} method to compare Permissions. Basically, 26 * "permission p1 implies permission p2" means that 27 * if one is granted permission p1, one is naturally granted permission p2. 28 * Thus, this is not an equality test, but rather more of a 29 * subset test. 30 * 31 * <P> Permission objects are similar to string objects in that they 32 * are immutable once they have been created. Subclasses should not 33 * provide methods that can change the state of a permission 34 * once it has been created. 35 * 36 * @see Permissions 37 * @see PermissionCollection 38 * 39 * 40 * @author Marianne Mueller 41 * @author Roland Schemers 42 */ 43 44 abstract class Permission : Guard { 45 46 // private static final long serialVersionUID = -5636570222231596674L; 47 48 private string name; 49 50 /** 51 * Constructs a permission with the specified name. 52 * 53 * @param name name of the Permission object being created. 54 * 55 */ 56 57 this(string name) { 58 this.name = name; 59 } 60 61 /** 62 * Implements the guard interface for a permission. The 63 * {@code SecurityManager.checkPermission} method is called, 64 * passing this permission object as the permission to check. 65 * Returns silently if access is granted. Otherwise, throws 66 * a SecurityException. 67 * 68 * @param object the object being guarded (currently ignored). 69 * 70 * @throws SecurityException 71 * if a security manager exists and its 72 * {@code checkPermission} method doesn't allow access. 73 * 74 * @see Guard 75 * @see GuardedObject 76 * @see SecurityManager#checkPermission 77 * 78 */ 79 void checkGuard(Object object) { 80 81 // SecurityManager sm = System.getSecurityManager(); 82 // if (sm !is null) sm.checkPermission(this); 83 } 84 85 /** 86 * Checks if the specified permission's actions are "implied by" 87 * this object's actions. 88 * <P> 89 * This must be implemented by subclasses of Permission, as they are the 90 * only ones that can impose semantics on a Permission object. 91 * 92 * <p>The {@code implies} method is used by the AccessController to determine 93 * whether or not a requested permission is implied by another permission that 94 * is known to be valid in the current execution context. 95 * 96 * @param permission the permission to check against. 97 * 98 * @return true if the specified permission is implied by this object, 99 * false if not. 100 */ 101 102 abstract bool implies(Permission permission); 103 104 /** 105 * Checks two Permission objects for equality. 106 * <P> 107 * Do not use the {@code equals} method for making access control 108 * decisions; use the {@code implies} method. 109 * 110 * @param obj the object we are testing for equality with this object. 111 * 112 * @return true if both Permission objects are equivalent. 113 */ 114 override 115 abstract bool opEquals(Object obj); 116 117 /** 118 * Returns the hash code value for this Permission object. 119 * <P> 120 * The required {@code hashCode} behavior for Permission Objects is 121 * the following: 122 * <ul> 123 * <li>Whenever it is invoked on the same Permission object more than 124 * once during an execution of a Java application, the 125 * {@code hashCode} method 126 * must consistently return the same integer. This integer need not 127 * remain consistent from one execution of an application to another 128 * execution of the same application. 129 * <li>If two Permission objects are equal according to the 130 * {@code equals} 131 * method, then calling the {@code hashCode} method on each of the 132 * two Permission objects must produce the same integer result. 133 * </ul> 134 * 135 * @return a hash code value for this object. 136 */ 137 override 138 abstract size_t toHash() @trusted nothrow; 139 140 /** 141 * Returns the name of this Permission. 142 * For example, in the case of a {@code java.io.FilePermission}, 143 * the name will be a pathname. 144 * 145 * @return the name of this Permission. 146 * 147 */ 148 149 final string getName() @trusted nothrow { 150 return name; 151 } 152 153 /** 154 * Returns the actions as a string. This is abstract 155 * so subclasses can defer creating a string representation until 156 * one is needed. Subclasses should always return actions in what they 157 * consider to be their 158 * canonical form. For example, two FilePermission objects created via 159 * the following: 160 * 161 * <pre> 162 * perm1 = new FilePermission(p1,"read,write"); 163 * perm2 = new FilePermission(p2,"write,read"); 164 * </pre> 165 * 166 * both return 167 * "read,write" when the {@code getActions} method is invoked. 168 * 169 * @return the actions of this Permission. 170 * 171 */ 172 173 abstract string getActions(); 174 175 /** 176 * Returns an empty PermissionCollection for a given Permission object, or null if 177 * one is not defined. Subclasses of class Permission should 178 * override this if they need to store their permissions in a particular 179 * PermissionCollection object in order to provide the correct semantics 180 * when the {@code PermissionCollection.implies} method is called. 181 * If null is returned, 182 * then the caller of this method is free to store permissions of this 183 * type in any PermissionCollection they choose (one that uses a Hashtable, 184 * one that uses a Vector, etc). 185 * 186 * @return a new PermissionCollection object for this type of Permission, or 187 * null if one is not defined. 188 */ 189 190 PermissionCollection newPermissionCollection() { 191 return null; 192 } 193 194 /** 195 * Returns a string describing this Permission. The convention is to 196 * specify the class name, the permission name, and the actions in 197 * the following format: '("ClassName" "name" "actions")', or 198 * '("ClassName" "name")' if actions list is null or empty. 199 * 200 * @return information about this Permission. 201 */ 202 override 203 string toString() { 204 string actions = getActions(); 205 if ((actions is null) || (actions.length == 0)) { // OPTIONAL 206 return "(\"" ~ typeid(this).name ~ "\" \"" ~ name ~ "\")"; 207 } else { 208 return "(\"" ~ typeid(this).name ~ "\" \"" ~ name ~ 209 "\" \"" ~ actions ~ "\")"; 210 } 211 } 212 }