I was looking for a little help to find all users with a particular Custom Permission
assigned to them, either via Profile
or Permission Set
.
-
Apart from Adrian's answer here is a good apex class example to look at : github.com/john-brock/Custom-Permissions/blob/master/classes/…– Mukesh VermaCommented Aug 27, 2016 at 18:19
-
@MukeshVerma It's not entirely straightforward how to change direction when you get so many inner-joins involved. Interesting class though.– Adrian Larson ♦Commented Aug 27, 2016 at 18:38
-
Yes @Adrian Larson I understand the complexity. May be it would be good to vote for this idea success.salesforce.com/ideaView?id=08730000000DiLXAA0– Mukesh VermaCommented Aug 27, 2016 at 18:48
-
@MukeshVerma I had found that class and was using it as a reference but was struggling to adapt it. Others may find it helpful; That's a good addition.– Austin RussellCommented Aug 27, 2016 at 18:49
-
@MukeshVerma Both of those links are focused on permissions for a single user, which actually is not what is being asked here.– Adrian Larson ♦Commented Aug 27, 2016 at 18:52
1 Answer
Update
Please note that for the running user, you can use the FeatureManagement
class:
Boolean isEnabled = FeatureManagement.checkPermission('My_Permission_Api_Name');
Surprisingly, I don't think you can do it more simply than the below.
Execution
public static List<User> getUsersWithCustomPermission(String name)
{
Set<Id> permissionSetIds = new Set<Id>();
for (SetupEntityAccess access : [
SELECT ParentId
FROM SetupEntityAccess
WHERE SetupEntityId IN (
SELECT Id
FROM CustomPermission
WHERE DeveloperName = :name
)
]) {
permissionSetIds.add(access.ParentId);
}
return permissionSetIds.isEmpty() ? new List<User>() : [
SELECT Username FROM User WHERE Id IN (
SELECT AssigneeId FROM PermissionSetAssignment
WHERE PermissionSetId IN :permissionSetIds
)
];
}
Explanation
At the end of the day, you need to hit four separate tables to make this work.
CustomPermission
SetupEntityAccess
(adds the CustomPermission to a PermissionSet)PermissionSet
PermissionSetAssignment
You can reduce your queries consumed to two by using inner-joins.
EDIT
It was mentioned in the comments that you may want to filter for namespace. To do so, I would modify the above join on CustomPermission
as below:
SELECT Id
FROM CustomPermission
WHERE DeveloperName = :name
AND NamespacePrefix = null
You could also use overloads at the method level:
public static List<User> getUsersWithCustomPermission(String name)
{
return getUsersWithCustomPermission(name, null);
}
public static List<User> getUsersWithCustomPermission(String name, String namespacePrefix)
{
// use modified queries
}
-
1I was somewhere in the ball Park but was not quite getting the SOQL Correct. You did an excellent Job of laying out the procedure. Thank you Commented Aug 27, 2016 at 18:45
-
1@Scott as to your comment in the edit history, the ternary is so you don't consume a second query when you know there will be no results.– Adrian Larson ♦Commented May 24, 2017 at 13:37
-
-
You should probably filter by namespace in this query, as well. Commented Aug 14, 2019 at 19:51
-