-
Notifications
You must be signed in to change notification settings - Fork 458
CanTheUser
A reusable, intuitive library for determining wether or not the
current use can create, read, edit, or delete objects as well as
determining if the user has access or update permissions on specific fields.
This class name was chosen to facilitate easy-to-understand and read code.
Whenever you need to check FLS or CRUD access your code reads like this
if(CanTheUser.read(new account())){}
making the calling and use of this
code easy and intuitive.
Group Security Recipes
TESTVISIBLE
private static accessibleFieldsByObject
Map<String,Set<String>>
TESTVISIBLE
private static updatableFieldsByObject
Map<String,Set<String>>
public static Boolean crud(SObject obj, CrudType permission)
Name | Type | Description |
---|---|---|
obj | SObject | the object type to check |
permission | CrudType | create, read, update or delete |
Boolean
System.debug(CanTheUser.crud(new Account(), CanTheUser.CrudType.READ));
TESTVISIBLE
private static Boolean crud(List<SObject> objs, CrudType permission)
Name | Type | Description |
---|---|---|
objs | List<SObject> | |
permission | CrudType |
Boolean
TESTVISIBLE
private static Boolean crud(String objectName, CrudType permission)
Name | Type | Description |
---|---|---|
objectName | String | |
permission | CrudType |
Boolean
convenience api for determining if the running user can create the specified object
public static Boolean create(SObject obj)
Name | Type | Description |
---|---|---|
obj | SObject | Object type to check create permissions on |
Boolean
System.debug(CanTheUser.create(new Account()));
convenience api for determining if the running user can create the specified object
public static Boolean create(List<SObject> objs)
Name | Type | Description |
---|---|---|
objs | List<SObject> | list of objects. Only the first will be checked. (logically, a list is of uniform type |
and, and if the user can create one) |
Boolean
convenience api for determining if the running user can create the specified object
public static Boolean create(String objName)
Name | Type | Description |
---|---|---|
objName | String |
Boolean
System.debug(CanTheUser.create('Account'));
convenience api for determining if the running user can read / access the specified object
public static Boolean read(SObject obj)
Name | Type | Description |
---|---|---|
obj | SObject | object type to check read permissions on |
Boolean
System.debug(CanTheUser.read(new Account()));
convenience api for determining if the running user can read / access the specified objects
public static Boolean read(List<SObject> objs)
Name | Type | Description |
---|---|---|
objs | List<SObject> |
Boolean
convenience api for determining if the running user can read the specified object
public static Boolean read(String objName)
Name | Type | Description |
---|---|---|
objName | String |
Boolean
System.debug(CanTheUser.read('Account'));
convenience api for determining if the running user can edit / update the specified object
public static Boolean edit(SObject obj)
Name | Type | Description |
---|---|---|
obj | SObject | object type to check edit permissions on |
Boolean
System.debug(CanTheUser.edit(new Account()));
convenience api for determining if the running user can edit / update the specified objects
public static Boolean edit(List<SObject> objs)
Name | Type | Description |
---|---|---|
objs | List<SObject> |
Boolean
convenience api for determining if the running user can edit the specified object
public static Boolean edit(String objName)
Name | Type | Description |
---|---|---|
objName | String |
Boolean
System.debug(CanTheUser.edit('Account'));
convenience api for determining if the running user can upsert (insert and update) the specified objects
public static Boolean ups(SObject obj)
Name | Type | Description |
---|---|---|
obj | SObject | object type to check edit permissions on |
Boolean
System.debug(CanTheUser.ups(new Account()));
convenience api for determining if the running user can edit / update the specified objects
public static Boolean ups(List<SObject> objs)
Name | Type | Description |
---|---|---|
objs | List<SObject> |
Boolean
convenience api for determining if the running user can upsert the specified object
public static Boolean ups(String objName)
Name | Type | Description |
---|---|---|
objName | String |
Boolean
System.debug(CanTheUser.ups('Account'));
convenience api for determining if the running user can delete/destroy the specified object
public static Boolean destroy(SObject obj)
Name | Type | Description |
---|---|---|
obj | SObject | object type to check destroy permissions on |
Boolean
System.debug(CanTheUser.destroy(new Account()));
convenience api for determining if the running user can delete the specified object
public static Boolean destroy(List<SObject> objs)
Name | Type | Description |
---|---|---|
objs | List<SObject> |
Boolean
convenience api for determining if the running user can delete the specified object
public static Boolean destroy(String objName)
Name | Type | Description |
---|---|---|
objName | String |
Boolean
System.debug(CanTheUser.destroy('Account'));
public method to determine if a given field on a given object is Accessible (readable)
public static Boolean flsAccessible(String obj, String field)
Name | Type | Description |
---|---|---|
obj | String | the object in question, in string form |
field | String | the field in question in SObjectField form |
Boolean
System.debug(CanTheUser.flsAccessible('Account', 'Name'));
bulk form of flsAccessible
public static Map<String,Boolean> bulkFLSAccessible(String obj, Set<String> fields)
Name | Type | Description |
---|---|---|
obj | String | Obj name on which to check |
fields | Set<String> | Set of Fields to check for accessibility. |
Map<String,Boolean>
String[] fields = new String[]{'Name', 'ShippingStreet'};
System.debug(CanTheUser.bulkFLSAccessible('Account', fields));
public method to determine if a given field on a given object is Updatable.
public static Boolean flsUpdatable(String obj, String field)
Name | Type | Description |
---|---|---|
obj | String | the string version of an object name |
field | String | the field to check |
Boolean
System.debug(CanTheUser.flsUpdatable('Account', 'Name'));
bulk form of flsUpdatable call
public static Map<String,Boolean> bulkFLSUpdatable(String obj, Set<String> fields)
Name | Type | Description |
---|---|---|
obj | String | Name of the object |
fields | Set<String> | Set of Field names to check |
Map<String,Boolean>
String[] fields = new String[]{'Name', 'ShippingStreet'};
System.debug(CanTheUser.bulkFLSUpdatable('Account', fields));
SUPPRESSWARNINGS
TESTVISIBLE
Utilizes the Metadata catalog to determine FLS
Note: this method contains a false-positive PMD violation. Normally, we'd want to check for FLS/CRUD here, but for metadata catalog objects that admins cannot remove permissions to we're ok.
Additionally, even the minimum access profile user has read access to the FieldPermissions object.
private static Set<String> memoizeFLSMDC(String objType, FLSType action)
Name | Type | Description |
---|---|---|
objType | String | String version of the object type to check |
action | FLSType | Enum of the FLS action to check permissions for |
Set<String>
Abstracted method for retrieving or calculating (memoization) of the FLS for a given field on a given object.
private static Boolean getFLSForFieldOnObject(String obj, String field, FLSType checkType)
Name | Type | Description |
---|---|---|
obj | String | String version of object name to check |
field | String | String version of the field to check |
checkType | FLSType | Enum of Accessible or Updatable. |
Boolean
Internal custom exception class
this cachebuilder interface allows the CanTheUser class to cache per-object results for each object requested. This prevents the need to repeatedly calculate permission usage by calling Schema.Describe* calls
Implements
Cache.CacheBuilder
Required method for the CacheBuilder interface. Used here to either calculate an objects per-user FLS, OR to return it from Cache. The return datastructure for this is Map<String, Map<FLSType,Boolean>> and represents: FieldName -> FLStype -> True/False
public Object doLoad(String objType)
Name | Type | Description |
---|---|---|
objType | String | String object name used as the cache key |
Object
Calculates the FLS for a given object type
public Map<String,Map<FLSType,Boolean>> calculateFLS(string objType)
Name | Type | Description |
---|---|---|
objType | string | String name of the object type |
Map<String,Map<FLSType,Boolean>>
Value | Description |
---|---|
CREATE | |
READ | |
EDIT | |
DEL | |
UPS |
Value | Description |
---|---|
ACCESSIBLE | |
UPDATABLE |