1

There is a Access Denied error being thrown when I try to access a list from the host web from the app web. The app has read access to the entire site collection. Why is it throwing this error?

"use strict";
var context = SP.ClientContext.get_current();
var hostUrl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));
var appweburl = decodeURIComponent(getQueryStringParameter("SPAppWebUrl"));
var hostContext = new SP.AppContextSite(context, hostUrl);
var web = hostContext.get_web()
//var lists = web.get_lists();
var BlogURL = decodeURIComponent(getQueryStringParameter("BlogURL"));
var PostLimit = decodeURIComponent(getQueryStringParameter("PostLimit"));
var BackgroundColor = decodeURIComponent(getQueryStringParameter("BackgroundColor"));

window.Communica = window.Communica || {};

//var app = angular.module('blogPart', []);

$(document).ready(function () {
    Communica.Part.init();

    var scriptbase = hostUrl + "/_layouts/15/";
    $.getScript(scriptbase + 'SP.Runtime.js',
     function () {
         $.getScript(scriptbase + 'SP.js',
             function () {
                 $.getScript(scriptbase + 'SP.UserProfiles.js',
                    function () {
                        $.getScript(scriptbase + 'SP.RequestExecutor.js', execCrossDomainRequest);
                    });
             });
     });
});

function getQueryStringParameter(paramToRetrieve) {
    var params;
    var strParams;

    params = document.URL.split("?")[1].split("&");
    strParams = "";
    for (var i = 0; i < params.length; i = i + 1) {
        var singleParam = params[i].split("=");
        if (singleParam[0] == paramToRetrieve)
            return singleParam[1];
    }
}
function execCrossDomainRequest() {
    var context;
    var factory;
    var appContextSite;
    var mylist;
    var today = new Date();
    var todayString = today.toString("yyyy-MM-ddTHH:mm:ssZ");
    var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"];
    var BlogTitle = BlogURL;
    if (BlogURL[BlogTitle.trim().length - 1] == "/") {
        BlogTitle = BlogURL.substring(0, BlogTitle.length - 1);
    }
    if (BlogTitle.indexOf("/") > -1) {
        var x = "/" + BlogTitle.split(/[/ ]+/).pop();
        if (x.indexOf(".") > -1) {
            BlogTitle = BlogTitle.substring(0, BlogTitle.lastIndexOf("/"));
        }
    }
    if (BlogTitle.indexOf("/sites/") > -1) {
        BlogTitle = BlogTitle.substring(BlogTitle.lastIndexOf("/sites/"), BlogTitle.length);
    }
    context = new SP.ClientContext(appweburl);
    factory = new SP.ProxyWebRequestExecutorFactory(appweburl);
    context.set_webRequestExecutorFactory(factory);
    appContextSite = new SP.AppContextSite(context, BlogTitle);
    this.web = appContextSite.get_web();
    mylist = this.web.get_lists().getByTitle('Posts');
    var camlQuery = new SP.CamlQuery();
    camlQuery.set_viewXml('<View><Query><Where><Leq><FieldRef Name="PublishedDate"/><Value IncludeTimeValue="TRUE" Type="DateTime">'+todayString+'</Value></Leq></Where><OrderBy><FieldRef Name="PublishedDate" Ascending="FALSE" /></OrderBy></Query><RowLimit>'+PostLimit+'</RowLimit></View>');
    var collListItem = mylist.getItems(camlQuery);
    context.load(mylist);
    context.load(collListItem);
    context.executeQueryAsync(
         Function.createDelegate(this, successHandler),
         Function.createDelegate(this, errorHandler)
    );
0

Make sure you have the permissions set correctly in the AppManifest.xml I needed to have site read and have the app-only check-box unchecked.

0

I believe your context is the problem, specifically the SPAppWebUrl that you're using from the query strings includes the App path, so http://[appurl]/site/siteappisinstalled/AppName/ which results in your get_lists() call looking for the site under /site/siteappisinstalled/AppName/ and not /site/siteappisinstalled/. (Is that why you're using ProxyWebRequestFactory to get the web?)

Try something like this (working example to create an item in a list):

var context = new SP.ClientContext(getQueryStrings().SPAppWebUrl.replace('[AppName]',''));
var oList = context.get_web().get_lists().getByTitle('PV5Projektdata');
var itemCreationInfo = new SP.ListItemCreationInformation();
var oListItem = oList.addItem(itemCreationInfo);
oListItem.set_item('Title', 'List item title');
oListItem.update();
context.load(oListItem);
context.executeQueryAsync(Function.createDelegate(this, function (){
    alert('Item created: ' + oListItem.get_id());        
}), Function.createDelegate(this, function (ctx, args){        
    alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}));

Note the [AppName] in the replace.

Hope that helps.

  • getQueryStrings() is undefined. What is it supposed to be referenced to? – Christopher Oct 30 '15 at 16:13
  • Oh yes that is a helper method to get the query strings as an object so we can do the string replace easily.. – Martin Laukkanen Nov 3 '15 at 10:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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