How would you create an authorization rule for a property based on another field?

How would you create an authorization rule for a property based on another field?

Old forum URL: forums.lhotka.net/forums/t/10868.aspx


mattruma posted on Friday, November 11, 2011

I have two properties on my business object, Name and IsSystemDefined.

IsSystemDefined is already set in the database ... no way for the business object to change it, but it needs to know about it.

If the business object has IsSystemDefined = true, I want to add an authorization rule to prevent the user from editing the Name.

How would I do this?

StefanCop replied on Friday, November 11, 2011

You can create a rule, that takes a Predicate to decide.

I added two conditional wrappers for Authoritzation rule like  IsInRole, one requiring some role if a condition / unless a condition is true 

    public RequireIf(Predicate<T> cond, IAuthorizationRule rule) : base(rule.Action, rule.Element)
    {
      _cond_ cond;

      _rule = rule;

    }

StefanCop replied on Friday, November 11, 2011

holy crap, this formatting (IE is really bad, Firefox is better). Sorry about it.

And here's hwo I use the rule:

protected override void AddBusinessRules()
{
   BusinessRules.AddRule(new RequireUnless<MyBusinessObject>(
          IfNewOrPropertySet,
          new IsInRole(AuthorizationActions.WriteProperty, "PermissionRole") );
}

private static bool IfNewOrPropertySet(MyBusinessObject obj)
{
   return obj != null && (obj.IsNew || !obj.IsSystemDefined);
}

JonnyBee replied on Sunday, November 13, 2011

For Csla 4.2 - the stright forward way to understand authorization rules is:

    
    public class AuthIsSystemDefinedProp : AuthorizationRule
    {
      IPropertyInfo IsSystemProperty;
      public AuthIsSystemDefinedProp(AuthorizationActions action, IPropertyInfo method, IPropertyInfo isSystemProperty) : base(action, method)
      {
        IsSystemProperty = isSystemProperty;
      }
      
public bool CacheResult
{
get { return false; }
}

      protected override void Execute(AuthorizationContext context)       {         context.HasPermission = !(bool)ReadProperty(context.Target, IsSystemProperty);       }     }

Usage:

  BusinessRules.AddRule(new AuthIsSystemDefinedProp(AuthorizationActions.WriteProperty, NameProperty, IsSystemDefinedProperty))
 

Lambda rules is a nice way of making simple authorization rules - just posted this the most basic AuthorizationRule for your case.

Edited: Added CacheResult to return false as this rule can not be cached.

mattruma replied on Tuesday, November 15, 2011

Looks easy! Do you know when 4.2 will come out of beta and be available in Nuget? Maybe that's a question for Rocky?

JonnyBee replied on Tuesday, November 15, 2011

If no serious bugs pops up, 4.2 will be released next week.

Copyright (c) Marimer LLC