0

I've written code to check-in/check-out list items. It works great with administrators, but any other permissions level has trouble, a 401 unauthorized error with UpdateListItems on "_vti_bin/lists.asmx" for the site. I've confirmed that the users can view the "_vti_bin/lists.asmx" web service.

     //declare variables used for check-in/check-out.
  var varName;
  var varChecked;
  var varID
  var varQueryStringVals;
  //Check who has checked out the item
  function getCheckOutPerson (){
$().SPServices({
    operation: "GetListItems",
    async: false,
    listName: "Communications Services Request Form",
    CAMLQuery: "<Query><Where><Eq><FieldRef Name='ID' /><Value Type='Number'>" + varID + "</Value></Eq></Where></Query>",
    completefunc: function (xData, Status) {
      $(xData.responseXML).SPFilterNode("z:row").each(function() {
        varChecked = $(this).attr("ows_CheckedOutTo");
      });
    }
  });
  };

$(document).ready(function() {
//Check-in if edits cancelled
    $("#cancelBtn").click(function(){
      //Check in edited item.
      if (varName == varChecked){
    $().SPServices({
        operation: "UpdateListItems",
        async: false,
        debug: true,
        listName: "Communications Services Request Form",
        ID: varID,
        valuepairs: [["CheckedOutTo", ""]],
        completefunc: function(xData, Status) {}
    });
    };
    });
 //get current user 
  varName = $().SPServices.SPGetCurrentUser({
    fieldName: "Title",
    debug: false
});
//get current list item ID
varQueryStringVals = $().SPServices.SPGetQueryString();
varID = varQueryStringVals["ID"];
     //get checked out name
  getCheckOutPerson();
  // item checked in or checked out by current user?
    if (varChecked == undefined || varName == varChecked){
//check out item
    $().SPServices({
        operation: "UpdateListItems",
        async: false,
        debug: true,
        listName: "Communications Services Request Form",
        ID: varID,
        valuepairs: [["CheckedOutTo", varName]],
        completefunc: function(xData, Status) {
        }
    });
};
//checked out message
if (varChecked != undefined && varName != varChecked) {
alert ("You cannot edit this item. It is check out by " + varChecked +".");
history.back();
}; 
//Display 'checked out to' in dispitem.aspx
getCheckOutPerson();
  if ($('.CheckedOut').text('')) {
    $('.CheckedOut').append(varChecked);
  }
  });

 function PreSaveAction() {
 if (varName != varChecked){
alert ("You cannot make changes to this item. It it checked out to " + varChecked);
return false;
};
        //Check in edited item.
    $().SPServices({
        operation: "UpdateListItems",
        async: false,
        debug: true,
        listName: "Communications Services Request Form",
        ID: varID,
        valuepairs: [["CheckedOutTo", ""]],
        completefunc: function(xData, Status) {}
    });
    return true;
 };
Calen
  • 11
  • 4

2 Answers2

0

Does the non-admin users have sufficient permissions? Read-only would not be sufficent for check-out/check-in.

Do you happen to be using item-level permissions? http://www.novolocus.com/2009/05/08/updatelistitems-web-service-fails-when-using-item-level-permissions/

I was able to get a working example using lists.asmx UndoCheckOut. Testing passed with a user that has admin/owner and another that just has contribute. The docUrl needs to be the full url to the item (e.g. - http://server/site/list/item.txt). Note, the SOAPAction in the header (see Jan Tielen - http://weblogs.asp.net/jan/archive/2009/05/25/quot-the-security-validation-for-this-page-is-invalid-quot-when-calling-the-sharepoint-web-services.aspx).

function UndoCheckout(docUrl){
    var soapEnv =
        "<?xml version='1.0' encoding='utf-8'?> \
            <soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'> \
                <soap:Body> \
                    <UndoCheckOut xmlns='http://schemas.microsoft.com/sharepoint/soap/'> \
                        <pageUrl>"+ docUrl +"</pageUrl> \
                    </UndoCheckOut> \
                </soap:Body> \
            </soap:Envelope>";
$.ajax({
    url: "http://server/mysite/_vti_bin/lists.asmx",
        type: "POST",
        dataType: "xml",
        data: soapEnv,
        contentType: "text/xml; charset=\"utf-8\"",
        beforeSend: function(xhr) {
            xhr.setRequestHeader("SOAPAction",
            "http://schemas.microsoft.com/sharepoint/soap/UndoCheckOut");
        },
        complete: function(xData, status){
            var result = $(xData.responseXML).find("UndoCheckOutResult").text();
            if (result == "true") alert("Undo checkout succeeded.");
        },
        error: function(){
            alert("error");
        }
    });
}
buck
  • 207
  • 2
  • 9
  • The users have contribute permissions, but I also tried with Full Access and it still gives the 401 unauthorized error. – Calen Feb 29 '12 at 17:28
  • Also, I'm using the ID in my UpdateListItems call and the contributor level accounts are getting the correct ID. – Calen Feb 29 '12 at 18:23
  • Yeah, it turns out the permissions were messing up so that users didn't have permission to use remote API. that's what was causing the problem. – Calen Mar 01 '12 at 22:54
0

Turns out this had nothing to do with anything I posted there. The permissions hierarchy is messed up, so read permissions are being given to users for a higher site when I try to give them contribute permissions at the list level and the list level permissions are being ignored.

Calen
  • 11
  • 4