On May 3, 2009, at 4:57 AM, Adrian Crum wrote:
--- On Sat, 5/2/09, David E Jones <david.jo...@hotwaxmedia.com> 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)
I've been thinking about that aspect of it. If I understand
correctly, here are two of the issues being addressed by the new
security:
1. Permission checking is being done in scripts, so a programmer is
required to change the permission checking logic. An ordinary
systems administrator with no knowledge of mini-language would not
be able to change how permissions are checked. The new permission
string is supposed to make changes to permission checking easier for
the non-programmer administrators.
2. Permission checking isn't consistent. Two similar branches of
logic will check permissions in two different ways: one will check a
permission string, and another will run a script. This is common in
the UI versus the services called by the UI. A simple "has
permission" check is done in the UI, and then the service invoked
runs a script to check permissions.
I agree with you that substituting the permission service with a
permission string is too inflexible.
One of the ideas I've been toying with is the idea of a permission
expression. I started writing some code for that and was going to
put it in Jira, but I decided to put it on the shelf until the dust
settles from this thread.
Let's say we took Andrew's new permission string and gave it more
oomph - where it could contain functions and such. (The expression
language would be simple enough for common administrators to
understand.) That could eliminate many of the permission checking
scripts. In effect, the permission string becomes a mini-script.
This mini-script could be used anywhere a permission string is being
used now.
One of the problems I have with what has been proposed so far is
that the permission string can be ambiguous when it comes to
inserting parameters. For example, "update:example:${exampleId}" -
what does that mean? There's no way to tell by looking at it. It
would be preferable to have something like "update:example +
relatedTo(exampleId)". That permission tells me something - it
requires update:example permission and the user must be related to
exampleId in some way.
I think permission expressions would solve both of the issues above.
Part of the point (if I remember right) of putting permission logic
into little services was to help keep it consistent when that service
is called in multiple places, especially in the input processing
service and the output generating screen.
If we have cases where a direct permission check is done on the screen
and a permission service is used for the input processing service,
then we should really change the screen to also call that same service.
I guess the real trick with all of this is to make any easy way to do
dynamic permissions. So far we have these approaches on the table
(sorry if I missed any others...):
1. the current recommended practice of writing a service to perform
permission logic (service can be implemented in simple-method, java,
groovy, etc; normally the easiest way to write and maintain (and in
the future to create tools to help write and maintain) is a simple-
method XML snippet)
2. Andrew's new pattern of attaching a groovy script to certain
permission strings to override the normal behavior of that string
3. Adrian's idea to create some new expression (possibly extend what
Andrew has done) and add functions to the permission string itself
(which might eventually have boolean logic and other things, and be a
little expression language of its own)
Does that sound about right?
When comparing these the big question for me is what will be easiest
for users to maintain, especially less technical users (ie non-
programmers, or I guess also programmers with little time and patience)?
In general I don't know if we'll EVER be able to come up with
something that allows non-technical users to easily configure dynamic
permissions to handle any possible situation. On the other hand, maybe
we can create something that handles most common cases (including both
functionality level and simple record level cases) and leave in
extension points so that it is possible to create more complicated
permission logic when needed.
In other words, however we do this we probably want some configurable
permissions that cover most stuff, and then extension mechanisms to
drop-down to lower level tools. That is the pattern used in pretty
much all of the OFBiz framework tools, and it would be good to apply
it here too.
A quick note on the extension mechanism: another pattern that has
emerged over time is to allow programmers to create custom logic and
put it somewhere that less-technical users can refer to. The reason
for this is that the custom stuff becomes a sort of tool that can be
documented and then used (but not manipulated) by less technical users
as part of their configuration. In other words the pattern would look
like the configuration part of things having the ability to reference
the custom logic part of things, and not the other way around (to make
it clear, that's a big distinction between #1 and #2 above, and I'm
not sure about #3 since it seems to mostly be meant to internalize
things in the permission string/expression instead of referring to
external stuff, but could certainly easily point explicitly to
external stuff).
Anyway, THANK YOU Adrian, this message is a breath of fresh air (part
of why I changed the subject line :) ) and it's great to discuss
actual issues and patterns and possible solutions.
-David