diff --git a/dlrs/main/classes/RollupCalculateJobTest.cls b/dlrs/main/classes/RollupCalculateJobTest.cls index a0840f31..d125b95c 100644 --- a/dlrs/main/classes/RollupCalculateJobTest.cls +++ b/dlrs/main/classes/RollupCalculateJobTest.cls @@ -189,7 +189,7 @@ private class RollupCalculateJobTest { static void testRunBatchWithCustPermDisable() { // find the profile that has access to the Custom Permission we want to use to check (if it even exists in the system) List permSetsWithAccess = [ - SELECT ParentId + SELECT ParentId, SetupEntityId FROM SetupEntityAccess WHERE SetupEntityId IN ( @@ -202,6 +202,18 @@ private class RollupCalculateJobTest { if (permSetsWithAccess.isEmpty()) { return; // this org doesn't have the necessary metadata to test this feature } + + CustomPermission perm = [ + SELECT DeveloperName, NamespacePrefix + FROM CustomPermission + WHERE Id = :permSetsWithAccess[0].SetupEntityId + ]; + + String permName = perm.DeveloperName; + if (String.isNotBlank(perm.NamespacePrefix)) { + permName = perm.NamespacePrefix + '__' + perm.DeveloperName; + } + // see if the running user already has that permission set List assignments = [ SELECT Id @@ -236,7 +248,7 @@ private class RollupCalculateJobTest { CalculationMode__c = 'Realtime', AggregateAllRows__c = false, Active__c = true, - BypassPermissionApiName__c = 'DisableDLRS' + BypassPermissionApiName__c = permName ); RollupSummariesSelector.setRollupCache( false, @@ -251,7 +263,7 @@ private class RollupCalculateJobTest { String jobId; System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); - Assert.isTrue(FeatureManagement.checkPermission('DisableDLRS')); + Assert.isTrue(FeatureManagement.checkPermission(permName)); // go into runAs because we need to get the perms recalculated jobId = Database.executeBatch(job); Test.stopTest(); diff --git a/dlrs/main/classes/RollupJobTest.cls b/dlrs/main/classes/RollupJobTest.cls index b59f1b0b..a24f730b 100644 --- a/dlrs/main/classes/RollupJobTest.cls +++ b/dlrs/main/classes/RollupJobTest.cls @@ -165,7 +165,7 @@ private class RollupJobTest { static void testDisabledSpecificRollupRunJob() { // find the profile that has access to the Custom Permission we want to use to check (if it even exists in the system) List permSetsWithAccess = [ - SELECT ParentId + SELECT ParentId, SetupEntityId FROM SetupEntityAccess WHERE SetupEntityId IN ( @@ -178,6 +178,18 @@ private class RollupJobTest { if (permSetsWithAccess.isEmpty()) { return; // this org doesn't have the necessary metadata to test this feature } + + CustomPermission perm = [ + SELECT DeveloperName, NamespacePrefix + FROM CustomPermission + WHERE Id = :permSetsWithAccess[0].SetupEntityId + ]; + + String permName = perm.DeveloperName; + if (String.isNotBlank(perm.NamespacePrefix)) { + permName = perm.NamespacePrefix + '__' + perm.DeveloperName; + } + // see if the running user already has that permission set List assignments = [ SELECT Id @@ -211,7 +223,7 @@ private class RollupJobTest { CalculationMode__c = 'Realtime', AggregateAllRows__c = false, Active__c = true, - BypassPermissionApiName__c = 'DisableDLRS' + BypassPermissionApiName__c = permName ); RollupSummariesSelector.setRollupCache( @@ -241,7 +253,10 @@ private class RollupJobTest { String jobId; System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); - Assert.isTrue(FeatureManagement.checkPermission('DisableDLRS')); + Assert.isTrue( + FeatureManagement.checkPermission(permName), + 'Expected user to have the ' + permName + ' permission set' + ); // go into runAs because we need to get the perms recalculated jobId = Database.executeBatch(new RollupJob()); Test.stopTest(); diff --git a/dlrs/main/classes/Utilities.cls b/dlrs/main/classes/Utilities.cls index 16a23cf3..3c23defd 100644 --- a/dlrs/main/classes/Utilities.cls +++ b/dlrs/main/classes/Utilities.cls @@ -25,6 +25,8 @@ **/ public class Utilities { + static Set permsHeldByUser; + /** * Get the namespace of this package **/ @@ -90,12 +92,15 @@ public class Utilities { * returns `true` if user has any of those custom permissions */ public static Boolean userHasCustomPermission(String permissionNames) { + // early out to avoid performance overhead, most rollups probably don't need to check perms if (String.isBlank(permissionNames)) { return false; } + Set userPerms = getUserCustomPerms(); for (String permName : permissionNames.split(',')) { - if (FeatureManagement.checkPermission(permName.trim())) { + // match lowercase because the index was built lowercase + if (userPerms.contains(permName.trim().toLowerCase())) { return true; } } @@ -103,6 +108,49 @@ public class Utilities { return false; } + private static Set getUserCustomPerms() { + if (permsHeldByUser == null) { + permsHeldByUser = new Set(); + // need to init the list of perms held by the user + + // Get the list of CustomPermission Ids that the user has access to + // this respects Perm Sets, Perm Set Groups, and Profiles + List customPermIds = new List(); + for (SetupEntityAccess entity : [ + SELECT SetupEntityId + FROM SetupEntityAccess + WHERE + SetupEntityType = 'CustomPermission' + AND ParentId IN ( + SELECT PermissionSetId + FROM PermissionSetAssignment + WHERE AssigneeId = :UserInfo.getUserId() + ) + ]) { + customPermIds.add(entity.SetupEntityId); + } + // resolve the Custom Permission Id into string names + for (CustomPermission perm : [ + SELECT Id, DeveloperName, NamespacePrefix + FROM CustomPermission + WHERE Id IN :customPermIds + ]) { + String permName = perm.DeveloperName; + if (String.isNotBlank(perm.NamespacePrefix)) { + // if this has a namespace prefix we should build a unified string + permName = String.format( + '{0}__{1}', + new List{ perm.NamespacePrefix, permName } + ); + } + // normalize to lowercase for matching purposes + permsHeldByUser.add(permName.toLowerCase()); + } + } + + return permsHeldByUser; + } + // Regular expression for Order By Clause // Case-Insensitive pattern // Group 1 - Field Name (required) diff --git a/dlrs/main/classes/UtilitiesTest.cls b/dlrs/main/classes/UtilitiesTest.cls index 9f47be43..0daf47c0 100644 --- a/dlrs/main/classes/UtilitiesTest.cls +++ b/dlrs/main/classes/UtilitiesTest.cls @@ -2,20 +2,60 @@ public class UtilitiesTest { @IsTest static void testUserHasCustomPermission() { + // find the permission set that has access to the Custom Permission we want to use to check (if it even exists in the system) + List permSetsWithAccess = [ + SELECT ParentId, SetupEntityId + FROM SetupEntityAccess + WHERE + SetupEntityId IN ( + SELECT Id + FROM CustomPermission + WHERE DeveloperName = 'DisableDLRS' + ) + AND Parent.IsOwnedByProfile = FALSE + ]; + if (!permSetsWithAccess.isEmpty()) { + CustomPermission perm = [ + SELECT DeveloperName, NamespacePrefix + FROM CustomPermission + WHERE Id = :permSetsWithAccess[0].SetupEntityId + ]; + // there is a compatible permission set that we can use for testing + // see if the running user already has that permission set + List assignments = [ + SELECT Id + FROM PermissionSetAssignment + WHERE + AssigneeId = :UserInfo.getUserId() + AND PermissionSetId = :permSetsWithAccess[0].ParentId + ]; + if (assignments.isEmpty()) { + // user doesn't have the necessary perm set to grant it to them, add it + System.runAs(new User(Id = UserInfo.getUserId())) { + insert new PermissionSetAssignment( + AssigneeId = UserInfo.getUserId(), + PermissionSetId = permSetsWithAccess[0].ParentId + ); + } + } + // make sure the utility can see the perm set correctly + // (we do it here because any earlier and the utility would have built the cache already) + String permName = perm.DeveloperName; + if (String.isNotBlank(perm.NamespacePrefix)) { + permName = perm.NamespacePrefix + '__' + perm.DeveloperName; + } + Assert.areEqual( + true, + Utilities.userHasCustomPermission(permName), + 'Expected user to have ' + permName + ); + } + Assert.areEqual(false, Utilities.userHasCustomPermission(null)); Assert.areEqual(false, Utilities.userHasCustomPermission('madeup_name')); Assert.areEqual( false, Utilities.userHasCustomPermission('madeup_name,name2 , name3,name4') ); - // TODO: add custom perm and perm set assigned to working user for tests but not add to package - // Assert.areEqual( - // true, - // Utilities.userHasCustomPermission('DLRSLimitedDisable') - // ); - // Assert.areEqual( - // true, - // Utilities.userHasCustomPermission('rollup1, DLRSLimitedDisable ,rollup2') - // ); } }