Last active
June 18, 2024 23:10
-
-
Save innateessence/f1c8acc99924acf9eb9b7356605c62b4 to your computer and use it in GitHub Desktop.
Binary Permission System Snippet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.db import models | |
class Permission: | |
# Random permissions added here | |
# Follow binary pattern 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, ... | |
VIEW = 1 | |
EDIT = 2 | |
EXECUTE = 4 | |
MANAGE_OTHERS = 8 | |
STAFF = 16 | |
ROOT = 32 | |
class Role(models.Model): | |
"""django model for permission""" | |
name = models.CharField() | |
permissions = models.IntegerField(default=0) | |
def add_permission(self, perm): | |
if not self.has_permission(perm): | |
self.permissions += perm | |
def remove_permission(self, perm): | |
if self.has_permission(perm): | |
self.permissions -= perm | |
def reset_permissions(self): | |
self.permissions = 0 | |
def has_permission(self, perm): | |
# This does a bitwise AND | |
return self.permissions & perm == perm | |
def __str__(self): | |
return f"Role {self.name}" | |
class User(AbstractUser): | |
... # What already existed before this PR | |
role = models.OneToOneField(Role) | |
# Inserting roles with permissions | |
def insert_roles(): | |
roles = { | |
"User": [Permission.VIEW], | |
"Manager": [Permission.VIEW, Permission.EDIT, Permission.EXECUTE], | |
"Root": Permission().get_all_permissions(), | |
} | |
for r, permissions in roles.items(): | |
role, created = Role.objects.get_or_create(name=r) | |
role.reset_permissions() | |
for perm in permissions: | |
role.add_permission(perm) | |
role.save() | |
# Example of checking the binary permission management approach | |
r = Role(name="FooBar") | |
r.add_permission(Permission.EXECUTE) # Add 4 | |
r.add_permission(Permission.MANAGE_OTHERS) # Add 8 | |
r.has_permission( | |
Permission.EXECUTE | |
) # 12 & 4 == 4 # true, we have permissions 8 and 4 to make up 12 | |
r.has_permission( | |
Permission.MANAGE_OTHERS | |
) # 12 & 8 == 8 # true, we have permissions 8 and 4 to make up 12 | |
r.has_permission(Permission.VIEW) # 12 & 1 == 1 # false, we do not have permission 1 | |
me = User.objects.first() | |
me.role = r | |
me.save() | |
me.role.has_permission(Permission.VIEW) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is intended as a conceptual example, applied to a Django codebase.
Feel free to adapt it to suit your own needs.