Managing Role Assignments/Permissions with SharePoint REST

To assign permissions in SharePoint, you make one or more role assignments, which requires three things:

  • Some kind of handle for a securable object. That’s basically a site, list, library, folder, document, or item.
  • The principal id for something to which roles can be assigned. That’s either an Active Directory user or security group, or a SharePoint group.
  • The id of a role definition. Like ‘Full Control’ or ‘Edit’ or ‘Contribute’. This is basically a named collection of granular permissions that are defined at the site collection root and can be assigned to a securable object in that site collection.

In this post, I’m going to explain the REST service calls required in order to make role assignments to SharePoint securable objects. I will show the calls using jQuery’s ajax (because I’m working through them in the console and the console won’t resolve promises). I’ll follow up with a post with some demo code pulling it all together and probably using fetch.


Role Assignments: Prerequisites

As explained above, there are three things I need to make a role assignment, and while these aren’t directly related to role assignments, this is a series on REST in general so I’m going to explain all of the service calls.

Lists

The first thing I will get is collection of lists that are available in the current site, via the endpoint /_api/web/lists. Now this endpoint basically returns the whole list schema, and I don’t need all of that, so to reduce the payload I’ll add $select=Id,Title as a request parameter. I also want to weed out hidden lists, so I’ll add $filter=Hidden eq false. With that, the call looks like:

And the returned JSON structure looks like this:

I’ll use this data to populate some sort of multi-select control for lists and can then get a handle on each list by either id or title.

Site Groups

Next, I’ll need to populate a drop-down list with site collection groups. Again, I’ll add the request parameter $select=Id,Title, and while with lists I could have gotten away with just title, here I need both because add role assignment requires the id, and users are likely going to need the title. Here’s the call:

And the response JSON structure looks like this:

I’m not actually going to need this in the demo page, but to be thorough, if you know the name of the group, you can get it’s ID with this call (a lot less chatty):

And the response from this call is quite succinct:

Role Definitions

And the final preliminary piece of the puzzle is that I need a role definition id. To get a list of role definitions defined in the site collection, I make the following call:

Now I didn’t actually select anything, so I’m getting back more information than I actually need, but it’s not that big a structure and I wanted to show the whole thing. In particular, note the base permissions structure. I talked about this a bit in my last post Determining the Permissions of the Current User with REST, and how to dissect this structure to get the granular access controls it represents. Anyway, here is the complete JSON structure returned from the role definitions endpoint.

The only things I actually need from this are the name and the id.

If you know the name of the role definition you’re interested in, you can get the id with the following REST call:

And the very simple returned JSON structure from this call looks like:

Manipulating Role Assignments

Whew! We finally have enough information to make a role assignment. It’s a bit tedious, but not that hard (which kind of describes programming in general). In the following code, I’m going to work on the permissions of the list titled “Speaker Evaluations”. And prior to doing anything, the permissions for that list look like this:


Initial Role Assignments

The first thing I need to do is check if the list is currently inheriting permissions. To do that, just like object model code, I need to call has unique role assignments like so:

Keep in mind that the part of the URL before /hasuniqueroleassignments is what I called earlier “a handle to a securable object”, in this case, a list. So I could just as easily use /_api/web/hasuniqueroleassignements, and the returned value would be in exactly the same format but would have told me if the web had broken inheritance. And I could do …/items(2)/hasuniqueroleassignments to determine if the item with id 2 has broken role inheritance. The same is true of all of the endpoints to follow in this post, they can all be tacked onto any URL that represents a securable object to perform securable operations on those objects.

Anyway, here is the returned value, which would be true if role inheritance had already been broken:

If the list is currently inheriting permissions, I now need to break role inheritance. I do that with the following call, passing in false. The input is true if I want to copy all of the role assignments from the parent and false if I want to start with a blank slate.

Which returns the terribly useful JSON structure shown below. Basically, if success gets called back, that’s enough to shout WOO HOO!

And if I re-check the permissions for my list it now looks like this:


Broken Inheritance

Yours will look a little different of course. I wouldn’t expect you to see permissions assigned to Joe McShea for instance ;). Breaking role inheritance with false just assigns full control to the current user to prevent orphaned objects.

But calling break role inheritance on an object that already doesn’t inherit does nothing. Even if you pass in false, it certainly doesn’t delete any previously copied role assignments from the parent. That’s why I had to check has unique role assignments, because if not then I call the above service, and if so then I call the following service.

This call just deletes all role assignments for the user I’m about to add role assignments for. That way, at least with respect to this one user, I always start with a clean slate. Curiously, this call returns nothing on success, just a blank string. not even a lousy { “object.null”: true }! One thing you need to know, however, is if the user has no role assignments, the result is a “404 Not Found”. This isn’t an error. You asked for a resource and it wasn’t found. So you should handle 404 errors as appropriate.

And finally, we’ve arrived at the point of this post, which is making a role assignment. The following service call adds a role assignment to the “Speaker Evaluation” list, which assigns Edit (i.e. roledefid=’1073741830′) to the SharePoint group “CSRDemos Members” (i.e. principalid=’9′).

And again we see this very useful structure. But again, the fact that the success callback was called is more than enough.

And now if I check the permissions for the list, I see:


Added Role Assignment

Sum Up

In this post I showed the various pieces you need to navigate in order to assign roles to SharePoint groups using the REST API. In my next post, I’ll pull it all together with a demo page.

Reference

Set custom permissions on a list by using the REST interface – Microsoft Docs

4 thoughts on “Managing Role Assignments/Permissions with SharePoint REST”

    • Hi Ganesh,

      So SharePoint Pages generally have a hidden control with an id of __REQUESTDIGEST. If you view source on a SharePoint page and search for that ID, you should see the control. It’s just some kind of hash, that you have to send back to the server in the X-RequestDigest header in order to do any write operations (i.e. POST, PUT, MERGE, or DELETE), if you’re not using OAuth.

      JavaScript that runs on a SharePoint page doesn’t need to do OAuth since the user has already authenticated in the browser, so it can just use the __REQUESTDIGEST value of the current page like I am.

      $("#__REQESTDIGEST").val() is using jQuery to get that digest value. Without jQuery, you can use pure JavaScript something like document.getElementById("__REQUESTDIGEST").value. If document.getElementById("__REQUESTDIGEST") returns undefined then you’re either not on a SharePoint page, or the page doesn’t use a request digest.

      And if you’re on a SharePoint page, meaning the user has already authenticated to SharePoint, but the page doesn’t have a control with an ID of __REQUESTDIGEST, then there is another way to get the request digest, which is to call the context info REST service to retrieve the digest, with a url like:

      http://[site url]/_api/contextinfo

      The digest serves a couple of purposes, including making sure your version of the item isn’t stale, so it expires from time to time (I believe 30 minutes by default). So if you try to use a stale digest, you’ll get an error like “An error has occurred with XXXX. Please refresh the page and try again”. In which case, you can use the context info service to refresh the digest.

      Now if you’re not on a SharePoint page, then you probably have to use OAuth and worry about CORS (Cross Origin Resource Sharing), which is a whole different can of worms, and not what my post is about.

      You can find a lot more info about this here:

      Complete basic operations using SharePoint REST endpoints

      That page has some information on the different contexts you might be in, like on a SharePoint page vs. using OAuth etc.

      Hope that helps some.

      Joe

  1. Hello Joe,

    First of all, thank you for this post, it’s very helpful.

    I’d like to ask you if you know how to remove an external user from a specific folder/file.

    I granted access to a folder with the “SP.Web.ShareObject” rest call method which accepts a “peoplePickerInput” body parameter (where you can define all the email addresses to invite), but the method “SP.Web.UnshareObject” only accepts the url parameter of the folder, so every external user will lose the access, which it’s not what I need.

    Do you have any solution for this ?
    Thanks in advance.

    Liev

Leave a Comment