|
from django.contrib.auth.models import Permission |
|
from typing import Iterable |
|
|
|
class CustomPermission(BasePermission): |
|
def __init__(self): |
|
self.perms = () |
|
|
|
def has_permission(self, request, view): |
|
if request.user.has_perms(self.perms): |
|
return True |
|
return False |
|
|
|
def has_object_permission(self, request, view, obj): |
|
return super().has_object_permission(request, view, obj) |
|
|
|
def get_all(custom=True): |
|
try: |
|
if custom: |
|
# custom permissions that don't follow default conventions |
|
# can also search using models' `Meta` classes |
|
perms = Permission.objects.all().filter(codename__regex=r'^(?!(add|change|delete|view)_).+') |
|
else: |
|
perms = Permission.objects.all() |
|
except: |
|
perms = None |
|
finally: |
|
return perms |
|
|
|
def get_all_permission_labels(custom=True): |
|
perms_q = get_all(custom) |
|
if perms_q: |
|
return [f"{perm.content_type.app_label}.{perm.codename}" for perm in perms_q] |
|
|
|
def parse_permissions(permission_label:"str"): |
|
if type(permission_label) == str: |
|
return (permission_label,) |
|
else: |
|
raise Exception("invalid permission format. Each custom permission class can only have 1 custom permission") |
|
|
|
def create_custom_drf_permission(name,permissoin_label:"str"): |
|
CustomClass = type(name,(CustomPermission,),{}) |
|
def custom_init(self): |
|
self.perms = parse_permissions(permissoin_label) |
|
CustomClass.__init__ = custom_init |
|
|
|
return CustomClass |
|
|
|
permission_store = {} |
|
def generate_custom_permissions(): |
|
permission_labels = get_all_permission_labels(custom=True) |
|
for permission_label in permission_labels: |
|
class_name = permission_label.replace(".","App_") # replace illegal class name char, add some info |
|
permission_store[permission_label]=create_custom_drf_permission(class_name,permission_label) |
|
|
|
def register_custom_permissions(): |
|
generate_custom_permissions() |
|
import yourapp.permissions |
|
from django.conf import settings |
|
for PermTypeClass in permission_store.values(): |
|
setattr(yourapp.permissions, PermTypeClass.__name__, PermTypeClass) |
|
settings.REST_FRAMEWORK['DEFAULT_PERMISSION_CLASSES'].append(f"yourapp.permissions.{PermTypeClass.__name__}") # requires this to be created in settings.py |
|
|
|
def get_custom_permission_type_class(permissionLabel): |
|
return permission_store[permissionLabel] # might want to make this thread-safe in future |
please let me know if you have a better solution! i have been searching for an easier way to no avail..