permissions.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. from django import http
  2. from django.core.urlresolvers import resolve
  3. from django.shortcuts import render,redirect
  4. from utils.permissions_list import perm_dic
  5. from django.conf import settings
  6. def perm_check(*args,**kwargs):
  7. request = args[0]
  8. resolve_url_obj = resolve(request.path)
  9. current_url_name = resolve_url_obj.url_name # 當前url的url_name
  10. print('---perm:',request.user,request.user.is_authenticated(),current_url_name)
  11. match_results = [None,]
  12. #match_flag = False
  13. match_key = None
  14. # 判断是否登录
  15. if request.user.is_authenticated() is False:
  16. return redirect(settings.LOGIN_URL)
  17. # 循环权限列表
  18. for permission_key,permission_val in perm_dic.items():
  19. per_url_name = permission_val[0]
  20. per_method = permission_val[1]
  21. perm_args = permission_val[2]
  22. perm_kwargs = permission_val[3]
  23. perm_hook_func = permission_val[4] if len(permission_val)>4 else None
  24. # 判断命名空间和权限是否匹配
  25. if per_url_name == current_url_name: #matches current request url
  26. # 判断请求方法
  27. if per_method == request.method: #matches request method
  28. # if not perm_args: #if no args defined in perm dic, then set this request to passed perm
  29. #逐個匹配參數,看每個參數時候都能對應的上。
  30. args_matched = False #for args only
  31. for item in perm_args:
  32. request_method_func = getattr(request,per_method)
  33. if request_method_func.get(item,None):# request字典中有此參數
  34. args_matched = True
  35. else:
  36. print("arg not match......")
  37. args_matched = False
  38. break # 有一個參數不能匹配成功,則判定為假,退出該循環。
  39. else:
  40. args_matched = True
  41. #判断特殊权限,字典匹配有特定值的參數
  42. kwargs_matched = False
  43. for k,v in perm_kwargs.items():
  44. request_method_func = getattr(request, per_method)
  45. arg_val = request_method_func.get(k, None) # request字典中有此參數
  46. print("perm kwargs check:",arg_val,type(arg_val),v,type(v))
  47. if arg_val == str(v): #匹配上了特定的參數 及對應的 參數值, 比如,需要request 對象里必須有一個叫 user_id=3的參數
  48. kwargs_matched = True
  49. else:
  50. kwargs_matched = False
  51. break # 有一個參數不能匹配成功,則判定為假,退出該循環。
  52. else:
  53. kwargs_matched = True
  54. #开始匹配自定义的权限钩子函数
  55. perm_hook_matched = False
  56. if perm_hook_func:
  57. perm_hook_matched = perm_hook_func(request)
  58. match_results = [args_matched,kwargs_matched,perm_hook_matched]
  59. print("--->match_results ", match_results)
  60. if all(match_results): #都匹配上了
  61. match_key = permission_key
  62. break
  63. if all(match_results):
  64. app_name, *per_name = match_key.split('_')
  65. print("--->matched ",match_results,match_key)
  66. print(app_name, *per_name)
  67. perm_obj = '%s.%s' % (app_name,match_key)
  68. print("perm str:",perm_obj)
  69. if request.user.has_perm(perm_obj):
  70. print('當前用戶有此權限')
  71. return True
  72. else:
  73. print('當前用戶沒有該權限')
  74. return False
  75. else:
  76. print("未匹配到權限項,當前用戶無權限")
  77. def check_permission(func):
  78. def inner(*args,**kwargs):
  79. if not perm_check(*args,**kwargs):
  80. request = args[0]
  81. return http.HttpResponseForbidden("对不起你没有权限")
  82. return func(*args,**kwargs)
  83. return inner