4

I have a global class (without sharing). One of its method is a @RemoteAction, which instantiate another class (public and without sharing) and uses one method of the instantiated class. This method tries to modify some field on an object.

Since "with sharing" is not written in the declaration of both classes I'd expect that the code is executed without considering the current user. Nonetheless an error is thrown because the current user doesn't have the permissions to do the modification.

Can you please help me understand what is going on :)?

Thank you very much, T.

EDIT: I've created a simple class to test the following strange behavior, the remote action of the "global class" throws permission error, while the normal action.. doesn't! The behavior of the normal action apparently is different from the remote one with respect to the "default/with sharing/without sharing".

If, as suggested, the token "without sharing" is added to the global class then both normal and remote method works.

    //
    // create an opportunity o with a user, then run this class with a user which has no
    // permissions to write on o
    // the behavior of remote action and normal action is different if there is no 
    // "without sharing" token
    //

`global class controllerTestSharing{`

    public opportunity o {get;set;}
    public controllerTestSharing(){
        o = [select name,description from opportunity where id =: ApexPAges.currentPage().getParameters().get('oppId')];    
    }

    global void normaleUpdate(){
        update o;
    }

    @remoteAction
    global static string remoteUpdate(string oppId,string descr){
        opportunity o = new opportunity(id=oppId,description=descr);
        try{
            update o;
        }catch(exception e){ return e.getMessage(); }
        return 'ok';
    }

}
  • I've also noticed this behavior. It seems that @RemoteAction methods observe sharing rules by default unless without sharing is specified, while the standard for non-remoting methods is to run in system context. – geeljire Dec 2 '13 at 14:51
4

The standard behaviour is "with sharing", and if you don't want this you need to declare the class "without sharing". If a class is not declared as either with or without sharing, the current sharing rules remain in effect. This means that if the class is called by a class that has sharing enforced, then sharing is enforced for the called class.

In API releases up to 29, if a @RemoteAction method was called on a class that didn’t explicitly declare with sharing or without sharing, the method ran as though the class was declared with sharing. In other words, the default behavior was different for methods depending on whether they were invoked as part of a standard Visualforce request or a JavaScript remoting request. This wasn’t intended behavior.

Beginning with API 30.0, requests execute consistently, regardless of how the class is declared, or how the method is invoked:

  • By default, without a sharing declaration, the method operates in
    system mode, as though the class was declared without sharing.

  • Methods in classes declared without sharing operate in system mode.

  • Methods in classes declared with sharing respect the user’s organization-wide defaults, role hierarchy, and sharing rules.

Refer to http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_keywords_sharing.htm

  • thanks for the fast reply, I am trying immediately to add the "without sharing" to the controller! I still think it's peculiar, because nor the global controller, nor the public instantiated class had "with or without sharing", they were just plain "global class" and "public class" – T. Rossi May 8 '13 at 14:31
  • Yes, but by default it will run in system context (access to all fields) and "with sharing" - respecting the users record access. You need to explicitly state "without sharing" if you want it to access all records. – Doug B May 8 '13 at 14:58
  • 1
    thanks, yes now it works! apparently though remote actions have a different behavior to normal actions. If I use a normal action, "without sharing" is not needed for the action to accomplish (??!) – T. Rossi May 8 '13 at 15:14
  • Perhaps, you should clarify if @RemoteAction methods are different than other methods in this regard which seems to be the main question. – geeljire Dec 2 '13 at 14:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.