· tutorials · 4 min read
How to Prevent Users Deleting Files in Salesforce
Learn how to prevent specific users from deleting files in Salesforce.
Salesforce has very granulated permissions that can control almost every aspect of a user’s experience. Unfortunately, the ability to prevent file deletion is not on that list. Users have been asking for this feature since 2008. It is possible to prohibit users from uploading and deleting files. But, to prevent users from deleting files, we need to put in place some apex code.
Requirements
You will need Enterprise edition or more to put in place this in Salesforce.
Creating a Custom Permission
Salesforce’s robust permission structure can be extended. We can create our own custom permissions. To do so:
- Go to
Setup
->Custom Permission
- Create a custom permission called
Delete Files
Additionally, we need a way to assign this to end users. With Salesforce sun-setting profiles in Spring ‘26, we should use permission sets to assign to users.
To assign the custom permission, perform the following:
- Create a permission set
Delete Files
. - Add the custom permission to the permission set
- Assign to desired Users
Prevent Users From Deleting Files In Salesforce
Now it’s time to create the apex code that will prevent file deletion. The code will
- Run every time a file
ContentDocument
is being deleted - Check if the current user has the
Delete Files
permission - If so, the file will be deleted.
- If not, the file will not be deleted, and an error will ocurr.
We need to create a few classes to perform these tasks. This is to keep the code organized inside of Salesforce. First, we want to create an Apex class ContentDocumentException
public class ContentDocumentException extends Exception {}
This will allow us to throw a custom exception (error) when the end user does not have the required permissions.
Next, we want to create a class ContentDocumentTriggerHandler
public class ContentDocumentTriggerHandler {
public static void beforeDeleteTriggerHandler(
List<ContentDocument> contentDocumentList
) {
if (!FeatureManagement.checkPermission('Delete_Files')) {
throw new ContentDocumentException(
'Cannot Delete File without the Delete Files Permission'
);
}
}
}
This class will hold all the logic to see if a file is deleted.
Finally, we want to run this code every time a file is delete. We can do so by creating the trigger, ContentDocumentTrigger
:
trigger ContentDocumentTrigger on ContentDocument(before delete) {
if (Trigger.isBefore && Trigger.isDelete) {ContentDocumentTriggerHandler.beforeDeleteTriggerHandler(Trigger.old);
}
}
Testing The Apex Code
To push this code to production, we need a test class that get’s at least 75% code coverage. To test this code, we can use the following class ContentDocumentTriggerTest
@isTest
public class ContentDocumentTriggerTest {
@isTest(seeAllData=false)
static void testDeleteWithPermission() {
Profile p = [SELECT Id FROM Profile WHERE Name = 'Standard User'];
User u1 = new User(
Alias = 'newUser',
Email = '[email protected]',
EmailEncodingKey = 'UTF-8',
LastName = 'Testing',
LanguageLocaleKey = 'en_US',
LocaleSidKey = 'en_US',
ProfileId = p.Id,
TimeZoneSidKey = 'America/Los_Angeles',
UserName = '[email protected]'
);
String message;
System.runAs(u1) {
try {
ContentVersion contentVersion = new ContentVersion(
Title = 'Test',
PathOnClient = 'test.jpg',
VersionData = Blob.valueOf('Test Content'),
IsMajorVersion = true
);
insert contentVersion;
List<ContentDocument> documents = [
SELECT Id, Title, LatestPublishedVersionId
FROM ContentDocument
];
delete documents;
} catch (Exception e) {
message = e.getMessage();
}
system.assert(
message.contains(
'Cannot Delete File without the Delete Files Permission'
) != null
);
}
}
@isTest(seeAllData=false)
static void testDeleteWithoutPermission() {
Profile p = [SELECT Id FROM Profile WHERE Name = 'Standard User'];
User u1 = new User(
Alias = 'newUser',
Email = '[email protected]',
EmailEncodingKey = 'UTF-8',
LastName = 'Testing',
LanguageLocaleKey = 'en_US',
LocaleSidKey = 'en_US',
ProfileId = p.Id,
TimeZoneSidKey = 'America/Los_Angeles',
UserName = '[email protected]'
);
insert u1;
PermissionSet ps = [
SELECT Id
FROM PermissionSet
WHERE Name = 'Delete_Files'
];
PermissionSetAssignment psa = new PermissionSetAssignment(
AssigneeId = u1.Id,
PermissionSetId = ps.Id
);
insert psa;
String message;
System.runAs(u1) {
ContentVersion contentVersion = new ContentVersion(
Title = 'Test',
PathOnClient = 'Test.jpg',
VersionData = Blob.valueOf('Test Content'),
IsMajorVersion = true
);
insert contentVersion;
List<ContentDocument> documents = [
SELECT Id, Title, LatestPublishedVersionId
FROM ContentDocument
];
try {
delete documents;
} catch (ContentVersionException e) {
message = e.getMessage();
}
system.assertEquals(
null,
message,
'User w/o custom permission should not be able to delete files'
);
}
}
}
Each method will:
- Run as a new user.
- Create a new file.
- Attempt to delete the file.
Keep in mind that you may need to change the username to a unique value to get this working in your organization.
Conclusion
Salesforce does not have a native way of preventing file deletion. We can use Apex code and custom permissions to put in place file deletion ourselves.
Need Our Help To Get Your Data Into Salesforce?
Join dozens of other companies by learning how you can get all your company's data in one place.