Wednesday, September 17, 2014

Sharing Documents with the SharePoint REST API

Technorati Tags: ,,

Sharing documents is a pretty basic thing in SharePoint. Most  everyone is familiar with the callout action “Share” which enables you to share a document with other people. It is a mainstay of collaboration when working with documents in a team.

However, there is very little documentation on how to do this through the remote API of SharePoint. In this post I will show how you can do this using the REST API and JavaScript. The call has many arguments which can be confusing. The best description I have found for the UpdateDocumentSharingInformation method is here API Description.  Just remember when you are sharing a document you are granting permissions. If you want to use this REST API method in a SharePoint app, then make sure you grant the “Web Manage” permissions in your app manifest. When you click the Share action you are presented a dialog to grant either view or edit permissions to multiple users or roles.

The Code

Below is the REST call using  JavaScript code that shares a document from a SharePoint hosted app.

function shareDocument()
{
var hostweburl = decodeURIComponent(getQueryStringParameter('SPHostUrl'));
var appweburl = decodeURIComponent(getQueryStringParameter('SPAppWebUrl'));
var restSource = appweburl + "/_api/SP.Sharing.DocumentSharingManager.UpdateDocumentSharingInfo";


$.ajax(
{
'url': restSource,
'method': 'POST',
'data': JSON.stringify({
'resourceAddress': 'http://basesmc15/Shared%20Documents/A1210251607172880165.pdf',
'userRoleAssignments': [{
'__metadata': {
'type': 'SP.Sharing.UserRoleAssignment'
},
'Role': 1,
'UserId': 'Chris Tester'
}],
'validateExistingPermissions': false,
'additiveMode': true,
'sendServerManagedNotification': false,
'customMessage': "Please look at the following document",
'includeAnonymousLinksInNotification': false
}),
'headers': {
'accept': 'application/json;odata=verbose',
'content-type': 'application/json;odata=verbose',
'X-RequestDigest': $('#__REQUESTDIGEST').val()
},
'success': function (data) {
var d = data;
},
'error': function (err) {
alert(JSON.stringify(err));
}
}
);

}

The Parameters


ResourceAddress: This is the full URL to the document you want to share


UserRoleAssignments: This an array of users and roles that you want to share the document with. The Role property represents which permission you are assigning. 1 =  View, 2 =  Edit, 3 = Owner, 0 = None. The UserId property can be the name of the user or a role.  For example, if you wanted to share the document with the “Translation Mangers” role and the “Steve Tester” user you would use this JSON:

'userRoleAssignments': [{
'__metadata': {
'type': 'SP.Sharing.UserRoleAssignment'
},
'Role': 1,
'UserId': 'Translation Managers'
},
{
'__metadata': {
'type': 'SP.Sharing.UserRoleAssignment'
},
'Role': 1,
'UserId': 'Steve Tester'
}]

ValidateExistingPermissions: A flag indicating how to honor a requested permission for a user. If this value is "true", SharePoint will not grant the requested permission if a user already has sufficient permissions, and if this value is "false", then SharePoint  will grant the requested permission whether or not a user already has the same or more permissions. This parameter only applies when the additiveMode  parameter is set to true.


AdditiveMode:A flag indicating whether the permission setting uses the additive or strict mode. If this value is "true", the permission setting uses the additive mode, which means that the specified permission will be added to the user’s current list of permissions if it is not there already, and if this value is "false", the permission setting uses the strict mode, which means that the specified permission will replace the user’s current permissions. This parameter is useful when you want to stop sharing a document with a person or group. In this case you would set AdditiveMode to false using the Role = 0.


SendServerManagedNotification: A  flag to indicate whether or not to generate an email notification to each recipient in the userRoleAssignments array after the document update is completed successfully. If this value is "true", then SharePoint will send an email notification if an email server is configured, and if the value is "false", no email notification will be sent.


CustomMessage: A custom message to be sent in the body of the email.


IncludeAnonymousLinksInNotification: A flag that indicates whether or not to include anonymous access links in the email notification to each recipient in the userRoleAssignments array after the document update is completed successfully. If the value is "true", the SharePoint will include an anonymous access link in the email notification, and if the value is "false", no link will be included. This is useful if you are sharing the document with an external user. You must be running this code with full control or as a Site Owner if you want to share the document with external users.


The Results


After calling the above code you will receive a result for every user or role you have shared the document with. The code does not return an error and you must examine the results to determine success. Check the Status property. If this is false typically there will be a message in the Message property explaining the problem. It also tells you whether the user is known. If the user is not known then it is considered an external user.



Resting and Sharing


As you can see there is a lot more to sharing a document versus what is presented in the SharePoint UI. The UpdateDocumentSharingInfo method has many options. You can use this in your custom SharePoint apps to build more robust sharing of documents which could include the option of a custom email message or bulk sharing of documents. This could also be used to stop sharing a document. I have yet to find an easy way to stop sharing a document using the SharePoint UI.

13 comments:

Myrag said...

Hi Steve,

This is great article. Is there a way to do something similar like list item security setup by breaking role inheritance and assigning unique permissions through REST service?

Kind regards,

Marc said...

Hi Steve,
What form of authentication can be used here?
Marc

TheSharePointHelper said...

Great post! Question for you. Where did you find the information that would allow you to learn this? I've searched for REST api file sharing but Microsoft's documents really seem to be lacking. For instance, when I look for information the JSOM method updateDocumentSharingInfo() and I run into this article https://msdn.microsoft.com/en-us/library/office/jj851011.aspx
No information exist on how to use it, just a argument that says "context" But I view the C# article it looks like I get a bit more info about the possible parameters, but I have to assume all the parameters apply to JSOM

Steve Curran said...

I use the SPRemoteAPIExplorer Visual Studio Extension https://visualstudiogallery.msdn.microsoft.com/26a16717-0c9a-4367-8dfd-bb09e7e2deb5. You can read more about his extension on this blog.

TheSharePointHelper said...

I searched everywhere and can't find out how to do this same thing using JSOM and not using REST.

Steve Curran said...

This can be done using JSOM. Post your question on the MSDN Forum and I will see if I can post some code.

TheSharePointHelper said...

Thanks Steve, I'll try the SPRemoteAPIExplorer today. I've posted the JSOM question in this forum:

https://social.msdn.microsoft.com/Forums/office/en-US/d2514d91-ab74-4a08-b21d-6c0aff251232/how-to-share-files-using-the-javascript-object-model?forum=appsforsharepoint#d2514d91-ab74-4a08-b21d-6c0aff251232

Unknown said...

Hi Steve,

We are using the DocumentSharingManager.UpdateDocumentSharingInfo method in a solution we built.

The Problem:
Within the same company, the code works as expected for most of the users, however, for some users we get an error "Access denied. You do not have permission to perform this action or access this resource." when trying to implement Share (Role=1/View, UserID=Everyone). Have you seen this before where it works for some users but not others in the same O365 company account?



var newRoleAssignment = new Microsoft.SharePoint.Client.Sharing.UserRoleAssignment()
{
Role = Microsoft.SharePoint.Client.Sharing.Role.View,
UserId = "Everyone"
};

Microsoft.SharePoint.Client.Sharing.DocumentSharingManager.UpdateDocumentSharingInfo(
clientContext,
file.WebUrl,
new List() {newRoleAssignment},
validateExistingPermissions: true,
additiveMode: true,
sendServerManagedNotification: true,
customMessage: null,
includeAnonymousLinksInNotification: true);
clientContext.ExecuteQuery();

Thanks.

Steve Curran said...

Jason, the user calling this code must have "ManagePermissions" permission. The basically is changing permission on a SharePoint resource so the user calling the code must have this permission.

Unknown said...

Hi,
I am able to share document with external user by using above REST call but they are asking for account login.
How to share doc with the external user by which they can view/edit doc without sign-in by rest api?
Is there any variable I need to add to json body?
Thanks

Anonymous said...

When I try this I'm getting a 403 error saying the security validation for this page is invalid or corrupted. Please click your browser's back button and try again.

Also, how would you use this with an external user? Would you be able to put an email address into the UserId field?

Thanks

Unknown said...

When using the API "DocumentSharingManager.UpdateDocumentSharingInfo", I am getting the error as "DocumentSharing: Guest user: 'xxxxx@hotmail.com' failed to be enabled for an unknown reason."

I am the site collection admin and I have "ManagePermission" permission. Let me know if you know the reason for the same

The same thing is working on another site collection on another tenant

Anonymous said...

I have the same problem as @Prem Chand

Post a Comment