Table views and user roles

Is there any good example or general guidelines (thoughts …) on managing user roles with table views or otherwise?

User roles are typically defined together with permissions on resources (users – roles – permissions – resources). Table views functions (like client_readable(), client_writable()) “filter” on a person (e.g. owner field), but not on roles.

Client views are filtered, but the filters don’t have to be entries in the Users table.

I was thinking more in line with these https://libraries.io/search?keywords=rbac&languages=Python&q=.

Maybe there’s a way to write your own Server-Module-equivalent of table.client_writeable() and table.client_readable(). Failing that, you will have to layer over what Anvil already provides.

Thanks to Oracle and PostgreSQL exposure, I’m somewhat familiar with their role-based access control systems. SQLite delegates permission issues to user code, through a user-definable callback function. So there are a wide variety of systems out there, each working somewhat differently. You likely have a specific set of rules in mind.

A great deal depends upon the patterns of access you intend to support, as well as your actual rules, and how general you want to make it. (The YAGNI Principle comes to mind.) Some specific combinations may be simple to code up.

For a crude example, you could give each record a permissions column, and thus tag each record with the specific permissions needed to access it. Then table.client_*()-style equality-tests would largely work, once you’d boiled down the permissions actually available to the designated user. Your code could also compute the set of columns to include in the view, based on stored permissions, if necessary.

To some extent, it’s a bookkeeping issue. In simpler cases, roles and rules can be hard-coded in your Server Module. In the most general case, you’ll need to set up tables to record the access details, as needed by your implementation.

If you can’t use the existing table.client_*()functions to return a view, then perhaps you can return a buffer (list of dicts), instead. You’d have your own, custom-written Server Module functions, to return the list, and act upon any modifications sent back to the Server Module.

The simulation wouldn’t be perfect. (Date/time values, in particular, have to be converted to/from text/numbers, for transmittal between Server and Client [and Uplink].) But I suspect that you can probably implement much of the behavior you want.

Thanks for your thoughts which are in line with my research on that matter. I suppose the table.client_*() style would work nicely with discretionary access control, where the implementation could follow these ideas, for instance. DAC starts with the assumption that every object has its owner, as in file systems. The beauty of that would be a direct coding of permissions on the record level, and Anvil views with lazy loading and other interesting properties could be used.

On the other hand, role-based access control (RBAC) can be seen in web apps implementations and other settings; e. g. ASP.NET WebForms and MS Lightswitch had RBAC model, where the resources were tables, but not individual records.

It would be interesting to use one of the Python RBAC libraries (like policy and miracle-acl) and to combine their ‘permissions’ implementation with the Anvil data queries. For instance, let’s say that we have travel agents which can sell trips only for their region. We have a ‘travel agent’ role, the resource is the table ‘trips’, and permission is defined by the condition (Python expression):

 acl.grant('travel agent', 'trips', ('WRITE', 'trip["Region"]==user["EmployeeRegion"]'))

which would be somehow translated into:

 @anvil.server.callable
 def getTripsByUser_writeable(user):
   if acl.check(user['Role'], 'trips', 'WRITE'): 
     return [trip for trip in app_tables.trips.search() 
       if trip['Region']==user[EmployeeRegion]]

Or something like that. Of course, you are right in pointing out that for a particular case some simpler solutions are better, but still it’s an interesting field of development.

1 Like

Here’s an example … User roles and permissions