Skip to content

Instantly share code, notes, and snippets.

@gbutt
Created February 8, 2020 15:57
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save gbutt/db81dd3e5e7a9b26b8ab34dc69d4ce5f to your computer and use it in GitHub Desktop.
Save gbutt/db81dd3e5e7a9b26b8ab34dc69d4ce5f to your computer and use it in GitHub Desktop.
Grant Permission Set or Permission Set Group to Users in Batch Apex
/**
* Assigns a permission set or permission set group to all user with the specified profile.
* Additional filter criteria can be passed in if the users needs filtered further.
* Example: Only assign permission set to community users on the Salesforce account
* String filter = 'Contact.Account.Name = \'Salesforce\'';
* BatchGrantPermissionSet('Community User Profile', 'Salesforce_Account_Privs', filter);
*/
public class BatchGrantPermissionSet implements Database.Batchable<sObject> {
String query {get; set;}
Profile targetProfile {get; set;}
PermissionSet targetPermSet {get; set;}
PermissionSetGroup targetPermSetGroup {get; set;}
Id targetProfileId { get { return targetProfile.Id; } }
Id targetPermSetId { get { return targetPermSet.Id; } }
Id targetPermSetGroupId { get { return targetPermSetGroup.Id; } }
public static void schedule(String profileName, String permSetName) {
BatchGrantPermissionSet batch = new BatchGrantPermissionSet(profileName, permSetName);
Database.executeBatch(batch, 200);
}
public BatchGrantPermissionSet(String profileName, String permSetName) {
if (String.isBlank(profileName)) {
throw new GeneralException('profileName is required');
}
if (String.isBlank(permSetName)) {
throw new GeneralException('permSetName is required');
}
this.query = 'SELECT Id FROM User ' +
' WHERE IsActive = true AND ProfileId = :targetProfileId ';
this.targetProfile = [SELECT Id, Name FROM Profile WHERE Name = :profileName];
PermissionSet[] permSets = [SELECT Id, Name FROM PermissionSet WHERE Name = :permSetName];
if (permSets.size() > 0) {
this.targetPermSet = permSets[0];
this.query += ' AND Id NOT IN (SELECT AssigneeId FROM PermissionSetAssignment WHERE PermissionSetId = :targetPermSetId)';
} else {
this.targetPermSetGroup = [SELECT Id, DeveloperName FROM PermissionSetGroup WHERE DeveloperName = :permSetName];
this.query += ' AND Id NOT IN (SELECT AssigneeId FROM PermissionSetAssignment WHERE PermissionSetGroupId = :targetPermSetGroupId)';
}
}
public BatchGrantPermissionSet(String targetProfileName, String permSetName, String filter) {
this(targetProfileName, permSetName);
//Build out user query
this.query += 'AND (' + filter + ')';
}
public Database.QueryLocator start(Database.BatchableContext BC) {
return Database.getQueryLocator(query);
}
public void execute(Database.BatchableContext BC, List<sObject> scope) {
List<PermissionSetAssignment> psaList = new List<PermissionSetAssignment>();
for (User u : (List<User>)scope) {
PermissionSetAssignment psa = new PermissionSetAssignment(
AssigneeId = u.Id
);
if (targetPermSet != null) {
psa.PermissionSetId = targetPermSet.Id;
} else {
psa.PermissionSetGroupId = targetPermSetGroup.Id;
}
psaList.add(psa);
}
//Insert Permission Set Assignments
if (psaList.size() > 0) {
insert psaList;
}
}
public void finish(Database.BatchableContext BC) {
}
}
@isTest(IsParallel=false)
private class BatchGrantPermissionSetTest {
public static Integer year = System.today().year() + 1;
public static String CRON_EXP = '0 0 0 22 9 ? ' + year;
@TestSetup
static void setupTestData() {
Id profileid = [select id from profile where Name = 'System Administrator'][0].id;
PermissionSet ps = new PermissionSet(Name = 'Support_Community', Label = 'Support Community Access');
insert ps;
PermissionSetGroup psg = new PermissionSetGroup(DeveloperName = 'Test_Group', MasterLabel = 'Test Group');
insert psg;
List<User> users = new List<User>();
for (Integer i =0; i < 10; i++) {
User u = TestFactory.buildAdminUser('admin' + i + '@example.com', 'admin@example.com');
users.add(u);
}
insert users;
}
@isTest
static void it_should_assign_permissionset() {
Test.startTest();
BatchGrantPermissionSet b = new BatchGrantPermissionSet('System Administrator', 'Support_Community');
Id batchId = Database.executeBatch(b);
Test.stopTest();
//then - test sys admin users should have the permission set
List<PermissionSetAssignment> psa = [
SELECT Id
FROM PermissionSetAssignment
WHERE AssigneeId IN(SELECT Id FROM User WHERE Email = 'admin@example.com')
AND PermissionSet.Name = 'Support_Community'
];
System.assertEquals(10, psa.size(), 'Permission set should be assigned to the user.');
}
@isTest
static void it_should_assign_permissionsetgroup() {
Test.startTest();
BatchGrantPermissionSet.schedule('System Administrator', 'Test_Group');
Test.stopTest();
//then - test sys admin users should have the permission set
List<PermissionSetAssignment> psa = [
SELECT Id
FROM PermissionSetAssignment
WHERE AssigneeId IN(SELECT Id FROM User WHERE Email = 'admin@example.com')
AND PermissionSetGroup.DeveloperName = 'Test_Group'
];
System.assertEquals(10, psa.size(), 'Permission set should be assigned to the user.');
}
@isTest
static void it_should_add_filter() {
User adminUser = [SELECT Username FROM User WHERE Email = 'admin@example.com' LIMIT 1];
Test.startTest();
BatchGrantPermissionSet b = new BatchGrantPermissionSet('System Administrator', 'Support_Community', 'Id = \'' + adminUser.Id + '\'');
Id batchId = Database.executeBatch(b);
Test.stopTest();
//then - test sys admin users should have the permission set
List<PermissionSetAssignment> psa = [
SELECT Id
FROM PermissionSetAssignment
WHERE AssigneeId IN(SELECT Id FROM User WHERE Email = 'admin@example.com')
AND PermissionSet.Name = 'Support_Community'
];
System.assertEquals(1, psa.size(), 'Permission set should be assigned to the user.');
}
@isTest
static void it_should_throw_error_when_perm_set_is_fake() {
QueryException caught;
try {
new BatchGrantPermissionSet('System Administrator', 'Never Going to be Real');
} catch (QueryException ex) {
caught = ex;
}
System.assertNotEquals(null, caught);
}
@isTest
static void it_should_throw_error_when_profile_is_fake() {
QueryException caught;
try {
new BatchGrantPermissionSet('Fake Profile', 'Support_Community');
} catch (QueryException ex) {
caught = ex;
}
System.assertNotEquals(null, caught);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment