add OAuth
Showing
11 changed files
with
395 additions
and
8 deletions
... | @@ -11,6 +11,8 @@ tags: | ... | @@ -11,6 +11,8 @@ tags: |
11 | schemes: | 11 | schemes: |
12 | - https | 12 | - https |
13 | - http | 13 | - http |
14 | security: | ||
15 | - OAuth2: [] | ||
14 | paths: | 16 | paths: |
15 | /api/create/v1: | 17 | /api/create/v1: |
16 | post: | 18 | post: |
... | @@ -32,6 +34,43 @@ paths: | ... | @@ -32,6 +34,43 @@ paths: |
32 | description: ok | 34 | description: ok |
33 | schema: | 35 | schema: |
34 | $ref: '#/definitions/ApiResponse' | 36 | $ref: '#/definitions/ApiResponse' |
37 | /api/priority/v1: | ||
38 | post: | ||
39 | tags: | ||
40 | - doc | ||
41 | summary: GCAP提高申请单对应文件优先级 | ||
42 | consumes: | ||
43 | - application/json | ||
44 | produces: | ||
45 | - application/json | ||
46 | parameters: | ||
47 | - in: body | ||
48 | name: body | ||
49 | required: true | ||
50 | schema: | ||
51 | $ref: '#/definitions/Application' | ||
52 | responses: | ||
53 | 200: | ||
54 | description: ok | ||
55 | schema: | ||
56 | $ref: '#/definitions/ApiResponse' | ||
57 | securityDefinitions: | ||
58 | OAuth2: | ||
59 | type: oauth2 | ||
60 | flow: application | ||
61 | description: 'This API uses OAuth 2 with the application(clientCredentials) grant | ||
62 | flow. | ||
63 | |||
64 | client_id=sMlciTkppsMzARwHpCVarm5q7DP2Vucj3ny8JFhw | ||
65 | |||
66 | client_secret=WNoOilDx140ZLcenDKfsnikv7S2LIFs60DciYoqnrZaYLqYsKpcmt7mJIL69o9AEf84uQvRnS3K2UioxfjNyImjR4UOyXbDcF6qYgTLC4KDVByKFdVhKfrn2Lc4q4BNW | ||
67 | |||
68 | scopes=write | ||
69 | |||
70 | ' | ||
71 | tokenUrl: https://staging-bmw-ocr.situdata.com/api/oauth/token/ | ||
72 | scopes: | ||
73 | write: Grants write access | ||
35 | responses: | 74 | responses: |
36 | ErrorResponse: | 75 | ErrorResponse: |
37 | description: 调用异常, 具体情况请参考`HTTP`状态码和`code`字段 | 76 | description: 调用异常, 具体情况请参考`HTTP`状态码和`code`字段 |
... | @@ -130,6 +169,54 @@ definitions: | ... | @@ -130,6 +169,54 @@ definitions: |
130 | description: 元数据版本ID | 169 | description: 元数据版本ID |
131 | type: string | 170 | type: string |
132 | example: '8410480' | 171 | example: '8410480' |
172 | Application: | ||
173 | type: object | ||
174 | required: | ||
175 | - APPLICATION_INFORMATION | ||
176 | properties: | ||
177 | APPLICATION_INFORMATION: | ||
178 | description: 申请单信息 | ||
179 | type: object | ||
180 | required: | ||
181 | - SUBMIT_DATETIME | ||
182 | - STATUS | ||
183 | - ENTITY | ||
184 | - RATING | ||
185 | - APPLICATION_ID | ||
186 | - APPLICATION_VERSION | ||
187 | - INTERMEDIATE_DECISION | ||
188 | properties: | ||
189 | SUBMIT_DATETIME: | ||
190 | description: 提交时间 | ||
191 | type: string | ||
192 | example: 2020-07-08 18:33:31+08:00 | ||
193 | STATUS: | ||
194 | description: 状态 | ||
195 | type: integer | ||
196 | example: 42 | ||
197 | ENTITY: | ||
198 | description: 业务类型 | ||
199 | type: string | ||
200 | example: CO00001 | ||
201 | enum: | ||
202 | - CO00001 | ||
203 | - CO00002 | ||
204 | RATING: | ||
205 | description: 排名 | ||
206 | type: integer | ||
207 | example: 4 | ||
208 | APPLICATION_ID: | ||
209 | description: 申请id | ||
210 | type: string | ||
211 | example: CH-B0011010101 | ||
212 | APPLICATION_VERSION: | ||
213 | description: 申请版本 | ||
214 | type: integer | ||
215 | example: 1 | ||
216 | INTERMEDIATE_DECISION: | ||
217 | description: '' | ||
218 | type: string | ||
219 | example: MUW | ||
133 | ApiResponse: | 220 | ApiResponse: |
134 | description: 响应对象,code字段用于表示响应的状态; data字段用于存放响应内容 | 221 | description: 响应对象,code字段用于表示响应的状态; data字段用于存放响应内容 |
135 | type: object | 222 | type: object | ... | ... |
... | @@ -9,6 +9,7 @@ certifi==2020.6.20 | ... | @@ -9,6 +9,7 @@ certifi==2020.6.20 |
9 | chardet==3.0.4 | 9 | chardet==3.0.4 |
10 | defusedxml==0.6.0 | 10 | defusedxml==0.6.0 |
11 | Django==2.1 | 11 | Django==2.1 |
12 | django-oauth-toolkit==1.3.2 | ||
12 | djangorestframework==3.9.0 | 13 | djangorestframework==3.9.0 |
13 | djangorestframework-jwt==1.11.0 | 14 | djangorestframework-jwt==1.11.0 |
14 | idna==2.9 | 15 | idna==2.9 |
... | @@ -17,6 +18,7 @@ isodate==0.6.0 | ... | @@ -17,6 +18,7 @@ isodate==0.6.0 |
17 | lxml==4.5.1 | 18 | lxml==4.5.1 |
18 | marshmallow==3.6.1 | 19 | marshmallow==3.6.1 |
19 | multidict==4.7.6 | 20 | multidict==4.7.6 |
21 | oauthlib==3.1.0 | ||
20 | pdfminer3k==1.3.4 | 22 | pdfminer3k==1.3.4 |
21 | Pillow==7.1.2 | 23 | Pillow==7.1.2 |
22 | ply==3.11 | 24 | ply==3.11 | ... | ... |
src/apps/account/authentication.py
0 → 100644
1 | from django.contrib.auth import get_user_model | ||
2 | from oauth2_provider.contrib.rest_framework import OAuth2Authentication | ||
3 | from oauth2_provider.oauth2_backends import get_oauthlib_core | ||
4 | |||
5 | |||
6 | class OAuth2AuthenticationWithUser(OAuth2Authentication): | ||
7 | """ | ||
8 | OAuth 2 authentication backend using `django-oauth-toolkit` | ||
9 | """ | ||
10 | www_authenticate_realm = "api" | ||
11 | user = get_user_model().objects.first() | ||
12 | |||
13 | def authenticate(self, request): | ||
14 | """ | ||
15 | Returns two-tuple of (user, token) if authentication succeeds, | ||
16 | or None otherwise. | ||
17 | """ | ||
18 | oauthlib_core = get_oauthlib_core() | ||
19 | valid, r = oauthlib_core.verify_request(request, scopes=[]) | ||
20 | if valid: | ||
21 | return self.user, r.access_token | ||
22 | request.oauth2_error = getattr(r, "oauth2_error", {}) | ||
23 | return None |
1 | import os | ||
2 | import fitz | ||
3 | import signal | ||
4 | from PIL import Image | ||
5 | from io import BytesIO | ||
6 | |||
7 | from django.core.management import BaseCommand | ||
8 | from common.mixins import LoggerMixin | ||
9 | |||
10 | |||
11 | class Command(BaseCommand, LoggerMixin): | ||
12 | |||
13 | def __init__(self): | ||
14 | super().__init__() | ||
15 | self.log_base = '[pdf to img]' | ||
16 | # 处理文件开关 | ||
17 | self.switch = True | ||
18 | # pdf页面转图片 | ||
19 | self.zoom_x = 2.0 | ||
20 | self.zoom_y = 2.0 | ||
21 | self.trans = fitz.Matrix(self.zoom_x, self.zoom_y).preRotate(0) # zoom factor 2 in each dimension | ||
22 | # 优雅退出信号:15 | ||
23 | signal.signal(signal.SIGTERM, self.signal_handler) | ||
24 | |||
25 | def signal_handler(self, sig, frame): | ||
26 | self.switch = False # 停止处理文件 | ||
27 | |||
28 | @staticmethod | ||
29 | def getimage(pix): | ||
30 | if pix.colorspace.n != 4: | ||
31 | return pix | ||
32 | tpix = fitz.Pixmap(fitz.csRGB, pix) | ||
33 | return tpix | ||
34 | |||
35 | def recoverpix(self, doc, item): | ||
36 | x = item[0] # xref of PDF image | ||
37 | s = item[1] # xref of its /SMask | ||
38 | is_rgb = True if item[5] == 'DeviceRGB' else False | ||
39 | |||
40 | # RGB | ||
41 | if is_rgb: | ||
42 | if s == 0: | ||
43 | return doc.extractImage(x) | ||
44 | # we need to reconstruct the alpha channel with the smask | ||
45 | pix1 = fitz.Pixmap(doc, x) | ||
46 | pix2 = fitz.Pixmap(doc, s) # create pixmap of the /SMask entry | ||
47 | |||
48 | # sanity check | ||
49 | if not (pix1.irect == pix2.irect and pix1.alpha == pix2.alpha == 0 and pix2.n == 1): | ||
50 | pix2 = None | ||
51 | return self.getimage(pix1) | ||
52 | |||
53 | pix = fitz.Pixmap(pix1) # copy of pix1, alpha channel added | ||
54 | pix.setAlpha(pix2.samples) # treat pix2.samples as alpha value | ||
55 | pix1 = pix2 = None # free temp pixmaps | ||
56 | return self.getimage(pix) | ||
57 | |||
58 | # GRAY/CMYK | ||
59 | pix1 = fitz.Pixmap(doc, x) | ||
60 | pix = fitz.Pixmap(pix1) # copy of pix1, alpha channel added | ||
61 | |||
62 | if s != 0: | ||
63 | pix2 = fitz.Pixmap(doc, s) # create pixmap of the /SMask entry | ||
64 | |||
65 | # sanity check | ||
66 | if not (pix1.irect == pix2.irect and pix1.alpha == pix2.alpha == 0 and pix2.n == 1): | ||
67 | pix2 = None | ||
68 | return self.getimage(pix1) | ||
69 | |||
70 | pix.setAlpha(pix2.samples) # treat pix2.samples as alpha value | ||
71 | |||
72 | pix1 = pix2 = None # free temp pixmaps | ||
73 | |||
74 | pix = fitz.Pixmap(fitz.csRGB, pix) # GRAY/CMYK to RGB | ||
75 | return self.getimage(pix) | ||
76 | |||
77 | @staticmethod | ||
78 | def get_img_data(pix): | ||
79 | if type(pix) is dict: # we got a raw image | ||
80 | ext = pix["ext"] | ||
81 | img_data = pix["image"] | ||
82 | else: # we got a pixmap | ||
83 | ext = 'png' | ||
84 | img_data = pix.getPNGData() | ||
85 | return ext, img_data | ||
86 | |||
87 | @staticmethod | ||
88 | def split_il(il): | ||
89 | img_il_list = [] | ||
90 | start = 0 | ||
91 | length = len(il) | ||
92 | for i in range(length): | ||
93 | if i == start: | ||
94 | if i == length - 1: | ||
95 | img_il_list.append(il[start: length]) | ||
96 | continue | ||
97 | elif i == length - 1: | ||
98 | img_il_list.append(il[start: length]) | ||
99 | continue | ||
100 | if il[i][2] != il[i - 1][2]: | ||
101 | img_il_list.append(il[start: i]) | ||
102 | start = i | ||
103 | elif il[i][3] != il[i - 1][3]: | ||
104 | img_il_list.append(il[start: i + 1]) | ||
105 | start = i + 1 | ||
106 | return img_il_list | ||
107 | |||
108 | def handle(self, *args, **kwargs): | ||
109 | pdf_dir = '/Users/clay/Desktop/普通打印-部分无线/竖版-无表格-农业银行' | ||
110 | img_dir = '/Users/clay/Desktop/普通打印-部分无线_img/竖版-无表格-农业银行' | ||
111 | os.makedirs(img_dir, exist_ok=True) | ||
112 | for d in os.listdir(pdf_dir): | ||
113 | # if d in ['.DS_Store', 'CH-B008486764.pdf', 'CH-B008003736.pdf', 'CH-B008487476.pdf', 'CH-B006763780.pdf', | ||
114 | # 'CH-B009000564.pdf', 'CH-B009020488.pdf']: | ||
115 | if d in ['.DS_Store', '1竖版-无表格-农业银行样例.PNG']: | ||
116 | continue | ||
117 | pdf_path = os.path.join(pdf_dir, d) | ||
118 | # pdf_path = '/Users/clay/Desktop/普通打印part2/工商银行(标准版)/CH-B006754676.pdf' | ||
119 | if os.path.isfile(pdf_path): | ||
120 | img_save_path = os.path.join(img_dir, d) | ||
121 | if os.path.exists(img_save_path): | ||
122 | continue | ||
123 | os.makedirs(img_save_path, exist_ok=True) | ||
124 | with fitz.Document(pdf_path) as pdf: | ||
125 | self.cronjob_log.info('{0} [pdf_path={1}] [metadata={2}]'.format( | ||
126 | self.log_base, pdf_path, pdf.metadata)) | ||
127 | # xref_list = [] | ||
128 | for pno in range(pdf.pageCount): | ||
129 | il = pdf.getPageImageList(pno) | ||
130 | il.sort(key=lambda x: x[0]) | ||
131 | img_il_list = self.split_il(il) | ||
132 | del il | ||
133 | |||
134 | print(img_il_list) | ||
135 | if len(img_il_list) > 3: # 单页无规律小图过多时,使用页面转图片 | ||
136 | page = pdf.loadPage(pno) | ||
137 | pm = page.getPixmap(matrix=self.trans, alpha=False) | ||
138 | save_path = os.path.join(img_save_path, 'page_{0}_img_0.png'.format(page.number)) | ||
139 | pm.writePNG(save_path) | ||
140 | # img_path_list.append(save_path) | ||
141 | # self.cronjob_log.info('{0} [page to img success] [doc_id={1}] [pdf_path={2}] ' | ||
142 | # '[page={3}]'.format(self.log_base, doc_id, pdf_path, page.number)) | ||
143 | else: # 提取图片 | ||
144 | for img_index, img_il in enumerate(img_il_list): | ||
145 | if len(img_il) == 1: # 当只有一张图片时, 简化处理 | ||
146 | pix = self.recoverpix(pdf, img_il[0]) | ||
147 | ext, img_data = self.get_img_data(pix) | ||
148 | save_path = os.path.join(img_save_path, 'page_{0}_img_{1}.{2}'.format( | ||
149 | pno, img_index, ext)) | ||
150 | with open(save_path, "wb") as f: | ||
151 | f.write(img_data) | ||
152 | # img_path_list.append(save_path) | ||
153 | # self.cronjob_log.info( | ||
154 | # '{0} [extract img success] [doc_id={1}] [pdf_path={2}] [page={3}] ' | ||
155 | # '[img_index={4}]'.format(self.log_base, doc_id, pdf_path, pno, img_index)) | ||
156 | else: # 多张图片,竖向拼接 | ||
157 | height_sum = 0 | ||
158 | im_list = [] | ||
159 | width = img_il[0][2] | ||
160 | for img in img_il: | ||
161 | # xref = img[0] | ||
162 | # if xref in xref_list: | ||
163 | # continue | ||
164 | height = img[3] | ||
165 | pix = self.recoverpix(pdf, img) | ||
166 | ext, img_data = self.get_img_data(pix) | ||
167 | |||
168 | # xref_list.append(xref) | ||
169 | |||
170 | im = Image.open(BytesIO(img_data)) | ||
171 | im_list.append((height, im, ext)) | ||
172 | height_sum += height | ||
173 | |||
174 | save_path = os.path.join(img_save_path, 'page_{0}_img_{1}.{2}'.format( | ||
175 | pno, img_index, im_list[0][2])) | ||
176 | res = Image.new(im_list[0][1].mode, (width, height_sum)) | ||
177 | h_now = 0 | ||
178 | for h, m, _ in im_list: | ||
179 | res.paste(m, box=(0, h_now)) | ||
180 | h_now += h | ||
181 | res.save(save_path) | ||
182 | # else: | ||
183 | # img_dir_path = os.path.join(img_dir, d) | ||
184 | # os.makedirs(img_dir_path, exist_ok=True) |
... | @@ -5,6 +5,7 @@ import datetime | ... | @@ -5,6 +5,7 @@ import datetime |
5 | from django.utils import timezone | 5 | from django.utils import timezone |
6 | from django.db.utils import IntegrityError | 6 | from django.db.utils import IntegrityError |
7 | from django.db.models import Q | 7 | from django.db.models import Q |
8 | from rest_framework.permissions import IsAuthenticated | ||
8 | from webargs import fields, validate | 9 | from webargs import fields, validate |
9 | from webargs.djangoparser import use_args, parser | 10 | from webargs.djangoparser import use_args, parser |
10 | from settings import conf | 11 | from settings import conf |
... | @@ -15,6 +16,7 @@ from common.redis_cache import redis_handler as rh | ... | @@ -15,6 +16,7 @@ from common.redis_cache import redis_handler as rh |
15 | from .models import UploadDocRecords, DocStatus, PriorityApplication, GCAPRecords | 16 | from .models import UploadDocRecords, DocStatus, PriorityApplication, GCAPRecords |
16 | from .mixins import DocHandler | 17 | from .mixins import DocHandler |
17 | from . import consts | 18 | from . import consts |
19 | from apps.account.authentication import OAuth2AuthenticationWithUser | ||
18 | 20 | ||
19 | 21 | ||
20 | # restframework将request.body封装至request.data, webargs从request.data中获取参数 | 22 | # restframework将request.body封装至request.data, webargs从request.data中获取参数 |
... | @@ -86,7 +88,9 @@ priority_doc_args = { | ... | @@ -86,7 +88,9 @@ priority_doc_args = { |
86 | 88 | ||
87 | 89 | ||
88 | class UploadDocView(GenericView, DocHandler): | 90 | class UploadDocView(GenericView, DocHandler): |
89 | permission_classes = [] | 91 | permission_classes = [IsAuthenticated] |
92 | authentication_classes = [OAuth2AuthenticationWithUser] | ||
93 | # required_scopes = ['write'] | ||
90 | 94 | ||
91 | # 上传(接收)文件接口 | 95 | # 上传(接收)文件接口 |
92 | @use_args(doc_upload_args, location='data') | 96 | @use_args(doc_upload_args, location='data') |
... | @@ -134,8 +138,8 @@ class UploadDocView(GenericView, DocHandler): | ... | @@ -134,8 +138,8 @@ class UploadDocView(GenericView, DocHandler): |
134 | is_priority = PriorityApplication.objects.filter(application_id=application_id, on_off=True).exists() | 138 | is_priority = PriorityApplication.objects.filter(application_id=application_id, on_off=True).exists() |
135 | value = ['{0}_{1}'.format(prefix, doc.id)] | 139 | value = ['{0}_{1}'.format(prefix, doc.id)] |
136 | redis_res = rh.enqueue(value, is_priority) | 140 | redis_res = rh.enqueue(value, is_priority) |
137 | self.running_log.info('[doc upload success] [args={0}] [record_id={1}] [is_hil={2}] [doc_id={3}] ' | 141 | self.running_log.info('[doc upload success] [args={0}] [record_id={1}] [prefix={2}] [doc_id={3}] ' |
138 | '[is_priority={4}] [enqueue_res={5}]'.format(args, record.id, is_hil, doc.id, | 142 | '[is_priority={4}] [enqueue_res={5}]'.format(args, record.id, prefix, doc.id, |
139 | is_priority, redis_res)) | 143 | is_priority, redis_res)) |
140 | return response.ok() | 144 | return response.ok() |
141 | 145 | ||
... | @@ -160,7 +164,8 @@ class UploadDocView(GenericView, DocHandler): | ... | @@ -160,7 +164,8 @@ class UploadDocView(GenericView, DocHandler): |
160 | 164 | ||
161 | 165 | ||
162 | class PriorityDocView(GenericView, DocHandler): | 166 | class PriorityDocView(GenericView, DocHandler): |
163 | permission_classes = [] | 167 | permission_classes = [IsAuthenticated] |
168 | authentication_classes = [OAuth2AuthenticationWithUser] | ||
164 | 169 | ||
165 | # 优先级订单接口 | 170 | # 优先级订单接口 |
166 | @use_args(priority_doc_args, location='data') | 171 | @use_args(priority_doc_args, location='data') |
... | @@ -195,6 +200,25 @@ class PriorityDocView(GenericView, DocHandler): | ... | @@ -195,6 +200,25 @@ class PriorityDocView(GenericView, DocHandler): |
195 | args, task_str_list, enqueue_res)) | 200 | args, task_str_list, enqueue_res)) |
196 | return response.ok() | 201 | return response.ok() |
197 | 202 | ||
203 | post.openapi_doc = ''' | ||
204 | tags: [doc] | ||
205 | summary: GCAP提高申请单对应文件优先级 | ||
206 | consumes: [application/json] | ||
207 | produces: [application/json] | ||
208 | parameters: | ||
209 | - in: body | ||
210 | name: body | ||
211 | required: true | ||
212 | schema: | ||
213 | $ref: "#/definitions/Application" | ||
214 | |||
215 | responses: | ||
216 | 200: | ||
217 | description: ok | ||
218 | schema: | ||
219 | $ref: '#/definitions/ApiResponse' | ||
220 | ''' | ||
221 | |||
198 | 222 | ||
199 | class DocView(GenericView, DocHandler): | 223 | class DocView(GenericView, DocHandler): |
200 | 224 | ... | ... |
... | @@ -22,4 +22,5 @@ urlpatterns = [ | ... | @@ -22,4 +22,5 @@ urlpatterns = [ |
22 | path(r'api/create/', include('apps.doc.create_urls')), | 22 | path(r'api/create/', include('apps.doc.create_urls')), |
23 | path(r'api/priority/', include('apps.doc.priority_urls')), | 23 | path(r'api/priority/', include('apps.doc.priority_urls')), |
24 | path(r'api/doc/', include('apps.doc.internal_urls')), | 24 | path(r'api/doc/', include('apps.doc.internal_urls')), |
25 | path('api/oauth/', include('oauth2_provider.urls', namespace='oauth2_provider')), | ||
25 | ] | 26 | ] | ... | ... |
... | @@ -12,10 +12,26 @@ tags: | ... | @@ -12,10 +12,26 @@ tags: |
12 | schemes: | 12 | schemes: |
13 | - "https" | 13 | - "https" |
14 | - "http" | 14 | - "http" |
15 | security: | ||
16 | - OAuth2: [] | ||
15 | ''' | 17 | ''' |
16 | 18 | ||
17 | # scheme: bearer | 19 | # scheme: oauth |
18 | security_definitions = ''' | 20 | security_definitions = ''' |
21 | OAuth2: | ||
22 | type: oauth2 | ||
23 | flow: application | ||
24 | description: > | ||
25 | This API uses OAuth 2 with the application(clientCredentials) grant flow. | ||
26 | |||
27 | client_id=sMlciTkppsMzARwHpCVarm5q7DP2Vucj3ny8JFhw | ||
28 | |||
29 | client_secret=WNoOilDx140ZLcenDKfsnikv7S2LIFs60DciYoqnrZaYLqYsKpcmt7mJIL69o9AEf84uQvRnS3K2UioxfjNyImjR4UOyXbDcF6qYgTLC4KDVByKFdVhKfrn2Lc4q4BNW | ||
30 | |||
31 | scopes=write | ||
32 | tokenUrl: https://staging-bmw-ocr.situdata.com/api/oauth/token/ | ||
33 | scopes: | ||
34 | write: Grants write access | ||
19 | ''' | 35 | ''' |
20 | 36 | ||
21 | responses = ''' | 37 | responses = ''' |
... | @@ -99,6 +115,46 @@ Doc: | ... | @@ -99,6 +115,46 @@ Doc: |
99 | type: string | 115 | type: string |
100 | example: '8410480' | 116 | example: '8410480' |
101 | 117 | ||
118 | Application: | ||
119 | type: object | ||
120 | required: [APPLICATION_INFORMATION] | ||
121 | properties: | ||
122 | APPLICATION_INFORMATION: | ||
123 | description: 申请单信息 | ||
124 | type: object | ||
125 | required: [SUBMIT_DATETIME, STATUS, ENTITY, RATING, APPLICATION_ID, APPLICATION_VERSION, INTERMEDIATE_DECISION] | ||
126 | properties: | ||
127 | SUBMIT_DATETIME: | ||
128 | description: 提交时间 | ||
129 | type: string | ||
130 | example: 2020-07-08T18:33:31.000+08:00 | ||
131 | STATUS: | ||
132 | description: 状态 | ||
133 | type: integer | ||
134 | example: 42 | ||
135 | ENTITY: | ||
136 | description: 业务类型 | ||
137 | type: string | ||
138 | example: CO00001 | ||
139 | enum: [CO00001, CO00002] | ||
140 | RATING: | ||
141 | description: 排名 | ||
142 | type: integer | ||
143 | example: 4 | ||
144 | APPLICATION_ID: | ||
145 | description: 申请id | ||
146 | type: string | ||
147 | example: CH-B0011010101 | ||
148 | APPLICATION_VERSION: | ||
149 | description: 申请版本 | ||
150 | type: integer | ||
151 | example: 1 | ||
152 | INTERMEDIATE_DECISION: | ||
153 | description: '' | ||
154 | type: string | ||
155 | example: MUW | ||
156 | |||
157 | |||
102 | ApiResponse: | 158 | ApiResponse: |
103 | description: 响应对象,code字段用于表示响应的状态; data字段用于存放响应内容 | 159 | description: 响应对象,code字段用于表示响应的状态; data字段用于存放响应内容 |
104 | type: object | 160 | type: object | ... | ... |
... | @@ -4,6 +4,7 @@ from django.core.exceptions import PermissionDenied | ... | @@ -4,6 +4,7 @@ from django.core.exceptions import PermissionDenied |
4 | from django.utils.translation import ugettext_lazy as _ | 4 | from django.utils.translation import ugettext_lazy as _ |
5 | from django.http import Http404 | 5 | from django.http import Http404 |
6 | from rest_framework import exceptions, status | 6 | from rest_framework import exceptions, status |
7 | from rest_framework.exceptions import NotAuthenticated, PermissionDenied | ||
7 | from rest_framework.response import Response | 8 | from rest_framework.response import Response |
8 | from marshmallow.exceptions import ValidationError | 9 | from marshmallow.exceptions import ValidationError |
9 | 10 | ||
... | @@ -29,7 +30,9 @@ def exception_handler(exc, context): | ... | @@ -29,7 +30,9 @@ def exception_handler(exc, context): |
29 | if getattr(exc, 'wait', None): | 30 | if getattr(exc, 'wait', None): |
30 | headers['Retry-After'] = '%d' % exc.wait | 31 | headers['Retry-After'] = '%d' % exc.wait |
31 | 32 | ||
32 | if exc.status_code == 403: | 33 | if isinstance(exc, NotAuthenticated) or isinstance(exc, PermissionDenied): |
34 | data = res_content(MetaStatus.NO_PERMISSION.value, MetaStatus.NO_PERMISSION.verbose_name) | ||
35 | elif exc.status_code == 403: | ||
33 | data = res_content(MetaStatus.NEED_LOGIN.value, MetaStatus.NEED_LOGIN.verbose_name) | 36 | data = res_content(MetaStatus.NEED_LOGIN.value, MetaStatus.NEED_LOGIN.verbose_name) |
34 | else: | 37 | else: |
35 | data = res_content(MetaStatus.INTERNAL_ERROR.value, exc.detail) | 38 | data = res_content(MetaStatus.INTERNAL_ERROR.value, exc.detail) | ... | ... |
... | @@ -48,7 +48,7 @@ class Command(BaseCommand): | ... | @@ -48,7 +48,7 @@ class Command(BaseCommand): |
48 | view_class = view.view_class | 48 | view_class = view.view_class |
49 | url_path, path_parameters = pattern[0][0] | 49 | url_path, path_parameters = pattern[0][0] |
50 | url_path = unify_url_path_format(url_path) | 50 | url_path = unify_url_path_format(url_path) |
51 | if url_path != '/api/create/v1': | 51 | if url_path not in ['/api/create/v1', '/api/priority/v1']: |
52 | continue | 52 | continue |
53 | url_path_paramters = getattr(view, 'parameters_doc', None) | 53 | url_path_paramters = getattr(view, 'parameters_doc', None) |
54 | if url_path_paramters: | 54 | if url_path_paramters: |
... | @@ -82,7 +82,7 @@ class Command(BaseCommand): | ... | @@ -82,7 +82,7 @@ class Command(BaseCommand): |
82 | api_doc_dct[url_path][method] = doc | 82 | api_doc_dct[url_path][method] = doc |
83 | doc_dct = yaml.load(base_part) | 83 | doc_dct = yaml.load(base_part) |
84 | doc_dct['paths'] = api_doc_dct | 84 | doc_dct['paths'] = api_doc_dct |
85 | # doc_dct['securityDefinitions'] = yaml.load(security_definitions) | 85 | doc_dct['securityDefinitions'] = yaml.load(security_definitions) |
86 | doc_dct['responses'] = yaml.load(responses) | 86 | doc_dct['responses'] = yaml.load(responses) |
87 | doc_dct['definitions'] = yaml.load(definitions) | 87 | doc_dct['definitions'] = yaml.load(definitions) |
88 | 88 | ... | ... |
... | @@ -42,6 +42,7 @@ INSTALLED_APPS = [ | ... | @@ -42,6 +42,7 @@ INSTALLED_APPS = [ |
42 | 'django.contrib.messages', | 42 | 'django.contrib.messages', |
43 | 'django.contrib.staticfiles', | 43 | 'django.contrib.staticfiles', |
44 | # 'corsheaders', | 44 | # 'corsheaders', |
45 | 'oauth2_provider', | ||
45 | 'rest_framework', | 46 | 'rest_framework', |
46 | 'common', | 47 | 'common', |
47 | 'apps.account', | 48 | 'apps.account', |
... | @@ -145,6 +146,7 @@ REST_FRAMEWORK = { | ... | @@ -145,6 +146,7 @@ REST_FRAMEWORK = { |
145 | 'DEFAULT_AUTHENTICATION_CLASSES': ( | 146 | 'DEFAULT_AUTHENTICATION_CLASSES': ( |
146 | 'rest_framework.authentication.BasicAuthentication', | 147 | 'rest_framework.authentication.BasicAuthentication', |
147 | 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', | 148 | 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', |
149 | # 'oauth2_provider.contrib.rest_framework.OAuth2Authentication', | ||
148 | ), | 150 | ), |
149 | 'EXCEPTION_HANDLER': 'common.exceptions.exception_handler' | 151 | 'EXCEPTION_HANDLER': 'common.exceptions.exception_handler' |
150 | } | 152 | } |
... | @@ -173,3 +175,8 @@ JWT_AUTH = { | ... | @@ -173,3 +175,8 @@ JWT_AUTH = { |
173 | # 跨域设置 | 175 | # 跨域设置 |
174 | # CORS_ORIGIN_ALLOW_ALL = True | 176 | # CORS_ORIGIN_ALLOW_ALL = True |
175 | # CORS_ALLOW_CREDENTIALS = True | 177 | # CORS_ALLOW_CREDENTIALS = True |
178 | |||
179 | OAUTH2_PROVIDER = { | ||
180 | # this is the list of available scopes | ||
181 | 'SCOPES': {'read': 'Read scope', 'write': 'Write scope'} | ||
182 | } | ... | ... |
wsdl/DocumentFinder.wsdl
0 → 100644
This diff could not be displayed because it is too large.
-
Please register or sign in to post a comment