Skip to main content
If you do a SOQL query for a single UserRecordAccess record, you get the correct values. But if you query for multiple UserRecordAccess records in a single query, the values returned are often incorrect (for instance the HasAllAccess value may be true when it should be false).

This problem makes it impossible for us to reliably communicate object permissions to our users.

This is nearly identical to the following issues that was marked as fixed back in the Winter 15 release: https://success.salesforce.com/issues_view?id=a1p30000000T4iiAAC

Below is a test class I wrote that reproduces the issue.  In this test class I use the Macro sobject, but the problem applies to other objects as well.  I first noticed it on a custom object.

@isTest

public without sharing class UserRecordAccessTest {

private static testMethod void test(){

//Create the users that will own the records

final User[] users = createStandardUsers(2);

final User u1 = users[0];

final User u2 = users[1];

//Create the records, each owned by a different user

final SObject o1 = createRecord(u1.Id);

final SObject o2 = createRecord(u2.Id);

insert new SObject[]{o1, o2};

system.runAs(u1){

//Query for each UserRecordAccess entry individually

final UserRecordAccess access1 = queryForSingleUserRecordAccess(u1.Id, o1.Id);

final UserRecordAccess access2 = queryForSingleUserRecordAccess(u1.Id, o2.Id);

//Query for both UserRecordAccess entries at the same time

final UserRecordAccess[] accessList = queryForUserRecordAccesses(u1.Id, new Set<Id>{o1.Id, o2.Id});

//The UserRecordAccess entries should have the same values, regardless of how they were queried

compareUserRecordAccesses(access1, accessList[0]);//This fails because the HasAllAccess value is false for the entry queried individually, but is true for the entry queried in a list

compareUserRecordAccesses(access2, accessList[1]);

}

}

private static UserRecordAccess queryForSingleUserRecordAccess(final Id userId, final Id recordId){

return [

SELECT RecordId, HasReadAccess, HasEditAccess, HasDeleteAccess, HasTransferAccess, HasAllAccess

FROM UserRecordAccess

WHERE UserId = :userId AND RecordId = :recordId

];

}

private static UserRecordAccess[] queryForUserRecordAccesses(final Id userId, final Set<Id> recordIds){

return [

SELECT RecordId, HasReadAccess, HasEditAccess, HasDeleteAccess, HasTransferAccess, HasAllAccess

FROM UserRecordAccess

WHERE UserId = :userId AND RecordId IN :recordIds

ORDER BY RecordId

];

}

private static void compareUserRecordAccesses(final UserRecordAccess expected, final UserRecordAccess actual){

system.assertEquals(expected.RecordId, actual.RecordId);

system.assertEquals(expected.HasReadAccess, actual.HasReadAccess);

system.assertEquals(expected.HasEditAccess, actual.HasEditAccess);

system.assertEquals(expected.HasDeleteAccess, actual.HasDeleteAccess);

system.assertEquals(expected.HasTransferAccess, actual.HasTransferAccess);

system.assertEquals(expected.HasAllAccess, actual.HasAllAccess);

}

private static User[] createStandardUsers(final Integer count){

final Profile standardUser = [SELECT Id FROM Profile WHERE Name = 'Standard User'];

final User[] users = new User[]{};

for(Integer i = 0; i < count; i++){

users.add(new User(

UserName = 'test' + i + '@userrecordaccesstest.com',

LastName = 'Smith',

Email = 'test@user.com',

Alias = 'test',

CommunityNickname = 'test' + i,

TimeZoneSidKey = 'America/Indiana/Indianapolis',

LocaleSidKey = 'en_US',

EmailEncodingKey = 'UTF-8',

LanguageLocaleKey = 'en_US',

ProfileId = standardUser.Id

));

}

insert users;

return users;

}

private static SObject createRecord(final Id ownerId){

return new Macro(Name = 'Macro' + ownerId, OwnerId = ownerId);

}

}

 
4 Antworten
  1. 6. Sept. 2018, 20:01
    I have seen the problem on some of the other HasXAccess fields as well.
0/9000