Improved Sitecore delete item access rights

Sitecore has a quite advanced access right management system. However, I’ve found a few quite common requirements that, as far as I know, isn’t supported out of the box. One is to allow content authors to remove individual item versions without allowing them to remove the entire item. This is especially useful for multi language sites. Another requirement is to allow authors to delete items they have created themselves, but no other items.

I’ve seen people work around these kind of issues by playing around in the core database, modifying ribbon buttons etc. Personally I don’t like that approach. That would just hide the button and if the user could initiate the command in any other way, Sitecore will gladly perform the delete action. It’s easy to forget a command action in a context menu or something like that.

Instead I created a very small Sitecore module to solve these issues. All the source is available on Github.

Ability to remove item versions

While looking into this, I reflected parts of the Sitecore security model and found that this is already partly implemented. Looking into the Sitecore.Security.AccessControl.AccessRight class, we’ll see that there is already a hard coded item:removeversion access right. Looking at the common Item class, we already have the method item.Access.CanRemoveVersion(). Looking further into the QueryState() method of the DeleteVersion command, I found that it also evaluates using these access rights method.

So far so good. However, the ItemAuthorizationHelper.GetAccess() that evaluates this, is hard coded to explicitly require item delete access when evaluating the item:removeversion access right. So by replacing the two default AuthorizationProviders (SqlServerAuthorizationProvider and BucketAuthorizationProvider), with new ones that uses an overridden version of the GetAccess() method, we can easily change the behavior of this.

To be able to configure remove version access rights without delete item access rights, we can just add a “Remove version” right to the list of existing rights, like this:

<accessRights>
  <rights>
    <add patch:after="add[@name='item:delete']" 
         name="item:removeversion" 
         comment="Remove version right for items." 
         title="Remove version" 
         modifiesData="true" />
  </rights>
</accessRights>

With this, the access rights will appear in all UI’s, like this:

Remove version access option

Ability to remove own items

Allowing authors to delete their own items can be implemented in a similar way. I just added the logic for it in the same overridden ItemAuthorizationHelper.GetAccess() method. When the method evaluates access rights, its results is “Allow”, “Deny” or “NotSet”. “NotSet” means Deny in practice, but this is very useful in this scenario. If Item Delete access is explicitly set to “Allow” or “Deny”, that setting will rule. But when it evaluates to “NotSet”, I’ll look at the item creator and see if it matches the current user.

One caveat though is that the CreatedBy field is a versioned field, so I can’t just look at that one. The current author could be the creator of the current language version, but might not have created the item in the first place. So I load all the language versions of the items and use the very first version and compares the current author with the initial creator.

As I mentioned previously, I prefer implementing the functionality close to the core, like this. That way all existing UI’s follows as expected. In the screen shot below, I’ve created two items as the user “test” and allowed the “test” user to remove item versions. On one of the items, I’ve explicitly set the deny delete item access.

Sitecore access viewer

Let me know what you think about this. Do you find this to be a common requirement too? Is this a good way of solving it? Should it perhaps go into the product?