Tuesday, April 5, 2016

Grant unique permissions to Sharepoint group on web site using client object model

Sometime we need to assign unique permissions on Sharepoint site. Suppose that we have Content Producers group and need to grant Contribute permission on the site. The following example shows how to do it using client object model:

   1: var clientContext = new ClientContext("http://example.com");
   2: clientContext.Credentials = credentials;
   3: var web = clientContext.Web;
   4:  
   5: clientContext.Load(web);
   6: clientContext.ExecuteQueryRetry();
   7:  
   8: var permissions = new List<PermissionEntity>();
   9: permissions.Add(new PermissionEntity
  10: {
  11:     GroupName = "Content Producers",
  12:     RoleType = "Contribute"
  13: });
  14: SetPermission(clientContext, web, permissions);
  15:  
  16: public static void SetPermission(ClientContext clientContext, Web newSubSite,
  17:     List<PermissionEntity> permissions)
  18: {
  19:     clientContext.Load(newSubSite, w => w.RoleAssignments,
  20:         w => w.RoleDefinitions,
  21:         w => w.SiteGroups,
  22:         w => w.HasUniqueRoleAssignments);
  23:     clientContext.ExecuteQueryRetry();
  24:  
  25:     foreach (var p in permissions)
  26:     {
  27:         var group = newSubSite.SiteGroups.FirstOrDefault(g =>
  28:             string.Compare(g.LoginName, p.GroupName, true) == 0);
  29:         if (group == null)
  30:         {
  31:             return;
  32:         }
  33:  
  34:         if (roleAssigned(clientContext, newSubSite, group, p.RoleType))
  35:         {
  36:             continue;
  37:         }
  38:  
  39:         if (!newSubSite.HasUniqueRoleAssignments)
  40:         {
  41:             newSubSite.BreakRoleInheritance(true, true);
  42:             clientContext.ExecuteQueryRetry();
  43:         }
  44:  
  45:         newSubSite.AddPermissionLevelToGroup(p.GroupName, p.RoleType);
  46:     }
  47: }
  48:  
  49: public static bool roleAssigned(ClientContext clientContext, Web web, Group group,
  50:     string roleType)
  51: {
  52:     foreach (var roleAssignment in web.RoleAssignments)
  53:     {
  54:         if (roleAssignment.PrincipalId == group.Id)
  55:         {
  56:             var rd = web.RoleDefinitions.GetByName(roleType);
  57:             var roleDefinitionBindings = roleAssignment.RoleDefinitionBindings;
  58:             clientContext.Load(rd);
  59:             clientContext.Load(roleDefinitionBindings);
  60:             clientContext.ExecuteQueryRetry();
  61:             foreach (var rdb in roleDefinitionBindings)
  62:             {
  63:                 if (rdb.RoleTypeKind == rd.RoleTypeKind)
  64:                 {
  65:                     return true;
  66:                 }
  67:             }
  68:         }
  69:     }
  70:     return false;
  71: }
  72:  
  73: public class PermissionEntity
  74: {
  75:     public string GroupName;
  76:     public string RoleType;
  77: }

In this example we used helper extension method AddPermissionLevelToGroup from Office365 Developer Patterns and Practices project, which at the end implemented like this:

   1: private static void AddPermissionLevelImplementation(
   2:     this SecurableObject securableObject,
   3:     Principal principal, RoleDefinition roleDefinition,
   4:     bool removeExistingPermissionLevels = false)
   5: {
   6:     if (principal == null)
   7:     {
   8:         return;
   9:     }
  10:     RoleAssignmentCollection roleAssignments = securableObject.RoleAssignments;
  11:     securableObject.Context.Load(roleAssignments);
  12:     securableObject.Context.ExecuteQueryRetry();
  13:     RoleAssignment roleAssignment = roleAssignments.FirstOrDefault(ra =>
  14:         ra.PrincipalId.Equals(principal.Id));
  15:     if (roleAssignment == null)
  16:     {
  17:         RoleDefinitionBindingCollection roleDefinitionBindingCollection =
  18:             new RoleDefinitionBindingCollection(securableObject.Context);
  19:         roleDefinitionBindingCollection.Add(roleDefinition);
  20:         securableObject.RoleAssignments.Add(principal,
  21:             roleDefinitionBindingCollection);
  22:         securableObject.Context.ExecuteQueryRetry();
  23:         return;
  24:     }
  25:     RoleDefinitionBindingCollection roleDefinitionBindings =
  26:         roleAssignment.RoleDefinitionBindings;
  27:     securableObject.Context.Load(roleDefinitionBindings);
  28:     securableObject.Context.ExecuteQueryRetry();
  29:     if (removeExistingPermissionLevels)
  30:     {
  31:         roleDefinitionBindings.RemoveAll();
  32:     }
  33:     if (!roleDefinitionBindings.Any(r =>
  34:         r.Name.Equals(roleDefinition.EnsureProperty(rd => rd.Name))))
  35:     {
  36:         roleDefinitionBindings.Add(roleDefinition);
  37:         roleAssignment.ImportRoleDefinitionBindings(roleDefinitionBindings);
  38:         roleAssignment.Update();
  39:         securableObject.Context.ExecuteQueryRetry();
  40:     }
  41: }

This approach may be used to grant permissions both on-premise and in Sharepoint Online.

No comments:

Post a Comment