最近在写发布系统,涉及到权限的控制
参考 黄小墨同学的博客实现了
如下
1;定义一张权限控制的表
1 [root@localhost app01]# tailf -25 models.py 2 3 4 5 class Permission(models.Model): 6 name = models.CharField("权限名称", max_length=64) 7 url = models.CharField('URL名称', max_length=255) 8 chioces = ((1, 'GET'), (2, 'POST')) 9 per_method = models.SmallIntegerField('请求方法', choices=chioces, default=1) 10 argument_list = models.CharField('参数列表', max_length=255, help_text='多个参数之间用英文半角逗号隔开', blank=True, null=True) 11 describe = models.CharField('描述', max_length=255) 12 13 def __str__(self): 14 return self.name 15 16 class Meta: 17 verbose_name = '权限表' 18 verbose_name_plural = verbose_name 19 #权限信息,这里定义的权限的名字,后面是描述信息,描述信息是在django admin中显示权限用的 20 permissions = ( 21 ('views_svns_list', '查看svn版本库信息表'), 22 ('views_onlinecode_info', '查看推送代码详细信息表'), 23 ('views_assets_info', '查看资产详细信息表'), 24 )
2:定义权限文件
[root@localhost app01]# cat permission.py #!/usr/bin/env python #_*_coding:utf-8_*_ from django.shortcuts import render from app01 import models from django.db.models import Q from django.core.urlresolvers import resolve #此方法可以将url地址转换成url的name def perm_check(request, *args, **kwargs): url_obj = resolve(request.path_info) url_name = url_obj.url_name perm_name = '' #权限必须和urlname配合使得 if url_name: #获取请求方法,和请求参数 url_method, url_args = request.method, request.GET url_args_list = [] #将各个参数的值用逗号隔开组成字符串,因为数据库中是这样存的 for i in url_args: url_args_list.append(str(url_args[i])) url_args_list = ','.join(url_args_list) #操作数据库 get_perm = models.Permission.objects.filter(Q(url=url_name) and Q(per_method=url_method) and Q(argument_list=url_args_list)) if get_perm: for i in get_perm: perm_name = i.name perm_str = 'app01.%s' % perm_name if request.user.has_perm(perm_str): print('====》权限已匹配') return True else: print('---->权限没有匹配') return False else: return False else: return False #没有权限设置,默认不放过 def check_permission(fun): #定义一个装饰器,在views中应用 def wapper(request, *args, **kwargs): if perm_check(request, *args, **kwargs): #调用上面的权限验证方法 return fun(request, *args, **kwargs) return render(request, '403.html', locals()) return wapper
3:定义views.py
from app01.permission import check_permission @login_required(login_url='/login/') @check_permission def svnupdate(request,svn_id,u_type): pass
20170426
添加权限控制,具体使用方式登录admin,然后在权限表里操作。
权限名称 就是models中定义的权限
URL名称 就是具体访问的某个url 就是在urls.py里的name字段
以上两个字段必须和models中和url中的一致。
添加这个为拒绝的权限,如果普通用户需要访问,需要单独对普通用户授权。
点击admin 的User选项,具体的赋权操作
以上权限控制对应的是单个页面的,根据自己业务的不同,发布系统需要按项目实现对用户的控制,比如:A项目user1有发布的权限。B项目user2 有发布的权限,user3 有AB两个项目的所有权限。这样上面的权限管理就无法满足需求。于是参照上面的例子,自己改了改。大致的方式就是 加一个表存储 用户和发布项目的对应关系,然后在比较request.user.username和数据库里的这个表,如果存在,就返回True,然后获取项目id,比较这个用户在数据库里的的项目是否存在。
代码为:
models.py 并没有用多对多的关系,当时选择多对多的关系好多问题,于是干脆搞成这样了
1 class svn_permission(models.Model): 2 permission_info = models.CharField(max_length=100,blank=True,null=True) 3 web_users = models.CharField(max_length=100) 4 svn_projects = models.TextField() 5 6 def __unicode__(self): 7 return self.permission_info 8 class Meta: 9 verbose_name = 'SVN权限表' 10 verbose_name_plural = verbose_name 11 12 13 class online_permission(models.Model): 14 permission_info = models.CharField(max_length=100,blank=True,null=True) 15 web_users = models.CharField(max_length=100) 16 src_dir = models.TextField() 17 18 def __unicode__(self): 19 return self.permission_info 20 class Meta: 21 verbose_name = '上线代码权限表' 22 verbose_name_plural = verbose_name
权限py文件
cat svnprojectpermission.py
#!/usr/bin/env python #_*_ coding:utf-8_*_ from django.shortcuts import render from app01 import models from django.db.models import Q from django.core.urlresolvers import resolve def perm_svnproject_check(request,**kwargs): url_obj = resolve(request.path_info) print("urlobj",url_obj) print"webusername",request.user.username url_name = url_obj.url_name print "---->urlname:",url_name kw = url_obj.kwargs print("kwargs",kw) for k,v in kw.items(): if k=='svn_id': print'v',v adf = str(models.svns.objects.get(id=v)) print("web submit svnproject",adf) all_list = [] sql_infos = models.svn_permission.objects.all() for info in sql_infos: users = info.web_users all_list.append(users) svn_pro = str(info.svn_projects).split(',') all_list.append(svn_pro) print("user,svn_pro",users,svn_pro) print("all_list",all_list) webuser = str(request.user.username) if webuser in all_list: num = all_list.index(webuser) print"user success" print("num",num) webdir = str(adf) if adf in all_list[num+1]: print("--success--") return True else: print("fail") return False else: print("---no include user---fail--- ") return False def check_svnproject_permission(fun): def wapper(request, *args, **kwargs): if perm_svnproject_check(request, **kwargs): return fun(request, *args, **kwargs) return render(request, 'forbiden.html', locals()) return wapper
具体的方式参考发布系统里的代码