Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

i am working on a custom system I am building into a site that allows various reps, of various departments to enter project information and many different aspects of related data (children) into the system in order to automate reporting and metrics. the project types themselves vary and the level of child data aspects vary greatly. because of this, and the fact that the relationships are complex i am doing this all custom design/COM development (js/jquery).

one thing I am trying to learn that is pivotal to this task is whether or not i can, and how i can (using JSOM) break inheritance on item by item level and add groups to each item that should see the item upon its creation. I would like to use groups because there are support and admin groups that can see everything, but reps should not see each others data.

per MSDN I see at least part of this is possible with breaking role inheritance:

function breakSecurityInheritanceChangeUser(thisId) {

    var clientContext = new SP.ClientContext.get_current();
    var oList = clientContext.get_web().get_lists().getByTitle('MyList');
    var itemId = thisId;
    this.oListItem = oList.get_items().getById(itemId);
    oListItem.breakRoleInheritance(true);
    this.oUser = clientContext.get_web().get_siteUsers().getByLoginName('DOMAIN\\alias');
    oListItem.get_roleAssignments().getByPrincipal(oUser).deleteObject();
    var collRoleDefinitionBinding = SP.RoleDefinitionBindingCollection.newObject(clientContext);

    collRoleDefinitionBinding.add(clientContext.get_web().get_roleDefinitions().getByType(SP.RoleType.administrator));

    oListItem.get_roleAssignments().add(oUser, collRoleDefinitionBinding);
    clientContext.load(oUser);
    clientContext.load(oListItem);        
    clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
}

function onQuerySucceeded(sender, args) {

    alert('Role inheritance broken for item ' + 
        this.oListItem.get_item('Title') + 
        ' and new role assignment for ' + 
        this.oUser.get_loginName());
}

function onQueryFailed(sender, args) {

    alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}

so i am not sure if this is the approach i need or not. as described above I would like to be able to dictate that when an item is created I break the inheritance immediately, then assign permissions to group admin, support and the user that created the item. so can i load more than one user to oUser, or is there another approach to oGroup....what if I want to set different roles for each item (admin = full control, support & user = contribute kind of thing)...would I have to break this into several different function like - break inheritance, and add admin, - go back through and add support, - go back through again and add user?

in order to add a group, do I need to cycle through a group and get each user of group and use something like above in order to add each user and role individually.....this means a lot of calls.

sorry i just really need help understanding the proper approach and have never done this aspect before.....limited to COM/SPD.

thanks as always!

share|improve this question

1 Answer 1

up vote 0 down vote accepted

So I have figured out how to do this, and even though the flow is a bit crazy, it seems to work everytime:

first I create a new group which will be the group even eventually set on the item:

var projGroupId = 0;
var projGroupMemberObj = [];
var projGroup = '';

    //id is my unique parent id, probably replace with GUID I generate that maps to Id
    function updatePermissions(thisId) {
        //this is my example scheme for dynamic group creation
        varn groupName = "project-" + thisId + "-Group";

        var clientContext = new SP.ClientContext.get_current();
        this.oWebsite = clientContext.get_web();
        var groupCreationInfo = new SP.GroupCreationInformation();
        groupCreationInfo.set_title(groupName);
        groupCreationInfo.set_description('Group for project ' + thisId);
        this.oGroup = oWebsite.get_siteGroups().add(groupCreationInfo);
        var collRoleDefinitionBinding = SP.RoleDefinitionBindingCollection.newObject(clientContext);
        this.oRoleDefinition = oWebsite.get_roleDefinitions().getByType(SP.RoleType.contributor);
        collRoleDefinitionBinding.add(oRoleDefinition);
        var collRollAssignment = oWebsite.get_roleAssignments();
        collRollAssignment.add(oGroup, collRoleDefinitionBinding);
        clientContext.load(oGroup, 'Title');
        clientContext.load(oRoleDefinition, 'Name');
        clientContext.executeQueryAsync(
            Function.createDelegate(this, this.onCreateGroupQuerySucceeded), 
            Function.createDelegate(this, this.onQueryFailed));
    }

    //after group is created set the global to the new name to ensure it is what it was supposed to be
    function onCreateGroupQuerySucceeded() {
        projGroup = oGroup.get_title();
        getProjectUserGroupId();
    }


    //get all the site groups and then match by name in order to get id
    function getProjectUserGroupId() {
        var clientContext = new SP.ClientContext.get_current();
        this.collGroup = clientContext.get_web().get_siteGroups();
        clientContext.load(collGroup);
        clientContext.executeQueryAsync(Function.createDelegate(this, this.onGetProjectGroupIdSucceeded), Function.createDelegate(this, this.onQueryFailed));
    }


//get the results, match by name and create the group object
function onGetProjectGroupIdSucceeded(sender, args) {
    var groupDataObj = [];
    var groupEnumerator = collGroup.getEnumerator();
    while (groupEnumerator.moveNext()) {
        var thisGroup = groupEnumerator.get_current();
        var thisObj = { groupId: thisGroup.get_id(),
                        groupTitle: thisGroup.get_title()
                        };
        if (thisObj.groupTitle == projGroup) {
            projGroupId = thisObj.groupId;
            groupDataObj.push(thisObj);
        }   
    }
    if (!projGroupId == 0) {
              //start loading the group with users, starting with static groups
        getAdminUsers();    
    }   
}

function getAdminUsers() {
    var clientContext = new SP.ClientContext.get_current();
    var collGroup = clientContext.get_web().get_siteGroups();
    var oGroup = collGroup.getById(10);
    this.collUser = oGroup.get_users();
    clientContext.load(oGroup);
    clientContext.load(collUser);
    clientContext.executeQueryAsync(Function.createDelegate(this, this.onGetAdminsQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
}

function onGetAdminsQuerySucceeded() {
    var userEnumerator = collUser.getEnumerator(); 
    while (userEnumerator.moveNext()) {
        var oUser = userEnumerator.get_current();
        var thisObj = {
                        userID : oUser.get_id(),
                        userLogin : oUser.get_loginName(),
                        userEmail : oUser.get_email(),
                        userTitle: oUser.get_title()
                       };
        projGroupMemberObj.push(thisObj);     
    } 

    var clientContext = new SP.ClientContext.get_current();
    var collGroup = clientContext.get_web().get_siteGroups();
    var oGroup = collGroup.getById(14);
    this.collUser = oGroup.get_users();
    clientContext.load(oGroup);
    clientContext.load(collUser);
    clientContext.executeQueryAsync(Function.createDelegate(this, this.onGetSupportGroupCallback), Function.createDelegate(this, this.onQueryFailed));
}

so its really the same last functions as I go through the groups I need to add to the object, then I use this to break inheritance and apply the group to permissions

//what I use to build the user group object
function onGetCurrentUserSuccessMethod(sender, args) {
    var userObject = web.get_currentUser();
    var thisObj = { userID : userObject.get_id(), userLogin : userObject.get_loginName(), userEmail : userObject.get_email(), userTitle: userObject.get_title()  };
    projGroupMemberObj.push(thisObj);

     for ( var i = 0; i < projGroupMemberObj.length; i++ )
    {
        var thisDataObj = projGroupMemberObj[i];
        setProjectGroupUsers(thisDataObj);
    }
}

//load all these users from object to group I created
function setProjectGroupUsers(dataObj) {
    var clientContext = new SP.ClientContext.get_current();
    var collGroup = clientContext.get_web().get_siteGroups();
    var oGroup = collGroup.getById(projGroupId);
    var userCreationInfo = new SP.UserCreationInformation();
    userCreationInfo.set_email(dataObj.userEmail);
    userCreationInfo.set_loginName(dataObj.userLogin);
    userCreationInfo.set_title(dataObj.userTitle);
    this.oUser = oGroup.get_users().add(userCreationInfo);
    clientContext.load(oUser);
    clientContext.executeQueryAsync(Function.createDelegate(this, this.setProjectGroupUsersSuceeded), Function.createDelegate(this, this.onQueryFailed));
}

then I use this ridiculous counter to c ompare the length of object, so that when all the objects in the array have reached callback it fires the function that sets the permissions

function setProjectPermissionsScheme() {        
        var clientContext = new SP.ClientContext.get_current();
        var oList = clientContext.get_web().get_lists().getByTitle('Projects');
        var itemId = globProjectID;
        this.oListItem = oList.getItemById(itemId);
        oListItem.breakRoleInheritance(false);
        var collGroup = clientContext.get_web().get_siteGroups();
        var oGroup = collGroup.getById(projGroupId);

        var collRoleDefinitionBinding = SP.RoleDefinitionBindingCollection.newObject(clientContext);
        collRoleDefinitionBinding.add(clientContext.get_web().get_roleDefinitions().getByType(SP.RoleType.reader));
        oListItem.get_roleAssignments().add(oUser, collRoleDefinitionBinding);
        clientContext.load(oUser);
        clientContext.load(oListItem);
        oListItem.get_roleAssignments().getByPrincipal(oUser).deleteObject();
        var collRoleDefinitionBinding = SP.RoleDefinitionBindingCollection.newObject(clientContext);
        collRoleDefinitionBinding.add(clientContext.get_web().get_roleDefinitions().getByType(SP.RoleType.administrator));
        oListItem.get_roleAssignments().add(oGroup, collRoleDefinitionBinding);
        clientContext.load(oUser);
        clientContext.load(oListItem);        
        clientContext.executeQueryAsync(Function.createDelegate(this, this.onSetProjectPermissionsSucceeded), Function.createDelegate(this, this.onQueryFailed));

}
function onSetProjectPermissionsSucceeded(sender, args) {

    alert('Role inheritance broken for item ' + 
        this.oListItem.get_item('Title') + 
        ' and new role assignment for ' + 
        this.oUser.get_loginName());
}


function onQueryFailed(sender, args) {
    alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}

this ridiculous (perhaps?) flow is working consistently, however since I am novice at best I would welcome comments or advice on improving it in anyway.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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