Sunday, July 22, 2007

Manage site/list/item permissions in SharePoint from C#

Hi guys,

I have a little code bit that allows you, once you have a permission level defined in your SharePoint site, to change a site/list/item permissions using C#.

As you may or may not know, WSS 3 and MOSS 2007 handles security in 3 levels:
1 - Permission - which cannot be used directly to give access to a user
2 - Permission Level - which can be used to give access to a user or to control a SharePoint group access
3 - SharePoint Group - which is much like a cross site group that handles permission levels and user assignments to a group that can be used in several sites in the same site collection that does not inherit permissions, but share the same contributors/readers etc.

This code allows you to break the permissions inheritance of a site / list / item and assign a user to a permission level on that object only.

So, without further ado, here it is:



public static void CreatePermissions(SPWeb theWeb, string loginName, string roleName, string permissionLevel)
{
try
{
theWeb = new SPSite(theWeb.Site.ID).OpenWeb(theWeb.ID);
theWeb.AllowUnsafeUpdates = true;

SPRoleAssignment roleAssignment = new SPRoleAssignment(loginName, "", roleName, "");

SPRoleDefinition RoleDefinition = theWeb.RoleDefinitions[permissionLevel];

if (!roleAssignment.RoleDefinitionBindings.Contains(RoleDefinition))
roleAssignment.RoleDefinitionBindings.Add(RoleDefinition);

//Check inheritance
if (!theWeb.HasUniqueRoleAssignments)
{
theWeb.BreakRoleInheritance(false);
}

theWeb.RoleAssignments.Add(roleAssignment);

//If user already exists - update its display name
try
{
SPUser user = null;
user = theWeb.Users[loginName];
user.Name = roleName;
user.Update();
}
catch { }

theWeb.Update();
}
catch (Exception exc)
{
}
}

public static void CreatePermissions(SPWeb theWeb, SPListItem ListItem, string loginName, string roleName, string permissionLevel)
{
try
{
theWeb = new SPSite(theWeb.Site.ID).OpenWeb(theWeb.ID);
theWeb.AllowUnsafeUpdates = true;

ListItem = theWeb.Lists[ListItem.ParentList.ID].GetItemById(ListItem.ID);

SPRoleAssignment roleAssignment = new SPRoleAssignment(loginName, "", roleName, "");

SPRoleDefinition RoleDefinition = theWeb.RoleDefinitions[permissionLevel];

if (!roleAssignment.RoleDefinitionBindings.Contains(RoleDefinition))
roleAssignment.RoleDefinitionBindings.Add(RoleDefinition);

//Check inheritance
if (!ListItem.HasUniqueRoleAssignments)
{
ListItem.BreakRoleInheritance(false);
}

ListItem.RoleAssignments.Add(roleAssignment);

ListItem.Update();

}
catch (Exception exc)
{
}
}

public static void CreatePermissions(SPWeb theWeb, SPList list, string loginName, string roleName, string permissionLevel)
{
try
{
theWeb = Utilities.Refresh(theWeb);

SPRoleAssignment roleAssignment = new SPRoleAssignment(loginName, "", roleName, "");

SPRoleDefinition RoleDefinition = theWeb.RoleDefinitions[permissionLevel];

if (!roleAssignment.RoleDefinitionBindings.Contains(RoleDefinition))
roleAssignment.RoleDefinitionBindings.Add(RoleDefinition);

//Check inheritance
if (!list.HasUniqueRoleAssignments)
{
list.BreakRoleInheritance(false);
}

list.RoleAssignments.Add(roleAssignment);

list.Update();

}
catch (Exception ex)
{
}
}

11 comments:

Anonymous said...

AMAZING. This works beautifully.

Thank you so much.

Titularizare said...

I was struggling for 2 days to figure it how to set ListItem permissions, and your article helped me a lot. Thanks!

Rob said...

hey man, what's with the empty catch statements?

Also, the 6th line needs to be wrapped in a using block:

using (theWeb = new SPSite(theWeb.Site.ID).OpenWeb(theWeb.ID))

Anonymous said...

hi buddy

this works but can you exclude programming with some simple tools or any kind of interfaces

Pious

Anonymous said...

Do you really have to use HasUniqueRoleAssignments before you call BrealRoleInheritance?

Shai Petel said...

Hi Rob,

This is just a code sample not production ready.

Hence no disposing and no error handling.

I put the try catch there to let you know this might invoke an error and you should implement your own error handler there.

You are right about your comments in real-life scenarios.

Thanks!

Anonymous said...

"This is just a code sample not production ready.
Hence no disposing and no error handling."


Some of us are learning by example found on the Web. How can we learn the proper way if nobody takes the time to post proper code? Please, show us the Microsoft Trainer way! ;op

Shai Petel said...

It's in the interest of saving time for the author (me in this case:) )

Error handling- meaningless in an example, as you may want to log or prompt your user based on your solution.

Regarding dispose, each call to new SPSite() CTor, as well as site.OpenWeb() method should be wrapped in using block like so:

using(SPSite site = new SPSite(...))
{
using(SPWeb web = site.OpenWeb(...))
{
//Handle web code in here
}
}

There is a great MSDN article on disposing of objects, this is why it felt right to leave it out for achieving a clearer code example that is easier to read.

Disposing objects in MSDN:
http://msdn.microsoft.com/en-us/library/aa973248(office.12).aspx

Prakash Madheswaran said...

Hi,
how to get item permission from one item and assign those permissions to a target item. In my case source item may have sharepoint group, domain group, claims or user..

Shai Petel said...

Hi Prakash,
This is a little out of scope and the post itself is pretty outdated.
According to which version of SharePoint you are using the answer will differ.

In a nutshell - you will have to get the source item's permissions, and if it inherits - get its first unique permissions ancestor (there is an API call for that).

Then you will have to break inheritance of permission in your target item and manually copy the same permission object from source to target item once by one.

This is not a practice I recommend. It's best if possible in these cases to create folders with the right permissions you need and just move items of same permission to the same folder. moving an item is better than manually applying permissions.

Phil said...

Thanks! This just helped with our SharePoint 2007 upgrade project.