Restricting Episerver UI views for a content type based on a user's roles

Customizing the editor UI for a content type is achieved via the UIDescriptor class, and in most scenarios this handles all the customization you could require. However, what about if you want available or default views to be restricted based upon a user's roles?

At first, I imagined that this would be an extremely complex issue to solve. Also seeing an old post to the "Feature requests" forum requesting that the the UIDescriptor DefaultView property was changed to a delegate (see here) made me think it had probably been tried before (it probably has). Regardless, I thought I'd give it a go.

What I found was that in was achievable far more easily than I expected (at least in CMS 11, I haven't tested in early versions).

I started by digging around in EPiServer.Shell looking for a possible approach whilst lamenting that fact that DefaultView was not virtual. Before I got too deep into things I thought I'd just try creating a DefaultView property in my UIDescriptor whilst hiding the inherited property using the new modifier. Honestly, I wasn't expecting anything, but...it worked!

This means that changing the DefaultView based on a whether a user is admin or not (and also disabling the 'All Properties' view for non-admins) is as simple as:

[UIDescriptorRegistration]
public class RestrictAllPropertiesViewUIDescriptor : UIDescriptor<SitePageData>
{
    public new string DefaultView
    {
        get
        {
            return PrincipalInfo.HasAdminAccess ? CmsViewNames.AllPropertiesView : CmsViewNames.OnPageEditView;
        }
    }

    public new ICollection<string> DisabledViews
    {
        get
        {
            return PrincipalInfo.HasAdminAccess ? null : new[] { CmsViewNames.AllPropertiesView };
        }
    }
}

In this example SitePageData represents an abstract base class that all page types inherit from, common practice in Episever solutions (à la the Alloy demo site). This is used opposed to PageData because:

"[there is] no good way to alter the setting for built in EPiServer types (PageData, BlockData etc.)"

(This is from an old blog post, but as far as I'm aware it's still the case).

Would really like to hear how this works out for other people, I haven't tested it extensively, but it seems to do the trick. I'm definitely surprised by the solution as well, thought I'd need far more than 20 lines!