by

How to apply custom permissions to a list in SharePoint

In Windows SharePoint Services, all the lists are assigned inherited permissions from the container site by default. So how can we programmatically change these permissions to our own?
First we must understand how WSS controls access to its objects.
sharepoint-splist-Untitled
The access model for websites, lists, document libraries, picture libraries, task lists, workflows etc follows a role-based membership model. One might even say that's quite expected since WSS extends the capabilities of the ASP.NET as an application itself and .NET has a very flexible role-membership model framework. 
In this role-membership system, SharePoint users are assigned to specific roles, specifying what kind of access he/she will have (full access, read-only, write-access etc).
You can do this just like SQL Server, where groups are created and then users are included in these groups. The next step is to go to the Sharepoint object (a list, for example) and assign permissions to that group; but SharePoint extends this model one step further by creating role assignments.
sharepoint-splist-Untitled5   sharepoint-splist-Untitled4
A Role assignment is an object that binds roles and groups/users. This role assignment object can then be grouped in collections and that's where sharepoint do the trick: All the list objects in WSS implement a collection os role assignments which makes this approach the best and most scalable way to set permissions. Such a model can even be extended to apply to specific permissions to specific list items within the list. Even websites implement a collection of role assignments.
sharepoint-splist-Untitled3
Can you create a role assignment for a specific user without specifying the role?
Yes, we can. The user will be listed in the collection for the object but he won't have access to the object. So it's really pointless doing this.
Can we cascade permissions across lists?
Yes, we can. Not only across lists but all the objects. By default SharePoint will let you inherit the object's parent permissions. This behaviour, by the way, can also be modified programmatically as we will see later.
Can we assign specific permissions for just a group of items within a list?
Yes. And the process is very similar to the one we are going to demonstrate here.
What is the highest group on a SharePoint site collection? Is there such a super group?
yes, it is called cross-site group. It is an OTB functionality and by default has 3 sub-groups: Owners, members and visitors. Owners are the site administrators, members are the people who can have write-access to the site, visitors are the guests and can only read information.
sharepoint-splist-custom-permissions-1
So, any given user only becomes an effective SharePoint user once it is assigned to a role. You can take a look at the base permissions querying Microsoft.SharePoint.SPBasePermissions.
Now...In our case, we will remove all the predefined permissions for a given task list and set our own permissions. Only the people who are site administrators will have access to it.
sharepoint-splist-Untitled2
First thing is to break the inheritance to the list. That will untie the link between the list and its parent's permissions. The immediate effect you will notice on this command is that the UI will change accordingly.
sharepoint-splist-custom-permissions-0
NOtice how the menu in the UI get updated. You won’t see the tab refferring to the parent’s permissions anymore, instead you will be presented with an option to edit the permissions by user and a new option to revert the operation, which is to inherit again the permissions of parent.
 sharepoint-splist-custom-permissions-00.jpg
Returning to our case. Once we break the relationship to the parent,  we will need remove all the permissions in the list. If we could take a look at the UI during the code execution we would see a list like this.
sharepoint-splist-custom-permissions-2
with absolutely no users with permission to access the list. Note how dangerous this operation can be. If for some reason we left the code at this stage of execution we would compromise the SharePoint's health status and the implications can be very upsetting specially if the list is touched by many users or displayed in other sites.
So the next step is to setup the user we want to give the permission. In our case we want to give access to this list only to people in the administrators group.
Take a minute to see how we perform this.
Remember when we talked about the Roles and the Groups. Well, these are represented by the classes SPRole and SPGroup. So we will at some point need to have that information at hand. We extract the desired role R out of our website roles collection and our group G out of the website group collection.
sharepoint-sprole                 sharepoint-spgroup
There is a special trick here. In order for the group G useful in anyway, we need give a live identity to it. We will use the SPPrincipal object for that. SPPrincipal comes from the SharePoint super-class SPMember and it is the object that represents an user or a group within a website in SharePoint. Any user and any group attached to a site in SharePoint is automatically a SPPrincipal object and he will provide all the role-membership mechanisms for integration with the system.
sharepoint-Untitled
In older versions of Windows SharePoint Services SPRole and SPGroups were used combined and straight to configure the permissions. These objects are now obsolete for that function and the recommended approach is to instantiate a SPRoleAssignment. The SPRoleAssignment will be produced by associating the selected group plus the principal identity. Once you have your SPRoleAssignment setup based on the group, you then add the SPRole to the exposed collection.
The next steps are very direct. We bind the SPRole to the SPRoleAssignment…
sharepoint-sproleassignment 
And we add the SPRoleAssignment to the RoleAssignmentCollection exposed by the SPList.
sharepoint-sproleassignment-collection
We create a SPGroup and SPRoleDefinition objects based upon the existing site groups and roles in our site. The reference to the site can be accessed via the SPList object itself. Since we have that information now in our hands, we can then combine them with a SPRoleAssignment object and then add this assignment to the collection of assignments that belongs to the list. Our method is pretty atomic, and at some point a SPList.Update() call must be made in order to persist the changes we’ve done.
If everything went according to our plan, we should now see a list like this in our UI:
sharepoint-splist-custom-permissions-3

If you want to apply specific permissions to the items of this list, the only additional piece of code you must add is a loop around the SPList items and set the properties in the chosen SPLIstItem object.
Now the code:

   11         private void SetPermissionsForTheList(SPList selectedList)
   12         {
   13             // breaks the inheritance from the parent
   14             selectedList.BreakRoleInheritance(true);
   15 
   16             //removes all the permissions from the list, except for 'site - admins'
   17             while (selectedList.RoleAssignments.Count > 0)
   18                 selectedList.RoleAssignments.Remove(0);
   19 
   20             if (selectedList.RoleAssignments.Count == 0)
   21             {
   22                 // get the defined site admins group
   23                 SPGroupCollection groupCollection = selectedList.ParentWeb.SiteGroups;
   24                 SPGroup group = groupCollection["Site - Admins"];
   25 
   26                 // get the full access role definition
   27                 SPRoleDefinitionCollection roleDefCollection = selectedList.ParentWeb.RoleDefinitions;
   28                 SPRoleDefinition roleDefinition = roleDefCollection [0];
   29 
   30                 // create a role assignment based on the site admin group
   31                 // and bind to the full access role definition
   32                 SPRoleAssignment roleAssignment = new SPRoleAssignment((SPPrincipal)group);
   33 
   34                 roleAssignment.RoleDefinitionBindings.Add(roleDefinition);
   35 
   36                 selectedList.RoleAssignments.Add(roleAssignment);
   37             }
 
As a final note, remember that all this can be accomplished via the interface and by doing this SharePoint will verify and test if any rule isn't being broken during the process. By doing this programmatically you are easily introducing a new level of complexity in the SharePoint ecosystem. Via code, you can set any kind of permissions you want to any given user. PLAN AHEAD. Make sure you are not overwriting permissions that can be conflicting with other areas in the site collection.
See you later.

By

2 comments:

  1. AWESOME! thanks for the code. I was actually looking for this as of today.

    ReplyDelete
  2. thank god for the internet and I will copy and past that code exactly how it is :DDDD

    keep up the good work Edge

    ReplyDelete