1 /** 2 * Copyright © DiamondMVC 2019 3 * License: MIT (https://github.com/DiamondMVC/Diamond/blob/master/LICENSE) 4 * Author: Jacob Jensen (bausshf) 5 */ 6 module diamond.authentication.permissions; 7 8 import diamond.core.apptype; 9 10 static if (isWeb) 11 { 12 import diamond.http; 13 import diamond.http.method; // Bug: Cannot get acess to members from this module through "diamond.http" 14 import diamond.authentication.roles; 15 16 /// Enumeration of permission types. 17 enum PermissionType 18 { 19 readAccess, 20 writeAccess, 21 updateAccess, 22 deleteAccess 23 } 24 25 /// Wrapper around permissions. 26 final class Permission 27 { 28 private: 29 /// The resource. 30 string _resource; 31 32 /// Boolean determining the read-access. 33 bool _readAccess; 34 35 /// Boolean determining the write-access. 36 bool _writeAccess; 37 38 /// Boolean determining the update-access. 39 bool _updateAccess; 40 41 /// Boolean determining the delete-access. 42 bool _deleteAccess; 43 44 public: 45 final: 46 /** 47 * Creates a new permission. 48 * Params: 49 * resource = The resource. 50 * readAccess = Boolean determining the read-access. 51 * writeAccess = Boolean determining the write-access. 52 * updateAccess = Boolean determining the update-access. 53 * deleteAccess = Boolean determining the delete-access. 54 */ 55 this(string resource, bool readAccess, bool writeAccess, bool updateAccess, bool deleteAccess) 56 { 57 _resource = resource; 58 _readAccess = readAccess; 59 _writeAccess = writeAccess; 60 _updateAccess = updateAccess; 61 _deleteAccess = deleteAccess; 62 } 63 64 @property 65 { 66 /// Gets the resource. 67 string resource() { return _resource; } 68 69 /// Gets a boolean determining the read-access. 70 bool readAccess() { return _readAccess; } 71 72 /// Gets a boolean determining the write-access. 73 bool writeAccess() { return _writeAccess; } 74 75 /// Gets a boolean determining the update-access. 76 bool updateAccess() { return _updateAccess; } 77 78 /// Gets a boolean determining the delete-access. 79 bool deleteAccess() { return _deleteAccess; } 80 } 81 } 82 83 /// The permissions for http methods. 84 private static __gshared PermissionType[][HttpMethod] permissions; 85 86 /// Boolean for the default permission access. 87 public static __gshared bool defaultPermission; 88 89 /// The default permissions for http methods. 90 private static __gshared PermissionType[] defaultPermissions = []; 91 92 /** 93 * Unrequires a permission for a http method. 94 * Params: 95 * method = The method. 96 * permission = The permission. 97 */ 98 void unrequirePermissionMethod(HttpMethod method, PermissionType permission) 99 { 100 import std.algorithm : filter; 101 import std.array : array; 102 103 permissions[method] = permissions[method].filter!(p => p != permission).array; 104 } 105 106 /** 107 * Requires a permission for a http method. 108 * Params: 109 * method = The method. 110 * permission = The permission. 111 */ 112 void requirePermissionMethod(HttpMethod method, PermissionType permission) 113 { 114 permissions[method] ~= permission; 115 } 116 117 /** 118 * Checks whether a specific role has access with a specific method's permissions on a resource. 119 * Params: 120 * role = The role. 121 * method = The method. 122 * resourcce = The resource. 123 * Returns: 124 * Returns true if the role has access, false otherwise. 125 */ 126 bool hasAccess(Role role, HttpMethod method, string resource) 127 { 128 bool access = true; 129 auto accessPermissions = permissions.get(method, defaultPermissions); 130 131 foreach (permission; accessPermissions) 132 { 133 if (!role.hasPermission(resource, permission)) 134 { 135 access = false; 136 break; 137 } 138 } 139 140 return access; 141 } 142 }