For one of our provider-hosted apps, we had a situation where we had to Grant and Remove permissions to folders in a Document Library of a SharePoint Online site.
This blog gives the code for achieving it. In the code, you will see how:
- It fetches the User ID and Password from the config file to log into the SharePoint site.
- It uses SecureString to secure the Password. You have to use “using System.Security” to achieve this.
- It also checks if the folder has unique permission before attempting to grant or remove permission. If not, it breaks the inheritance before granting or removing the permission.
- Both, GrantPermission and RemovePermission, methods take string array with user accounts. In my case, we have only the user id in the array, so you will see we add “@domain.com” to get the email Id.
So, here is the code to grant permission.
- private static void GrantPermissionTo(params string[] accounts)
- {
- var DocumentLibName= "<YourDocumentLibraryName>"
- context = new ClientContext(webUrl);
- context.Credentials = new SharePointOnlineCredentials(userId, FetchPasswordFromConsole());
- Web web = context.Web;
- context.Load(web);
- context.ExecuteQuery();
-
- context.Load(web.Lists);
- context.ExecuteQuery();
- context.Load(web.SiteUsers);
- context.ExecuteQuery();
- context.Load(web.RoleDefinitions);
- context.ExecuteQuery();
- context.Load(web.RoleAssignments);
- context.ExecuteQuery();
-
- var list = web.Lists.OfType<List>().FirstOrDefault(l => l.Title.Equals(DocumentLibName, StringComparison.CurrentCultureIgnoreCase));
- context.Load(list);
- context.Load(list.RootFolder);
- context.ExecuteQuery();
- context.Load(list.RootFolder.Folders);
- context.ExecuteQuery();
-
- var folderName = Path.GetFileName("<YourFolderName>");
- var folder = list.RootFolder.Folders.OfType<Folder>().FirstOrDefault(t => t.Name == folderName);
- if (folder == null)
- return;
- context.Load(folder);
- context.ExecuteQuery();
- context.Load(
- folder,
- fields => fields.ListItemAllFields,
- fields => fields.ListItemAllFields.HasUniqueRoleAssignments,
- fields => fields.ListItemAllFields.RoleAssignments);
- context.ExecuteQuery();
-
- if (!folder.ListItemAllFields.HasUniqueRoleAssignments)
- {
- folder.ListItemAllFields.BreakRoleInheritance(true, true);
- context.ExecuteQuery();
- }
-
- Array.ForEach(accounts, account =>
- {
- account = account+"@"+<YourDomain>+".com";
- try
- {
- RoleDefinition def;
-
- def = web.RoleDefinitions.GetByName("Read");
-
- def = web.RoleDefinitions.GetByName("Contribute");
- RoleDefinitionBindingCollection rdb = new RoleDefinitionBindingCollection(context);
- rdb.Add(def);
- Principal usr = context.Web.EnsureUser(account);
- folder.ListItemAllFields.RoleAssignments.Add(usr, rdb);
- }
- catch (Exception ex)
- {
- WriteLogMessage(ex.Message);
- }
- });
- folder.Update();
- context.ExecuteQuery();
- }
And this is the code to remove permission.
- private static void RemovePersmissionFrom(params string[] accounts)
- {
- var DocumentLibName= "<YourDocumentLibraryName>"
- context = new ClientContext(webUrl);
- context.Credentials = new SharePointOnlineCredentials(userId, FetchPasswordFromConsole());
- Web web = context.Web;
- context.Load(web);
- context.ExecuteQuery();
-
- var web = WebSite;
- context.Load(web.Lists);
- context.ExecuteQuery();
- context.Load(web.SiteUsers);
- context.ExecuteQuery();
- context.Load(web.RoleDefinitions);
- context.ExecuteQuery();
- context.Load(web.RoleAssignments);
- context.ExecuteQuery();
-
- var list = web.Lists.OfType<List>().FirstOrDefault(l => l.Title.Equals(DocumentLibName, StringComparison.CurrentCultureIgnoreCase));
-
- context.Load(list);
- context.ExecuteQuery();
-
- context.Load(list.RootFolder);
- context.ExecuteQuery();
- context.Load(list.RootFolder.Folders);
- context.ExecuteQuery();
-
- var folderName = Path.GetFileName("Your folder Name");
- var folder = list.RootFolder.Folders.OfType<Folder>().FirstOrDefault(t => t.Name == folderName);
- if (folder == null)
- return;
- context.Load(folder);
-
- context.ExecuteQuery();
- context.Load(
- folder,
- fields => fields.ListItemAllFields,
- fields => fields.ListItemAllFields.HasUniqueRoleAssignments,
- fields => fields.ListItemAllFields.RoleAssignments);
- context.ExecuteQuery();
-
- if (!folder.ListItemAllFields.HasUniqueRoleAssignments)
- {
- folder.ListItemAllFields.BreakRoleInheritance(true, true);
- context.ExecuteQuery();
- }
-
- Array.ForEach(accounts, account =>
- {
- account = account+"@"+<YourDomain>+".com";
- try
- {
- web.EnsureUser(account);
- var user = web.SiteUsers.OfType<User>().FirstOrDefault(u => u.LoginName.Equals(account, StringComparison.CurrentCultureIgnoreCase));
- context.Load(user);
- context.ExecuteQuery();
- if (user != null)
- {
- var user_group = web.SiteUsers.GetByLoginName(user.LoginName);
- folder.ListItemAllFields.RoleAssignments.GetByPrincipal(user_group).DeleteObject();
- context.ExecuteQuery();
- }
- var def = web.RoleDefinitions.GetByName("Read");
- RoleDefinitionBindingCollection rdb = new RoleDefinitionBindingCollection(context);
- rdb.Add(def);
- Principal usr = context.Web.EnsureUser(account);
- folder.ListItemAllFields.RoleAssignments.Add(usr, rdb)
-
- }
- catch (Exception ex)
- {
- WriteLogMessage(ex.Message);
- HandleError(ex);
- }
-
- });
- folder.Update();
- context.ExecuteQuery();
- }
As mentioned above, we secured the password using SecureString and here is the code for that:
- private static SecureString FetchPasswordFromConsole()
- {
- string password = System.Configuration.ConfigurationSettings.AppSettings["Password"].ToString();
- Console.WriteLine();
- var securePassword = new SecureString();
- foreach (char c in password)
- securePassword.AppendChar(c);
- securePassword.MakeReadOnly();
- return securePassword;
- }
Hope this is useful.