You need to sign in to do that
Don't have an account?
Ian Robertson.ax927
How to determine Record Level access of the current user?
I am struggling with determining whether the current user has Edit or Read Only rights on a record. In this case its an opportunity.
I check if the User has a sharing record. As the Owner or someone who has been manually/APEX shared with, they will have a sharing record.
I check if they have elevated rights using our own custom permission model.
I want to know if the user is also in the hierarchy above the owner, but don't seem to be able to code against the role hierarchy. The only option I have found is to try an edit on the opportunity, and revert it back. Its the last step if they don't have edit rights by other means. It means 2 updates which I believe are unnecessary and ineloquent. I check if the update fails for the reason they only have READ ONLY rights. It could fail for other reasons such as validation rules, but that doesnt mean they dont have edit rights, it means they didnt complete the form properly.
The function below determines how a VF component on the Opportunity page layout behaves. If they have edit rights on the opportunity they see one thing, if they dont they see something else. This logic should work as the page loads and not when a user clicks a button on the opportunity.
Below is my function.
private boolean bCanBeEdited()
{
boolean edit = false;
try
{
//Get a list of Users/Groups that the Opportunity is shared with, limited by opp id and the users ID.
List<OpportunityShare> SharedWith = [Select o.id, o.UserOrGroupId, o.RowCause, o.OpportunityAccessLevel From OpportunityShare o where o.UserOrGroupId = :UserInfo.getUserId() AND o.OpportunityId = :oppId];
edit = (!opp.Revenue_From_Order__c && SharedWith.Size() > 0); //Allow edit if the check box is not checked (as before) and the user has a share on the Opportunity.
edit = (edit || SecurityFunctions.hasPrivilege(SecurityFunctions.CanEditOpportunityRevenue)); // Allow Edit if they are an owner or SysAdmin
system.debug('##########1 Edit: ' + edit);
if(!edit)
{
string temp = opp.Name;
system.debug('################1 Opp Name: ' + opp.name);
opp.name = opp.Name + 'Edit';
system.debug('################2 Opp Name: ' + opp.name);
update opp;
system.debug('################3 Opp Name: ' + opp.name);
opp.name = temp;
system.debug('################4 Opp Name: ' + opp.name);
update opp;
system.debug('################5 Opp Name: ' + opp.name);
edit = true;
}
}
catch (System.DmlException DMLEx)
{
if(StatusCode.INSUFFICIENT_ACCESS_OR_READONLY == DMLEx.getDmlType(0))
{
system.debug('##########Exception - Edit Rights: None');
edit = false;
}
else
{
system.debug('##########Exception - Another Exception');
edit = true;
}
system.debug('##########2 Edit: ' + edit);
return (edit || SecurityFunctions.hasPrivilege(SecurityFunctions.CanEditOpportunityRevenue)); // Allow Edit if they are an owner or SysAdmin
}
system.debug('##########2 Edit: ' + edit);
return (edit || SecurityFunctions.hasPrivilege(SecurityFunctions.CanEditOpportunityRevenue)); // Allow Edit if they are an owner or SysAdmin
}
Have you tried using the 'isAccessible' and 'isCreatable'' methods of Schema.DescribeFieldResult?
Yes, it is saying the user has general access to update records in the opportunity table. It doesn't mean he/she can update all of them or any given one in particular.
About the best you can do today is check describe like this then see if the user is the owner, then see if there is a share record for this user and the access. There is no efficient way to evaluate the user's role hierarchy access or if he/she is the member of a group share via an implicit association, i.e. member of a group that is part of another group, etc. There is another factor that can determine editability and that's if the record has been locked by an approval process which you also can't determine programmatically unfortunately. Locking supersedes ownership and sharing access but administrators can still edit even if the record is locked.
For now the only way to truly know if the user can edit a record is to try and catch the exception. I would do something benign that doesn't need a compensating reset like setting a field to be the same as it was before or incrementing a number field that is reserved for this purpose. The thing you can't fix is lastmodifieddate/by and of course this requires burning a dml request.
Sorry there isn't a better answer today. I spent some time looking on the ideaexchange to see if anyone had submitted these but didn't see them. I recommend creating an idea for what you are looking for, describe the use case a bit and add a pointer to that idea in a comment on this thread.
Regards
Promote the following idea:
API call for checing [sic] user access level for a record
See also this post by BudVieira.