from django import http from django.core.urlresolvers import resolve from django.shortcuts import render,redirect from utils.permissions_list import perm_dic from django.conf import settings def perm_check(*args,**kwargs): request = args[0] resolve_url_obj = resolve(request.path) current_url_name = resolve_url_obj.url_name # 當前url的url_name print('---perm:',request.user,request.user.is_authenticated(),current_url_name) match_results = [None,] #match_flag = False match_key = None # 判断是否登录 if request.user.is_authenticated() is False: return redirect(settings.LOGIN_URL) # 循环权限列表 for permission_key,permission_val in perm_dic.items(): per_url_name = permission_val[0] per_method = permission_val[1] perm_args = permission_val[2] perm_kwargs = permission_val[3] perm_hook_func = permission_val[4] if len(permission_val)>4 else None # 判断命名空间和权限是否匹配 if per_url_name == current_url_name: #matches current request url # 判断请求方法 if per_method == request.method: #matches request method # if not perm_args: #if no args defined in perm dic, then set this request to passed perm #逐個匹配參數,看每個參數時候都能對應的上。 args_matched = False #for args only for item in perm_args: request_method_func = getattr(request,per_method) if request_method_func.get(item,None):# request字典中有此參數 args_matched = True else: print("arg not match......") args_matched = False break # 有一個參數不能匹配成功,則判定為假,退出該循環。 else: args_matched = True #判断特殊权限,字典匹配有特定值的參數 kwargs_matched = False for k,v in perm_kwargs.items(): request_method_func = getattr(request, per_method) arg_val = request_method_func.get(k, None) # request字典中有此參數 print("perm kwargs check:",arg_val,type(arg_val),v,type(v)) if arg_val == str(v): #匹配上了特定的參數 及對應的 參數值, 比如,需要request 對象里必須有一個叫 user_id=3的參數 kwargs_matched = True else: kwargs_matched = False break # 有一個參數不能匹配成功,則判定為假,退出該循環。 else: kwargs_matched = True #开始匹配自定义的权限钩子函数 perm_hook_matched = False if perm_hook_func: perm_hook_matched = perm_hook_func(request) match_results = [args_matched,kwargs_matched,perm_hook_matched] print("--->match_results ", match_results) if all(match_results): #都匹配上了 match_key = permission_key break if all(match_results): app_name, *per_name = match_key.split('_') print("--->matched ",match_results,match_key) print(app_name, *per_name) perm_obj = '%s.%s' % (app_name,match_key) print("perm str:",perm_obj) if request.user.has_perm(perm_obj): print('當前用戶有此權限') return True else: print('當前用戶沒有該權限') return False else: print("未匹配到權限項,當前用戶無權限") def check_permission(func): def inner(*args,**kwargs): if not perm_check(*args,**kwargs): request = args[0] return http.HttpResponseForbidden("对不起你没有权限") return func(*args,**kwargs) return inner