Skip to content

Commit

Permalink
Merge pull request #1508 from SFDO-Community/feature/1507-change-cust…
Browse files Browse the repository at this point in the history
…om-permission-check
  • Loading branch information
aheber authored Nov 25, 2024
2 parents 2ed442e + 9961585 commit 7a40051
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 16 deletions.
18 changes: 15 additions & 3 deletions dlrs/main/classes/RollupCalculateJobTest.cls
Original file line number Diff line number Diff line change
Expand Up @@ -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<SetupEntityAccess> permSetsWithAccess = [
SELECT ParentId
SELECT ParentId, SetupEntityId
FROM SetupEntityAccess
WHERE
SetupEntityId IN (
Expand All @@ -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<PermissionSetAssignment> assignments = [
SELECT Id
Expand Down Expand Up @@ -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,
Expand All @@ -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();
Expand Down
21 changes: 18 additions & 3 deletions dlrs/main/classes/RollupJobTest.cls
Original file line number Diff line number Diff line change
Expand Up @@ -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<SetupEntityAccess> permSetsWithAccess = [
SELECT ParentId
SELECT ParentId, SetupEntityId
FROM SetupEntityAccess
WHERE
SetupEntityId IN (
Expand All @@ -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<PermissionSetAssignment> assignments = [
SELECT Id
Expand Down Expand Up @@ -211,7 +223,7 @@ private class RollupJobTest {
CalculationMode__c = 'Realtime',
AggregateAllRows__c = false,
Active__c = true,
BypassPermissionApiName__c = 'DisableDLRS'
BypassPermissionApiName__c = permName
);

RollupSummariesSelector.setRollupCache(
Expand Down Expand Up @@ -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();
Expand Down
50 changes: 49 additions & 1 deletion dlrs/main/classes/Utilities.cls
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
**/

public class Utilities {
static Set<String> permsHeldByUser;

/**
* Get the namespace of this package
**/
Expand Down Expand Up @@ -90,19 +92,65 @@ 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<String> 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;
}
}

return false;
}

private static Set<String> getUserCustomPerms() {
if (permsHeldByUser == null) {
permsHeldByUser = new Set<String>();
// 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<Id> customPermIds = new List<Id>();
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<String>{ 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)
Expand Down
58 changes: 49 additions & 9 deletions dlrs/main/classes/UtilitiesTest.cls
Original file line number Diff line number Diff line change
Expand Up @@ -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<SetupEntityAccess> 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<PermissionSetAssignment> 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')
// );
}
}

0 comments on commit 7a40051

Please sign in to comment.