I have an apex class that is declared 'without sharing'. This class does some background processing and as a part of that processing, determines whether or not record owners have access to other records. This is accomplished by querying the UserRecordAccess object and filtering on RecordId and UserId (this is not the running user by instead different record owners from the system).
When I run controller as a System Administrator, I get the expected results (results from the UserRecordAccess query with values in MaxAccessLevel). However, when I run the controller as a user with limited record access, queries to UserRecordAccess for any records that the running user does not have access to simply return no results. I see there is a line in the documentation for the object that says:
SOQL restrictions for API version 29.0 and earlier:
When the running user is querying a user's access to a set of records, records that the running user does not have read access to are
filtered out of the results.
I am using API version 35 for my class so I would expect to get results back even when the current running user does not have read access to the record in question (I can query for that record without issue because I am in a 'without sharing' context). Am I missing something here for why I cannot get UserRecordAccess records? This seems like a bug to me since the purpose of the UserRecordAccess object is to be able to check access levels for a user that is not the current running user.
** EDIT – Additional findings **
I have discovered an additional detail for this problem. If the current user does not have access to a record, the user can get their own UserRecordAccess, but not for a different user. This is still a problem because I am trying to answer the question 'Does the record owner for this record have access to another record?'. The record owner is frequently not the running user.
** EDIT – Gist **
Here is a link to a gist for the basic controller/page I am using when I see these results: https://gist.github.com/dsharrison/b0b03c661bf65fc18348.
Thanks for any insight,
D.S.
Best Answer
This could be related to sharing changes on the User Object that happened with API 34.
If you didn't explicitly declare it as
without sharing
, this behavior would be expected. From the docs:But, as you say you've explicitly declared your class as
without sharing
, that wouldn't seem to be the only issue involved. But, as you say you did, the below would apply:So, that would seem to leave possibilities like these:
Might it be possible that the problematic code in question is called from an inner class? If so, that code wouldn't be
without sharing
unless it too, was defined as beingwithout sharing
. Alternatively, is thewithout sharing
class calling another class that'swith sharing
for providing the final interface? Those would seem to be two scenarios that could be the cause of your issues.