Thursday, 27 July 2017

SharePoint: How to remove all permissions of a user using CSOM?


Visual Studio > Project > References > Manage NuGet Packages > Online > Search 'Microsoft.SharePointOnline.CSOM' > Accept and Install

Visual Studio > Project > References > Manage NuGet Packages > Online > Search 'OfficeDevPnP.Core' > Accept and Install


private void btnRemove_Click(object sender, EventArgs e)
{
try
{
    progressBar1.Minimum = 0;
    progressBar1.Maximum = 100;
    progressBar1.Value = 1;

    ClientContext context = new ClientContext(txtSiteUrl.Text);
    context.RequestTimeout = 9999999;
    string decryptedPwd = txtAdminPassword.Text;

    foreach (char c in decryptedPwd)
    {
      securePassword.AppendChar(c);
    }
    
    if (rbtnOnpremise.Checked)
    {
      context.Credentials = new NetworkCredential(GetEnterpriseIDFromEmail(txtAdminID.Text),
      securePassword,
      txtDomain.Text);
    }
    else if (rbtnOnline.Checked)
    {
      context.Credentials = new SharePointOnlineCredentials(GetEnterpriseIDFromEmail(txtAdminID.Text) +       "@companyname.com",
      securePassword);

//Multifactor Authentication
//PnP.AuthenticationManager authManager = new PnP.AuthenticationManager();

//context = authManager.GetWebLoginClientContext(txtSiteUrl.Text);
    }

    Web web = context.Web;
    context.Load(web, w => w.Title, w => w.HasUniqueRoleAssignments);
    context.ExecuteQuery();

    string usr_loginName = "i:0#.w|" + txtDomain.Text + "\\" + GetEnterpriseIDFromEmail(txtResourceID.Text);
    User usr = web.EnsureUser(usr_loginName);
    context.Load(usr);
    progressBar1.Value = 5;

    //Remove User from Site
    if (web.HasUniqueRoleAssignments)
    {
  //!!!ExpensiveOperation!!!web.SiteUsers.RemoveByLoginName(usr_loginName);

  try
  {
      RoleAssignment directPermission = web.RoleAssignments.GetByPrincipal(usr);
      directPermission.DeleteObject();
      context.ExecuteQuery();

  }
  catch { }
 
    }
    progressBar1.Value = 10;

    //Remove User from Groups
    if (chkRemoveFromGroups.Checked)
    {
      GroupCollection userGroups = web.SiteGroups;
      context.Load(userGroups);

      context.ExecuteQuery();

  foreach (Group grp in userGroups)
  {
    try
    {
    grp.Users.Remove(usr);
    context.ExecuteQuery();

    }
    catch { }
  }
 
  }
  progressBar1.Value = 30;

    //Remove User from Lists
   if (chkRemoveFromList.Checked)
   {
      ListCollection lists = web.Lists;
      context.Load(lists, lsts => lsts.Where(l => l.HasUniqueRoleAssignments == true &&
                        l.Hidden == false &&
                        l.IsApplicationList == false &&
                        l.IsSiteAssetsLibrary == false).
                        Include(l => l.HasUniqueRoleAssignments, l => l.Title));
      context.ExecuteQuery();

  foreach (List list in lists)
  {
   if (list.HasUniqueRoleAssignments)
   {
     try
     {
       RoleAssignment listLevelPermission = list.RoleAssignments.GetByPrincipal(usr);
       listLevelPermission.DeleteObject();
       context.ExecuteQuery();
     }
     catch { }

   }
  }
 
 }
 progressBar1.Value = 50;

    //Remove User from Items
 if (chkRemoveFromItems.Checked)
 {
   ListCollection lists = web.Lists;
   context.Load(lists, lsts => lsts.Where(l => l.Hidden == false &&
                        l.IsApplicationList == false &&
                        l.IsSiteAssetsLibrary == false).
                        Include(l => l.Title));
   context.ExecuteQuery();

   foreach (List list in lists)
   {
     CamlQuery camlQuery = new CamlQuery();
     camlQuery.ViewXml = "<View Scope=\"RecursiveAll\"><RowLimit>10000</RowLimit></View>";

    ListItemCollection collListItem = list.GetItems(camlQuery);
    context.Load(collListItem,
    items => items.Where(
    item => item.HasUniqueRoleAssignments == true).
    Include(
    item => item.Id,
    item => item.DisplayName,
    item => item.HasUniqueRoleAssignments));
    context.ExecuteQuery();

    foreach (ListItem item in collListItem)
    {
    if (item.HasUniqueRoleAssignments)
    {
     try
     {
      RoleAssignment itemLevelPermission = item.RoleAssignments.GetByPrincipal(usr);
      itemLevelPermission.DeleteObject();
      context.ExecuteQuery();
     }
     catch { }
    }
 }
 }
 }

 progressBar1.Value = 100;
 MessageBox.Show("User Permissions removed!");
}
catch (Exception ex)
{
    MessageBox.Show("Error: " + ex.Message);
    progressBar1.Value = 100;
}
}

Sunday, 9 July 2017

Best Practices: Using SPWeb and SPSite objects in server model.



1. Use dispose method, instead of Close, because SPWeb and SPSite objects implement the IDisposable interface, and standard .NET Framework garbage collection calls the Dispose method to free any resources associated with the object from memory.

2. Add try-finally block within foreach loop to dispose or close the current object.

foreach (SPSite siteCollectionInner in siteCollections)
        {
            try
            {
                // ...
            }
            finally
            {
                if(siteCollectionInner != null)
                    siteCollectionInner.Dispose();
            }
        }

3. Test null before disposing:

finally
{
   if (oSPWeb != null)
     oSPWeb.Dispose();

   if (oSPSite != null)
      oSPSite.Dispose();
}

4. Use 'using' with SPSite and SPWeb. This will automatically create a finnaly block to dispose the object.

5. Never use 'using' on objects created/returned by SPContext. Because, SPContext returns managed objects.

6. Bad Coding Practice:

using (SPWeb web = new SPSite(SPContext.Current.Web.Url).OpenWeb())
    {
        // SPSite leaked !
    } // SPWeb object web.Dispose() automatically called.

Good Practice:

using (SPSite siteCollection = new SPSite("http://url"))
    {
        using (SPWeb web = siteCollection.OpenWeb())
        {
        } // SPWeb object web.Dispose() automatically called.
    }  // SPSite object siteCollection.Dispose() automatically called.

7. In general, any time a calling application uses the new SPSite constructors (any signature), it should call the Dispose() method when it is finished using the object. If the SPSite object is obtained from GetContextSite(), the calling application should not dispose of the object. Because the SPWeb and SPSite objects keep an internal list that is derived in this way, disposing of the object may cause the SharePoint object model to behave unpredictably. Internally, Windows SharePoint Services enumerates over this list after page completion to dispose of the objects properly.

Source: https://msdn.microsoft.com/en-us/library/aa973248.aspx

Monday, 3 July 2017

SharePoint: How to remove all permissions of a user using Server Object Model?


protected void RemovePermission(string siteUrl)
        {
            try
            {
                string userToBeRemoved = txtResourceID.Text.Trim();
                if (string.IsNullOrEmpty(userToBeRemoved))
                {
                    lblMessage.Text = "Enter the enterprise id of the rolled off resource (without '@companyname.com').";
                }
                else
                {
                    if (userToBeRemoved.Contains("@"))
                    {
                        userToBeRemoved = userToBeRemoved.Split('@')[0];
                    }

                    using (SPSite site = new SPSite(siteUrl))
                    {
                        using (SPWeb web = site.OpenWeb())
                        {
                            web.AllowUnsafeUpdates = true;
                            SPPrincipal user = web.EnsureUser("Domain_name\\" + userToBeRemoved);

                            try
                            {
                                if (web.HasUniqueRoleAssignments)
                                {
                                    SPRoleAssignmentCollection webRollColl = web.RoleAssignments;
                                    webRollColl.Remove(user);
                                    web.Update();
                                }
                            }
                            catch { }


                            SPListCollection lists = web.Lists;
                            foreach (SPList list in lists)
                            {
                                try
                                {
                                    if (list.HasUniqueRoleAssignments)
                                    {
                                        if (list.BaseTemplate == SPListTemplateType.GenericList || list.BaseTemplate == SPListTemplateType.DocumentLibrary)
                                        {
                                            if (list.Hidden == false || list.IsSiteAssetsLibrary == false || list.IsApplicationList == false)
                                            {
                                                SPRoleAssignmentCollection listRollColl = list.RoleAssignments;
                                                listRollColl.Remove(user);
                                                list.Update();
                                            }
                                        }
                                    }

                                }
                                catch { }
                            }


                            SPGroupCollection groupColl = web.Groups;
                            foreach (SPGroup group in groupColl)
                            {
                                try
                                {
                                    group.Users.Remove("i:0#.w|Domain_name\\" + userToBeRemoved);
                                    group.Update();
                                }
                                catch { }
                            }

                        }
                    }

                }
            }
            catch { throw; }


        }


Note: webRollColl.Remove(user); will also delete the role assignment for the same user in all lists/items that have unique role assignments. This can be useful to remove permissions for outgoing employees. But, may not be required in all the cases. This cascading effect will slow down a site with too many items.

So, to remove permission only from the site/targeted level use:


foreach (SPRoleAssignment roleAssignment in web.RoleAssignments)
{
                            roleAssignment.RoleDefinitionBindings.Remove(roleDef);
roleAssignment.Update();

}

SPQuery: How to check for blank fields?


Query to filter empty SharePoint fields:

                SPQuery query = new SPQuery();

                query.Query = "<Where>" +

                    "<Or>" +
                    "<IsNotNull><FieldRef Name='Hobbies'/></IsNotNull>" +
                    "<Neq><FieldRef Name='Hobbies'/><Value Type='Text'></Value></Neq>" +
                    "</Or>" +

                    "</Where>" +
                    "<OrderBy>" +
                    "<FieldRef Name='Created' Ascending='FALSE' />" +
                     "</OrderBy>";