• steve.stogner
  • NEWBIE
  • 0 Points
  • Member since 2012

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 0
    Questions
  • 6
    Replies

I want to know what level of CRUD access the current user has on a particular record.   In other words, can this user read, update and/or delete this record.  On the surface this seems like it should be simple using Apex.  However I'm at a loss.

 

This is particularly painful because the UI gives me the answer.  Go to a Record Detail page, click Sharing, click Expand List.  Voila!   A complete list of users that have access to that record, and what that access is.

 

So what's the best way to achieve this programmatically?

 

At least 3 things to consider:

 

1) Profile Permissions.  This part is simple.  The sObject's various Describe Result methods tell me whether a User's Profile permits him to read (isAccessible()) or update  (isUpdatable()) or delete (isDeletable()) records of this object type.   This is a top-level check.  It doesn't address this particular record, just records of this type.

 

2) Record ownership.  If 1) is satisfied, and the current user is the owner of this particular record, all CRUD operations should be available

 

3) Managed and Manual Sharing.  **Here's where I'm having trouble.**  Is there a simple way to discover if this record is shared with this user and with what level of access? The sharing information for a record can be found by querying its equivalent Share object (AccountShare is the sharing object for the Account object).  But if a sharing rule is defined on a Role (or Role plus subordinates), you cannot see all users given access by that rule!   As far as I can tell, you must:

 

  a) query the Share object's userOrGroupId column

  b) figure out if that Id is a User, Group or Role

  c) If it's a Role, query the groups table to find all users in that role

  d) If it's a Role, use recursive logic to find all users above that role in the role heirarchy

  e) If it's a Role and the sharing applies to this Role *and subordinates*, use recursive logic to find all users subordinate to that role in the role heirarchy

 

Isn't there a simpler way?

 

 

 

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
    }

 

Is there a way to determine the record level access (view/edit) for a user? (Note: this is record level not object level)

 

The code will be running under a single user and for every record we need to determine which users in Salesforce have view and which users have edit access to the record.

 

Thanks! 

 

  • March 24, 2010
  • Like
  • 0
Is it possible to determine whether the current user has delete permissions (aka Full Access) for a particular record (custom object), without actually attempting to delete the record?

I'm creating some custom actions using VF/apex, and for some of them I want to limit who can perform the action to the same users who can delete the record.  The action does not involve deleting the record, but I want it to be more restrictive than who can perform an edit.

I looked into the sharing table (object_share) but that only lists the owner as Full Access.  Since anyone above the owner in the role hierarchy also has full access, and the hierarchy might be several levels tall, it seems like a tall order for my code to walk the entire hierarchy and determine if that applies.  Is there an easier way?

Thanks much!
  • August 04, 2008
  • Like
  • 0