Authorisation Rule - PerType Property Read/Write How to rule check on type (instead of instance)

Authorisation Rule - PerType Property Read/Write How to rule check on type (instead of instance)

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


Jaans posted on Thursday, January 17, 2013

I'm trying to build a custom convention for Caliburn Micro that automatically sets a input control to be ReadOnly/Disabled if the user doesn't have write permission against the Csla Property that is being bound to.

Where I'm stuck is to be able to test whether a particular property can be written to for a given CSLA Type.

I do not have the instance of the CSLA business object available yet, so I cannot call CanWrite() on it.
What I do have is the Type of the business object and I need to see if the user can write to the property on the given business object type.

My property authorisation rules are setup as per type (and not per instance).

Any ideas anyone?

JonnyBee replied on Thursday, January 17, 2013

It may be a bit of an edge case.

Have you considered this alternative - to add the PropertyInfo control in the template? 
http://forums.lhotka.net/forums/p/11633/53888.aspx#53888

Jaans replied on Thursday, January 17, 2013

Thanks Jonny

Yeah... we currently use the PropertyInfo control which works well, but it's quite a bit of effort for all the controls, especially when you have projects with many views.

At the moment, with Caliburn Micro we are able to quite easily and automatically make input controls read-only, or even set grid columns to be read-only when the binding is against a CSLA business object and the property doesn't have a publicly accessible setter. This works really well as it requires less time spend in XAML for the team.

The new idea was to reduce our XAML footprint further and stop writing the PropertyInfo control (at last not for CanWrite checks via binding) for each UI element that represents data from a business object..

Since we define our property authorisation rules as per type rules (as opposed to per-instance) on the business object, I'm speculating that static information is there for the static HasPermission(...) method overloads on the BusinessRules to be extended with an overload that can check for permissions for a AutorizationAction.CanWrite/CanRead together with a Type and a Property (as opposed to an instance and a property).

What do you think, would it be possible / useful?
You have a much deeper understanding of the Rules system and the greater impact such a check would have. 

Ps: Leave the forum alone and enjoy your holiday in paradise Paradise

Alternatively, we can see if we can have Caliburn Micro's SetBinding convention dynamically inject PropertyInfo controls for each of the controls and setup the relevant CanWrite binding checks.  

JonnyBee replied on Thursday, January 17, 2013

Jaans
Alternatively, we can see if we can have Caliburn Micro's SetBinding convention dynamically inject PropertyInfo controls for each of the controls and setup the relevant CanWrite binding checks.  

This would be my recommended solution. 

The concept for CanRead/CanWrite is that 

 

 

You _could_ modify CSLA and create your own version and allow this. Just be aware that doing so will require that your authz rules can ONLY do static checks. You _could_ comment out the checks in the static AuthorizationRules.HasPermission.

Or - you could create a "dummy" instance and call the CanRead/CanWrite methods on that instance.

 

    private static bool HasPermission(AuthorizationActions action, object obj, Type objType, string ruleSet)
    {
      // COMMMENT THESE LINES WILL ALLOW CHECK OF Read/Write/Ececute
      // -however this may make context.Target be null depending on whether a type or an instance was supplied to the check
      //if (action == AuthorizationActions.ReadProperty ||
      //    action == AuthorizationActions.WriteProperty ||
      //    action == AuthorizationActions.ExecuteMethod)
      //  throw new ArgumentOutOfRangeException("action");
 
      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;
      }
      return result;
    }
I do not believe we will make this change in CSLA rules framework. 

 

Jaans replied on Saturday, January 19, 2013

@Jonny

Thanks for that.
I see what you are saying about rules that might depend on the Target. As you say if we *know* our roles are only using the standard IsInRole permissions, then we'll be fine but it's clearly not a guaranteed scenario and is up to us to ensure that is true for our environment.

@Skagen00

I'm assuming you are referring to the CSLA PropertyInfo class used to represent registered CSLA business object properties and not the XAML <csla:PropertyInfo /> control. That sure is an interesting idea, not just for this scenario but for some other scenario's too. I assume this will have a direct impact to the size of the object when serializing / deserialising.

JonnyBee replied on Saturday, January 19, 2013

Actually - extending the static PropertyInfo object will NOT increase the amount of data that is serialized. 

The managed propertyinfo bag uses only an integer index to access the field data so the amount of data to be serialized is not increased unless you create your own FieldData class and add extra properties here. 

skagen00 replied on Thursday, January 17, 2013

I may be misunderstanding, but could you extend propertyinfo (your custom propertyinfo derived from propertyinfo, which you proably already have) to perhaps have an extra piece of information for the role permissions/etc that are required for that given property?  Then you could have a CanReadProperty/CanWriteProperty directly off of the propertyinfo and check the current identity's roles/permissions against them.

Your businessbase CanReadProperty/CanWriteProperty can piggy back off of that when you have an instance, too - including both instance CanReadProperty/CanWriteProperty as well as those from the PropertyInfo...

Just a suggestion

Copyright (c) Marimer LLC