Pages

Saturday, November 8, 2014

Query User Record Access in Salesforce

Few months back, I wrote a blog to determine user record Access in Salesforce, that blog is good for admin to debug if a user not able to access or edit record. While this blog will explain how to check user accessibility to a record using query.

Use case for this functionality, such as: for a visualforce page, when user do not have edit access, Edit button will be automatically removed from the page, when user do not have read access, link to open the record automatically removed.

From API version 24, Salesforce introduce a new object called UserRecordAccess. This object represents a user’s access to a set of records. It is also only for query, not for create / delete / update / upsert. The query method also a little special compare to other standard object, you have to follow specific rule to query it:
  1. RecordId - must be selected in for query result
  2. RecordId - must be in query criteria, for RecordId you can use "=" for single record OR use "IN" to query multiple records
  3. UserId - must be in query criteria, but NOT in query result
  4. Id - you cannot query this field
  5. MaxAccessLevel value: None, Read, Edit, Delete, Transfer, All
Sample query:
SELECT RecordId, MaxAccessLevel, HasAllAccess, HasDeleteAccess, HasEditAccess, HasReadAccess, HasTransferAccess FROM UserRecordAccess where UserId = '00550000000rlrX' and RecordId IN ('0015000000TaWdI','0065000000N1CMz')

Query result:
So, one query is only for one user for up to 200 record id.

From API version 30.0 and later, UserRecordAccess is a foreign key on the records. You can’t filter by provide the UserId or RecordId fields when using this object as a lookup or foreign key.

Sample Query:
SELECT Id, Name, UserRecordAccess.HasReadAccess, UserRecordAccess.HasTransferAccess,
UserRecordAccess.MaxAccessLevel FROM Opportunity

Above query will return all Opportunity with record access for each record based on the running user. 

You can add normal filter criteria applied when you query Opportunity, sample:
SELECT Id, Name, UserRecordAccess.HasReadAccess, UserRecordAccess.HasTransferAccess,
UserRecordAccess.MaxAccessLevel FROM Opportunity WHERE Id = '0065000000N1CMz'


Known Issue: When accessing UserRecordAccess as foreign key of records, unexpected results are given. This issue does not occur when accessing to UserRecordAccess directly. Here is the detail
https://success.salesforce.com/issues_view?id=a1p30000000T4NxAAK, if you would like to be notified when issue solved, click 'This Issue Affects Me' link.


ReferenceUserRecordAccess