Recently, a colleague of mine was working on a SharePoint event handler to automatically apply security to an item on insert into a list. In performing my own research on the topic, I came to realize there wasn’t a lot of concise or really usable information out there on the Interwebs about programmatically modifying the security and roles for a list item. An additional constraint was that the list of users and groups to be added were contained in SharePoint “Users or Groups” column in another list.
After a lot of research and some time spent stubbing out a test harness, I came upon the solution and created a helper method with overloads that allows you to programmatically add security to a list item with a number of different options for how the user or group is passed in, including support for passing in a list of SPRoleDefinition items to grant to the security item:
- SPFieldUserValue - Useful if you're iterating through the values of a SharePoint User or Group column
- String – Useful for passing in an ActiveDirectory group or user account name (If the user or group don’t already have access to the site itself, they will be automatically added)
- SPPrincipal – Useful if you have an SPPrincipal, SPGroup, or SPUser object (since the latter two inherit from SPPrincipal).
#region addPermissionToListItem Overloads
/// <summary>
/// Applies role-based security to a user or group for a particular list item.
/// This overload is useful if you're iterating through the values of a SharePoint User or Group column.
/// </summary>
/// <param name="SharePointWeb">The SharePoint Web the List belongs to.</param>
/// <param name="ListItemToAddTo">The particular List Item to apply the security to.</param>
/// <param name="UserOrGroupToAdd">The SPFieldUserValue type from a SharePoint User or Group column.</param>
/// <param name="RolesToGrant">SPRoleDefinition items to apply to the user or group being added.</param>
private void addPermissionToListItem(SPWeb SharePointWeb, SPListItem ListItemToAddTo, SPFieldUserValue UserOrGroupToAdd, params SPRoleDefinition[] RolesToGrant)
{
if (SharePointWeb != null && ListItemToAddTo != null && UserOrGroupToAdd != null && RolesToGrant != null && RolesToGrant.Length > 0)
{
// Get SPPrincipal from the UserOrGroupToAdd parameter
SPPrincipal newItemToAdd;
if (UserOrGroupToAdd.User != null)
{
// We have a user
newItemToAdd = UserOrGroupToAdd.User as SPPrincipal;
}
else
{
// We have a group
newItemToAdd = SharePointWeb.SiteGroups.GetByID(UserOrGroupToAdd.LookupId) as SPPrincipal;
}
// Call the overload that accepts an SPPrincipal object to add to the list
addPermissionToListItem(ListItemToAddTo, newItemToAdd, RolesToGrant);
}
}
/// <summary>
/// Applies role-based security to a user or group for a particular list item.
/// This overload is useful if you only have the windows login id of a user or a group name.
/// If the user or group doesn't belong to the site, they will be automatically added.
/// </summary>
/// <param name="SharePointWeb">The SharePoint Web the List belongs to.</param>
/// <param name="ListItemToAddTo">The particular List Item to apply the security to.</param>
/// <param name="WindowsUserIdOrGroupToAdd">The SPFieldUserValue type from a SharePoint User or Group column.</param>
/// <param name="RolesToGrant">SPRoleDefinition items to apply to the user or group being added.</param>
private void addPermissionToListItem(SPWeb SharePointWeb, SPListItem ListItemToAddTo, string WindowsUserIdOrGroupToAdd, params SPRoleDefinition[] RolesToGrant)
{
if (SharePointWeb != null && ListItemToAddTo != null && WindowsUserIdOrGroupToAdd != null && RolesToGrant != null && RolesToGrant.Length > 0)
{
// Get SPPrincipal from the UserOrGroupToAdd parameter
SPPrincipal newItemToAdd;
if (Microsoft.SharePoint.Utilities.SPUtility.IsLoginValid(SharePointWeb.Site, WindowsUserIdOrGroupToAdd))
{
// We have a user
newItemToAdd = SharePointWeb.EnsureUser(WindowsUserIdOrGroupToAdd) as SPPrincipal;
}
else
{
// We have a group
SPGroup groupToAdd = SharePointWeb.SiteGroups[WindowsUserIdOrGroupToAdd];
if (groupToAdd != null)
{
// The group exists, so get it
newItemToAdd = groupToAdd as SPPrincipal;
}
else
{
// The group didn't exist so we need to create it:
// Create it:
SharePointWeb.SiteGroups.Add(WindowsUserIdOrGroupToAdd, SharePointWeb.Site.Owner, SharePointWeb.Site.Owner, string.Empty);
// Get it:
newItemToAdd = SharePointWeb.SiteGroups[WindowsUserIdOrGroupToAdd] as SPPrincipal;
}
}
// Call the overload that accepts an SPPrincipal object to add to the list
addPermissionToListItem(ListItemToAddTo, newItemToAdd, RolesToGrant);
}
}
/// <summary>
/// Applies role-based security to a user or group for a particular list item.
/// </summary>
/// <param name="ListItemToAddTo">The particular List Item to apply the security to.</param>
/// <param name="UserOrGroupToAdd">The SPFieldUserValue type from a SharePoint User or Group column.</param>
/// <param name="RolesToGrant">SPRoleDefinition items to apply to the user or group being added.</param>
/// <remarks>This overload is called by the other overloads to actually set the the security.</remarks>
private void addPermissionToListItem(SPListItem ListItemToAddTo, SPPrincipal UserOrGroupToAdd, params SPRoleDefinition[] RolesToGrant)
{
if (ListItemToAddTo != null && UserOrGroupToAdd != null && RolesToGrant != null && RolesToGrant.Length > 0)
{
// Create a new role assignment for the principal
SPRoleAssignment newRoleAssignmentToAdd = new SPRoleAssignment(UserOrGroupToAdd);
// Bind the role definitionss to the new role assignment
foreach (SPRoleDefinition roleDefinition in RolesToGrant)
{
if (roleDefinition != null)
{
newRoleAssignmentToAdd.RoleDefinitionBindings.Add(roleDefinition);
}
}
// Add the new role assignment to the list item
ListItemToAddTo.RoleAssignments.Add(newRoleAssignmentToAdd);
}
}
#endregion
I wrapped the overloads (titled addPermissionToListItem) in a winform test harness that linked below. The test harness will pull groups and users from a SharePoint “Users and Groups” column in a separate list, and use those items to replace any existing permissions on a specified list item (breaking inheritance along the way).
Test Harness Screenshot:
Test Harness and referenced code:
Applicable Code KeyWords: RoleDefinitionBindings, SPFieldUserValue, SPFieldUserValueCollection, SPGroup, SPPrincipal, SPRoleDefinition, SPUser