--- On Sat, 5/2/09, David E Jones <[email protected]> wrote:
> My personal opinion on this is that the design has only
> subjective improvements and most of it is a big step
> backwards (easier but less flexible, for the services versus
> direct permission part anyway, and we decided long ago that
> flexibility was better than ease in this case; and yes there
> is a creative way to invoke code attached to permissions,
> but that is a bit inflexible IMO since much permission logic
> involved multiple permissions... it's the artifact we
> want the code attached to not the permission itself)
Take your comment - "it's the artifact we want the code attached to not the
permission itself" - and combine that with Scott's suggestion to have a
security-aware delegator, and you have a solution I proposed years ago: a
domain-driven security system.
In a domain-driven security system, each OFBiz artifact is responsible for
handling security for itself. There is no explicit permission-checking code.
Each OFBiz artifact identifies itself in a security domain. When a user tries
to use that artifact, it checks the user's permissions against its own position
in the domain.
Using the Example component's EditExample screen as an example, here is what a
security domain might look like:
framework
example
screen
EditExample (screen)
EditExample (form)
Permissions are hierarchical - each artifact inherits permissions from the
artifact above it. This is very similar to what Andrew is trying to achieve,
but it's different because the artifacts themselves control the security -
there is no call to a permission service with a permission string.
Here's what it might look like in ExampleScreens.xml:
<screens xmlns:xsi="...">
<security domain="framework:example:screen"/>
<screen name="EditExample">
<security domain="EditExample"/>
...
</screen>
</screens>
Notice there are no explicit permission checks. Instead, each artifact has
identified itself in the security domain.
When the widget is run, each artifact checks the user's permissions against its
own security domain. So, the EditExample screen would look for the
framework:example:screen:EditExample" permissions and handle itself
accordingly. (Andrew - this is why I suggested having permission checking code
return all permissions for a context.)
If a user has the access:framework:example:screen:EditExample permission, the
screen will display.
Let's take a look at what happens in the form widget. Here is what ExampleForms
would look like:
<form name="EditExample" type="single" target="updateExample" title=""
default-map-name="example">
<security domain="EditExample"/>
...
</form>
Again, when the widget is run, each artifact checks the user's permissions
against its own security domain. So, the EditExample form would look for the
framework:example:screen:EditExample:EditExample" permissions and handle itself
accordingly.
Let's say the user doesn't have any permissions for that context. Keep in mind
permissions are hierarchical - so the form widget would work its way up the
hierarchy to find permissions. If a user has the
access:framework:example:screen:EditExample permission, the form will display
plain text with no input fields. If the user has the
update:framework:example:screen:EditExample permission, the form will provide
input fields.
Form fields could identify themselves in the security domain as well - so only
the fields the user is permitted to access will appear.
Service definitions and entities could identify themselves in the security
domain in a similar way, and have similar permissions checking logic. Some
examples:
framework
example
service
updateExample
framework
example
entity
Example
The nice thing about this approach is that you could leverage the artifact
gathering code to display the security domain as a tree - with permission
checkboxes next to each "leaf." That would enable any administrator to manage
user security easily.
-Adrian