|
5 | 5 | from rest_framework import status |
6 | 6 | from .exceptions import APIPermissionException |
7 | 7 | from .models import APIPermissionModel |
8 | | -from .api_settings import API_PREFIX |
| 8 | +from .api_settings import API_PREFIX, PERMISSION_DENIED_CODE, API_AUTHORIZATION_HEADER, ADMIN_SITE_PATH |
9 | 9 | import logging |
10 | 10 | import re |
11 | 11 |
|
12 | 12 |
|
13 | | -logger = logging.getLogger(__name__) |
14 | | - |
15 | | - |
16 | 13 | class APIPermCheckMiddleware(MiddlewareMixin): |
17 | 14 |
|
18 | 15 | def process_request(self, request): |
19 | 16 | path = request.path |
20 | 17 | method = request.method |
21 | | - header_token = request.META.get('HTTP_AUTHORIZATION', None) |
| 18 | + header_token = request.META.get(API_AUTHORIZATION_HEADER, None) |
22 | 19 | user = request.user or AnonymousUser() |
23 | 20 | if request.user and header_token is not None: |
24 | 21 | try: |
25 | | - token = header_token.split(' ') |
26 | | - assert len(token) == 2, "token maybe invalid" |
27 | | - token_obj = Token.objects.get(key=token[1]) |
| 22 | + token = header_token.strip().split(' ') |
| 23 | + assert len(token) > 0, f"token maybe invalid: {header_token}" |
| 24 | + token_obj = Token.objects.get(key=token[-1]) |
28 | 25 | user = token_obj.user |
29 | 26 | except Token.DoesNotExist as e: |
30 | 27 | msg = f"api_permission checker: bearer token not exists: {e}" |
31 | | - logger.warning(msg) |
32 | 28 | return self._return_403_res(msg) |
33 | 29 | except Exception as e: |
34 | | - msg = f"APIPermissionException : {e}" |
35 | | - logger.warning(msg) |
36 | | - return self._return_403_res(msg) |
| 30 | + msg = f"{e}" |
| 31 | + raise APIPermissionException(msg) |
37 | 32 |
|
38 | | - logger.debug(f"header_token is:{header_token} user: {user}, method: {method}, path: {path}") |
39 | | - if not path.startswith('/admin/') or not user.is_superuser: |
40 | | - if path.startswith(API_PREFIX): |
41 | | - if not self._has_permission(path, user, method): |
42 | | - res = JsonResponse({ |
43 | | - 'code': 1, |
44 | | - 'msg': f'permission denied: user: {user}, method: {method}, path: {path}', |
45 | | - }, status=status.HTTP_403_FORBIDDEN) |
46 | | - return res |
| 33 | + api_prefix_list = [] |
| 34 | + if type(API_PREFIX) == str: |
| 35 | + if API_PREFIX == '/': |
| 36 | + api_prefix_list = ['/'] |
| 37 | + else: |
| 38 | + if not API_PREFIX.startswith('/'): |
| 39 | + api_prefix_list.append('/' + str(API_PREFIX)) |
| 40 | + else: |
| 41 | + api_prefix_list = API_PREFIX |
| 42 | + elif type(API_PREFIX) == list: |
| 43 | + for prefix in API_PREFIX: |
| 44 | + if not prefix.startswith('/'): |
| 45 | + prefix = '/' + str(prefix) |
| 46 | + api_prefix_list.append(prefix) |
| 47 | + |
| 48 | + |
| 49 | + if not path.startswith(ADMIN_SITE_PATH) or not user.is_superuser: |
| 50 | + for api_prefix in api_prefix_list: |
| 51 | + if path.startswith(api_prefix): |
| 52 | + if not self._has_permission(path, user, method): |
| 53 | + return self._return_403_res(f'permission denied: user: {user}, method: {method}, path: {path}') |
47 | 54 |
|
48 | 55 | def _has_permission(self, path, user, method): |
49 | 56 | groups = user.groups.all() |
50 | 57 | queryset = APIPermissionModel.objects.filter(group__in=groups, method__in=[method, APIPermissionModel.ALL], active=True) |
51 | | - logger.debug(f'api permission queryset count: {queryset.count()}') |
52 | 58 | for api in queryset: |
53 | 59 | if re.match(api.pattern, path): |
54 | 60 | if api.method in [APIPermissionModel.ALL, method]: |
55 | 61 | return True |
56 | | - else: |
57 | | - logger.debug(f"permission denied: user: {user} api.method:{api.method}, method: {method}") |
58 | | - else: |
59 | | - logger.info(f"path not match: user: {user} api.pattern:{api.pattern}, path: {path}") |
60 | 62 | return False |
61 | 63 |
|
62 | 64 | def _return_403_res(self, msg): |
63 | 65 | res = { |
64 | | - 'code': 1, |
65 | | - 'msg': 'api_permission exception:{}'.format(msg), |
66 | | - 'data': None |
| 66 | + 'code': PERMISSION_DENIED_CODE, |
| 67 | + 'msg': msg, |
67 | 68 | } |
68 | 69 | return JsonResponse(res, status=status.HTTP_403_FORBIDDEN) |
0 commit comments