django 扩展自带权限,使其支持对象权限

扩展django 自带权限

说明

在不重写 自带权限的基础上,完成支持对象权限,适用于小型项目。
欢迎提出修改意见

软件支持

jsonfield

数据库

新建3个表

from django.db import models
from django.contrib.auth.models import AbstractUser, Group ,User

from jsonfield import JSONField

class Request(models.Model):
    request = models.CharField(max_length=16, verbose_name=‘请求类型(大写)‘)

    class Meta:
        db_table = "request"
        verbose_name = "请求类型"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.request

class RolePermission(models.Model):
    role = models.CharField(max_length=32, verbose_name=‘角色组‘)
    table = models.CharField(max_length=32, verbose_name=‘表名字‘)
    request = models.ManyToManyField(Request, verbose_name=‘请求‘, related_name=‘re‘, )
    permission = JSONField(max_length=1024, verbose_name=‘权限条件‘)

    class Meta:
        db_table = "role_permission"
        verbose_name = "角色组权限"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.role

class Role(models.Model):
    group = models.ForeignKey(Group, verbose_name=‘用户组‘, on_delete=models.CASCADE)
    roles = models.ManyToManyField(RolePermission, verbose_name=‘角色组权限‘, blank=True,related_name=‘roles‘ )

    class Meta:
        db_table = "role"
        verbose_name = "角色组关系"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.group.name
system/models
Role                 角色组关系    : 系统用户组  <-->  角色组权限
Request             请求类型      : GET ,POST
RolePermission      角色组权限    : 角色  表名字  请求  权限条件(JSON类型)

重点为 RolePermission 表。

例子

  • 以常见的资产 asset 为例

    表名字  asset     字段 groups     (分组 为 dev,ops)
  • 权限划分
  • 新建用户 hequan
  • 新建组 dev
  • 在Request 表 添加

    GET (代表只读)
    POST (代表更新 删除)

  • 在RolePermission 添加

    角色 asset-dev只读
    表名字assset
    请求 GET
    权限条件 {"groups":‘dev‘}

  • 在Role 表中 添加

    系统用户组 dev
    角色组权限 asset-dev只读

权限验证代码

import json
from system.models import Role
from functools import wraps
from django.shortcuts import HttpResponse

def role_permission_get_list(function):
    """
    列表页面 控制权限
    :param function:
    :return:
    """

    @wraps(function)
    def wrapped(self):
        user = self.request.user
        groups = [x[‘name‘] for x in self.request.user.groups.values()]
        request_type = self.request.method
        model = str(self.model._meta).split(".")[1]

        filter_dict = {}
        not_list = [‘page‘, ‘order_by‘, ‘csrfmiddlewaretoken‘]
        for k, v in dict(self.request.GET).items():
            if [i for i in v if i != ‘‘] and (k not in not_list):
                if ‘__in‘ in k:
                    filter_dict[k] = v
                else:
                    filter_dict[k] = v[0]

        if not user.is_superuser:
            role_groups = Role.objects.filter(group__name__in=groups).values_list(‘roles__table‘,
                                                                                  ‘roles__request__request‘,
                                                                                  ‘roles__permission‘)

            permission_dict = {}
            for i in role_groups:
                if i[0] == model and i[1] == request_type:
                    permission_dict = json.loads(i[2])

            if permission_dict:
                if filter_dict:
                    for k, v in permission_dict.items():
                        if ‘__in‘ in k:
                            k1 = k.replace(‘__in‘, ‘‘)
                        if ‘__gt‘ in k:
                            k1 = k.replace(‘__gt‘, ‘‘)
                        if ‘__lt‘ in k:
                            k1 = k.replace(‘__lt‘, ‘‘)
                        else:
                            k1 = k
                        if k1 in list(filter_dict.keys()):
                            del filter_dict[k1]

                    if filter_dict:
                        filter_dict.update(**permission_dict)
                    else:
                        print(‘查询条件处理后为空,默认权限‘)
                        filter_dict = permission_dict
                else:
                    print(‘查询条件为空,默认权限‘)
                    filter_dict = permission_dict
            else:
                print(‘没有权限‘)
                filter_dict = {‘id‘: -1}

        self.filter_dict = filter_dict
        result = function(self)
        return result

    return wrapped

def role_permission_detail(function):
    """
    详情页面 控制权限
    :param function:
    :return:
    """

    @wraps(function)
    def wrapped(self, request, *args, **kwargs):
        user = self.request.user

        if not user.is_superuser:
            groups = [x[‘name‘] for x in self.request.user.groups.values()]
            request_type = self.request.method
            model = str(self.model._meta).split(".")[1]
            pk = self.kwargs.get(self.pk_url_kwarg, None)

            role_groups = Role.objects.filter(group__name__in=groups).values_list(‘roles__table‘,
                                                                                  ‘roles__request__request‘,
                                                                                  ‘roles__permission‘)

            permission_dict = {}
            for i in role_groups:
                if i[0] == model and i[1] == request_type:
                    permission_dict = json.loads(i[2])

            permission_dict[‘id‘] = pk
            obj = self.model.objects.filter(**permission_dict).count()
            if not obj:
                return HttpResponse(status=403)

        result = function(self, request, *args, **kwargs)
        return result

    return wrapped

def role_permission_update_delete(function):
    """
    详情页面 控制权限
    :param function:
    :return:
    """

    @wraps(function)
    def wrapped(self, request):
        user = self.request.user
        if not user.is_superuser:

            groups = [x[‘name‘] for x in self.request.user.groups.values()]
            request_type = self.request.method
            model = str(self.model._meta).split(".")[1]
            pk = self.request.POST.get(‘nid‘, None)

            role_groups = Role.objects.filter(group__name__in=groups).values_list(‘roles__table‘,
                                                                                  ‘roles__request__request‘,
                                                                                  ‘roles__permission‘)

            permission_dict = {}
            for i in role_groups:
                if i[0] == model and i[1] == request_type:
                    permission_dict = json.loads(i[2])

            permission_dict[‘id‘] = pk
            obj = self.model.objects.filter(**permission_dict).count()
            if not obj:
                ret = {‘status‘: None, ‘error‘: "没有权限,拒绝", ‘msg‘: ‘Without permission, rejected‘}
                return HttpResponse(json.dumps(ret))

        result = function(self, request)
        return result

    return wrapped

CBV 例子

  • 省略部分代码

    class AssetListAll(LoginRequiredMixin, ListView):
    model = Ecs
    
    @role_permission_get_list
    def get_queryset(self):
        filter_dict = self.filter_dict
        self.queryset = self.model.objects.filter(**filter_dict)
        return self.queryset
class AssetChange(LoginRequiredMixin, UpdateView):
    model = Ecs

    @role_permission_detail
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    @role_permission_update_delete
    def form_valid(self, form):
        self.object = form.save()
        return super().form_valid(form)

class AssetDetail(LoginRequiredMixin, DetailView):
    model = Ecs

    @role_permission_detail
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)
class AssetDel(LoginRequiredMixin, View):
    model = Ecs

    @role_permission_update_delete
    def post(self, request):
        pass

原文地址:http://blog.51cto.com/hequan/2301300

时间: 2024-11-06 21:26:20

django 扩展自带权限,使其支持对象权限的相关文章

oracle新建对象 权限管理

代码 CREATE USER target IDENTIFIED BY target ; GRANT CONNECT, RESOURCE TO target; 刚刚创建的oracle实例中会内建两个用户:system和sys. (1)新建用户 我们先使用system用户登录oracle实例来新建t_user用户. 新建用户格式:create user 用户名 identified by 密码 ; 如: create user t_user identified by t_user ; 修改用户的

Oracle对象权限

对象权限指访问其他方案的权利,用户直接访问自己的方案的对象,但是如果要访问别的方案的 对象,则必须具有对象的权限. 比如smith用户要访问scott.emp表(scott:方案,emp:表),则不需再scott.emp 表上具有对象的权限. 常用的对象权限: Alter --修改(修改表结构) delete --删除 Select --查询 insert --添加 Update --修改(更新数据) index --索引 References --引用 execute --执行 显示对象权限

Oracle笔记之对象权限与系统权限总结

对象权限与系统权限 创建表和创建session是系统权限: 系统管理员是有权限去訪问其它表的 以sys登录 sqlplus sys/on_change_install as sysdba; 创建用户wangwu create user wangwu identified by wangwu; 系统权限 grant create session to wangwu; grant create table to wangwu; grant unlimited tablespace to wangwu

SQL Fundamentals || DCL(Data Control Language) || 系统权限&amp;对象权限管理(GRANT&amp;REVOKE)

SQL Fundamentals || Oracle SQL语言 语句 解释 Create user Creates a user(usually performed by a DBA) Grant Gives other users privileges to access the objects Create role Creates a collection of privileges, usually performed by a DBA Alter user Changes a use

Oracle 用户、对象权限、系统权限

--================================ --Oracle 用户.对象权限.系统权限 --================================  一.用户与模式 用户:对数据库的访问,需要以适当用户身份通过验证,并具有相关权限来完成一系列动作 SYS用户,缺省始终创建,且未被锁定,拥有数据字典及其关联的所有对象 SYSTEM用户,缺省始终创建,且未被锁定,可以访问数据库内的所有对象 模式(schema):是某个用户拥有所有对象的集合.具有创建对象权限并创建

Oracle系统权限与对象权限

oracle权限分为: 系统权限: 允许用户执行特定的数据库动作,如创建表.创建索引.连接实例等. 对象权限: 允许用户操纵一些特定的对象,如读取视图,可更新某些列.执行存储过程等. 系统权限 超过一百多种有效的权限(查询约209种) SQL> select count(*) from system_privilege_map; COUNT(*) ---------- 209 数据库管理员具有高级权限以完成管理任务,例如: – 创建新用户 – 删除用户 – 删除表 – 备份表 常用的系统权限:

2.4、使用Django自带的admin用户管理,权限管理

如何创建项目请参考2.2.创建项目. 通常web服务会要求注册的用户通过用户名和密码登录,然后才可能管理自己的信息或者对一些页面进行授权,判断用户是否拥有执行某种操作的权限. Django已经提供了一个django.contrib.auth应用来处理登录,登出和权限验证,同时还提供了django.contrib.admin应用来管理用户.可以参考你的虚拟python环境的/lib/python27/site-packges/django/contrib/admin里面的文件和源码. 我们要做的就

如何配置IIS使其支持APK文件的下载

如何配置IIS使其支持APK文件的下载APK文件是安卓的安装程序的文件,IIS里的MIME里默认是不支持的.如果没有配置MIME时,直接输入网址要下载APK文件时,会提示找不到此文件.这里教你如何配置IIS的MIME设置,使其可以支持APK文件的下载.1.在管理工具里打开Internet 信息服务(IIS)管理器.然后选择需要配置的网站.2.右侧的界面中会显示该网站的所有功能配置,我们选择并点击进入“MIME类型”3.在右侧的操作区选择点击“添加”MIME.4.在弹出的添加窗口里的文件扩展名输入

配置apache使之支持浏览器端的缓存

当直接在浏览器中输入一个URL,或者点击一个链接的时候,那么浏览器缓存就会起作用,如果缓存没有过期,那么浏览器会从本地读取资源,不会发起HTTP请求,如果缓存过期,那么浏览器会发起新的浏览器请求. 一.适用直接访问,非F5刷新页面的情况下 Expires是HTTP/1.0的缓存头, Cache-Control: max-age 是HTTP/1.1是用来进行HTTP缓存的头.Expires指定了资源过期的绝对时间,GMT格式,Cache-Control: max-age指定了资源过期的相对时间,单