All posts by Alexander Bautz

Break permission inheritance on a new list item and assign edit rights to users selected in a people picker

I got a request for a solution to break inheritance of permissions on a new list item and assign edit rights to users selected in a people picker.

IMPORTANT INFORMATION:

Unfortunately users must have Manage Permissions rights to be able to use this code. You must assign this right to the users by going to Site settings > Site permissions > Permission levels > Edit permission level > Site permissions > Manage permissions. Do this with caution as it will give general Mange permission rights if you don’t add a custom permission level and assign it to a specific SharePoint user group.

This example requires a list with a multichoice people picker where you select the users to assign edit item permissions – the name of this people picker is in this code is EditRightsPeoplePicker, but you can specify the name in the bottom of the code snippet.

Add the below snippet to the Custom JS textarea of your DFFS Enabled NewForm. When saving the item the default save function will be cancelled and the custom function will create an item, break permission inheritance and assign edit rights to the users selected in the people picker. In addition, the current user will get full control over the list item.

Please note that this is not a complete fully functional solution – it is only a proof of concept and you can use it as a starting point for making your own solution.

// Don't edit this function
 function breakroleinheritance(arg) {
     var deferred = jQuery.Deferred();
     jQuery.ajax({
         "url": arg.listBaseUrl + "/_api/web/lists/getbyid('" + arg.listGuid + "')/items(" + arg.itemId + ")/breakroleinheritance(false)",
         "type": 'POST',
         "headers": {
             'X-RequestDigest': jQuery('#__REQUESTDIGEST').val(),
             "accept": "application/json;odata=verbose",
             "content-type": "application/json;odata=verbose"
         },
         "success": function(data) {
             deferred.resolve(true);
         },
         "error": function(err) {
             console.log(err);
             deferred.reject(err);
         }
     });
     return deferred.promise();
 }
 // Don't edit this function
 function doAssignNewRole(arg) {
     var deferred = jQuery.Deferred(),
         ticker = 1;
     jQuery.each(arg.roles, function(i, r) {
         jQuery.ajax({
             "url": arg.listBaseUrl + "/_api/web/lists/getbyid('" + arg.listGuid + "')/items(" + arg.itemId + ")/roleassignments/addroleassignment(principalid=" + r.principalid + ",roledefid=" + r.roledefid + ")",
             "type": 'POST',
             "headers": {
                 'X-RequestDigest': jQuery('#__REQUESTDIGEST').val()
             },
             "success": function(data) {
                 if (ticker === arg.roles.length) {
                     deferred.resolve(true);
                 } else {
                     ticker += 1;
                 }
             },
             "error": function(err) {
                 console.log(err);
                 deferred.reject(err);
             }
         });
     });
     return deferred.promise();
 }
 // Don't edit this function
 function setItemLevelSecurity(arg) {
     var deferred = jQuery.Deferred();
     breakroleinheritance(arg).done(function() {
         doAssignNewRole(arg).done(function(success) {
             deferred.resolve(arg.itemId);
         }).fail(function(err) {
             spjs.dffs.alert({
                 "title": "Add roles error",
                 "msg": JSON.stringify(err)
             });
         });
     });
     return deferred.promise();
 }
 // Don't edit this function
 function init_setItemLevelSecurity(arg) {
     var deferred = jQuery.Deferred();
     var users = spjs.utility.getFieldValue({
         "fin": arg.peoplePicker,
         "key": "loginName"
     });
     var roleArr = [],
         userIdArr = [];
     jQuery.each(users, function(i, login) {
         var userId = spjs.utility.userInfo(login).ID;
         roleArr.push({
             "principalid": userId,
             "roledefid": "1073741830" // 1073741830 = edit
         });
         userIdArr.push(userId);
     });
     // Create new item
     var newItemData = {};
     newItemData.Title = getFieldValue("Title");
     newItemData[arg.peoplePicker] = userIdArr.join(";#;#");
     var res = spjs.utility.addItem({
         "listName": _spPageContextInfo.pageListId,
         "data": newItemData
     });
     arg.roles = roleArr;
     if (res.success) {
         arg.itemId = res.id;
         setItemLevelSecurity(arg).done(function(id) {
             deferred.resolve(id);
         });
     }
     return deferred.promise();
 }
 function dffs_PreSaveAction() {
     createNewItemWithItemLevelSecurity();
     return false;
 }
 // Edit this function
 function createNewItemWithItemLevelSecurity() {
     init_setItemLevelSecurity({
         "listBaseUrl": _spPageContextInfo.webServerRelativeUrl,
         "listGuid": _spPageContextInfo.pageListId,
         "peoplePicker": "EditRightsPeoplePicker"
     }).done(function(itemId) {
         // Done
         location.href = location.href.split("NewForm.aspx")[0] + "EditForm.aspx?ID=" + itemId;
     });
 }

Please post any questions in the comments below.

Alexander

Breaking change in SharePoint online – Error with webservice calls: Value does not fall within the expected range

January 22 10:30PM: I got feedback from Microsoft and have verified that the problems is fixed.

When using the /_vti_bin/lists.asmx webservice call to a list to retrieve multichoice people picker fields, multichoice lookup fields or multichoice managed metadata fields it fails with this error:

Value does not fall within the expected range.

The error goes away when changing the fields back to single choice.

This will affect queries where you use spjs.utility.queryItems and spjs.utility.getItemByID in your CustomJS.

The issue does not affect all tenants at this moment, but the support ticked with Microsoft has been escalated to the product engineering team. Hopefully it will be resolved soon.

I’ll update this page as soon as I hear back from Microsoft.

Alexander