# 1. permissions.json """ { "mapping":{ "c":"create", "r":"read", "u":"update", "d":"delete" }, "group":{ "admin":{ "cart":"r,u,d,buy,send,telandc,read-pending,read-paid,read-bought", "province":"c,r,u,d", "district":"c,r,u,d", "sub_district":"c,r,u,d", "customer":"r,u,d,suspend", "admin":"c,r,u,d,suspend" }, "operator":{ "cart":"buy,r", "province":"r", "district":"r", "sub_district":"r" } } } """ # app/management/commands/create_permissions.py import os import json from django.db.models import Q from django.conf import settings from django.contrib.contenttypes.models import ContentType from django.contrib.auth.models import (User, Group, Permission) from django.core.management.base import (BaseCommand, CommandError) from apps.models_helper.address import (Province, District, SubDistrict) from apps.models_helper.cart import Cart PERMISSIONS_JSON_FILE = os.path.join(settings.BASE_DIR, 'permissions.json') class Command(BaseCommand): """ command to generate/recheck all groups & permissions which following `permissions.json` file. ./manage.py create_permissions """ help = 'Command to generate groups and permissions for users' def add_message(self, message, status='success'): """ to add message for success or warning only """ message = self.style.SUCCESS(message) \ if status == 'success' \ else self.style.WARNING(message) self.stdout.write(message) def load_json_file(self): """ load json file as dictionary """ open_file = open(PERMISSIONS_JSON_FILE, 'r').read() return json.loads(open_file) def key_name_to_content_type(self, key_name): """ parsing a `key_name` to `content_type` object. :param `key_name` is like 'cart', 'province', etc. """ key_maps = { 'admin': User, 'operator': User, 'customer': User, 'cart': Cart, 'province': Province, 'district': District, 'sub_district': SubDistrict } if key_name in key_maps.keys(): class_name = key_maps.get(key_name) return ContentType.objects.get_for_model(class_name) # when `key_name` dosn't exist at `key_maps` raise Exception('You need to update `key_maps` in this file: %s' % __file__) def generate_permissions(self, key_name, str_permissions): """ :param `key_name` is like "cart", "province", "admin", or etc. :param `str_permissions` is like "c,r,u,d,buy,send,telandc" parsing some access names: c: to create- r: to read- u: to update- d: to delete- return list objects of permissions. """ list_permissions = str_permissions.split(',') json_file = self.load_json_file() mapping = json_file.get('mapping') new_permissions = [] for permission in list_permissions: if permission in mapping.keys(): permission = mapping.get(permission) code = '%s-%s' % (permission, key_name) name = 'can %s %s' % (permission, key_name) content_type = self.key_name_to_content_type(key_name) permission, truefalse = Permission.objects.get_or_create(codename=code, name=name, content_type=content_type) permission.save() new_permissions.append(permission) return new_permissions def check_group(self, group_name): """ to get or create the group """ group, truefalse = Group.objects.get_or_create(name=group_name) group.save() return group def check_permissions(self): """ to get or create the permissions, and register the permissions into groups. """ group_names = self.load_json_file().get('group') for key_group_name, value_dict in group_names.items(): permissions = [] for key_name, str_permissions in value_dict.items(): new_permissions = self.generate_permissions(key_name, str_permissions) permissions.extend(new_permissions) group = self.check_group(key_group_name) permissions = list(set(permissions)) for permission in permissions: group.permissions.add(permission) self.add_message('Groups & Permissions successfully added!') def handle(self, *args, **kwargs): # noqa self.check_permissions()