using System;
using System.Web;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.WebControls;
namespace KiranK.SharePointSite.EventHandlers
{
public class DownloadManager : SPItemEventReceiver
{
public override void ItemAdding(SPItemEventProperties properties)
{
try
{
this.DisableEventFiring();
//Get Security Level and Select Users/Groups values
string strSecLevel = properties.AfterProperties["Security_x0020_Level"].ToString().Trim();
string strUserOrGroups = properties.AfterProperties["Select_x0020_Users_x0020_or_x002"].ToString().Trim();
//If Specific User is selected, but Users/Groups is blank, we need to display an error message and prevent saving of the Item.
if (strSecLevel == "Specific User" & (strUserOrGroups == "" | strUserOrGroups == string.Empty))
{
properties.ErrorMessage = "The 'Select Users or Groups' field cannot be blank, if you select 'Specific User' as the Security Level for this Document." + "
" + "Please click on the Back button in the browser and select User(s) and/or Group(s).";
properties.Cancel = true;
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
this.EnableEventFiring();
}
}
public override void ItemAdded(SPItemEventProperties properties)
{
try
{
//This prevents the Event Receiver from running twice
this.DisableEventFiring();
//Collect the values entered by the user in the newly created Item in the Download Manager List
//Retrieve the properties associated with the newly created Item in the Download Manager List here
SPListItem dwdMgrItem = properties.ListItem;
//Get the Security Level value selected here
string strSecLevel = dwdMgrItem["Security Level"].ToString().Trim();
//Check if Security Level = Specific User
//If True, then we need to call the function that breaks role inhertitance from the Parent List, and implements Item Level permissions
if (strSecLevel == "Specific User")
{
BreakRoleInheritance(properties);
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
this.EnableEventFiring();
}
}
public void BreakRoleInheritance(SPItemEventProperties properties)
{
//Get the Users or Groups selected here
//Multiple Users are stored like this -> User or Group selected = 173;#John Doe;#175;#Jane Doe;#172;#John Pongo
//Single User is stored like this -> 173;#John Doe
//Multiple values are separated by semicolons
//string strUserGroupSelected = dwdMgrItem["Select Users or Groups"].ToString().Trim();
//Initialize a SPWeb and SPListItem objects
SPWeb elevatedWeb = null;
SPListItem elevatedListItem = null;
try
{
//Run this code block with Elevated Privileges
//This is because Site Users will NOT have FULL CONTROL in SharePoint
//They will have CONTRIBUTE access in SharePoint and this access level
//does not allow you to break role inheritance.
//However, SPSite and SPWeb objects obtained via the Run With Elevated Privileges method
//will allow these Users to perform this operation.
SPSecurity.RunWithElevatedPrivileges(delegate()
{
//This will be a POST request. Call ValidateFormDigest to ensure that this is a valid update and not a cross-site scripting attack
//Refer: http://hristopavlov.wordpress.com/2008/05/21/what-you-need-to-know-about-allowunsafeupdates-part-2/
SPUtility.ValidateFormDigest();
//Get a handle to the SPSite object inside the Elevated code block
using (SPSite elevatedSite = new SPSite(properties.SiteId))
{
//Get a handle to the SPWeb object inside the Elevated code block
using (elevatedWeb = elevatedSite.OpenWeb())
{
//Get the following error if AllowUnsafeUpdates is NOT set to True
//Microsoft.SharePoint.SPException: The security validation for this page is invalid.
elevatedWeb.AllowUnsafeUpdates = true;
//Get a handle to the List Item using the elevated SPWeb object
elevatedListItem = elevatedWeb.GetListItem(properties.ListItem.Url);
//Get all the Users in the Web
//SPUserCollection users = elevatedWeb.AllUsers;
SPUserCollection users = elevatedWeb.SiteUsers;
//Get all the Cross-site Groups for the Site Collection
//SPGroupCollection groups = web.Groups;
SPGroupCollection groups = elevatedWeb.SiteGroups;
//Call BreakRoleInheritance. false indicates that current role assignments in the Parent List will NOT be copied to this Item.
elevatedListItem.BreakRoleInheritance(false);
//Update the List Item
elevatedListItem.Update();
//Call function that will set Item Level Permissions.The user or users will be assigned Contributor permissions to this Item
elevatedListItem = SetItemLevelPermissions(elevatedWeb, elevatedListItem, SPRoleType.Contributor, users, groups);
//Update the Item again
elevatedListItem.Update();
//Set AllowUnsafeUpdates back to false
elevatedWeb.AllowUnsafeUpdates = false;
} //using elevatedWeb
} //using elevateSite
}); //closing for SPSecurity.RunWithElevatedPrivileges
}
catch (Exception ex)
{
throw ex;
}
finally
{
//Dispose SPWeb object
if (elevatedWeb != null)
elevatedWeb.Dispose();
////Dispose SPSite object
//if (elevatedSite != null)
// elevatedSite.Dispose();
}
}
public SPListItem SetItemLevelPermissions(SPWeb setSPWeb, SPListItem setListItem, SPRoleType setRoleType, SPUserCollection users, SPGroupCollection groups)
{
try
{
//Create an ArrayList that will store the User or Group IDs
ArrayList alUserGroup = new ArrayList();
//Get the Users or Groups selected here
//Multiple Users are stored like this -> User or Group selected = 173;#John Doe;#175;#Jane Doe;#172;#John Pongo
//Single User is stored like this -> 173;#John Doe
//Multiple values are separated by semicolons
string strUserGroupSelected = setListItem["Select Users or Groups"].ToString().Trim();
//Split the multiple values and store them in an Array
string[] strArrUserGroup = Regex.Split(strUserGroupSelected, ";#");
//Iterate through the Array and store the User or Group IDs in the ArrayList
foreach (string strUserGroupValue in strArrUserGroup)
{
//Check if the value is a number
//If True, this is a User or Group ID
if (IsWholeNumber(strUserGroupValue))
{
//Add User or Group IDs to the ArrayList
alUserGroup.Add(Int32.Parse(strUserGroupValue));
}
}
//Set the Role Definition to Contribute here...
SPRoleDefinition roleDefinition = setSPWeb.RoleDefinitions.GetByType(setRoleType);
//Iterate through the ArrayList
//Get the User or Group ID
foreach (int intUserGroupID in alUserGroup)
{
//determine if ID is user or group
Boolean isGroup = false;
foreach (SPGroup testGroup in setSPWeb.SiteGroups)
{
if (testGroup.ID == intUserGroupID)
{
isGroup = true;
}
}
if (isGroup == false) //this is a User ID
{
SPUser userToAdd = users.GetByID(intUserGroupID);
SPRoleAssignment userRoleAssignment = new SPRoleAssignment(userToAdd);
userRoleAssignment.RoleDefinitionBindings.Add(roleDefinition);
setListItem.RoleAssignments.Add(userRoleAssignment);
}
else //this is a Group ID
{
SPGroup groupToAdd = groups.GetByID(intUserGroupID);
SPRoleAssignment groupRoleAssignment = new SPRoleAssignment(groupToAdd);
groupRoleAssignment.RoleDefinitionBindings.Add(roleDefinition);
setListItem.RoleAssignments.Add(groupRoleAssignment);
}
}
//Add 'SP Site Administrators' group to the Item Permissions List
SPGroup oSiteAdminGroup = setSPWeb.SiteGroups["SP Site Administrators"];
SPRoleAssignment siteAdminGroupRoleAssignment = new SPRoleAssignment(oSiteAdminGroup);
siteAdminGroupRoleAssignment.RoleDefinitionBindings.Add(roleDefinition);
setListItem.RoleAssignments.Add(siteAdminGroupRoleAssignment);
return setListItem;
}
catch (Exception ex)
{
throw ex;
}
finally
{
//Do nothing
}
}
public override void ItemUpdating(SPItemEventProperties properties)
{
try
{
this.DisableEventFiring();
//Get Security Level and Select Users/Groups values
string strSecLevel = properties.AfterProperties["Security_x0020_Level"].ToString().Trim();
string strUserOrGroups = properties.AfterProperties["Select_x0020_Users_x0020_or_x002"].ToString().Trim();
//If Specific User is selected, but Users/Groups is blank, we need to display an error message and prevent saving of the Item.
if (strSecLevel == "Specific User" & (strUserOrGroups == "" | strUserOrGroups == string.Empty))
{
properties.ErrorMessage = "The 'Select Users or Groups' field cannot be blank, if you select 'Specific User' as the Security Level for this Document." + "
" + "Please click on the Back button in the browser and select User(s) and/or Group(s).";
properties.Cancel = true;
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
this.EnableEventFiring();
}
}
public override void ItemUpdated(SPItemEventProperties properties)
{
try
{
this.DisableEventFiring();
string strSecLevel = properties.AfterProperties["Security_x0020_Level"].ToString().Trim();
if (strSecLevel != "Specific User")
{
ResetRoleInheritance(properties);
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
this.EnableEventFiring();
}
}
private void ResetRoleInheritance(SPItemEventProperties properties)
{
//Initialize a SPWeb and SPListItem objects
SPWeb elevatedWeb = null;
SPListItem elevatedListItem = null;
try
{
//Run this code block with Elevated Privileges
//This is because Site Users will NOT have FULL CONTROL in SharePoint
//They will have CONTRIBUTE access in SharePoint and this access level
//does not allow you to reset role inheritance.
//However, SPSite and SPWeb objects obtained via the Run With Elevated Privileges method
//will allow these Users to perform this operation.
SPSecurity.RunWithElevatedPrivileges(delegate()
{
//This will be a POST request. Call ValidateFormDigest to ensure that this is a valid update and not a cross-site scripting attack
//Refer: http://hristopavlov.wordpress.com/2008/05/21/what-you-need-to-know-about-allowunsafeupdates-part-2/
SPUtility.ValidateFormDigest();
//Get a handle to the SPSite object inside the Elevated code block
using (SPSite elevatedSite = new SPSite(properties.SiteId))
{
//Get a handle to the SPWeb object inside the Elevated code block
using (elevatedWeb = elevatedSite.OpenWeb())
{
//Get the following error if AllowUnsafeUpdates is NOT set to True
//Microsoft.SharePoint.SPException: The security validation for this page is invalid.
elevatedWeb.AllowUnsafeUpdates = true;
//Get a handle to the List Item using the elevated SPWeb object
elevatedListItem = elevatedWeb.GetListItem(properties.ListItem.Url);
//Remove Users and Groups from the People Picker field in this Item
elevatedListItem["Select Users or Groups"] = string.Empty;
//Call ResetRoleInheritance.
//This will remove Item Level Permissions and restore List level Permissions.
//In other words, the Permissions assigned to the List will be inherited by the Item.
elevatedListItem.ResetRoleInheritance();
//Update the List Item
elevatedListItem.Update();
//Set AllowUnsafeUpdates back to false
elevatedWeb.AllowUnsafeUpdates = false;
} //using elevatedWeb
} //using elevateSite
}); //closing for SPSecurity.RunWithElevatedPrivileges
}
catch (Exception ex)
{
throw ex;
}
finally
{
//Dispose SPWeb object
if (elevatedWeb != null)
elevatedWeb.Dispose();
////Dispose SPSite object
//if (elevatedSite != null)
// elevatedSite.Dispose();
}
}
//This method checks if the string that is passed is a valid whole number or not
public bool IsWholeNumber(String strNumber)
{
Regex objNotWholePattern = new Regex("[^0-9]");
return !objNotWholePattern.IsMatch(strNumber);
}
}
}
Thursday, February 11, 2010
SharePoint BreakRoleInheritance() and ResetRoleInheritance() code sample
Wednesday, February 3, 2010
Using JavaScript event handlers in SharePoint List Form Page
Credits:
http://blogs.msdn.com/sharepointdesigner/archive/2007/06/13/using-javascript-to-manipulate-a-list-form-field.aspx
http://boris.gomiunik.net/2008/04/add-functions-and-events-to-sharepoint-form-fields/
Here is the JavaScript solution that I came up with. I left the alert statements in the code, for debugging purposes. Insert this code in a Content Editor Web Part and ensure that it is hidden. Also, place the Content Editor Web Part at the very bottom of the page.
IMPORTANT: Insert the JavaScript OR operator (i.e. double pipe) after the identifier == "" portion in the if() statement in the getTagFromIdentifierAndTitle() function below. For some odd reason the OR operator gets removed whenever I publish the post.
<script type="text/javascript">
//This code runs on the onload event of the custom Form
_spBodyOnLoadFunctionNames.push("getSecurityLevelValue");
function hidePeoplePicker() {
//alert("HIDE");
var control = getTagFromIdentifierAndTitle('textarea','UserField_downlevelTextBox','People Picker');
control.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.style.display="none";
}
function showPeoplePicker() {
//alert("SHOW");
var control = getTagFromIdentifierAndTitle('textarea','UserField_downlevelTextBox','People Picker');
control.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.style.display="";}
function getTagFromIdentifierAndTitle(tagName, identifier, title)
{
//alert("tagName = " + tagName);
var len = identifier.length;
//alert("Len = " + len);
var tags = document.getElementsByTagName(tagName);
//alert("tags length = " + tags.length);
for (var i=0; i < tags.length; i++)
{
var tempString = tags[i].id;
//alert("tempString = " + tempString);//NOTE: Insert the OR operator after the identifier == "" portion in the code below
//For some odd reason the OR operator gets removed when I post the blog
if (tags[i].title == title && (identifier == "" tempString.indexOf(identifier) == tempString.length - len))
{
return tags[i];
}
}
return null;
}
function getField(fieldType,fieldTitle) {
var docTags = document.getElementsByTagName(fieldType);
//alert("Length = " + docTags.length);
for (var i=0; i < docTags.length; i++) {
if (docTags[i].title == fieldTitle) {
//alert("Value in getField = " + docTags[i].value);
return docTags[i];
}
}
}
function getSecurityLevelValue() {
//alert("In getSecurityLevelValue");
selectedId = getField('select','Security Level').options[getField('select','Security Level').selectedIndex].value;
//alert("Value in hide =" + selectedId);
if(selectedId != 'Specific User')
{
//alert("NOT Specific User");
hidePeoplePicker();
}
else
{
//alert("Specific User");
showPeoplePicker();
}
}//This code runs on the onchange event of the drop down list field
getField('select','Security Level').onchange = function() {getSecurityLevelValue()};
</script>