CopyCat: Using Built-in WebServices to Copy Document Library Permissions Across Servers

 

Here's a sample console application written in C# which will copy the permissions from one document library to another using the built-in Permissions.asmx WebService.  Note that this sample does not account for cross-domain use, etc.  This will *only* work if the same users exist on the destination.  Overall, this is a fairly rough sample, but it covers some good material, so I thought I'd go ahead and post here.  :)

 

The sample does the following:

 

-Gets the current destination list permissions using the web service on the destination site

-Removes the current destination list permissions using the web service on the destination site

-Gets the source list permissions using the web service on the source site

-Sets the destination list permissions using the web service on the destination site

 

This project will require adding a Web Reference -- to the Permissions web service on any machine (the URL will be overwritten in the code) -- in the VC# project.  Adding the Web Reference should add standard references to System.Web.Services, System.XML, and System.Data.

Two notes on this sample:

 

1) There is little error handling.

 

2) We cannot remove or add implicit members (Administrator, Guest) of a list. These members are automatically added when a list is created, and are not controlled by the user; as such, they can not be programmatically modified.

 

=====

 

using System;

using System.Xml;

using System.Diagnostics;

 

namespace CopyDocLibPermissions

{

public class AddWithWS

{

[STAThread]

static void Main(string[] args)

{

string sSourceSiteURL = "http://<server>/sites/<site1>"; //TODO: modify

string sSourceList = "MySourceList"; //TODO: modify

 

string sDestSiteURL = "http://<server>/sites/<site2>"; //TODO: modify

string sDestList = "MyDestinationList"; //TODO: modify

 

int iReturn = CopyPermissions(sSourceSiteURL, sSourceList, sDestSiteURL, sDestList);

 

Console.ReadLine();

}

 

static int CopyPermissions(string SourceSite, string SourceList, string DestSite, string DestList)

{

//get permissions from destination list

System.Xml.XmlNode xDestPerms = GetPermissions(DestSite, DestList);

 

//remove existing permissions from destination list

RemovePermissions(DestSite, DestList, xDestPerms);

 

//get source list permissions

System.Xml.XmlNode xSourcePerms = GetPermissions(SourceSite, SourceList);

 

//add source list permissions to destination list

SetPermissions(DestSite, DestList, xSourcePerms);

 

Console.WriteLine("==COMPLETE!==\n");

 

return 0;

}

 

static XmlNode GetPermissions(string URL, string ListName)

{

URL += "/_vti_bin/Permissions.asmx";

 

localhost.Permissions oPermissionsService = new localhost.Permissions();

oPermissionsService.Url = URL;

oPermissionsService.Credentials = System.Net.CredentialCache.DefaultCredentials;

 

try

{

XmlNode oNode = oPermissionsService.GetPermissionCollection(ListName, "List");

return oNode;

}

catch(System.Exception exGet)

{

Console.WriteLine("Error Getting Permissions!");

Debug.WriteLine(exGet.ToString());

return null;

}

 

}

static bool RemovePermissions(string URL, string ListName, XmlNode Permissions)

{

URL += "/_vti_bin/Permissions.asmx";

 

localhost.Permissions oPermissionsService = new localhost.Permissions();

oPermissionsService.Url = URL;

oPermissionsService.Credentials = System.Net.CredentialCache.DefaultCredentials;

 

XmlNodeList xNL = Permissions.FirstChild.ChildNodes;

 

string sPerm = "";

string sIsUser = "";

string sName = "";

string sType = "";

 

for(int i=0;i<xNL.Count;i++)

{

sIsUser = xNL[i].Attributes["MemberIsUser"].Value.ToString().ToUpper();

if(sIsUser == "TRUE")

{

//is user

sName = xNL[i].Attributes["UserLogin"].Value.ToString();

sType = "user";

}

else

{

sPerm = xNL[i].OuterXml.ToString();

if(sPerm.IndexOf("RoleName") > 0)

{

//is Role

sName = xNL[i].Attributes["RoleName"].Value.ToString();

sType = "role";

}

else

{

//is group

sName = xNL[i].Attributes["GroupName"].Value.ToString();

sType = "group";

}

}

 

try

{

oPermissionsService.RemovePermission(ListName, "List", sName, sType);

Console.WriteLine("Permission Removed: {0}", sName);

}

catch(System.Exception exRemove)

{

Console.WriteLine("Can't Remove Permission: {0}",sName);

Debug.WriteLine(exRemove.ToString());

}

 

}

 

return true;

}

 

static bool SetPermissions(string URL, string ListName, XmlNode Permissions)

{

URL += "/_vti_bin/Permissions.asmx";

 

localhost.Permissions oPermissionsService = new localhost.Permissions();

oPermissionsService.Url = URL;

oPermissionsService.Credentials = System.Net.CredentialCache.DefaultCredentials;

 

XmlNodeList xNL = Permissions.FirstChild.ChildNodes;

 

string sPerm = "";

string sIsUser = "";

string sName = "";

string sType = "";

int iMask = 0;

 

for(int i=0;i<xNL.Count;i++)

{

sIsUser = xNL[i].Attributes["MemberIsUser"].Value.ToString().ToUpper();

iMask = Int32.Parse(xNL[i].Attributes["Mask"].Value);

 

if(sIsUser == "TRUE")

{

//is user

sName = xNL[i].Attributes["UserLogin"].Value.ToString();

sType = "user";

}

else

{

sPerm = xNL[i].OuterXml.ToString();

if(sPerm.IndexOf("RoleName") > 0)

{

//is Role

sName = xNL[i].Attributes["RoleName"].Value.ToString();

sType = "role";

}

else

{

//is group

sName = xNL[i].Attributes["GroupName"].Value.ToString();

sType = "group";

}

}

 

try

{

oPermissionsService.AddPermission(ListName, "List", sName, sType, iMask);

Console.WriteLine("Permission Added: {0}", sName);

}

catch(System.Exception exAdd)

{

Console.WriteLine("Can't Add Permission: {0}",sName);

Debug.WriteLine(exAdd.ToString());

}

 

}

 

return true;

}

 

}

}