Allow permissions to optionally return a message
Description
The current permission checks only tell a user that they are not allowed to issue a specific command. However they do not explain any reason why.
For e.g. a permission check if a issuer can or cannot create a rule returns
Account joe cannot add a replication rule.
https://github.com/rucio/rucio/blob/dc97725de99d438966d412c81918a52755b63baa/lib/rucio/api/rule.py#L89-L90
This is often not enough when there are multiple criteria in an experiments policy package to determine if a rule can be created or not.
This has become increasingly important for CMS due to user policy around rule creation that are AutoApproved.
We would like to optionally, attach a reason when the permission fails to let the user if there is an unintended mistake or in cases when they should get required permissions from ops.Joe
Motivation
No response
Change
Modify the has_permissions call to accept an optional (For backward compatibility and opt-in support) "Message" (reason for failure) in the return value and raise it with the Access Denied exception.
I think this is a good idea and should not be too complicated to implement.
I've discussed this with Martin and I'm happy to take a look at it if people want me to? I think it should be possible to make it backwards compatible so that policy packages that implement their own permission checks and don't return a message will still work, probably by adding some code to the dispatcher in core/permission/__init__.py.
Hello James It is good with us if you take this. I am not sure if @alexanderrichards has already started working on it.
I am finally looking at this now. I plan to do the following:
- Add a new class
PermissionResultcontaining a boolean and a string for the message. The return value fromhas_permissionwill be of this type. - Implement
__bool__()to maintain compatibility with old code that expects a raw boolean. - The top level
has_permissionfunction in__init__.pywill check the type returned by the policy packages. If it's a raw boolean, it will wrap the value in aPermissionResultobject with an empty string, to maintain compatibility with old policy packages that return raw booleans. - The code in the gateway layer (mostly) that calls
has_permissioncan be modified to expect aPermissionResultobject and report the message when it throws an exception. This could be done incrementally.
I've already done some tests to ensure this will work, but I wanted to check it's acceptable before I spend time updating all the callers to report the message.