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