3

I am using the code below to get all the list of a site. However the user might not have access to all lists, so how can I get only the list the current user has access to?

When accessing the site with an unprivileged user the code below results in

Error: Access denied. You do not have permission to perform this action or access this resource.

Any help here would be much appreciated

var ctx = SP.ClientContext.get_current();
var web = ctx.get_site().get_rootWeb();

function MyFunction(web) {
    var ctx = web.get_context();
    var webs  = web.getSubwebsForCurrentUser(null); 
    var lists = web.get_lists();
    ctx.load(webs, 'Include(Title,Webs,Url)');
    ctx.load(lists,'Include(Title,RootFolder,Hidden)');
    ctx.executeQueryAsync(
        function() { ... },
        function(sender,args){
            console.log('Error: ' + args.get_message());
        }
    );
}

MyFunction(web);

Edit: I thought I mention that the code works fine without the get_lists, it shows me the sites the user can access, but I now would like to do the same for the lists on the sites.

4
  • JSOM code doesn't have any elevated privileges, so this code returns only the information the current user (executing this code) has access to. Jan 13, 2016 at 19:43
  • 1
    @DannyEngelman : Returning the information the current user has access to is exactly what I want to do. I want all the lists the user has access to, but how do I go about doing that (without getting the access denied error)?
    – Kees
    Jan 14, 2016 at 10:52
  • This code does not error when I try it, so there is something not correct with (your) Permissions. Jan 14, 2016 at 12:21
  • @DannyEngelman : The code works for my user, which has full access permissions, but when I access the site with an external test user that has read only permissions I get the 'access denied' error.
    – Kees
    Jan 14, 2016 at 15:30

3 Answers 3

0

SharePoint CSOM does not allow for elevated privileges within it's code. This is not a bad thing. If you have a site open to the public, they could do whatever they want by adding a script at their end that ignores the security on your site.

To get around this, you will need to write a web service on the SP server side that will authenticate the user and run your reads and updates from there. You can make the call from the client side and have some authentication in place to ensure the user accessing the web service can do it. What you are attempting cannot be done within the context you are working.

Another option is to accomplish this with a SharePoint add in. You can then allow your add-in to run with elevated privileges to accomplish your needs. Here is some information on that: https://msdn.microsoft.com/en-us/library/office/mt210897.aspx

3
  • I do not want to use elevated priviledges, all I want is a list of all the lists/libraries/pages the user has access to, but how do I go about doing that (without getting the access denied error)?
    – Kees
    Jan 14, 2016 at 10:54
  • It would be fairly easy in SOM as you have a couple of methods available to you (alaindeklerk.com/…) however, in CSOM you don't have all these options. The only thing I can think of that you can use is first build your code to bring back your list collection. Then loop through each list in the collection and determine if the user has access. If they do, add it to your list. If not, continue on to the next list. You are basically using error handling to perform business logic (I hate this)... Jan 14, 2016 at 13:06
  • ...but I can't think of an elegant way to do what you are attempting. The problem is that in order for you to check to see if a user has permissions from CSOM, you have to access the list, which forces a failure message. DoesUserHavePermissions exists in CSOM, but it is only at the web level and not the list. This site has an example of a more elegant method of checking list access then using the error handling method: silver-it.com/node/64 Hope this helps some. Jan 14, 2016 at 13:13
0

Ran into the same issue today. What seems to fix it:

  1. remove the include statement when loading the lists (I only tested the scenario with RootFolder, maybe Title and Url are 'safe').
  2. fetch the needed properties inside the loop; per returned list item

Not the prettiest of solutions, but better than an access denied message.

1
  • (I had forgotten about this thread.) I ended up solving this using the REST API. That way you can do what I was trying to do in one statement. It has been a while since I looked at this code, but if you want to I can post here what I did in the end.
    – Kees
    Aug 15, 2016 at 8:41
0

Sorry for the very late post to this question. I solved it a while ago, but forgot to post what I did. I hope this will help someone.

I ended up using the REST API instead. It essentially is now based around the following ajax call:

jQuery.ajax({
    type: "GET",
    url: origin + siteCollectionUrl + url + "/_api/web/lists?$select=title,hidden,parentweburl,entitytypename,basetype,isapplicationlist,EffectiveBasePermissions",
    headers: { "Accept":"application/json; odata=verbose"},
    dataType: "json",
    success: parseListData,
    error: error
});

Where the parsListData function looks like this:

function parseListData(data) {
    data.d.results.sort(function(a, b) { return (a.Title < b.Title) ? -1 : ( (a.Title > b.Title) ? 1 : 0 ); }).forEach( function(list) {
        var listPerms = new SP.BasePermissions();
        listPerms.initPropertiesFromJson(list.EffectiveBasePermissions);
        // If the user has at least read access to the list, the list isn't hidden
        if (listPerms.has(SP.PermissionKind.viewListItems) && ! list.Hidden ) {

            ...

        }
    });
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.