0

I've got a force.com public site that is accessible without user login via guest user.

For some strange reason, this site works 100% when it is inserting a record alone, but throws an error when inserting 2 objects of which is a master-detail relationship.

I added a DML Exception statement to show error messages instead of authentication required, but it is still throwing an error through catch.

What I know:

  • Commenting out anotherPerson.dog__c = dog.Id; it works. This line of code is the problem.
  • Person records insert successfully when the parent record dog is not assigned suggesting the problem could be with the master-detail relationship assignment
  • My constructor is empty, so the issue is not DML statement in a constructor
  • All permissions enabled for objects and fields in question via public access settings
  • This page works successfully when accessing from my org, but not via a force.com site/externally

Any help on this issue would be greatly appreciated

Apex controller Created random objects dog and person to replicate this issue in my production org

 public with sharing class ContactCreateController {

  // Initalize person, dog, and list
  public Person__c person {
    get {
      if (person == null)
        person = new person__c();
      return person;
    }
    set;
  }
    
    public Dog__c dog {
        get {
            if(dog == null)
               dog = new dog__c();
            return dog;
        }
        set;
    }
  
    public List<person__c> allcontacts {
        get {
            if (allcontacts == null)
                allcontacts = new List<person__c>();
            return allcontacts;
        }
        set;
    }

  public ContactCreateController() {
    // blank constructor
  }
    //Adds record to the list
    public PageReference add_person(){
        Person__c anotherPerson = new person__c();
        anotherPerson.Name = person.Name;
        //Insert dog record before assigning as parent of person
        upsert dog;
        //Assign dog as parent of person
        anotherPerson.Dog__c = dog.Id;
        
        allcontacts.add(anotherPerson);
        person = new person__c();
        return null;
    }
    
  
  // save button is clicked
  public PageReference save() {
  
    try {
      upsert allcontacts; // inserts the new record into the database


  //Throw an exception if try doesn't work        
    } catch (DMLException e) {
      ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,'Error creating new contact.'));
      return null;
    }
    
    
    return null;
  }

}

VF Markup

    <apex:page controller="ContactCreateController">
  <apex:sectionHeader title="Hello Dog" subtitle="Create a Person"/>

  <apex:form >
    <apex:pageMessages /> <!-- this is where the error messages will appear -->
      
      <apex:pageBlock>
      <apex:pageBlockSection>
          <apex:inputField value="{!dog.Name}"/>
      </apex:pageBlockSection>
      </apex:pageBlock>
      
      <apex:pageBlock >
      <apex:pageBlockSection showHeader="false" columns="2">
        <apex:inputField value="{!person.Name}" />
      </apex:pageBlockSection>
      <apex:pageBlockButtons >
        <apex:commandButton action="{!add_person}" value="Add Person"/>
      </apex:pageBlockButtons>
      </apex:pageBlock>
      
      <!--List-->
    <apex:pageBlock >
    <apex:pageBlockTable id="people" value="{!allcontacts}" var="person">
        
        <apex:column headervalue="Name" value="{!person.Name}"/> 
        <!--Submit button-->
    </apex:pageBlockTable>
      <apex:pageBlockButtons >
        <apex:commandButton action="{!save}" value="Save"/>
      </apex:pageBlockButtons>
    </apex:pageBlock>
  </apex:form>
</apex:page>

1 Answer 1

1

Probably the guest user sharing changes. The moment you have finished inserting the Dog, guest user no longer has sharing access to it. Setting it as a parent record will throw insufficient access on cross-reference.

You could add guest user sharing rules, or you could put the DML into a without sharing context. Really up to the business requirements.

Mainly you just have to ensure that whatever method you use to open up security here, there is nothing a guest user can do to retrieve data they should not be entitled to see.

8
  • Edit: Sharing rules may not work for this case since we want to grant access to records that the user is creating but in a sharing rule I need to specific the name of the record. Will try without sharing Oct 6, 2020 at 18:06
  • It works! Thank you. You've saved me a client demo lol Oct 6, 2020 at 18:26
  • Wait. Uncommented the assignment. Still returns an error with the without sharing class :( Oct 6, 2020 at 19:13
  • What is the actual error thrown? You can get it by doing a debug log trace on the Guest User while they do this.
    – Charles T
    Oct 6, 2020 at 19:14
  • I've added guest user for my site in the User Trace Flag - how can I view the logs? Oct 6, 2020 at 21:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .