14 January 2013

Using SOQL to Determine Your Force.com User’s Permissions


I often get the following question from administrators, “now that a user can have multiple permission sets in addition to their profile, how can I tell what permissions they have?”

It makes sense, after all: a user’s permissions determines their right to do almost anything in an org. For compliance and troubleshooting reasons, it’s important to be able to track down why a user has a certain access right and correct it if need be.

Summer ’12 introduces the ability to answer this question using the permission set API. We’ve created a new field on the PermissionSet SObject called IsOwnedByProfile. This field determines whether a permission set is a custom one or if it is parented by a profile. This is made possible because for every profile, there is one underlying permission set. That way, permissions layer equally across permission sets without having to treat a profile differently. In the setup user interface, you only see the profile but in the API, you can see both the profile and the underlying permission set.

As a result, running the following query in SOQL, for instance in a tool like workbench, will return both permission sets you’ve created and permission sets parented by a profile:

SELECT Id,IsOwnedByProfile,Label
FROM PermissionSet

By adding IsOwnedByProfile to the WHERE clause, you will quickly differentiate between permission sets you’ve created versus those parented by a profile:

SELECT Id,IsOwnedByProfile,Label
FROM PermissionSet
WHERE IsOwnedByProfile = TRUE

Once you have the hang of this, you can start to answer all sorts of questions about your users such as, “which users have Read on Accounts and why”:

SELECT Assignee.Name, PermissionSet.Id, PermissionSet.isOwnedByProfile, PermissionSet.Profile.Name, PermissionSet.Label
FROM PermissionSetAssignment
WHERE PermissionSetId
IN (SELECT ParentId
    FROM ObjectPermissions
    WHERE SObjectType = 'Account' AND
    PermissionsRead = true)

You might need to answer questions about a specific user such as, “what are all of the Account fields where John Doe has at least Read access and why”

SELECT Id, SObjectType, PermissionsRead, Parent.label, Parent.IsOwnedByProfile
FROM ObjectPermissions
WHERE (ParentId
IN (SELECT PermissionSetId
    FROM PermissionSetAssignment
    WHERE Assignee.Name = 'John Doe'))
    AND
   (PermissionsRead = true)
    AND
   (SobjectType = 'Account')

Using permission sets in this way, you can find out why a user has access to an apex page, class or a particular user, object, or field permission, regardless of whether it’s through their profile or permission set.

These SOQL queries are great if you have one off questions about your user’s permissions. If you have a more regular need to query user’s permissions, think about creating a Visualforce page with an Apex controller that uses these queries to find out what your users can do and why.

1 comment:

  1. @Adam The last query, should it not be from FieldPermissions instead?

    ReplyDelete

Note: Only a member of this blog may post a comment.