theconductor
06/06/2024, 1:02 AMallow and deny fields for their permissions. It would be neat to see this represented in the schema, but not necessary
- Bonus: Threads inside channels, but can additionally be public (to the channel) or private to specific members.
- I imagine public/private would be represented with a caveat?vroldanbet
06/06/2024, 6:48 AMvroldanbet
06/06/2024, 6:51 AMtheconductor
06/06/2024, 2:32 PMtheconductor
06/06/2024, 9:43 PMparent relation on a channel could capture this well enough, and left out explicit mention of threads. Application-level logic can handle preventing infinite nesting.
- In the context of Discord, public/private is the same as checking if the built-in role @ everyone has read access, which is adequately handled by standard role logic.
- An improvement to this schema would include built_in_role as an additional relation, only including @ everyone. Left out for now.
- Overrides! These are objects where the subject either is or isn't included on each individual relation. A resource then relates to an override via an allow or deny relation. If neither exist, then the resource inherits permissions from the parent.
- https://discord.com/developers/docs/resources/channel#overwrite-object
- This is the overwrite "object" that Discord exposes, implying that they store it as its own DB table. I modeled the schema to sorta match
- For some reason, Discord allows by default? As in, if someone has a role that explicitly denies a permission and also a role that explicitly grants the permission, Discord will grant the permission. This isn't the choice I would've made, but to stay true to reality, I modeled the schema this way
https://cdn.discordapp.com/attachments/1248079453041459270/1248391718014025870/discord0.zed?ex=66637ee3&is=66622d63&hm=04734caf6029ee9cdc4e62d28e86517a42398b687d23e6d8a86f41de450ea330&
https://cdn.discordapp.com/attachments/1248079453041459270/1248391718353506386/discord1.zed?ex=66637ee3&is=66622d63&hm=ffd110915769c94fe21af0ce8915bbecbc8d63b3ebe7d5761130f07a03cf82e3&theconductor
06/06/2024, 9:43 PMtheconductor
06/06/2024, 9:44 PMtheconductor
06/06/2024, 10:09 PMpermission read = ((((parent->read) - deny_role->read) + allow_role->read) - deny_user->read) + allow_user->readtheconductor
06/06/2024, 10:09 PMvroldanbet
06/10/2024, 9:34 AMtheconductor
06/10/2024, 1:58 PMvroldanbet
06/11/2024, 12:41 PMvroldanbet
06/11/2024, 12:43 PMrole didn't seem to aggregate any permissions, just users, and all grants are handled via an "overwrite", which seems required even when there are no overwrites.
My approach uses the "custom roles" pattern where roles and assignment are decoupled.theconductor
06/11/2024, 3:00 PMtheconductor
06/11/2024, 3:04 PMdefinition role {
relation allow_send_messages: user:*
relation admin: user:*
}
definition role_grant {
relation assignees: user | guild#member
relation role: role
permission send_messages = assignees & role->allow_send_messages
permission admin = assignees & role->admin
}
and this (no role_grant)?
definition role {
relation assignees: user | guild#member
relation allow_send_messages: user:*
relation allow_admin: user:*
permission send_messages = assignees & allow_send_messages
permission admin = assignees & allow_admin
}theconductor
06/11/2024, 3:24 PMtheconductor
06/11/2024, 3:48 PMpermission send_messages = parent->send_messages - everyone_deny_overwrite->send_messages + everyone_allow_overwrite->send_messages - role_deny_overwrite->send_messages + role_allow_overwrite->send_messages
equivalent to this
permission send_messages = ((((parent->send_messages - everyone_deny_overwrite->send_messages) + everyone_allow_overwrite->send_messages) - role_deny_overwrite->send_messages) + role_allow_overwrite->send_messages)
and not this?
permission send_messages = (parent->send_messages - everyone_deny_overwrite->send_messages) + (everyone_allow_overwrite->send_messages - role_deny_overwrite->send_messages) + role_allow_overwrite->send_messagestheconductor
06/11/2024, 3:49 PMa - b + c - d + e vs ((((a - b) + c) - d) + e) vs (a - b) + (c - d) + etheconductor
06/11/2024, 6:37 PM((((a - b) + c) - d) + e)theconductor
06/11/2024, 7:20 PMtheconductor
06/12/2024, 10:19 PMoverride type
- role has a direct mapping to the Role that end-users interact with
- Or more explicitly, the mapping { Discord Roles } -> { SpiceDB roles } is surjective
- In the previous schema, I had to make "phantom roles" (o1, o2, and o3) to do the overrides
- permission_grant is both how roles get their permissions and how overrides get their extra_permissions
- This type is spicedb-specific, it doesn't get its own table in the standard DBtheconductor
02/03/2025, 6:18 PM