4

I've got a situation where there are strict permissions requirements on an a list of which I already have written a custom form. The requirement is that upon creation, based on metadata, only certain users have access to read and write the item.

My first attempt at this was to put this in an event receiver on the list to make sure the permissions get updated at when the item is added. I put the item in the item added event since during item adding I don't have a way to elevate privileges and get an elevated instance of the item (that I know of). This caused an unwanted delay, though short, between the time the item was created and the time the code actually ran.

The next thing I tried was to put set the item permissions in the form immediately after the item is created since I would then have an ID for the item so I can retrieve it in an elevated context (I want the item to be created under the context of the current user). This is problematic because as soon as this approach was implemented, about 50% of the time we get an error in a workflow that runs on item create saying: “Failed to start workflow. The workflow cannot access the item that is has been applied to.” (It's probably worth noting this is a Nintex workflow) - I assume the problem is due to some race condition where in the middle of the item.Update() to set the permissions, the workflow tries to start at the same time.

Ideally I would like to be able to update permissions on the very first item update (create) or during an ItemAdding event, but I am not sure how to do this without elevating the whole process such that the item is then created by the system account and not the user who actually created the item.

What options do I have available to me?

4 Answers 4

1

The way you originally had it using the ItemAdded event was correct. There is just one step missing though - you can make the event run immediately by changing it to run synchronously instead of asynchronously.

Details of how to switch the synchronous mode are here: http://blogs.technet.com/b/stefan_gossner/archive/2011/11/10/using-synchronous-quot-after-quot-events-e-g-itemupdated-in-sharepoint-2010.aspx

1
  • I knew that feature existed but clearly forgot when I was working on this. Great answer! Jan 12, 2015 at 16:33
2

One approach you could try, is enabling content approval on that list. This will mean, that whenever a new item is created, it will remain in Pending status until it is approved. When an item is in Pending status, only the originator of the item and the people who have permissions to manage lists and libraries can see it, provided you chose the following setting: Who should see draft items in this document library? -> Only users who can approve items (and the author of the item). Then, you could use the ItemAdded event to change the permissions of the file and also put in the Approved state.

I hope this helps you out in your particular scenario.

1
  • I've upvoted this answer because this would indeed work but it's not the answer for me because it either a) adds a bunch of manual steps for the end user which is not desirable; or b) require a lot of updates to automate this process. I do appreciate the input though! Jun 26, 2013 at 13:34
1

You should be able to impersonate the user that created the item or made the change in your code.

    public override void ItemUpdating(SPItemEventProperties properties)     
       {     
           base.ItemUpdating(properties);

           SPUserToken objSPUserToken = properties.OriginatingUserToken;

           if (objSPUserToken != null) 
           { 
               using (SPSite objSPSite = new SPSite(properties.SiteId, objSPUserToken)) 
               { 
                   using (SPWeb objSPWeb = objSPSite.OpenWeb())

                   { 
                       //You can perform user context specific changes here... 
                   } 
               } 
           }
       }

Impersonation Elevation of Privileges

Event Impersonation in SharePoint 2010

6
  • But if I'm impersonating a user won't I then LOSE the elevated privileges? The users I want to impersonate wouldn't necessarily have privileges to modify permissions. Jun 25, 2013 at 18:35
  • Have you tried a SP Designer workflow to modify the permissions in an "Impersonation Step"
    – Mike
    Jun 25, 2013 at 20:24
  • Workflow steps are too slow in this case due to the sensitive nature of the data. There is simply too long of a pause between item create and the workflow kicking off and the step executing that someone who wouldn't otherwise have access to this single item would be able to read the data. Jun 25, 2013 at 20:37
  • Specifically, what criteria depicts the permission on the item? Have you thought about using the content organizer with rules?
    – Mike
    Jun 25, 2013 at 20:45
  • As of right now its just the user who creates the item and some predefined groups. I could very well be mistaken about the content organizer since I have not personally used it, but based on the little research I've done, my gut tells me its for documents only? Jun 25, 2013 at 21:34
1

What I've done to get around this issue is to instead of automatically start the workflow via the settings of the workflow, we are "manually" kicking off the workflow via code after permissions are updated.

string workflowId = "{...}"; //dynamically retrieve workflow id
SPWorkflowManager workflowManager = item.Web.Site.WorkflowManager;
SPWorkflowAssociationCollection workflowCollection = item.ParentList.WorkflowAssociations;

foreach (SPWorkflowAssociation workflow in workflowCollection)
{
    if (String.Compare(workflow.BaseId.ToString("B"), workflowId, true) == 0)
    {
        workflowManager.StartWorkflow(item, workflow, workflow.AssociationData, true);
        break;
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.