Permissions
Warning, this page will be heavy on mathematics.
Define a User to be a (mostly human) member that can login on his User account. An Entity can be any object in the system, the most common will likely be Bodies, Circles and Users, but it is entirely possible for an Address, of even something such as a GlobalOption to be considered an Entity in this explanation.
First off, intepret the problem of dealing with permissions as a graph-based problem, a permission entity A has over entity B is then defined as a (uni-directional) edge from node A to B. The desired permissional model will then be the combined graph of these nodes and edges.
Every entity has 2 ways it can grant permissions:
It can define permissions it has on itself
It can define permissions it has over others
A permission can be granted by achieven either of those. Let's consider one of both cases:
Entity A wants to do an action on Entity A, for example changing it's name. Entity A then checks if it can give itself this permission, which will likely be granted, and therefore this action will succeed.
Note that while this might sound unecessary now, this will become useful later on.
Entity A wants to do an action on Entity B, for example changing entity B's name. Let's say Entity A has this permission over others, and Entity B is considered to be in this 'others', therefore the action will succeed
Defining this 'others': While the permission entity A has over others are defined in entity A, the definition of this 'others' is not, this is crucial to understand and probably feels counter-intuitive. Entity A does not define this others, but other entity define themself to be in Entity A's 'others'. This works as follows, using the example above: Entity A tries to do an action on Entity B (renaming), entity B says it requires permissions for this, and will thus start a search for this specific permission. Since it is Entity A trying to do the action, Entity B skips asking itself, but instead starts asking the Entity's it trusts (Entity B's delegates), Entity A happens to be one of these delegates, placing Entity B among entity A's others. Since entity A has defined the renaming permission over others and Entity B has been shown to be in this 'others', the permission is granted.
It can help to say Entity B trusts entity A to make correct decisions on it's permissions.
Optimizations:
Remove the need for Users to be considered as an Entity (removes ~10.000 entities)
While some actions might be initiated by an Entity itself, we are mostly interested by the permissions User A has over entity X. Note that User A could be considered an
A proposal on implementing permissions.
Split between actions on lists and single objects.
Only Users have rights.
Bodies define default rights between its Users and default rights the User have on the Body
Body Circles grant extra rights between Users in the same Body Circles, extra rights over Users within that same Body, as well as defining extra rights Users of that Circle have over the Body
Global Circles grant extra rights between Users in the same Global Circle, extra rights over Users in general, as well as defining extra rights over other (Global and/or Body) Circles
Group - A parent of a set of Users. For example: Body, Circle, Event.
METHOD 1: Gather permissions first
User - Body
Start with the default rights the User has over that Body
Find User relations to Body
Find all the Body Circles the User is in
Filter on the Body in question
Find permissions for each relation (role)
Merge permissions
Apply permissions
User - Bodies
Find User relations to global Circles
Find User circles
Check each Circle for global parent Circle
Get Both
Find permissions for each relation (role)
Merge permissions
Apply permissions
User - Circle
Get default rights the Users of the Circle have over the Circle
Find User's global Circles
Find User's Body Circles
Find parent Global Circles of those Body Circles
Find permissions each of the Global Circles have over Circles
Merge permissions
Apply permissions
User - User
For each User:
Find the Bodies the User is in
Find the (Body) Circles the User is in
Find the Global Circles the User is in through the Body Circles
Query other microservices for relations.
Get the cross-section of the groups
Find permissions for the remaining common relations
Merge permissions
Apply permissions
User - Users
Specify the group of which to use the rights (a single group)
Find Users within that Group
Find permissions over those Users based on the given Group
Apply permissions on each User
A cross section with the groups of a User with every set of groups from Users in the system would result in a too complex query, therefor this is only allowed for single User on single User.
User - External Object
Delegated to the external object
To Be Solved:
Allowing external objects to have circles assigned to them. → Giving Circles a variable parent Object
METHOD 2: Search required permissions - abstract
Have 2 Permission interfaces/traits/basemodels/whatever and initiate a (preferably breadth-first) search to find a GPO that can grant the User this permission.
RequiresPermission Object (RPO)
Pretty much everything, including Bodies and Circles
GrantsPermission Object (GPO)
Typically Bodies, Circles
Extension of an RPO
When a User wants to do an action on a RPO, the required permission will be determined first
If default permissions allow the action, permission is granted
Next the RPO asks its GPO's whether any of them can grant the User permission for this action on itself
The GPO then takes the following steps upon receiving a request from the RPO:
The GPO can grant this permission itself
Typically this comes down to whether both the User and the requesting RPO are members of this GPO (and members receive those rights on eachother)
Next, the GPO delegates this RPO's permission request from the User (acting as an RPO)
The GPO gathers the set of GPO's it trusts
Typically Circles inside a Body or Bodies/Circles it extends
It queries these GPO's for the permission requests (and step 4 restarts)
At any time once a permission is found, the action is approved
If the search ends without result, permission is not granted
Loop prevention has to be done
Several optimization tactics can probably implemented
Short-routing frequent actions, basically knowing where to search for a permission
Filtering trusted GPO's on Circles the User is a member of
This is very much a networking question
Existing network optimization (caching) techniques might be usable