Reply
Regular Contributor
AT-Greg
Posts: 86
0

Incorrect "UserOrGroupId" in share object for criteria-based sharing on custom object

Hello.

 

I have a custom object, called "Deal__c", that has it's default sharing access set to private. I have a number of criteria-based sharing rules on that object, and they are properly sharing the records to the appropriate groups specified in the criteria sharing rules.

 

My problem lies when I query the "Deal__Share" object to programmatically obtain the groups that have been shared to via criteria sharing. In the code sample below, I'm querying the Deal__Share object for all of the sharing rules applied to a specific record. I'm using Workbench for this testing, but I'm getting identical results when querying through Apex:

 

SELECT AccessLevel,Id,ParentId,RowCause,UserOrGroupId FROM Deal__Share WHERE ParentId='<deal_id_here>'

This particular record has four shares returned: two are manual shares, and two criteria-based. For the two manual shares, the UserOrGroupId shows the correct user/group that has been shared to. But, for the two that are criteria-based, it's not showing the correct Id for the groups that have been shared via criteria sharing. In fact, I don't know what IDs it's returning, because when I attempt to view those Ids from within Salesforce, I'm returned an "Insufficient Priveleges" page. I'm logged in as the system administrator, so priveleges shouldn't be an issue.

 

Any insight or help is greatly appreciated. Thank you.

 

-Greg

 

 

 

Super Contributor
sfdcfox
Posts: 3,892
0

Re: Incorrect "UserOrGroupId" in share object for criteria-based sharing on custom object

Examine the "key prefix" (the first three characters). Groups will be "00G...", and you can't view those directly. Instead, you would query for them (select ... from group ...) or you can view them in Setup (Setup > Manage Users > Public Groups and/or Setup > My Personal Information > My Groups). Note that you may not have access to a group, if the group is (a) private, and (b) not owned by you; this scenario can only be remedied by logging in as the user that owns the group. You cannot access private groups even as an administrator otherwise.

~ sfdcfox ~


I am a sandwich. That is all.

Regular Contributor
AT-Greg
Posts: 86
0

Re: Incorrect "UserOrGroupId" in share object for criteria-based sharing on custom object

Hi sfdcfox, and thanks for the reply.

 

I'm not sure I'm understanding, though. What do you mean that I can't view them directly and that I should query for them from the Group object? Do you mean groups shared via criteria-based sharing only? In my scenario, I own all of the public groups that would be shared via criteria sharing.

 

I do see the "00G" prefix on the 2 groups that are criteria-shared, but I also see it on another group that was shared manually. I can obtain the group members for the manually shared group (by querying the Deal__Share object for the UserOrGroupId, then by querying the GroupMember object) , but not the members of the groups shared via criteria sharing.

 

Thanks.

 

-Greg

 

Super Contributor
sfdcfox
Posts: 3,892
0

Re: Incorrect "UserOrGroupId" in share object for criteria-based sharing on custom object

That's odd. You should be able to query group members for criteria sharing entries the same as any other.

~ sfdcfox ~


I am a sandwich. That is all.

Regular Contributor
AT-Greg
Posts: 86
0

Re: Incorrect "UserOrGroupId" in share object for criteria-based sharing on custom object

I've managed to find a solution to this, but I don't quite understand why and was hoping if someone could shed some light. Below is my solution (not bulkified yet, just POC) for obtaining the list of users that have access to a custom object record due to criteria based sharing:

 

		// First, determine the users that have access to the deal. This is accomplished by
		// looking at the Title_Deal__Share object for the deal to see what public groups have
		// been shared through criteria-based sharing. Then, get the user for each person in
		// the group. 
		List<Title_Deal__Share> listShares = new List<Title_Deal__Share>();
		listShares = [SELECT Id,UserOrGroupId FROM Title_Deal__Share WHERE ParentId=:currentDeal.Id AND IsDeleted=false AND RowCause='Rule'];

		// Convert the list of shares to just a list of userorgroupids
		List<Id> listShareIds = new List<Id>();
		for (Title_Deal__Share s : listShares) {
			listShareIds.add(s.UserOrGroupId);			
		}

		// retrieve the list of group members that belong to each of thse groups.
		// Odd behavior here - need to query UserOrGroupId instead of GroupId.
		List<GroupMember> listGroupMembers = new List<GroupMember>();
		listGroupMembers = [SELECT Id,GroupId,UserOrGroupId FROM GroupMember WHERE GroupId IN :listShareIds];

		// Convert the list of groupmembers to just a list of group IDs
		List<Id> listGroupIds = new List<Id>();
		for (GroupMember g : listGroupMembers) {
			listGroupIds.add(g.UserOrGroupId);			
		}

		// Now, need to requery GroupMember with the UserOrGroupId as the ID, to get the user Ids
		List<GroupMember> newGroupMemberList = new List<GroupMember>();
		newGroupMemberList = [SELECT Id,GroupId,UserOrGroupId FROM GroupMember WHERE GroupId IN :listGroupIds];
		List<Id> listUserIds = new List<Id>();
		for (GroupMember g : newGroupMemberList) {
			listUserIds.add(g.UserOrGroupId);
		}

		// Finally, get the list of users.
		List<User> commUsers = new List<User>();
		commUsers = [SELECT Id,FirstName,LastName FROM User WHERE Id IN :listUserIds];

 Specifically, I don't understand why I first have to query the GroupMember object twice. If anyone has experienced this, has an explanation, or a simpler way of doing it, it would be appreciated.

 

Thanks.

 

-Greg