Technical Notes: Further Refinements on Access Control
Added 2019-06-23 22:02:33 +0000 UTC
Technical Notes: Further Refinements on Access Control
I briefly addressed how the Permission system works in my last post, though I left out considerable detail, and I've refined the system and written slews of unit tests over the weekend. I felt it would be nice to dive deep! Hold on to your butts; nerd stuff ahead:
Dev Disclaimer
Keep in mind that what I'm about to describe is 1) a WIP, and 2) what's happening under the hood. While it looks complex, it's important that the UI hides this complexity and makes this process easy to navigate. If you'd like an example of what this will look like in the end, take a look at the access control/sharing settings on the organizational app Notion.
Additionally, really exercising this system is only necessary if you're a DM wanting to finely control what information is available to your players. If you just want to use LegendKeeper to collaboratively world-build with people you trust, just add everyone to the Admin user-group and you're off to the races
Access Control
Permissions are established between users/user groups and elements (the things in your world/wiki.) Assume that whenever I say user, this could apply to an entire group of users under a common name, like "Editors" or "Party".
The standard access levels are CAN_READ, CAN_EDIT, and CAN_MANAGE, and these are considered escalations of each other--- each one approves the behaviors approved by the previous ones.
The Standard Access Levels
- CAN_READ: Does the viewing user have permission to see this element in the wiki or as a marker on a map?
- CAN_EDIT: Does the viewing user have permission to edit the element's document or change its name/tag/parent/pin?
- CAN_MANAGE: Does the viewing user have permission to delete or change the permissions for other users for this element?
This would be enough, but everything in the LK wiki can be nested, so special provisions need to be made to have a flexible, nested permissions system. This is where the special access levels, INHERIT and NO_ACCESS come into play.
The Special Access Levels
INHERIT tells an element to inherit its access level from its parents. If its parent also inherits, the search continues upward through the lineage until it finds a more specific access level. If the top of a permission lineage is still INHERIT, this element is considered to inherit from the base world rule, which is CAN_READ. The default access level for anything and everything created on the world is INHERIT, so a fresh world with fresh users will behave as if everything is set to CAN_READ.
NO_ACCESS is like it sounds: Setting NO_ACCESS for a user/element pair means that the user can't see that element in the wiki, or linked on any map as a pin. NO_ACCESS will also infectiously override all descendant elements.
For example, consider this hierarchy:
- Faerun (the top level Place element, the "World")
- Dessarin Valley
- Player's Hideout
- Red Larch
Let's say for User A, the DM has set these permissions:
Scenario 1
- Default: CAN_READ
- Faerun: INHERIT (CAN_READ)
- Dessarin Valley: INHERIT (CAN_READ)
- Player's Hideout: CAN_EDIT
- Red Larch: INHERIT (CAN_READ)
The user can view all elements, and can edit Hideout. If the DM later comes back and sets Dessarin Valley to NO_ACCESS, Dessarin Valley, Red Larch, and Hideout will be inaccessible in the wiki and on the map, because both are now considered to be in a NO_ACCESS chain.
Scenario 2
- Default: CAN_READ
- Faerun: INHERIT (CAN_READ)
- Dessarin Valley: NO_ACCESS
- Hideout: CAN_EDIT, overridden by NO_ACCESS
- Red Larch: INHERIT (NO_ACCESS)
In this way, the presence of NO_ACCESS in a permission chain forces all permissions below it to behave like NO_ACCESS, until it is is removed. When it's is removed, they regain whatever access they had before.
Building the permission system off of these foundations allows me to create really flexible permission frameworks for many different types of organizations. These rules could easily be manipulated to support, for example, a collaborative writing environment, a standard DM/party situation, or a huge West Marches campaign where many different parties and DMs are exploring and logging things about a world. Additionally, this naturally lends itself to managing access in terms of "folders" of things, which is easier than managing permissions individually for each little thing.
I'm still looking for unconsidered situations or logical holes in this setup, so let me know if you spot any!
Til next time!
Braden