• James Woodward
  • NEWBIE
  • 30 Points
  • Member since 2015

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 0
    Questions
  • 2
    Replies
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);
	}

}

 
Hello Helpers


by mistake I  started  recursive  batch class  chain

In the batch  finsih()  method  I  inserted a call for the same batch

Now  I  have a  batc running for  half  day  I  can not stop  it

Abor  does  not work If  i try to abort  I  get the be,ow  message
Failed to Abort Job Unable to remove job from Apex Job Queue.

I  need to stop  this  somehow
What  opton I have?

In the specs  I sew  that  "You can submit up to 5,000 batches per rolling 24 hour period."

but  since start my batch run more then 5000 times    


regards
csaba
  • April 20, 2015
  • Like
  • 0