rbac config

This commit is contained in:
RobbieHan
2018-11-16 20:15:05 +08:00
parent 1f94ffa857
commit e2edef0af2
22 changed files with 477 additions and 278 deletions

Binary file not shown.

100
apps/system/middleware.py Normal file
View File

@@ -0,0 +1,100 @@
import re
from django.utils.deprecation import MiddlewareMixin
from django.conf import settings
from django.shortcuts import render
class MenuCollection(MiddlewareMixin):
def get_user(self, request):
return request.user
def get_menu_from_role(self, request, user=None):
if user is None:
user = self.get_user(request)
try:
menus = user.roles.values(
'permissions__id',
'permissions__name',
'permissions__url',
'permissions__icon',
'permissions__code',
'permissions__parent'
).distinct()
return [menu for menu in menus if menu['permissions__id'] is not None]
except AttributeError:
return None
def get_permission_url(self, request):
role_menus = self.get_menu_from_role(request)
if role_menus is not None:
permission_url_list = [menu['permissions__url'] for menu in role_menus]
return permission_url_list
def get_permission_menu(self, request):
permission_menu_list = []
role_menus = self.get_menu_from_role(request)
if role_menus is not None:
for item in role_menus:
menu = {
'id': item['permissions__id'],
'name': item['permissions__name'],
'url': item['permissions__url'],
'icon': item['permissions__icon'],
'code': item['permissions__code'],
'parent': item['permissions__parent'],
'status': False,
'sub_menu': [],
}
permission_menu_list.append(menu)
return permission_menu_list
def get_top_reveal_menu(self, request):
top_menu = []
permission_menu_dict = {}
request_url = request.path_info
permission_menu_list = self.get_permission_menu(request)
if permission_menu_list is not None:
for menu in permission_menu_list:
url = menu['url']
if url and re.match(url, request_url):
menu['status'] = True
if menu['parent'] is None:
top_menu.insert(0, menu)
permission_menu_dict[menu['id']] = menu
menu_data = []
for i in permission_menu_dict:
if permission_menu_dict[i]['parent']:
pid = permission_menu_dict[i]['parent']
parent_menu = permission_menu_dict[pid]
parent_menu['sub_menu'].append(permission_menu_dict[i])
else:
menu_data.append(permission_menu_dict[i])
if [menu['sub_menu'] for menu in menu_data if menu['url'] in request_url]:
reveal_menu = [menu['sub_menu'] for menu in menu_data if menu['url'] in request_url][0]
else:
reveal_menu = None
return top_menu, reveal_menu
def process_request(self, request):
if self.get_top_reveal_menu(request):
request.top_menu, request.reveal_menu = self.get_top_reveal_menu(request)
request.permission_url_list = self.get_permission_url(request)
class RbacMiddleware(MiddlewareMixin):
def process_request(self, request):
if hasattr(request, 'permission_url_list'):
request_url = request.path_info
permission_url = request.permission_url_list
for url in settings.SAFE_URL:
if re.match(url, request_url):
return None
if request_url in permission_url:
return None
else:
return render(request, 'page404.html')

View File

@@ -0,0 +1,22 @@
# Generated by Django 2.1.2 on 2018-11-15 21:24
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('system', '0001_initial'),
]
operations = [
migrations.AlterModelOptions(
name='menu',
options={'ordering': ['number'], 'verbose_name': '菜单', 'verbose_name_plural': '菜单'},
),
migrations.AddField(
model_name='menu',
name='number',
field=models.FloatField(blank=True, null=True, verbose_name='编号'),
),
]

View File

@@ -11,6 +11,7 @@ class Menu(models.Model):
icon = models.CharField(max_length=50, null=True, blank=True, verbose_name="图标")
code = models.CharField(max_length=50, null=True, blank=True, verbose_name="编码")
url = models.CharField(max_length=128, unique=True, null=True, blank=True)
number = models.FloatField(null=True, blank=True, verbose_name="编号")
def __str__(self):
return self.name
@@ -18,10 +19,14 @@ class Menu(models.Model):
class Meta:
verbose_name = '菜单'
verbose_name_plural = verbose_name
ordering = ['number']
@classmethod
def get_menu_by_request_url(cls, url):
return dict(menu=Menu.objects.get(url=url))
try:
return dict(menu=Menu.objects.get(url=url))
except:
pass
class Role(models.Model):

View File

@@ -8,7 +8,10 @@ from .models import Menu
class MenuCreateView(SandboxCreateView):
model = Menu
fields = '__all__'
extra_context = dict(menu_all=Menu.objects.all())
def get_context_data(self, **kwargs):
kwargs['menu_all'] = Menu.objects.all()
return super().get_context_data(**kwargs)
class MenuListView(LoginRequiredMixin, ListView):
@@ -20,4 +23,7 @@ class MenuUpdateView(SandboxUpdateView):
model = Menu
fields = '__all__'
template_name_suffix = '_update'
extra_context = dict(menu_all=Menu.objects.all())
def get_context_data(self, **kwargs):
kwargs['menu_all'] = Menu.objects.all()
return super().get_context_data(**kwargs)