+ Start a Discussion
Paul Dyson.ax812Paul Dyson.ax812 

How to test whether a user has rights to edit a record or not?

With/without sharing allows us to write controllers and other classes that respect the sharing rules which is absolutely brilliant. But suppose we want to test whether a user has read or write permissions (example below)? There appears to be nothing in Apex which allows us to do that. We can query the CustomObject__Share table but that only gives us access to the raw sharing data: if a user has directly had a record shared with them their user Id will appear in the sharing table. But what if the user is a member of a group that has had the record shared with them. Or what if the user is in a sub-role of a role in the hierarchy that has had the record shared with 'Role and Subordinates'.

 

Clearly, with enough time and effort we could write something that crawls over the entire hierarchy of users, groups and roles and figures out which users a record has been shared in and whether the current user is in that list. But that's non-trivial and I can't believe no-one else has faced this problem before. Is their and Apex class or part of the API we're missing that does this (or at least helps to do this)? Is their a codeshare or other type of project that does some or all of this? Are we the only people facing this question?

 

The concrete example is that we want to determine whether a user is allowed to perform an action or not based on whether they have just read or read/write permissions on a record that isn't directly related to the action. So we have something called a Research Library which describes a set of Research, and Research Documents which relate to the Research Library. We only want people to be able to create Research Documents related to the Library if they have Read/Write permissions on the library record and not if they only have read (its easy if the library is not shared with them as they don't see it at all). Creating a Research Document doesn't alter the Library record at all so we can't catch a permissions exception and, besides, we don't want to offer the ability to create a Research Document if the user only has read permission for the library ... not tell them after they've entered a load of data that they never had permission to do so.

 

Any help gratefully received!

Starz26Starz26

Describe reults will allow you to do this at an object level.

 

So if they can see the record using with sharing then they have access to the record. Use the to determine if they have write access.

 

private Static Boolean[] canEdit(){
        
        Boolean[] aResults = New Boolean[]{};
    
        aResults.add(Account.SObjectType.getDescribe().isUpdateable());
        

        return aResults;
    
    }

 

Starz26Starz26

or field level:

 

 

private Static Boolean[] canEditField(String obj, String[] fields){
    
    Boolean[] aResults = New Boolean[]{};    
    

    Map<String, Schema.SObjectField> M= Schema.getGlobalDescribe().get(obj).getDescribe().fields.getMap();

        for(String field : fields){

            if(m.containsKey(field))
                aResults.add(m.get(field).getDescribe().isUpdateable());
        }
        

        return aResults;
    
    }

 

Paul Dyson.ax812Paul Dyson.ax812

Unfortunately both of these are answers to a different question. We understand how to check for object- and field-level permissions. What we're asking about here is record sharing and how to test whether the user has permission to just read or to write the record based on manual sharing and sharing rules.

Starz26Starz26

Maybe I am confused, probably.....

 

If you use with sharing in the class, then the record will not be returned for that user.

 

1. If you know the ID of the library record query for it, if no rows are returned, user cannot see it (no read or read/write).

2. If user only has read access and no read write to the record, then I believe you will have to set a savepoint, attempt to update, if an error no write access, if no error, in the finally block, rollback, and set flag that user can write.....

 

 

craigmhcraigmh

Yeah, there are no methods to test record-level security, so you have to attempt the work to see if it's possible.

Paul Dyson.ax812Paul Dyson.ax812

Well indeed and we've pretty much cracked it ... we'll release as a code share once we're happy with it.