function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Sten EbenauSten Ebenau 

database.merge can be executed without delete rights

HI Everyone, 

I'm testing something and it noticed that i was able to merge accounts, contact and leads via Apex even when the users executing these statements doesn't have delete rights. 

The Salesforce documentation is pretty clear on this, you need Delete rights. 

I've created my own test page to show this. 

Apex Code
public with sharing class aMerge {
    public pageReference doMergeLead() {

        Lead l1 = new Lead(Company = 'Test', LastName = 'Test', FirstName = 'Test');
        Lead l2 = new Lead(Company = 'Test', LastName = 'Test', FirstName = 'Test');
        
        insert l1;
        insert l2;
        
        merge l1 l2;
        
        return null;
    }
    
    public pageReference doMergeAccount() {
        
        Account l1 = new Account(Name = 'Test');
        Account l2 = new Account(Name = 'Test');
        
        insert l1;
        insert l2;
        
        merge l1 l2;
        
        return null;
    }
    
    public pageReference doMergeContact() {
        
        Account a1 = new Account(Name = 'Test');
        insert a1;
        
        Contact l1 = new Contact(AccountId = a1.Id, LastName = 'Test', FirstName = 'Test');
        Contact l2 = new Contact(AccountId = a1.Id, LastName = 'Test', FirstName = 'Test');
        
        insert l1;
        insert l2;
        
        merge l1 l2;
        
        return null;
    }

}

Visualforce page
<apex:page controller="aMerge">
    <apex:form >
    
    
    <br/>
    
    <table width="100%" border="1">
        <thead>
        <tr>
            <th>#</th>
            <th>Lead</th>
            <th>Account</th>
            <th>Contact</th>
        </tr>
        </thead>
        
        <tr>
            <td>Read</td>
            <td>{!$ObjectType.Lead.accessible}</td>
            <td>{!$ObjectType.Account.accessible}</td>
            <td>{!$ObjectType.Contact.accessible}</td>
        </tr>
        <tr>
            <td>Create</td>
            <td>{!$ObjectType.Lead.createable}</td>
            <td>{!$ObjectType.Account.createable}</td>
            <td>{!$ObjectType.Contact.createable}</td>
        </tr>
        <tr>
            <td>Delete</td>
            <td>{!$ObjectType.Lead.deletable}</td>
            <td>{!$ObjectType.Account.deletable}</td>
            <td>{!$ObjectType.Contact.deletable}</td>
        </tr>
        <tr>
            <td>Merge</td>
            <td>{!$ObjectType.Lead.mergeable}</td>
            <td>{!$ObjectType.Account.mergeable}</td>
            <td>{!$ObjectType.Contact.mergeable}</td>
        </tr>
        <tr>
            <td>Undelete</td>
            <td>{!$ObjectType.Lead.undeletable}</td>
            <td>{!$ObjectType.Account.undeletable}</td>
            <td>{!$ObjectType.Contact.undeletable}</td>
        </tr>
        <tr>
            <td>Update</td>
            <td>{!$ObjectType.Lead.updateable}</td>
            <td>{!$ObjectType.Account.updateable}</td>
            <td>{!$ObjectType.Contact.updateable}</td>
        </tr>
        <tr>
            <td>Test</td>
            <td><apex:commandButton action="{!doMergeLead}" value="test"/></td>
            <td><apex:commandButton action="{!doMergeAccount}" value="test"/></td>
            <td><apex:commandButton action="{!doMergeContact}" value="test"/></td>
        </tr>
        
        
        
        
        
    </table>
    
    </apex:form>
    
</apex:page>


Test Screen Shot
User-added image


In the screenshot you can see that my user doesn't have delete rights on all three objects. However when i execute the test button it creates two records and merges them afterwards without any issue. 

When i try to open the Salesforce Merge UI i directly see the error message that i'm not allowed to merge these records. 

So my question; did i hit a security bug or is the database.merge function not sticking to the security controls?

Thansk,
Sten








 

@Karanraj@Karanraj
Stean,

The custom controller code will run in system mode on the standard controller visualforce page will run in the user mode.The "with sharing" keyword will enforce the sharing rule settings not the profile level permission(CRUD). to enforce all those permission you have to check before you are inserting or deleting the record in your controller class code.

Check this link for more details to enforce CRUD and FLS permission in the custom controller code.  https://developer.salesforce.com/page/Enforcing_CRUD_and_FLS