Five New Optimizely Certifications are Here! Validate your expertise and advance your career with our latest certification exams. Click here to find out more

Linus Ekström
May 9, 2014
  7294
(0 votes)

Restricting access to who is allowed to edit a certain property

I did a presentation in Oslo about a month ago and one thing in EPiServer 7.5 that I wanted to emphasize on is the support for the IMetadataAware attribute. This, in combination with implementing a ValidationAttribute is very powerful and in this blog post I’ll show an example on how this can be used. The goal is to create an attribute when you can control which roles are required to edit a specific property.

First, let us look on how we can make a property that makes the property read only in the editorial interface. Here’s the code for the attribute :

using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
 
namespace EPiServer.Samples
{
    public class PropertyEditRestrictionAttribute : ValidationAttribute, IMetadataAware
    {
        public PropertyEditRestrictionAttribute(string[] allowedRoles)
        {
            AllowedRoles = allowedRoles;
        }
 
        public string[] AllowedRoles { get; set; }
 
        public void OnMetadataCreated(ModelMetadata metadata)
        {
            foreach (string role in AllowedRoles)
            {
                if (EPiServer.Security.PrincipalInfo.CurrentPrincipal.IsInRole(role))
                {
                    return;
                }
            }
            metadata.IsReadOnly = true;
        }
    }
}

 

And the usage on the model like this:

[PropertyEditRestriction(new string[]{"administrators2"})]
public virtual XhtmlString MainBody { get; set; }

 

Notice the rather odd group name “administrators2” just to make sure I’m not part of this group.

If we pop into the EPiServer UI, we can see that the editor has been disabled in the forms view:

ReadOnly

 

In the On-Page edit view, the property looks editable but when clicking on the overlay, a read only editor is loaded. There has actually been a bug fix recently that removes the overlay entirely when the property is not editable that’s been sent for testing and will hopefully be release withing a week or two.

ReadOnlyOnPageEdit

 

What about validation on the server?

The code above is really simple and probably solves the customer requirements in most cases. But since this only affects the editorial interface, it is of course possible to post a fake property update to the server even without having the correct access. Let’s see how we can add server validation as well to the same attribute.

using System;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using EPiServer.Core;
 
namespace EPiServer.Samples
{
    public class PropertyEditRestrictionAttribute : ValidationAttribute, IMetadataAware
    {
        public PropertyEditRestrictionAttribute(string[] allowedRoles)
        {
            AllowedRoles = allowedRoles;
        }
 
        public string[] AllowedRoles { get; set; }
 
        public void OnMetadataCreated(ModelMetadata metadata)
        {
            foreach (string role in AllowedRoles)
            {
                if (EPiServer.Security.PrincipalInfo.CurrentPrincipal.IsInRole(role))
                {
                    return;
                }
            }
            //Comment row below to test the server validation.
            metadata.IsReadOnly = true;
        }
 
        public override string FormatErrorMessage(string name)
        {
            return "You do not have access to change " + name;
        }
 
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var contentData = validationContext.ObjectInstance as IContentData;
            if (contentData == null)
            {
                //This attribute only handles instances of IContentData.
                return ValidationResult.Success;
            }
            if (!contentData.Property[validationContext.MemberName].IsModified)
            {
                return ValidationResult.Success;
            }
            if (Validate())
            {
                return ValidationResult.Success;
            }
            else { return new ValidationResult("You do not have access"); }
        }
 
        public override bool RequiresValidationContext
        {
            get
            {
                return true;
            }
        }
 
        public bool Validate()
        {
            foreach (string role in AllowedRoles)
            {
                if (EPiServer.Security.PrincipalInfo.CurrentPrincipal.IsInRole(role))
                {
                    return true;
                }
            }
            return false;
        }
    }
}

 

For demonstration purposes, we can comment out the line that makes the property readonly, and edit the property to validate that the server validation actually does work.

ServerValidation

May 09, 2014

Comments

Please login to comment.
Latest blogs
Optimizely Configured Commerce and Spire CMS - Figuring out Handlers

I recently entered the world of Optimizely Configured Commerce and Spire CMS. Intriguing, interesting and challenging at the same time, especially...

Ritu Madan | Mar 12, 2025

Another console app for calling the Optimizely CMS REST API

Introducing a Spectre.Console.Cli app for exploring an Optimizely SaaS CMS instance and to source code control definitions.

Johan Kronberg | Mar 11, 2025 |

Extending UrlResolver to Generate Lowercase Links in Optimizely CMS 12

When working with Optimizely CMS 12, URL consistency is crucial for SEO and usability. By default, Optimizely does not enforce lowercase URLs, whic...

Santiago Morla | Mar 7, 2025 |

Optimizing Experiences with Optimizely: Custom Audience Criteria for Mobile Visitors

In today’s mobile-first world, delivering personalized experiences to visitors using mobile devices is crucial for maximizing engagement and...

Nenad Nicevski | Mar 5, 2025 |

Unable to view Optimizely Forms submissions when some values are too long

I discovered a form where the form submissions could not be viewed in the Optimizely UI, only downloaded. Learn how to fix the issue.

Tomas Hensrud Gulla | Mar 4, 2025 |

CMS 12 DXP Migrations - Time Zones

When it comes to migrating a project from CMS 11 and .NET Framework on the DXP to CMS 12 and .NET Core one thing you need to be aware of is the...

Scott Reed | Mar 4, 2025