2

I'm getting some issues making my permission set works.

This is the use case. I have:

  1. A custom object with a single field and a button.
  2. Above button call a vf page that shows a button that execute a process
  3. Controller related to above vf page and runJob method that create some records, update them and delete a single record.
  4. A permission set with CRUD access but no ViewAll and ModifyAll checked. It has access to above vf page too.
  5. Object sharing settings are public Write/Read
  6. Grant access using hierarchies false
  7. A user related to a profile that has no access to anything (only custom object tab visibility)
  8. Permission Set is assigned to the user

Having above scenario, admin creates some records and run the job via the button.

If I login as the second user and open a record that was created by the admin, and run the process via the button I get this error:

enter image description here

If I try it manually, Update and Creation is ok, but Delete fails.

If I set ModifyAll value as true in the permission set, then I can execute my process without issues.

Why I cannot delete a record that other user has created? My object is public and the permission set gives me CRUD access. What am I missing?

This is the code just in case you want to reproduce by yourself

Controller public with sharing class A_TestSecurityController { private Id recordId; private ApexPages.StandardController theController;

    public A_TestSecurityController(ApexPages.StandardController controller)
    {
        theController = controller;
        recordId = theController.getId();
    }

    public PageReference runJob()
    {
        try
        {
            List<TestSecurity__c> listToUpdate = new List<TestSecurity__c>();
            for(TestSecurity__c item : [Select Id, Check__c From TestSecurity__c])
            {
                item.Check__c = false;
                listToUpdate.add(item);
            }
            update listToUpdate;

            TestSecurity__c item = [Select Id From TestSecurity__c limit 1];
            delete item;

            List<TestSecurity__c> listToInsert = new List<TestSecurity__c>();
            for(integer i=0; i<3; i++)
            {
                TestSecurity__c newItem = new TestSecurity__c();
                listToInsert.add(newItem);
            }
            insert listToInsert;

            return theController.view();
        }
        catch(Exception ex)
        {
            ApexPages.addMessages(ex);
            return null;
        }
    }
}

Visualforce

<apex:page standardController="TestSecurity__c" extensions="A_TestSecurityController" >
    <apex:form >
        <apex:sectionHeader title="Test Security"/>
        <apex:pageBlock title="Information">
            <apex:pageBlockButtons >
                <apex:commandButton value="Run Job" action="{!runJob}"/>
                <apex:commandButton value="Cancel" action="{!cancel}"/>
            </apex:pageBlockButtons>

            <apex:pageMessages />
            <apex:pageMessage summary="Please confirm you wish to start the job?" severity="info" strength="2" />
        </apex:pageBlock>
    </apex:form>
</apex:page>

Thanks

1

You're missing "full" control of the record.

The levels of control are, in ascending order:

  • None
  • Read
  • Edit
  • Transfer
  • Full

Each level of control implies the additional permissions that are lower than that, unless prohibited by the profile.

Full control can generally only be granted by:

  1. owning the record
  2. being a manager of the owner of the record (if enabled), or
  3. having Modify All Data for that object (included automatically if you have the global Modify All Data permission).

See the Help & Training modules on Sharing for more details, as well as other answers here on the SFSE.

"Full" control is also referred to as "Owner" permissions when viewed in Sharing, but basically just means "Delete", as that is the only additional permission it grants. You can have Transfer independently of Delete on some objects by Sharing Rules or Organization Wide Defaults, and you're also explicitly granted Transfer when a record is owned by a queue you are a member of or is in the same Territory as you with Territory Management and the appropriate settings.

As an exception to granting Full access, the "Financial Edition" of salesforce.com, used by companies like Merrill Lynch, offers the ability to create sharing rules that grant Full access to a record despite not meeting the usual criteria.

  • Thanks for your answer but it confused me a bit as my knowledge on Salesforce security is not really high. I have not modify anything on OWD or some other place, just sharing settings on object and the permission set. But I have a single question. How can I give Transfer access to my record? In any case: can we sum up it? My final understanding is We cannot delete a record that I don't own unless we give ModifyAll right in my permission set if these are the only elements that I have in my scenario. We can go for a, or b on some other use cases. Is that ok? – Agustina García Jun 25 '15 at 10:52
  • @AgustinaGarcía In summary, you can't generally give a user transfer permission on a specific record. Either the user owns the record, is a manager of the owner of the record, or has Modify All Data. There are a few extenuating circumstances, such as by using Territory Management, but that only applies to some types of records, like accounts, and most organizations don't use that feature anyway. It is possible, however, to build custom code that skirts around this. For example, a Visualforce page that runs "without sharing" to change ownership. – sfdcfox Jun 25 '15 at 15:00
  • Clearer now. Thanks a lot. Also I found this article. That also answer my question. help.salesforce.com/… – Agustina García Jun 25 '15 at 15:39

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.