I am currently 4.3.13 and am encountering what I believe might be I thought was a bug, but realize might be intentional.
I have a parent child scenario and have authorization rules on the parent. For what I can see, the authorization rules do not cascade down to the child. For example, if the parent is read only, I can still make changes to the child.
I can understand why if this is intentional. If it isn't, please let me know.
If it is intentional, how do I handle security on the children best. Should I:
1) Set security on each child class explicitly. This is a problem if there are multiple parent classes that use this child and have different security.
2) Access the Parent and check it's security. This seems to be a bit of a complex base class. How does one override this if a child as a special security requirement?
Any help would be appreciated.
Its intentional as it may be valid for someone's use case to allow editing of children but not the parent. you can use the same rule methods as the parent class or reference the parents methods directly. as for children with different types as parents, that's a bit unusual but you can write a rule method that makes a decision based on the parents type.
Like Andy said - this is intentional as a Child object is considered to have their own authorization rules.
(And I assume we are talking property level authorization rules here).
If the purpose is to "make the entire object readonly" I have often added overrides to CanWriteProperty (and CanExecuteMethod) to have a check on some condition and just return false.
Remember: there is a limit of 1-one AutohorizationRule per property and authorization action. So you cannot chain multiple AuthorizationRules in AddBusinessRules (althjo you can make AuthorizationRules that call other authorization riles). So I usually prefer to have AuthorizationRules that are for the necessary properties only - and if I need to make the entire object read only to use the override in CanWriteProperty.
I'm only dealing with object level authorization since it's the business requirement.
I do have classes that are shared with multiple parents. For example, Address is an object that could be a child of both Member and Business. Depending on who the parent is, the authorization should be different. I also have to plan that more parents could be added in the future.
I'm hoping I'm not over complicating this in my mind.
Is the child object a 1-1 or is it in a collection?
You could have a base Address<T> class which is abstract. You could create internally visible only subclasses which then have the AddObjectAuthorization rules setup specifically for each parent that will have an object and the factory methods to create the instance. All of the other logic could be in the base class; of course all your factory methods would have to be internal so that only the parent can create instances. So you'll need to create a new subclass for every new parent, but all that would end up there is the behavior specific to who the subclass is meant to be used with, which should just be the security code.
The real issue here is when and where to check authorization.
ObjectLevel authorization is checked only for "root" DataPortal calls (DataPortal.Create/Fetch/Delete/Execute/Update).
There is no authorization checks in the child dataportal calls. When a child object is created it has NO knowledge of any parent until it is added to a parent object/list (and SetParent method is called) and this occurs after the ChildDataPortal call has completed.
(and there is several other posts too on the forum)
I recognise this would be an issue on the Get security, but my more immediate concern is with Edit. In my case, all data should be loaded for Editing and SetParent should already be executed.
I guess I'm a little surprised a security inherited from the parent object has never been a requirement before.
If you're mainly concerned about editing child objects, you could override CanWriteProperty and have your parent (or grandparent in the case of a list of addresses) implement an interface which returns a Boolean CanEdit property. Then in the override just get your parent or grandparent, casting to your interface, and if it returns false you can return false otherwise call the base.CanWriteProperty.
I think it is what I'm looking at doing. My only remaining issue is how to override this behaviour if the child needs to have a different or additional security.
Just a caution.
ObjectLevel Authorization rules does NOT prevent edit of properties. In the case of EditObject is only checked in Save() on the "root" object.
PropertyLevel authorization rules can be used for ReadProperty/WriteProperty/ExecuteMethod.
Is this a difference between 4.3.x and 4.5.x?
I believe its the same for both versions.
Since you're talking about property rules though you can make the auth rule as smart as it needs to be. With property rules you don't need to override CanWriteProperty as the rule can contain any of the logic you need.
For property level AuthorizationRules be aware of:
If you already have role based authorization rules - it may be easier and safer to add an override to CanWriteProperty rather than create multiple sets of rules or change your rule registrations.
Copyright (c) Marimer LLC