Search code examples
sharepointsharepoint-2010permissionsweb-parts

Sharepoint: web part programmatically changing permissions, cannot get the changes to persist


I'm writing a visual web part in visual studio for sharepoint 2010. The whole point of this web part is to change permissions around at the click of a button. I am able to access the permissions and output them to the screen. I'm able to change the permissions in the objects that I have, and then show the changed permissions on the screen. My problem is, after everything is done, no actual permissions have been changed.

webpart.TargetLibrary is a text field, inputted elsewhere as the name of the library I wish to investigate.

SPListCollection docLibs = m_SharePointWeb.GetListsOfType(SPBaseType.DocumentLibrary);
SPDocumentLibrary targetLib = (SPDocumentLibrary)(docLibs[webPart.TargetLibrary]);
SPListItemCollection libFolders = targetLib.Folders;
  SPListItem folderItem = libFolders[0];
  SPRoleAssignmentCollection folderRoles = folderItem.RoleAssignments;
    SPRoleAssignment roleAssign = folderRoles[0];
    SPRoleDefinitionBindingCollection spRDBC = roleAssign.RoleDefinitionBindings;
    SPRoleDefinition Contribute = spRDBC[0].ParentWeb.RoleDefinitions["Contribute"];
  folderItem.RoleAssignments[0].RoleDefinitionBindings.Add(Contribute);
  folderItem.Update();    

This is a somewhat simplified version - the original had some for loops and various bits of other code doing other things. Regardless, by everything I've been able to piece together from looking online, this code should add "Contribute" privs to the first role on the list in the first folder. As I mentioned, it does so to the local objects, but has no permanent effect. The Update() call appears to do nothing, and I'm not certain it's meant to be there in this case. I tried UpdateOverwriteVersion() - that doesn't do anything either. Any suggestions on what I might be doing wrong would be appreciated.

As a side note, it's not nearly so much of an issue, but I can't help the feeling that there's a more efficient and straightforward way to get a web object so that I can acquire role definitions by name. Any advice on that matter would also be appreciated.

Edit: solution moved to answer, below.


Solution

  • I have found answers to both the base and the side note.

    For the side note, the following looks like it's the intended way to get an appropriate SPWeb object.

    SPContext.Current.Web.RoleDefinitions["Contribute"];
    

    For the base, the problem is that Sharepoint apparently does not save changing roles inside a SPRoleAssignment - only granting or removing permissions to the folder as a whole. This may or may not have to do with the fact that I was working inside a folder. In any case, in order to get it to save, you have to remove the person from SPRoleAssignmentCollection, make changes to their SPRoleAssignment, and then re-add the changed version. The correct version of the above code (integrating both answers) is as below.

    SPRoleDefinition Contribute = SPContext.Current.Web.RoleDefinitions["Contribute"];
    SPListCollection docLibs = m_SharePointWeb.GetListsOfType(SPBaseType.DocumentLibrary);
    SPDocumentLibrary targetLib = (SPDocumentLibrary)(docLibs[webPart.TargetLibrary]);
    SPListItemCollection libFolders = targetLib.Folders;
      SPListItem folderItem = libFolders[0];
      SPRoleAssignmentCollection folderRoles = folderItem.RoleAssignments;
        SPRoleAssignment roleAssign = folderRoles[0];
        folderRoles.Remove(roleAssign.Member);
        roleAssign.RoleDefinitionBindings.Add(Contribute);
        folderRoles.Add(roleAssign);