Commit 821b6fb8a0cc384f4a5bd757d6c79565cce7296f
1 parent
f96567709e
Exists in
master
remove pyqccr
Showing
1 changed file
with
3 additions
and
8 deletions
Show diff stats
decrators.py
1 | # coding: utf-8 | 1 | # coding: utf-8 |
2 | 2 | ||
3 | import django.http | 3 | import django.http |
4 | from functools import wraps | 4 | from functools import wraps |
5 | from django.conf import settings | 5 | from django.conf import settings |
6 | from django.utils.decorators import available_attrs | 6 | from django.utils.decorators import available_attrs |
7 | from pyqccr.http.response_code import REQUEST_FORBIDDEN | ||
8 | from pyqccr.http.status import HTTP_403_FORBIDDEN | ||
9 | from django.shortcuts import resolve_url | 7 | from django.shortcuts import resolve_url |
10 | from django.utils.six.moves.urllib.parse import urlparse | 8 | from django.utils.six.moves.urllib.parse import urlparse |
11 | 9 | ||
12 | def weapp_django_logout(request, response): | 10 | def weapp_django_logout(request, response): |
13 | assert isinstance(request, django.http.HttpRequest) | 11 | assert isinstance(request, django.http.HttpRequest) |
14 | assert isinstance(response, django.http.HttpResponse) | 12 | assert isinstance(response, django.http.HttpResponse) |
15 | # 请求统一认证登出 | 13 | # 请求统一认证登出 |
16 | response.delete_cookie('pt') | 14 | response.delete_cookie('pt') |
17 | response.delete_cookie('pu') | 15 | response.delete_cookie('pu') |
18 | response.delete_cookie('username') | 16 | response.delete_cookie('username') |
19 | return response | 17 | return response |
20 | 18 | ||
21 | def weapp_logout(func=weapp_django_logout): | 19 | def weapp_logout(func=weapp_django_logout): |
22 | """ | 20 | """ |
23 | Django登出视图函数装饰器 | 21 | Django登出视图函数装饰器 |
24 | :param func: 处理登出逻辑的函数,接受request和response两个参数 | 22 | :param func: 处理登出逻辑的函数,接受request和response两个参数 |
25 | :return: | 23 | :return: |
26 | """ | 24 | """ |
27 | return auth_decorator_factory(func) | 25 | return auth_decorator_factory(func) |
28 | 26 | ||
29 | 27 | ||
30 | def auth_decorator_factory(func=None): | 28 | def auth_decorator_factory(func=None): |
31 | """ | 29 | """ |
32 | 登录登出装饰器工厂函数,允许用户自定义外部登录登出函数 | 30 | 登录登出装饰器工厂函数,允许用户自定义外部登录登出函数 |
33 | :param func: | 31 | :param func: |
34 | :return: | 32 | :return: |
35 | """ | 33 | """ |
36 | 34 | ||
37 | def decorator(view_func): | 35 | def decorator(view_func): |
38 | @wraps(view_func) | 36 | @wraps(view_func) |
39 | def _wrapped_view(request, *args, **kwargs): | 37 | def _wrapped_view(request, *args, **kwargs): |
40 | response = view_func(request, *args, **kwargs) | 38 | response = view_func(request, *args, **kwargs) |
41 | if func: | 39 | if func: |
42 | func(request, response) | 40 | func(request, response) |
43 | return response | 41 | return response |
44 | 42 | ||
45 | return _wrapped_view | 43 | return _wrapped_view |
46 | 44 | ||
47 | return decorator | 45 | return decorator |
48 | 46 | ||
49 | import json | 47 | import json |
50 | 48 | ||
51 | from django.http import JsonResponse | 49 | from django.http import JsonResponse |
52 | 50 | ||
53 | from pyqccr.http.response_code import REQUEST_SUCCESS, REQUEST_FAILURE_UNIVERSAL | ||
54 | from pyqccr.http.status import HTTP_200_OK, HTTP_400_BAD_REQUEST | ||
55 | |||
56 | 51 | ||
57 | class QCCRJsonResponse(JsonResponse): | 52 | class QCCRJsonResponse(JsonResponse): |
58 | """ | 53 | """ |
59 | 封装了返回码和信息的JsonResponse类 | 54 | 封装了返回码和信息的JsonResponse类 |
60 | """ | 55 | """ |
61 | def __init__(self, obj=None, code=REQUEST_SUCCESS, msg="success", status=HTTP_200_OK, **kwargs): | 56 | def __init__(self, obj=None, code=200, msg="success", status=200, **kwargs): |
62 | data = {"code": code, "msg": msg, "result": json.loads(obj) if isinstance(obj, (str, unicode)) else obj} | 57 | data = {"code": code, "msg": msg, "result": json.loads(obj) if isinstance(obj, (str, unicode)) else obj} |
63 | super(QCCRJsonResponse, self).__init__(data=data, status=status, **kwargs) | 58 | super(QCCRJsonResponse, self).__init__(data=data, status=status, **kwargs) |
64 | 59 | ||
65 | 60 | ||
66 | class QCCRErrorResponse(QCCRJsonResponse): | 61 | class QCCRErrorResponse(QCCRJsonResponse): |
67 | """ | 62 | """ |
68 | 请求错误 | 63 | 请求错误 |
69 | """ | 64 | """ |
70 | def __init__(self, obj=None, code=REQUEST_FAILURE_UNIVERSAL, msg="failure", status=HTTP_400_BAD_REQUEST, **kwargs): | 65 | def __init__(self, obj=None, code=400, msg="failure", status=400, **kwargs): |
71 | super(QCCRErrorResponse, self).__init__(obj=obj, code=code, msg=msg, status=status, **kwargs) | 66 | super(QCCRErrorResponse, self).__init__(obj=obj, code=code, msg=msg, status=status, **kwargs) |
72 | 67 | ||
73 | def user_passes_test(test_func, login_url=None, | 68 | def user_passes_test(test_func, login_url=None, |
74 | redirect_field_name=getattr(settings, "QCCR_REDIRECT_FIELD_NAME", 'redirect')): | 69 | redirect_field_name=getattr(settings, "QCCR_REDIRECT_FIELD_NAME", 'redirect')): |
75 | """ | 70 | """ |
76 | 本装饰器通过test_func函数,检查views是否通过相应的检测,未通过则跳转到登录页面;test_func函数接受user对象作为参数,通过则返回True | 71 | 本装饰器通过test_func函数,检查views是否通过相应的检测,未通过则跳转到登录页面;test_func函数接受user对象作为参数,通过则返回True |
77 | """ | 72 | """ |
78 | 73 | ||
79 | def decorator(view_func): | 74 | def decorator(view_func): |
80 | @wraps(view_func, assigned=available_attrs(view_func)) | 75 | @wraps(view_func, assigned=available_attrs(view_func)) |
81 | def _wrapped_view(request, *args, **kwargs): | 76 | def _wrapped_view(request, *args, **kwargs): |
82 | if test_func(request.user): | 77 | if test_func(request.user): |
83 | return view_func(request, *args, **kwargs) | 78 | return view_func(request, *args, **kwargs) |
84 | # 如果未通过检查,且为ajax请求,返回403 | 79 | # 如果未通过检查,且为ajax请求,返回403 |
85 | if request.is_ajax(): | 80 | if request.is_ajax(): |
86 | return QCCRErrorResponse(code=REQUEST_FORBIDDEN, msg="用户身份检查失败", status=HTTP_403_FORBIDDEN) | 81 | return QCCRErrorResponse(code=403, msg="用户身份检查失败", status=403) |
87 | # 非ajax请求,跳转到登录页面 | 82 | # 非ajax请求,跳转到登录页面 |
88 | path = request.build_absolute_uri() | 83 | path = request.build_absolute_uri() |
89 | resolved_login_url = resolve_url(login_url or getattr(settings, "QCCR_LOGIN_URL", '/login/')) | 84 | resolved_login_url = resolve_url(login_url or getattr(settings, "QCCR_LOGIN_URL", '/login/')) |
90 | login_scheme, login_netloc = urlparse(resolved_login_url)[:2] | 85 | login_scheme, login_netloc = urlparse(resolved_login_url)[:2] |
91 | current_scheme, current_netloc = urlparse(path)[:2] | 86 | current_scheme, current_netloc = urlparse(path)[:2] |
92 | if ((not login_scheme or login_scheme == current_scheme) and | 87 | if ((not login_scheme or login_scheme == current_scheme) and |
93 | (not login_netloc or login_netloc == current_netloc)): | 88 | (not login_netloc or login_netloc == current_netloc)): |
94 | path = request.get_full_path() | 89 | path = request.get_full_path() |
95 | from django.contrib.auth.views import redirect_to_login | 90 | from django.contrib.auth.views import redirect_to_login |
96 | return redirect_to_login(path, resolved_login_url, redirect_field_name) | 91 | return redirect_to_login(path, resolved_login_url, redirect_field_name) |
97 | 92 | ||
98 | return _wrapped_view | 93 | return _wrapped_view |
99 | 94 | ||
100 | return decorator | 95 | return decorator |
101 | 96 | ||
102 | 97 | ||
103 | def weapp_login_required(function=None, | 98 | def weapp_login_required(function=None, |
104 | redirect_field_name=getattr(settings, "QCCR_REDIRECT_FIELD_NAME", 'redirect'), | 99 | redirect_field_name=getattr(settings, "QCCR_REDIRECT_FIELD_NAME", 'redirect'), |
105 | login_url=None): | 100 | login_url=None): |
106 | """ | 101 | """ |
107 | 登录状态检查装饰器,如果未登录,则直接跳转到登录页面 | 102 | 登录状态检查装饰器,如果未登录,则直接跳转到登录页面 |
108 | """ | 103 | """ |
109 | actual_decorator = user_passes_test( | 104 | actual_decorator = user_passes_test( |
110 | lambda u: u.is_authenticated(), | 105 | lambda u: u.is_authenticated(), |
111 | login_url=login_url, | 106 | login_url=login_url, |
112 | redirect_field_name=redirect_field_name | 107 | redirect_field_name=redirect_field_name |
113 | ) | 108 | ) |
114 | if function: | 109 | if function: |
115 | return actual_decorator(function) | 110 | return actual_decorator(function) |
116 | return actual_decorator | 111 | return actual_decorator |