Wednesday, September 3, 2014

Custom SharePoint web service - item level permissions


If you are reading this post, you have propably already found out that SharePoint 2010 native web services do not support setting permissions on an item level. Luckily you can create one yourself.

Again, im not going to cover the basics about creating a web service for SharePoint 2010. You can find an answer to that in my other post regarding SharePoint web services.

So here is the code for the web service that allows you to set permissions on an single item or a document:
   public class Service : System.Web.Services.WebService  
   {  
     public Service()  
     {  
     }  
     [WebMethod]  
     public string ItemPermission(string SitePath, string LibName, string ItemId, string Permissions)  
     {  
       // Permission setting pattern User/Group;#UserLoginName/GroupName;#Reader/Contributor  
       string ReturnVal = "Permission set. OK!";  
       string[] userGroupPermissions;  
       userGroupPermissions = Permissions.Split(new string[] { ";#" }, StringSplitOptions.None);  
       int multiplier = 0;  
       string[][] permissionMatrix = new string[multiplier][];  
       try  
       {  
         multiplier = (userGroupPermissions.Length) / 3;  
         permissionMatrix = new string[multiplier][];  
         for (int i = 1; i <= multiplier; i++)  
         {  
           permissionMatrix[i - 1] = new string[3];  
           for (int a = 0; a < 3; a++)  
           {  
             permissionMatrix[i - 1][a] = userGroupPermissions[((i - 1) * 3) + a];  
           }  
         }  
       }  
       catch (Exception e)  
       {  
         ReturnVal = "Permission string is not valid. Peale use pattern ;#User/Group;#UserLoginName/GroupName;#Reader/Contributor;# .\r\n Exception: " + e.Message + "\r\n StackTrace: " + e.StackTrace;  
       }  
       try  
       {  
         SPSecurity.RunWithElevatedPrivileges(delegate()  
         {  
         SPSite WebApp = new SPSite(SitePath);  
         SPWeb Site = WebApp.OpenWeb();  
         SPList list = Site.Lists[LibName];  
         SPQuery newSPQuery = new SPQuery();  
         newSPQuery.Query = "<Where><Eq><FieldRef Name='ID' /><Value Type='Counter'>" + ItemId + "</Value></Eq></Where>";  
         newSPQuery.ViewAttributes = "Scope=\"RecursiveAll\"";  
         SPListItemCollection listItemCol = list.GetItems(newSPQuery);  
           if (listItemCol.Count > 0)  
           {  
             foreach (SPListItem item in listItemCol)  
             {  
               if (!item.HasUniqueRoleAssignments)  
               {  
                 item.BreakRoleInheritance(true);  
               }  
               Site.EnsureUser(this.User.Identity.Name);  
               SPUser CurrentUser = Site.EnsureUser(this.User.Identity.Name);  
               SPRoleAssignmentCollection SPRoleAssColn = item.RoleAssignments;  
               for (int i = SPRoleAssColn.Count - 1; i >= 0; i--)  
               {  
                   SPRoleAssColn.Remove(i);  
               }  
               WebApp.AllowUnsafeUpdates = true;  
               Site.AllowUnsafeUpdates = true;  
               item.Update();  
               SPRoleDefinition RoleDefinition;  
               for (int i = 0; i < multiplier; i++)  
               {  
                 if (permissionMatrix[i][2] == "Contributor") { RoleDefinition = Site.RoleDefinitions.GetByType(SPRoleType.Contributor); }  
                 else { RoleDefinition = Site.RoleDefinitions.GetByType(SPRoleType.Reader); }  
                 if (permissionMatrix[i][0] == "Group")  
                 {  
                   SPGroup spGroup = Site.SiteGroups[permissionMatrix[i][1]];  
                   SPRoleAssignment RoleAssignment = new SPRoleAssignment(spGroup);  
                   RoleAssignment.RoleDefinitionBindings.Add(RoleDefinition);  
                   item.RoleAssignments.Add(RoleAssignment);  
                 }  
                 else if (permissionMatrix[i][0] == "User")  
                 {  
                   SPUser spUser = Site.EnsureUser(permissionMatrix[i][1]);  
                   SPRoleAssignment RoleAssignment = new SPRoleAssignment(spUser);  
                   RoleAssignment.RoleDefinitionBindings.Add(RoleDefinition);  
                   item.RoleAssignments.Add(RoleAssignment);  
                 }  
               }  
               WebApp.AllowUnsafeUpdates = true;  
               Site.AllowUnsafeUpdates = true;  
               item.Update();  
             }  
           }  
           WebApp.AllowUnsafeUpdates = false;  
           Site.AllowUnsafeUpdates = false;  
         });  
       }  
       catch (Exception ex)  
       {  
         ReturnVal = "Permission not set, reason: " + ex.Message + "\r\n StackTrace: " + ex.StackTrace;  
       }  
       return ReturnVal;  
     }  
   }  

The code is a bit of a mess, but it works. I will walk you trough it.

Because this web service allows you to set permissions for multiple users and groups with single soap request, we are first going to find out how many users or groups are there defined. 

Next we are making a query to find our item we wish to set permissions on.

Then we will loop through all the permissions that the item already has and delete them. It was something that was needed for my integration project and i didn't want to write two more methods for viewing and deleting item permissions.

I had only two permission sets that needed to be set, so next i loop through all the users and groups that are defined in the request and set them right permission sets and finally add these users with right permission to the item.

You can access the web service from
http://{yourservername:port}/_layouts/ItemLevelPermission/ItemLevelPermission.asmx

There you can find a method named ItemPermission. Here is an example of a soap request:

 <soap:envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">  
  <soap:body>  
   <itempermission xmlns="http://tempuri.org/">  
    <sitepath>http://sharepoint:80</sitepath>  
    <libname>Documents</libname>  
    <itemid>1234</itemid>  
    <permissions>User;#CONTOSO\adm.user;#Reader;#Group;#Administrators;#Contributor</permissions>  
   </itempermission>  
  </soap:body>  
 </soap:envelope>  

Test it with SoapUI. Here are instructions how to Using SoapUI to test SharePoint web services.

Source: http://bit.ly/1uyfM2G
.wsp: http://bit.ly/1nwEL2t

No comments:

Post a Comment