Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

I have been playing around with some custom workflow actions for SPD 2010, but I have an issue with one which works when running with the site collection admin user and not with a regular user with contribute.

The purpose of the action is to clear all permissions on an item and then in a later step add new groups/users with permissions.

But it fails, with the error code System.UnauthorizedAccessException:> Access is denied.

I use this method to elevate.

And here is most of the code:


try 
{
using (SPSite site = new SPSite(__Context.Web.Site.ID, GetSystemToken(__Context.Web.Site)))
    {
        var list = __Context.Web.Lists[new Guid(__ListId)];
        if (list == null) throw new ArgumentNullException("List");
        var item = list.GetItemById(__ListItem);

        item.BreakRoleInheritance(true);

        // Remove current roles
        SPRoleAssignmentCollection SPRoleAssColn = item.RoleAssignmnents;

        for (int i = SPRoleAssColn.Count - 1; i >= 0; i--)
               {
                   SPRoleAssColn.Remove(i);
               }
               using (DisabledItemEventsScope scope = new DisabledItemEventsScope())
               {
                   item.Update(); 
               }
    }           
}
catch(Exception ex)
{
//log
}
}
share|improve this question

2 Answers 2

up vote 1 down vote accepted

Assuming GetSystemToken is correct, the following line should get you an SPSite object with elevated permissions.

using (SPSite site = new SPSite(__Context.Web.Site.ID, GetSystemToken(__Context.Web.Site)))

However, you never use this object later in your code.

The following line is:

var list = __Context.Web.Lists[new Guid(__ListId)];

Here, you use the same context you've had from the start, so all further action happen with the same permissions. Instead, you should open an SPWeb from your elevated SPSite, and open the list thought it:

// open an elevated SPWeb
using (SPWeb web = site.OpenWeb())
{
    var list = web.Lists[new Guid(__ListId)];
    // ... 
}

Note that you've done exactly that on your solution :)

Personally, I like to use RunWithElevatedPrivileges, but the same issue exist in both options - you cannot use objects from the current context, they retain their original user token and permissions.

share|improve this answer
    
Ah, that explains a lot :) –  Anders Aune Nov 7 '11 at 12:01

I solved the problem, but I guess its probably not the best way to do it. I switched to run with elevated, I'm guessing it had to do with the context and from where I did access the objects (I'm not working as a developer, just a hobby when I have time :) )

Anyway, here is my solution that is working for me now:


string url = __Context.Web.Url;
string listName = __Context.Web.Lists[new Guid(__ListId)].Title;

SPSecurity.RunWithElevatedPrivileges(delegate()
{
 using (SPSite site = new SPSite(url))
  {
   using (SPWeb web = site.OpenWeb())
    {
      var list = web.Lists[listName];
      if (list == null) throw new ArgumentNullException("List");
      var item = list.GetItemById(__ListItem);

      item.BreakRoleInheritance(true);

      SPRoleAssignmentCollection SPRoleAssColn = item.RoleAssignments;
      for (int i = SPRoleAssColn.Count - 1; i >= 0; i--)
      {
        SPRoleAssColn.Remove(i);
      }
      using (DisabledItemEventsScope scope = new DisabledItemEventsScope())
      {
        item.SystemUpdate();
      }

  }
 }
});

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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