From 2b6e81894328ccd17a5ce9e01953e03bbb3aa10f Mon Sep 17 00:00:00 2001 From: xinwen Date: Sun, 28 Jun 2020 19:02:20 +0800 Subject: [PATCH] =?UTF-8?q?[Update]=20=E9=99=90=E5=88=B6=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?CSV=E6=96=87=E4=BB=B6=E7=9A=84=E5=A4=A7=E5=B0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/common/drf/parsers/csv.py | 47 ++++++++++++++++++++------- apps/locale/zh/LC_MESSAGES/django.mo | Bin 54151 -> 54229 bytes apps/locale/zh/LC_MESSAGES/django.po | 27 ++++++++------- 3 files changed, 52 insertions(+), 22 deletions(-) diff --git a/apps/common/drf/parsers/csv.py b/apps/common/drf/parsers/csv.py index 95a9ec732..58b3f7bc2 100644 --- a/apps/common/drf/parsers/csv.py +++ b/apps/common/drf/parsers/csv.py @@ -6,18 +6,27 @@ import chardet import codecs import unicodecsv +from django.utils.translation import ugettext as _ from rest_framework.parsers import BaseParser -from rest_framework.exceptions import ParseError +from rest_framework.exceptions import ParseError, APIException +from rest_framework import status from common.utils import get_logger logger = get_logger(__file__) +class CsvDataTooBig(APIException): + status_code = status.HTTP_400_BAD_REQUEST + default_code = 'csv_data_too_big' + default_detail = _('The max size of CSV is %d bytes') + + class JMSCSVParser(BaseParser): """ Parses CSV file to serializer data """ + CSV_UPLOAD_MAX_SIZE = 1024 * 1024 * 10 media_type = 'text/csv' @@ -46,23 +55,31 @@ class JMSCSVParser(BaseParser): return fields_map @staticmethod - def _process_row(row): + def _replace_chinese_quot(str_): + trans_table = str.maketrans({ + '“': '"', + '”': '"', + '‘': '"', + '’': '"', + '\'': '"' + }) + return str_.translate(trans_table) + + @classmethod + def _process_row(cls, row): """ 构建json数据前的行处理 """ _row = [] + for col in row: # 列表转换 - if isinstance(col, str) and col.find("[") != -1 and col.find("]") != -1: - # 替换中文格式引号 - col = col.replace("“", '"').replace("”", '"').\ - replace("‘", '"').replace('’', '"').replace("'", '"') + if isinstance(col, str) and col.startswith('[') and col.endswith(']'): + col = cls._replace_chinese_quot(col) col = json.loads(col) # 字典转换 - if isinstance(col, str) and col.find("{") != -1 and col.find("}") != -1: - # 替换中文格式引号 - col = col.replace("“", '"').replace("”", '"'). \ - replace("‘", '"').replace('’', '"').replace("'", '"') + if isinstance(col, str) and col.startswith("{") and col.endswith("}"): + col = cls._replace_chinese_quot(col) col = json.loads(col) _row.append(col) return _row @@ -82,11 +99,19 @@ class JMSCSVParser(BaseParser): def parse(self, stream, media_type=None, parser_context=None): parser_context = parser_context or {} try: - serializer = parser_context["view"].get_serializer() + view = parser_context['view'] + meta = view.request.META + serializer = view.get_serializer() except Exception as e: logger.debug(e, exc_info=True) raise ParseError('The resource does not support imports!') + content_length = int(meta.get('CONTENT_LENGTH', meta.get('HTTP_CONTENT_LENGTH', 0))) + if content_length > self.CSV_UPLOAD_MAX_SIZE: + msg = CsvDataTooBig.default_detail % self.CSV_UPLOAD_MAX_SIZE + logger.error(msg) + raise CsvDataTooBig(msg) + try: stream_data = stream.read() stream_data = stream_data.strip(codecs.BOM_UTF8) diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 23c9e90439ea278a96a5a632560b0e49fddf96f9..5854d565a426a859fd8fe87c2371a501f84f01cc 100644 GIT binary patch delta 13379 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 g-{ReYwN}^6I-vV-_unRAyT2LpYvbL|Pu\n" "Language-Team: JumpServer team\n" @@ -608,7 +608,7 @@ msgid "Assets" msgstr "资产管理" #: assets/models/user.py:111 templates/_nav.html:17 -#: users/views/profile/password.py:42 users/views/profile/pubkey.py:36 +#: users/views/profile/password.py:40 users/views/profile/pubkey.py:36 msgid "Users" msgstr "用户管理" @@ -1133,8 +1133,8 @@ msgid "" "after {} minutes)" msgstr "账号已被锁定(请联系管理员解锁 或 {}分钟后重试)" -#: authentication/errors.py:48 users/views/profile/otp.py:107 -#: users/views/profile/otp.py:146 users/views/profile/otp.py:166 +#: authentication/errors.py:48 users/views/profile/otp.py:63 +#: users/views/profile/otp.py:102 users/views/profile/otp.py:121 msgid "MFA code invalid, or ntp sync server time" msgstr "MFA验证码不正确,或者服务器端时间不对" @@ -1364,6 +1364,11 @@ msgstr "%(name)s 创建成功" msgid "%(name)s was updated successfully" msgstr "%(name)s 更新成功" +#: common/drf/parsers/csv.py:22 +#, python-format +msgid "The max size of CSV is %d bytes" +msgstr "CSV 文件最大为 %d 字节" + #: common/fields/form.py:33 msgid "Not a valid json" msgstr "不是合法json" @@ -2647,7 +2652,7 @@ msgstr "复制用户公钥到这里" msgid "Join user groups" msgstr "添加到用户组" -#: users/forms/user.py:103 users/views/profile/password.py:59 +#: users/forms/user.py:103 users/views/profile/password.py:57 #: users/views/profile/reset.py:123 msgid "* Your password does not meet the requirements" msgstr "* 您的密码不符合要求" @@ -3483,27 +3488,27 @@ msgstr "" "
\n" " " -#: users/views/profile/otp.py:190 +#: users/views/profile/otp.py:145 msgid "MFA enable success" msgstr "多因子认证启用成功" -#: users/views/profile/otp.py:191 +#: users/views/profile/otp.py:146 msgid "MFA enable success, return login page" msgstr "多因子认证启用成功,返回到登录页面" -#: users/views/profile/otp.py:193 +#: users/views/profile/otp.py:148 msgid "MFA disable success" msgstr "多因子认证禁用成功" -#: users/views/profile/otp.py:194 +#: users/views/profile/otp.py:149 msgid "MFA disable success, return login page" msgstr "多因子认证禁用成功,返回登录页面" -#: users/views/profile/password.py:43 +#: users/views/profile/password.py:41 msgid "Password update" msgstr "密码更新" -#: users/views/profile/password.py:74 +#: users/views/profile/password.py:72 msgid "Password invalid" msgstr "用户名或密码无效"