Aam-Digital / ndb-core

Easy-to-use case management web app for NGOs anywhere in the world.
http://www.aam-digital.com
GNU General Public License v3.0
50 stars 16 forks source link

Support advanced permission checks #1315

Open TheSlimvReal opened 2 years ago

TheSlimvReal commented 2 years ago

Currently, the permission definitions in CASL only allow to restrict access based on the active user, the requested entity and the properties of the requested entity. This allows permissions like user X can only read female children.

A more advanced but still common use case would involve a relationship check. E.g. user Y can only read children which currently attend school Z This is currently not possible, because it would require for each child that it requested, to load the child school relations and than check which school the child currently attends. This mechanism is not supported by the CASL library (only works synchronous).

I currently see the following options to support the described scenario

  1. Implement #693 to have more information in the child object and somehow store in the org.couchdb.user object or as a database role for which schoolID's a user has access.
  2. Make rules that automatically update the permission object whenever a write on a relevant object happens. E.g. add a child to the list of children for which a user has access, once a relation with a given school has been saved
  3. Keep an in-memory storage with synchronous access of important entities in the backend and extend CASL so checks across entities synchronously
TheSlimvReal commented 2 years ago

Point 3 would probably be the solution which would give us the most freedom how complex rule can get but I am not sure how well it scales and also the rule definitions can get increasingly complex (see the query syntax).

Point 2 has the danger that the permissions and the data might get out of sync when there are some errors which is difficult to recover from. Also the implementation effort is very high as this a completely new concept.

Point 1 is my preferred option as the restructuring comes with some other nice benefits (less indices, easy permissions on related data) but it still has limitations e.g. user X can only read notes where a child is linked for which user X has access. I am not sure though if we should support something like this. The other point is that for the above use case we would also need to update the org.couchdb.user object or the permission rule based on which schools a user is allowed to have access to. This needs to be incorporated into the UI (e.g. the school can be assigned to the user which triggers the user or the permission object to be updated - not supported yet).

sleidig commented 2 years ago

I'll try to list out essential user stories here:

Rule to give user access to ...

  1. [x] (1) any Note assigned to own User
  2. [x] (2) any Child with status/location/... "A" (i.e. value of a dropdown field of Child)
  3. [ ] (3) any Child of School "A" (i.e. child-school relationship entry)
  4. [ ] (4) any Note of any accessible Child (i.e. for children accessible through any other above rule; also Observation, ASER, ...)

Looking at our abstract entity property models we roughly had

We can maybe completely do away with the two-step refs by always embedding these (not sure, haven't carefully thought this through). But I think we do need a way to handle permissions for direct entity refs, where the rule is not only specifying individual IDs of the related entity but instead a rule based on rules.