Thursday, October 23, 2008

Managing permissions on SharePoint list items

As we know that, permissions in SharePoint are inherited only up to SharePoint list and are applied on all SharePoint list items. If we want to control the permissions on the list item based on a particular field on the list entry/edit from then it is not possible through SharePoint Out Of Box feature.
I got a requirement from my client, asking me that, certain list items should be only be visible to particular SharePoint groups based on the selected condition on the list items entry/edit form. Let's say I have a checkbox named "Is Confidential Project". If the user selects this checkbox in the list entry/edit form then this particular list item should only be visible to Administrators of the SharePoint site and Confidential Projects Access SharePoint group. To implement this requirement I have decided to write an event handler on the SharePoint list in "ItemAdded" and "ItemUpdated" methods.
const string confidentialProjectsAccessGroupName = "Confidential Projects Access";
const string administratorsGroupName = "Owners";
private void setListItemPermissions(SPItemEventProperties properties)
{
Guid webGuid = Guid.Empty;
using (SPWeb webInUserContext = properties.OpenWeb())
{
webGuid = webInUserContext.ID;
}
Guid siteGuid = properties.SiteId;

SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite siteCollection = new SPSite(siteGuid))
{
SPWeb oWebsite = siteCollection.OpenWeb(webGuid);
oWebsite.AllowUnsafeUpdates = true;
SPList oList = oWebsite.Lists[properties.ListId];
bool isConfidentialProject = false;
if (!string.IsNullOrEmpty(properties.AfterProperties["Confidential _x0020_ Project "].ToString().Trim()))
{
isConfidentialProject = Convert.ToBoolean(properties.AfterProperties["Confidential _x0020_ Project "].ToString().Trim());
}
//string projectAccess = properties.AfterProperties["Project_x0020_Access"].ToString().Trim();
SPListItem listItem = oList.GetItemById(properties.ListItemId);

if (isConfidentialProject)
{
if (!listItem.HasUniqueRoleAssignments)
{
listItem.BreakRoleInheritance(true);
}

//Loops over all the roles that exist in the item, removes the bindings
foreach (SPRoleAssignment roleAssignment in listItem.RoleAssignments)
{
//delete the existing permissions
roleAssignment.RoleDefinitionBindings.RemoveAll();
roleAssignment.Update();
}

oWebsite.AllowUnsafeUpdates = true;
/*When any object that implements ISecurable (those are SPWeb, SPList and SPListItem) breaks or reverts their role
* definition inheritance. This means every time you call SPRoleDefinitionCollection.BreakInheritance(),
* BreakRoleInheritance(), ResetRoleInheritance() or set the value of HasUniquePerm the AllowUnsafeUpdates
* property of the parent web will reset to its default value and you may need to set it back to true in order to
* do further updates to the same objects. http://hristopavlov.wordpress.com/2008/05/16/what-you-need-to-know-about-allowunsafeupdates/*/


SPRoleDefinition RoleDefinitionContributor = oWebsite.RoleDefinitions.GetByType(SPRoleType.Contributor);
SPRoleDefinition RoleDefinitionAdministrator = oWebsite.RoleDefinitions.GetByType(SPRoleType.Administrator);
/*SPRoleAssignment RoleAssignment = new SPRoleAssignment("\\", "email", "name", "notes");
RoleAssignment.RoleDefinitionBindings.Add(RoleDefinition);*/

SPGroup spGroupOwners = oWebsite.Groups[administratorsGroupName];
SPRoleAssignment RoleAssignmentOwners = new SPRoleAssignment(spGroupOwners);
RoleAssignmentOwners.RoleDefinitionBindings.Add(RoleDefinitionAdministrator);

SPGroup spGroupconfidentialProjectsAccess = oWebsite.Groups[confidentialProjectsAccessGroupName];
SPRoleAssignment RoleAssignmentContributor = new SPRoleAssignment(spGroupconfidentialProjectsAccess);
RoleAssignmentContributor.RoleDefinitionBindings.Add(RoleDefinitionContributor);

listItem.RoleAssignments.Add(RoleAssignmentOwners);
listItem.RoleAssignments.Add(RoleAssignmentContributor);
}
else
{
if (listItem.HasUniqueRoleAssignments)
{
listItem.ResetRoleInheritance();
}
}

this.DisableEventFiring();
listItem.Update();
this.EnableEventFiring();
oWebsite.AllowUnsafeUpdates = false;
oWebsite.Dispose();
}
});
}

In the above I have used "SPSecurity.RunWithElevatedPrivileges(delegate()" delegate since the logged in user may not have permissions to modify permissions on the SharePoint list items. RunWithElevatedPrivileges allows the logged in user to gain full control irrespective of his permissions on this list. I am using "listItem.BreakRoleInheritance(true);", which breaks the present inherited permissions on the list. Next I had removed all the existing permissions on the list and added my own permissions in the SharePoint list items.

1 comment:

  1. Hi Bharat,

    I have exactly same requirement and searched a lot in google to implement. Finally, found your blog. Thanks!!

    --aaroh

    ReplyDelete