Recently I had to create a custom web part where all users needed the ability to fill out a text box with some feedback and then submit it to a list where it could be reviewed. This is a pretty simple control to implement if the users that will be submitting the form have “Contribute” permissions on the list that the form will be submitted to, but what happens if users with “Read” permissions should also have the ability to fill out the form?
Fortunately, SharePoint makes it super simple to write custom code that can impersonate other users.
SPWeb web = SPContext.Current.Web; SPSite site = SPContext.Current.Site; // Get the user token of the user to impersonate SPUserToken sysAdminToken = site.SystemAccount.UserToken; // Open site collection as System Admin using (SPSite siteAsAdmin = new SPSite(site.Url, sysAdminToken)) { // Open web as System Admin using (SPWeb webAsAdmin = siteAsAdmin.OpenWeb(web.ServerRelativeUrl)) { // Do something as impersonated user } }
We can take it a step further and have the System Admin account create a list item and then stamp it with the correct user’s name.
SPWeb web = SPContext.Current.Web; SPSite site = SPContext.Current.Site; // Get the user token of the user to impersonate SPUserToken sysAdminToken = site.SystemAccount.UserToken; // Open site collection as System Admin using (SPSite siteAsAdmin = new SPSite(site.Url, sysAdminToken)) { // Open web as System Admin using (SPWeb webAsAdmin = siteAsAdmin.OpenWeb(web.ServerRelativeUrl)) { // Get the List to send the fields to SPList list = webAsAdmin.GetList("/Lists/myList"); if (list != null) { // Set Allow Unsafe Updates, so that the System Admin can update 'Editor' and 'Author' fields bool allowUnsafeUpdates = webAsAdmin.AllowUnsafeUpdates; webAsAdmin.AllowUnsafeUpdates = true; string[] fieldNames = new[] {"Author", "Editor"}; // Create an empty list item SPListItem item = list.AddItem(); // Apply some values to the fields item["Comments"] = "Some Text Value"; item["Title"] = string.Format("Post from: {0}", currentUser.Name); // Get and loop through each user field specified in the fieldNames variable foreach (SPField field in fieldNames.Select(name => item.Fields.GetFieldByInternalName(name))) { // Check if the fields are Read Only, if they are make them read-write. // this is where the AllowUnsafeUpdates comes into play. bool readOnly = field.ReadOnlyField; if (readOnly) { field.ReadOnlyField = false; field.Update(); } // Set the 'Author' and 'Editor' fields equal to the user who submitted the form. item[field.Id] = currentUser.ID; // Set the fields back to Read Only if (readOnly) { field.ReadOnlyField = true; field.Update(); } } // Update the fields, including the Author and Editor item.UpdateOverwriteVersion(); } } }
It is important to note, that you should be very careful when impersonating other users.