[SalesForce] Document: You don’t have permission to share this file

I am trying to upload a file from salesforce sites into Files and then relate it with a record using VF page.

i am able to upload the file and while creating a ContentDocumentLink i am getting this error.

Document: You don't have permission to share this file.

insert file; 
                    ContentVersion cv = [SELECT id, ContentDocumentId FROM ContentVersion where Id = :file.Id];
                    ContentDocumentLink link = new ContentDocumentLink();
                    link.LinkedEntityId = sr.id; // this is record i want the file to be related to 
                    link.ContentDocumentId = cv.contentdocumentid;
                    link.ShareType = 'V';
                    link.Visibility = 'AllUsers';
                    insert link;

Since the user who uploads the file is a site guest user, i am assuming thats the reason why i am getting this error.

Is there a way we can allow creation of ContentDocumentLink for site guest user? What i want is a way to associate the uploaded file with a record

Best Answer

Make sure that your guest site users has sharing record access to the entity the file is being shared with. I did a POC with a visualforce page exposed to public site and the guest user was able to create an account and upload a file to it without error.

Apex Controller

public class UploadDocumentDemoController {

// placeholder to upload files from visualforce page with
public Attachment file { get; set; }

public UploadDocumentDemoController() {
    this.file = new Attachment();
}

public void save() {

    System.debug( 'Saving document' );

    System.debug( file );

    // for proof of concept, will create one account for testing purposes
    // and each time we submit the form to upload file we don't create more and more accounts
    ID accountId = null;
    List<Account> accounts = [ SELECT id FROM Account WHERE name = :UserInfo.getUserId() LIMIT 1 ];
    if ( accounts.size() == 0 ) {
        Account acct = new Account(
            name = UserInfo.getUserId()
        );
        insert acct;
        accountId = acct.id;
    } else {
        accountId = accounts[0].id;
    }

    // create the chatter file
    ContentVersion cv = new ContentVersion(
        versionData = file.body,
        title = file.name,
        pathOnClient = '/' + file.name
    );

    insert cv;

    // look up the content document id
    cv = [ SELECT id, ownerId, contentDocumentId FROM ContentVersion WHERE id = :cv.id ];

    // link the document to the account
    ContentDocumentLink cdl = new ContentDocumentLink(
        linkedEntityId = accountId,
        contentDocumentId = cv.contentDocumentId,
        shareType = 'V',
        visibility = 'AllUsers'
    );

    insert cdl;

}

}

Visualforce Page

<apex:page controller="UploadDocumentDemoController" cache="false">

<apex:form>

    <apex:pageBlock>

        <apex:pageBlockButtons>
            <apex:commandButton action="{!save}" value="Upload"/>
        </apex:pageBlockButtons>

        <apex:pageBlockSection columns="1">
            <apex:inputFile value="{!file.body}" fileName="{!file.name}"/>
        </apex:pageBlockSection>

    </apex:pageBlock>

</apex:form>