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: