Anders G. Nordby

Senior Web Developer at CGI

EPiServer 8x: Restricting a Single Property

Setting access rights to a tab in the classic editor mode is out of the box, and I could have used this functionality to hide a single property from non-admins by creating a special tab only visible to admins. However, this will most surely make the administrators forget to set this property when they are editing content. Therefore, I thought it would be better to be able to restrict a single property.

I started out by creating a suitable attribute:

using System;

namespace MyProject
{
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class RestrictedPropertyAttribute : Attribute
    {
        /// <summary>
        /// Single group name or comma separated list of group names
        /// </summary>
        public virtual string GroupName { get; set; }
    }
}

Next, I inherited the EditorDescriptor to create my very own RestrictedPropertyExtender:

using System;
using System.Collections.Generic;
using System.Linq;
using EPiServer.Shell.ObjectEditing;
using System.Threading;
using EPiServer.Core;
using EPiServer.Shell.ObjectEditing.EditorDescriptors;

namespace MyProject
{
    [EditorDescriptorRegistration(TargetType = typeof(ContentData))]
    public class RestrictedPropertyExtender : EditorDescriptor
    {
        public override void ModifyMetadata(ExtendedMetadata metadata, IEnumerable<Attribute> attributes)
        {
            foreach (var modelMetadata in metadata.Properties)
            {
                var property = (ExtendedMetadata) modelMetadata;
                foreach (var attr in property.Attributes)
                {
                    var restrictedAttr = attr as RestrictedPropertyAttribute;
                    if (restrictedAttr != null)
                    {
                        var groupName = restrictedAttr.GroupName;
                        if (string.IsNullOrEmpty(groupName) || groupName.Split(',').Any(name => Thread.CurrentPrincipal.IsInRole(name)))
                        {
                            return;
                        }

                        property.ShowForEdit = false;
                    }
                }
            }
        }
    }
}

Finally, I hooked this up by creating an initializeable module:

using EPiServer.Core;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.ServiceLocation;
using EPiServer.Shell.ObjectEditing;

namespace Fellesforbundet.Web.Models.Properties
{
    [InitializableModule]
    public class RestrictedPropertyInitialization : IConfigurableModule
    {
        public void Initialize(InitializationEngine context)
        {
            var registry = context.Locate.Advanced.GetInstance<MetadataHandlerRegistry>();
            registry.RegisterMetadataHandler(typeof(ContentData), new RestrictedPropertyExtender());
        }

        public void Uninitialize(InitializationEngine context)
        {
        }

        public void ConfigureContainer(ServiceConfigurationContext context)
        {
        }
    }
}

Now, in my pagetype models, I can restrict a single property to only be visible (and thus editable) for my administrators:

        [RestrictedProperty(GroupName = "Administrators,WebAdmins")]
        public virtual string ThisPropertyIsOnlyEditableForAdmins { get; set; }

These posts pointed me in the right direction:

Follow

Get every new post delivered to your Inbox.