CSLA .NET

Vibrant discussion about CSLA .NET and using the framework to build great business applications.

Forum has moved

New location: CSLA .NET forum


CSLA .NET Resources:
  • CSLA .NET forum
  • CSLA .NET home page
  • Business Rule for Not Allowing Edit or Delete for a Specific Record

    Answered (Not Verified) This post has 0 verified answers | 22 Replies | 2 Followers

    Not Ranked
    3 Posts
    korzy1bj@gmail.com posted on Thu, Jan 19 2012 10:26 AM

    I have a business object and a corresponding database table called Role. In this table I am preloading two default records. The first is named "Administrators" and second is named "Users". I want to allow people to add, edit, and delete roles, except for these default ones. I was wondering how I should go about this. What I was thinking was to create a business rule, but I’m not sure how to add one to handle this particular situation. Any help / advice you can provide would be greatly appreciated.

    P.S. I have a business rule to not allow them to enter duplicate names, so I don’t have to worry about them creating another “Administrators” role.

    All Replies

    Top 10 Contributor
    2,279 Posts
    Suggested by JonnyBee

    Yes, but you could subclass existing Authz Rules like IsInRole rule and add custom checks in the execute method of the rule.

    You can however only have 1 rule per static action or per type action.

    This the actual code from BusinessRules.HasPermission (static method)

          bool result = true;
          var rule =
            AuthorizationRuleManager.GetRulesForType(objType, ruleSet).Rules.FirstOrDefault(c => c.Element == null && c.Action == action);

          if (rule != null)
          {
            var context = new AuthorizationContext { Rule = rule, Target = obj, TargetType = objType };
            rule.Execute(context);
            result = context.HasPermission;
          }

    Based on the code - you can also see that AutzRules for the static methods must have Element (IMemberInfo) = null. Which means that you may get the target object as parameter to the Execute method but cannot add PropertyInfo to the rule (by calling base(...)).
    This applies to the AuthorizationActions CreateObject, DeleteObject, GetObject, EditObject.

     

     

     

    Jonny Bekkum, Norway CslaContrib Coordinator

    Top 50 Contributor
    187 Posts

    Ok, then I guess it''s not practical and a dead end for me.

    I don't see any support for this scenario in CSLA at all, it's kind of wierd, I thought this was a super common requirement: prevent delete based on business object state, but it seems like it was never planned for in the framework itself.  I'm sure that can't be right and I'm just missing something but so far no luck.

    Perhaps I'll search again on the forum for all the people that asked how to do this and never really seemed to get it worked out and ask each of them what they ended up doing.

    Thanks again for your help.

    Top 10 Contributor
    2,279 Posts

    There is support for this - you just have to follow some basic guidelines.

    BusinessRules at Object level must have ProperyProperty = null.
    AuthorizationRules for Static methods must have Member = null          (CanGetObject, CanCreateObject, CanEditObject, CanDeleteObject)

    BusinessRules for a Property must have PrimaryProperty != null
    AuthorizationRules for property/method must have Member != null      (CanWriteProperty, CanReadProperty, CanExecuteMethod)

    And for AuthorizationRules there can only be one - 1 rule per check!

    Since AuthzRules does not support the concept of InputProperties you must store the PropertyInfos in member field on the rule and use ReadProperty to get the values.

    So there is nothing to stop you from having IPropertyInfo members in your AuthorizationRules - just follow the guidelines above.

    Take f.ex this rule to be used for static methods but will still check for property values when applicable (ie context.Target is not null):

      public class MyVeryOwnObjectAuthzRule : AuthorizationRule

      {

        private readonly IPropertyInfo _prop1;

        private readonly IPropertyInfo _prop2;

     

        public MyVeryOwnObjectAuthzRule(AuthorizationActions action, PropertyInfo<string> prop1, PropertyInfo<string> prop2)

          : base(action)

        {

          _prop1 = prop1;

          _prop2 = prop2;

        }

     

        protected override void Execute(AuthorizationContext context)

        {

          if (context.Target != null)

          {

            var val1 = (string)ReadProperty(context.Target, _prop1);

            var val2 = (string)ReadProperty(context.Target, _prop2);

     

            // add my own if tests here

          }

        }

      }

     

    or you can sublass an existing rule to add more tests:

     

     

      public class MyObjectAuthzRule : IsInRole

      {

        private readonly IPropertyInfo _prop1;

        private readonly IPropertyInfo _prop2;

     

        public MyObjectAuthzRule(AuthorizationActions action, PropertyInfo<string> prop1, PropertyInfo<string> prop2, params string[] roles)

          : base(action, roles)

        {

          _prop1 = prop1;

          _prop2 = prop2;

        }

     

        public MyObjectAuthzRule(AuthorizationActions action, PropertyInfo<string> prop1, PropertyInfo<string> prop2, List<string> roles)

          : base(action, roles)

        {

          _prop1 = prop1;

          _prop2 = prop2;

        }

     

        protected override void Execute(AuthorizationContext context)

        {

          // chect the base rule

          base.Execute(context);

          if (!context.HasPermission) return;

     

          if (context.Target != null)

          {

            var val1 = (string) ReadProperty(context.Target, _prop1);

            var val2 = (string) ReadProperty(context.Target, _prop2);

     

            // add my own if tests here

          }

        }

      }

     

    Jonny Bekkum, Norway CslaContrib Coordinator

    Top 50 Contributor
    187 Posts

    Ah!  I see what you're saying now.  This should really be documented specifically in the Ebook.  Thank you for taking the time to answer this so thoroughly.

    Cheers!

    Top 50 Contributor
    187 Posts

    Works perfectly, thanks again Jonny!

    Top 200 Contributor
    45 Posts

    Hi Jonny. Is there any working options for the Csla 3.8.4 Business & Auth Rules engine?

    Thanks,

    Troncho

    Top 10 Contributor
    2,279 Posts
    Suggested by Troncho

    Csla 3.x authz rules only get the Type as parameter.

    So you can only configure AllowedRoles/DenyRoles to be checked and not inspect the actual values of the object.

    Jonny Bekkum, Norway CslaContrib Coordinator

    Top 200 Contributor
    45 Posts
    Answered (Not Verified) Troncho replied on Sat, Nov 10 2012 10:29 AM
    Suggested by Troncho

    Ok, so for now, overriding the BO.Delete() will have to do.

    Thanks!

    Troncho

    Page 2 of 2 (23 items) < Previous 1 2 | RSS

    Copyright (c) 2006-2014 Marimer LLC. All rights reserved.
    Email admin@lhotka.net for support.
    Powered by Community Server (Non-Commercial Edition), by Telligent Systems