Skip to content

Instantly share code, notes, and snippets.

@innateessence
Last active June 18, 2024 23:10
Show Gist options
  • Save innateessence/f1c8acc99924acf9eb9b7356605c62b4 to your computer and use it in GitHub Desktop.
Save innateessence/f1c8acc99924acf9eb9b7356605c62b4 to your computer and use it in GitHub Desktop.
Binary Permission System Snippet
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)
@innateessence
Copy link
Author

This is intended as a conceptual example, applied to a Django codebase.

Feel free to adapt it to suit your own needs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment