Invop
Invop

Reputation: 35

How to copy folder permission from source to target

I have a code that copies a folder structure from 1 site to another, the question is how to copy folder access if the groups have the same name in 2 sites.

Group Title: PTO
Group Title: IK
Group Title: ITN
Group Title: DESIGNER
Group Title: CUSTOMER
Group Title: CONTRACTOR\

using PnP.Framework;
using Microsoft.SharePoint.Client;
using Folder = Microsoft.SharePoint.Client.Folder;
        public void CopyFolderStructureBetweenSites(string siteUrl)
        {
            string sourceSiteUrl = "MYSITEURL";
            string sourceLibraryName = "Documents";
            string targetLibraryName = "Documents";
            string folderName = "General";
            using ClientContext sourceContext  = GetSharePointContext(_clientId, _certPath, _certPass, _tenantName,
                sourceSiteUrl);
            using ClientContext targetContext = GetSharePointContext(_clientId, _certPath, _certPass, _tenantName,
                       siteUrl);
            
                // Getting the folder to copy from the source library
                Folder sourceFolder = GetFolder(sourceContext, sourceLibraryName, folderName);
                if (sourceFolder != null)
                {
                    // Check if the target library exists, if not, create it
                    List targetLibrary = EnsureTargetLibrary(targetContext, targetLibraryName);

                    CopyFolder(sourceContext, targetContext, sourceFolder, targetLibrary);
                    Console.WriteLine("Done.");
                }
                else
                {
                    Console.WriteLine("Unluck.");
                }
            
        }
        private void CopyFolder(ClientContext sourceContext, ClientContext targetContext, Folder sourceFolder, List targetLibrary)
        {
            targetContext.Load(targetLibrary.RootFolder);
            targetContext.ExecuteQuery();

            var folderUrl = targetLibrary.RootFolder.ServerRelativeUrl + "/" + sourceFolder.Name;
            Folder newFolder = targetLibrary.RootFolder.Folders.Add(sourceFolder.Name);
            targetContext.ExecuteQuery();
            CopyFolderRecursive(sourceContext, targetContext, sourceFolder, newFolder);
        }
        private void CopyFolderRecursive(ClientContext sourceContext, ClientContext targetContext, Folder sourceFolder, Folder targetFolder)
        {
            sourceContext.Load(sourceFolder.Files);
            sourceContext.Load(sourceFolder.Folders);
            sourceContext.ExecuteQuery();

            foreach (Folder subFolder in sourceFolder.Folders)
            {
                var newTargetFolder = targetFolder.Folders.Add(subFolder.Name);
                targetContext.ExecuteQuery();
                CopyFolderRecursive(sourceContext, targetContext, subFolder, newTargetFolder);
            }
        }

Upvotes: 0

Views: 179

Answers (1)

Invop
Invop

Reputation: 35

In general, with a little help from AI, I solved the problem.
CopyFolderPermissions handles copying permissions from one folder to another. It does this by iterating through all the role assignments in the source folder, copying those assignments to the destination folder. This involves getting the group (if it exists), dropping all relevant roles (except for limited access), and then adding those roles to the target folder.
CopyFolder deals with copying the contents of a folder from the source folder to the target folder. This includes creating subfolders and calling the CopyFolderPermissions function to copy permissions. The function recursively processes all subfolders and copies their contents and permissions.

        private void CopyFolderPermissions(ClientContext sourceCtx, ClientContext targetCtx, Folder sourceFolder, Folder targetFolder, string sourceDisplayName, string targetDisplayName)
    {
        var roleAssignments = sourceFolder.ListItemAllFields.RoleAssignments;
        sourceCtx.Load(roleAssignments);
        sourceCtx.ExecuteQuery();

        foreach (var assignment in roleAssignments)
        {
            var roleDefinitionBindings = assignment.RoleDefinitionBindings;
            sourceCtx.Load(assignment.Member);
            sourceCtx.Load(roleDefinitionBindings);
            sourceCtx.ExecuteQuery();

            // Replace the display name in the group's login name
            var groupName = assignment.Member.LoginName.Replace(sourceDisplayName, targetDisplayName);
    
            Group principal = null;
            try 
            {
                principal = targetCtx.Web.SiteGroups.GetByName(groupName);
                targetCtx.Load(principal);
                targetCtx.ExecuteQuery();
            } 
            catch (ServerException) 
            { 
                // Do nothing, Group doesn't exist.
            }

            if(principal != null)
            {
                var newRoleDefBindings = new RoleDefinitionBindingCollection(targetCtx);
                foreach (var roleDef in roleDefinitionBindings)
                {
                    // exclude Limited Access level
                    if(roleDef.RoleTypeKind != RoleType.Guest)
                    {
                        newRoleDefBindings.Add(targetCtx.Web.RoleDefinitions.GetById(roleDef.Id));
                    }
                }

                // Stop inheriting permissions
                targetFolder.ListItemAllFields.BreakRoleInheritance(false, false);
        
                // Add new role assignments
                targetFolder.ListItemAllFields.RoleAssignments.Add(principal, newRoleDefBindings);
            }
        }

        targetCtx.ExecuteQuery();
    }
        private void CopyFolder(ClientContext sourceCtx, ClientContext targetCtx, Folder sourceFolder, Folder targetFolder, string sourceDisplayName, string targetDisplayName)
    {
        Folder newFolder;
        if (targetFolder.FolderExists(sourceFolder.Name))
        {
            newFolder = targetFolder.Folders.GetByUrl(sourceFolder.Name);
        }
        else
        {
            newFolder = targetFolder;
        }

        targetCtx.Load(newFolder);
        targetCtx.ExecuteQuery();

        CopyFolderPermissions(sourceCtx, targetCtx, sourceFolder, newFolder, sourceDisplayName, targetDisplayName);

        sourceCtx.Load(sourceFolder.Folders);
        sourceCtx.ExecuteQuery();

        foreach (Folder subFolder in sourceFolder.Folders)
        {
            // We need to create a subfolder in the newFolder for each subfolder in the sourceFolder
            Folder targetSubFolder;
            if (!newFolder.FolderExists(subFolder.Name))
            {
                targetSubFolder = newFolder.Folders.Add(subFolder.Name);
                targetCtx.ExecuteQuery();
            }
            else
            {
                targetSubFolder = newFolder.Folders.GetByUrl(subFolder.Name);
            }

            CopyFolder(sourceCtx, targetCtx, subFolder, targetSubFolder, sourceDisplayName, targetDisplayName);
        }
    }

Upvotes: 0

Related Questions