Question around Item Level permission in SharePoint 2007 came out so many times by now, well I lost the count. It is one of the most fundamental requirements of creating client centric SharePoint solutions, and it builds on concepts of Personalization and Audience Targeting, exactly where these two fail, and that is to provide appropriate security trimmings to the personalised content.
I have covered this in my Social Networking SharePoint session (among other things) at TechEd Africa this year and I decided (due to numerous requests) to post the methods and code from the presentation.
Requirement is often to make sure that people and roles with permissions to the same library don't have access to the documents/items with the same
There is four effective ways to use Item Level Permissions in your SharePoint solutions and here they are in order of simplicity:
1. Change appropriate Item Level Permissions manually for Document/Item in a library by simply clicking on the drop down menu of the item and clicking on "Manage Permissions" option. You will be presented with a list of permissions for that item lone and options to change it for each role/user.
2. Second option is in also OOB (Out of the Box), used mainly when the solution should limit the access of the submitted documents (for example) in the same library to the rest of the users that have access to the same library until that item has been approved by a relevant role (note that this can be for many reasons), and it requires turning on "Require content approval for submitted items?" which can be found when navigating to Library Setting (of Document Library for Example) eg Documents(library) > Settings > Versioning Settings.
From the Help Files:
"When this content approval setting is applied, an item or file that has been changed remains in a pending state until it is approved or rejected by someone who has permission to approve it. If the item or file is approved, it is assigned an Approved status in the list or library, and it is displayed to anyone with permission to view the list or library. If the item or file is rejected, it remains in a pending state and is visible only to the people with permission to view drafts.
By default, a pending item or file is visible only to its creator and to the people with permission to manage lists, but you can specify whether other groups of users can view the item or file."
3. Automate who should have the specific permissions by means of developing a Custom Event Handler by means of SPSecurity.RunWithElevatedPrivileges Method. This method executes the specified method with Full Control rights even if the user does not otherwise have Full Control. You'll most likely use asynchronous ItemAdded event in your custom event handler.
Here‘s the sample source code:
//the following code sample removes all permissions from an item and assigns only permissions of the current user to the document
using (SPWeb web = properties.OpenWeb())
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(web.Site.ID))
{
using (SPWeb impersonatedWeb = site.OpenWeb())
{
SPList impersonatedScList = impersonatedWeb.Lists[scorecardList.Title];
SPRoleDefinition RoleDefinition = impersonatedWeb.RoleDefinitions.GetByType(SPRoleType.Contributor);
SPPrincipal principal = (SPPrincipal)web.CurrentUser;
SPRoleAssignment RoleAssignment = new SPRoleAssignment(principal);
RoleAssignment.RoleDefinitionBindings.Add(RoleDefinition);
SPListItem impersonatedListItem = impersonatedScList.Items[properties.ListItem.UniqueId];
//break permission inheritance
if (!impersonatedListItem.HasUniqueRoleAssignments)
{
impersonatedListItem.BreakRoleInheritance(true);
}
SPRoleAssignmentCollection roleCollection = impersonatedListItem.RoleAssignments;
foreach (SPRoleAssignment assignment in roleCollection)
{
assignment.RoleDefinitionBindings.RemoveAll();
assignment.Update();
}
impersonatedListItem.RoleAssignments.Add(RoleAssignment);
impersonatedListItem.Update();
}
}
});
}
4. Same as number 3 however this example uses proper SharePoint Impersonation to impersonate the System Account. "Why?" you might ask, well because number 3 (above) does not always work and doesn't seem to always have the absolute privileges like it promises, hence why I strongly recommend you use this option, just to be on a safe side.
Here's the sample source code:
//the following code sample also removes all permissions from an item and assigns only permissions of the current user to the document
using (SPWeb web = properties.OpenWeb())
{
SPUser user = web.Users["SHAREPOINT\\SYSTEM"];
SPUserToken token = user.UserToken;
SPSite impersonatedSiteColl = new SPSite(web.Url, token);
using (SPWeb impersonatedWeb = impersonatedSiteColl.OpenWeb())
{
SPList impersonatedScList = impersonatedWeb.Lists[scorecardList.Title];
SPRoleDefinition RoleDefinition = impersonatedWeb.RoleDefinitions.GetByType(SPRoleType.Contributor);
SPPrincipal principal = (SPPrincipal)web.CurrentUser;
SPRoleAssignment RoleAssignment = new SPRoleAssignment(principal);
RoleAssignment.RoleDefinitionBindings.Add(RoleDefinition);
SPListItem impersonatedListItem = impersonatedScList.Items[properties.ListItem.UniqueId];
if (!impersonatedListItem.HasUniqueRoleAssignments)
{
impersonatedListItem.BreakRoleInheritance(true);
}
SPRoleAssignmentCollection roleCollection = impersonatedListItem.RoleAssignments;
foreach (SPRoleAssignment assignment in roleCollection)
{
assignment.RoleDefinitionBindings.RemoveAll();
assignment.Update();
}
impersonatedListItem.RoleAssignments.Add(RoleAssignment);
impersonatedListItem.Update();
}
}
Please note that the two code samples above (in case of required automation) belong in a properly deployed Custom Event Handler and NOT a Workflow. Although it might be tempting for those that are familiar with Workflow design and not familiar with Event Handlers to use the fact that each deployed workflow support activation on item added, please resist the temptation and adhere to best practices, otherwise you're causing unnecessary resource overhead and introducing a really bad design into your solution.