Adrian,


I must be missing something. Still using the Example component as an example: the service definition called a service permission, which called a script, which ultimately called Security.hasPermission. Your modification has the service definition use the <required- permissions> which ultimately calls authz.hasPermission(). So, both methods end up calling a single hasPermission() method. What changed?

The only difference I see is that the permission string moved from a script to the service definition. Is that the desired benefit?


It is indeed the designed benefit. Previously, we had this:

1. A service with a permission service attached. The permission service checked static permission, and possibly (not in the case of the example component, but honestly this component doesn't utilize the full potential of the new code) processed other logic which would determine of the user had the ability to perform that function.

2. A screen definition which checked permissions, okay again the example component doesn't utilize all the possibilities, but let's say we wanted to add a delete button to the screen to delete the example. Using the old method you would then call the has-permission screen operator and check for a static permission probably something like EXAMPLE_DELETE.

Now, let's say we want to allow anyone to create examples, only the person who created the example and any admin can update or delete it.

Using what we had in the old model, the permission service logic would need to be adjusted to grant permission to the owner of the example. However, the screen operator will still only pickup the static EXAMPLE_DELETE permission. We don't want to give everyone delete access, we only want them to delete the examples they created. So, only admins or users with EXAMPLE_DELETE would see the button.

The new authz implementation handles all of this for us. First we define the permissions, access:example, update:example and delete:example as seed data. These are also attached to the example admin user's security group.

We will give all users access:example permission so they can access the application, but only give admins the update and delete permissions.

Next we define the Dynamic Access logic. Very little code need, check the example from the exampleId which is passed in the permissionContext and part of the permission string (which we will define in a moment) and if the owner is the userId return true, otherwise return false. This can be groovy or a simple method if desired. We then register this logic with the permissions in the seed data file. The same logic can be attached to both update:example as well as delete:example.

Now we will configure the services to include permissions. The createExample will have no permission or set it to access:example to make sure only users who can access the app can create (I have other more complex ideas for this, but this is a simple example). The updateExample service should be set with "update:example:${exampleId}" as the permission, the deleteExample service set with "delete:example:$ {exampleId}" permission.

Finally, we configure the screen definition and add the delete button (or update button whatever the case may be). But we do a permission check here as well for "delete:example:${exampleId}" (note: exampleId should be in the screen's context) to restrict the display of the button.

Now, using the new API the button is displayed under two conditions:
1. the user is an admin and has delete:example permission
2. the user is the owner of the example

The exact same logic is used by the service engine when submitting the request, so you can be sure that if the button was displayed then permission will be granted when submitting the form.

Maybe later you want to change how this works. Maybe being the owner is not enough, you must the be owner and have been active in the last 5 days. So, you simply edit the logic in the groovy (or simple method) script and clear the cache. The new logic kicks in, effective in all places which check that permission.

This is what I mean by 'centralized'. Instead of having security split up between the Security API and the Service Engine Permission API, everything is moved and centered around the permission.


Andrew


Reply via email to