Conditional AuthorizationRules ?

Conditional AuthorizationRules ?

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


guyroch posted on Monday, October 30, 2006

Is there a way to have an AuthorizationRule depend on the value of another property.  I have a use case where a 'Descriptor' property cannot be modified (DenyWrite) only when the value of another property (bool) value is 'true'.  Both properties are from the same BO, so I have access to its value.

AuthorizationRules.DenyWrite("Descriptor", "SomeRole");

The above will have the DenyWrite rule execute all the time, I need it to validate only the another property is true.

Thanks

hurcane replied on Monday, October 30, 2006

I haven't found a way to do this through the authorization rules. We have tried two ways to enforce these kinds of changes.

1) Put the logicin the setter method of the property and throw an exception.

2) Use a different object for the read-only state.

Option 1 is usually our first choice. Option 2 is used when there are several properties that become read-only. This is typically done with a "new" object vs. an "existing" object, if the existing object has lots of read-only properties.

SonOfPirate replied on Monday, October 30, 2006

Is the second condition really an authorization rule or a business rule?  What I mean is, granting access to the method or property is the role of the authorization rule.  If you are saying that someone in role 'x' is generally allowed to perform the operation but only if the object is in a certain state, then you are authorizing that user but have a business rule that may or may not prohibit use of the particular method or property given the current state of the object.

I tend to use the "Can I...", "May I..." approach to differentiating authorization and business rules.  authorization rules answer the question, "May I...", while business rules answer, "Can I...".

For example:

"May I write a value to property 'x'?"  If you are authorized, you may; otherwise, you may not.  It doesn't really matter whether the current state of the object would allow you to or not at this point.

"Can I write a value to property 'x'?"  This depends not only on your authorization but on the current state of the object and the business rules you have in place.  So, the answer will be something like "if 'this' and 'that' are true, then you can; otherwise, you cannot."

It's kind of like having a screener outside the enterance to a night club.  Whether you may or may not enter is up to the screener, whether you can or can't depends on if the door is locked or the place is so full there is no more room for you, etc.  The state of the door or the capacity of the club don't matter until you get past the screener (authorized) and the screener really doesn't care if the door is locked or the joint is full because that's not his job.

I know it's all just semantics, but sometimes that helps.  Sounds to me like you are trying to mix authorization and business rules together.

Hope that helps.

 

guyroch replied on Monday, October 30, 2006

SonOfPirate, I have it setup as a business rule currently but the user interaction is a bit clunky in that the BO let's the user modify the descriptor property only to throw an exception when the BO gets saved.  The more 'user friendly' approach would be to prevent the user to 'set' the property to any value in the first place.

In my case I'll always get pass the entrance of the night club.  However, there is a _special_ table in the night club.  Anybody that sits at that _special_ table cannot order a drink (DenyWrite).  Sit anywhere else and you can order whatever you want (AllowWrite).

I agree in principal in that this is a business rule and has nothing to do with your AuthorizationRules - but its all about user interaction in this case.

Brian Criswell, ...Just override CanWriteProperty()... Doh, you're right, I'll look into this.  Thanks

 

Brian Criswell replied on Monday, October 30, 2006

Just override CanWriteProperty()

ajj3085 replied on Monday, October 30, 2006

In your property setter for the bool, is it possible to just call DenyWrite or AllowWrite, depending on the value to which the property is being changed?

Brian Criswell replied on Monday, October 30, 2006

I find that it is better to override CanWriteProperty to handle the special cases.  Then all of your property setters look the same.  It then also integrates with the ReadWriteAuthorizationComponent.

ajj3085 replied on Monday, October 30, 2006

Yes, that's the way I have done it as well.  The method I suggested would integrate as well, since canread / canwrite look at the authrules.

Atlhough it might be good that the property setter is different; it more closely matches what is actually happening.  I guess it depends on where most people would look first; at the override, or the property setter.

Either way he'll have to call the reset method on the RWAuth component.

guyroch replied on Monday, October 30, 2006

Brian Criswell:
I find that it is better to override CanWriteProperty to handle the special cases.  Then all of your property setters look the same.  It then also integrates with the ReadWriteAuthorizationComponent.

I'm using code generation (thank god for partial class) to generate my BO's, so overriding seems to be the best approach as I can still generate as-is code for getters and setters and then override the method in my custom partial class.

guyroch replied on Monday, October 30, 2006

ajj3085:
In your property setter for the bool, is it possible to just call DenyWrite or AllowWrite, depending on the value to which the property is being changed?

Great idea, but the bool property is a readonly property :(

guyroch replied on Monday, October 30, 2006

ajj3085:
In your property setter for the bool, is it possible to just call DenyWrite or AllowWrite, depending on the value to which the property is being changed?

Ummm... now you got me thinking.  Would it work if I was to either call the DenyWrite or AllowWrite from within my dp_fetch method once I know the value of the bool property?

ajj3085 replied on Monday, October 30, 2006

It sounds like it should work... but I think you'll have to try and see.


I think your method would work, but if you allow that bool to change while the object is being used, then you'll likely have problems.  The roles which are allowed or denied are just lists... and you have no one to remove an entry once its on the list.

guyroch replied on Monday, October 30, 2006

Thank you ajj3085.  I did just that, I set the DenyWrite or AllowWrite in my dp_fetch method and it works like a charm.  Well almost like a charm, using the DenyWrite or AllowWrite directly will _SHARE_ the authorization rule between instances of the same object so would work the first time but could not guaranty it would work on subsequent instances of the object.  Luckily for me Rocky provided the InstanceDenyWrite and InstanceAllowWrite.  Ohhhh, now it works like a charm.  Thanks to everybody who participated in this thread.

Copyright (c) Marimer LLC