From 7e95a00c587e061ddb7e289b3c6b1e0905085644 Mon Sep 17 00:00:00 2001 From: wklken Date: Wed, 8 May 2024 16:12:33 +0800 Subject: [PATCH] refactor(remove): unused codes --- .../common/contexts/gateway_feature_flag.py | 1 + .../common/contexts/stage_proxy_http.py | 2 +- .../apigateway/apigateway/core/admin.py | 12 --- .../apigateway/apigateway/tests/conftest.py | 77 --------------- .../apigateway/tests/utils/test_crypto.py | 37 -------- .../apigateway/tests/utils/test_header.py | 37 -------- .../tests/utils/test_serializers.py | 43 --------- .../apigateway/apigateway/utils/crypto.py | 94 +------------------ .../apigateway/apigateway/utils/header.py | 22 ----- .../apigateway/utils/serializers.py | 37 -------- 10 files changed, 4 insertions(+), 358 deletions(-) delete mode 100644 src/dashboard/apigateway/apigateway/tests/utils/test_header.py delete mode 100644 src/dashboard/apigateway/apigateway/tests/utils/test_serializers.py delete mode 100644 src/dashboard/apigateway/apigateway/utils/header.py delete mode 100644 src/dashboard/apigateway/apigateway/utils/serializers.py diff --git a/src/dashboard/apigateway/apigateway/common/contexts/gateway_feature_flag.py b/src/dashboard/apigateway/apigateway/common/contexts/gateway_feature_flag.py index 63135a4ca..3af91daa7 100644 --- a/src/dashboard/apigateway/apigateway/common/contexts/gateway_feature_flag.py +++ b/src/dashboard/apigateway/apigateway/common/contexts/gateway_feature_flag.py @@ -24,6 +24,7 @@ from .context import BaseContext +# FIXME: remove it if no `Context` required class GatewayFeatureFlagContext(BaseContext): scope_type = ContextScopeTypeEnum.GATEWAY.value type = ContextTypeEnum.GATEWAY_FEATURE_FLAG.value diff --git a/src/dashboard/apigateway/apigateway/common/contexts/stage_proxy_http.py b/src/dashboard/apigateway/apigateway/common/contexts/stage_proxy_http.py index 53e515595..70b4dc698 100644 --- a/src/dashboard/apigateway/apigateway/common/contexts/stage_proxy_http.py +++ b/src/dashboard/apigateway/apigateway/common/contexts/stage_proxy_http.py @@ -24,7 +24,7 @@ from .context import BaseContext -# TODO DELETE IT 1.14 +# FIXME: remove it if no legacy release data exists class StageProxyHTTPContext(BaseContext): """Context data related with HTTP proxy in "stage" scope.""" diff --git a/src/dashboard/apigateway/apigateway/core/admin.py b/src/dashboard/apigateway/apigateway/core/admin.py index f0b572bca..8ae6592cf 100644 --- a/src/dashboard/apigateway/apigateway/core/admin.py +++ b/src/dashboard/apigateway/apigateway/core/admin.py @@ -154,18 +154,6 @@ class BackendConfigAdmin(admin.ModelAdmin): list_filter = ["gateway", "backend", "stage"] -class SslCertificateAdmin(admin.ModelAdmin): - list_display = ["id", "gateway", "name", "type", "expires", "updated_time"] - search_fields = ["name"] - list_filter = ["gateway"] - - -class SslCertificateBindingAdmin(admin.ModelAdmin): - list_display = ["id", "gateway", "scope_type", "scope_id", "ssl_certificate_id"] - search_fields = ["scope_id", "ssl_certificate_id"] - list_filter = ["gateway"] - - admin.site.register(Gateway, GatewayAdmin) admin.site.register(Stage, StageAdmin) admin.site.register(Resource, ResourceAdmin) diff --git a/src/dashboard/apigateway/apigateway/tests/conftest.py b/src/dashboard/apigateway/apigateway/tests/conftest.py index 03c01c517..5a82e0730 100644 --- a/src/dashboard/apigateway/apigateway/tests/conftest.py +++ b/src/dashboard/apigateway/apigateway/tests/conftest.py @@ -726,83 +726,6 @@ def fake_rsa_public_key(): -----END PUBLIC KEY-----""" -@pytest.fixture -def fake_tls_cacert(): - return """-----BEGIN CERTIFICATE----- -MIIDDjCCAfYCCQDJqct/JR+xnTANBgkqhkiG9w0BAQsFADBJMQswCQYDVQQGEwJD -TjETMBEGA1UECAwKR3VhbmcgRG9uZzESMBAGA1UEBwwJU2hlbiBaaGVuMREwDwYD -VQQKDAhCbHVla2luZzAeFw0yMjEyMTkwMzUxMThaFw0yMzAxMTgwMzUxMThaMEkx -CzAJBgNVBAYTAkNOMRMwEQYDVQQIDApHdWFuZyBEb25nMRIwEAYDVQQHDAlTaGVu -IFpoZW4xETAPBgNVBAoMCEJsdWVraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAxw/MwDiFwDI5XCwWpUu29q5ULFeJ/agwaa93Tvk4W/kzeX0JcrPf -Eg77+MoZe0N9p0EElxB1wFXuz9Q6zfF9+FP5OEhQ6i/ZA/hLyTy05ohGBqoIV4+X -qew8cYDReWkak8XJkSkSEwZ14KeL9MBHigyuXb6kDcvwlzym13KULKHpICyKOam3 -srFuwYfs3xXgImfkcVwPkU8Qu+fRjpSMOHmxJ7ZeYha5yaoBOxB63KGIyjTn7se7 -qzQ7xwUWVJc+SKHyD5OqVOVTG0KfYO0Zxiqy3Ig+GeOQ+EvqvZuY0cJegdBFv1YY -9BN14kheymA0YPrqXy+l49uYwy7VzyeE4wIDAQABMA0GCSqGSIb3DQEBCwUAA4IB -AQCUv7Bh6giFw3zanEYWMvBasPRoave4vh6ONpqx9a7b7ERLPb3FW99+2CIicvYg -HF450hAoOfprCOy1icqpwxb4epZImlYXOfn5GBarI7TOrBb3J6hIOSmrai5ej8XW -F2Hs9wDj2OUV+duyrD4yjSYoMc0QBz9Ysf++9mNClcmiofc8uDPgIw5SDLbI/jyt -THsHTVzrpx3rXACc8sqYzX23jOEzxpCHMmuQ/n1GJ7reIR4ym2FpZSaE904gUIni -Ba4fi0pI9a4o7fADpyB/RVaEcUThKhujueInkEcK8vPLmwCSL4cepgt7v63PITcY -K3s6g+mRLT9+jRicv0yHGnl0 ------END CERTIFICATE-----""" - - -@pytest.fixture -def fake_tls_cert(): - return """-----BEGIN CERTIFICATE----- -MIIDKjCCAhICCQCnAH4ftfJ0jzANBgkqhkiG9w0BAQsFADBJMQswCQYDVQQGEwJD -TjETMBEGA1UECAwKR3VhbmcgRG9uZzESMBAGA1UEBwwJU2hlbiBaaGVuMREwDwYD -VQQKDAhCbHVla2luZzAeFw0yMjEyMTkwMzUzMDhaFw0yMzAxMTgwMzUzMDhaMGUx -CzAJBgNVBAYTAkNOMRMwEQYDVQQIDApHdWFuZyBEb25nMRIwEAYDVQQHDAlTaGVu -IFpoZW4xETAPBgNVBAoMCEJsdWVraW5nMRowGAYDVQQDDBFia2FwaS5leGFtcGxl -LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKGuvyzagosT6XHx -LjnPGo/jpVAS7fCFXAarXIteC7WGkAADiHXB6XWbKnDtDx2N4Ubrqm6LsTLh2K/u -QLJI7SeOQOmt2Lm+C2FRorVhQ+HM7qKBDAajlFWuWL12vaFbDro5TlDe7uGXiOZy -ydCw/J9slCRhF6OPfAMl3xxj22HG/7Um5jyNK+txyuUFkR/wnpqDKstRzVmKQC3q -7XFvDd4ohh1ExumZeCrqr/JSzYKeMVjGnwJtvlhC/Qrhcq+j65Npg6I7jJLbzqvX -Rx/ufeqIsxF9nO+7/FEXESec37RRIj64EKQFZYXmoO/a7vMs9GDP6V1e5HQ+NcKS -/PzbuQsCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAL0NZnfp7Bo7RBelWDh23A1aQ -BGO8aVzhkQ58pqNhL4xmJ02G0CahoBwzcr3dk+dbY+ueNi0IQZ2Y6rw+EgFrJyEw -FQyhu15a54kEbMLuSCeLPtgRCMfEeJZZ/nNnPatLE5jhwdfzynBvjWG5U0LhTWYr -1NAldRcZo0GZtrPkQdsiLrWo8hBzTGrQQoNdKaK6qwf+LKMHMvvueH/B2TMPxXa3 -RsNRePuY7fHa/b/sostvxUWhWK1GIx79lJBTzq08iJwYXk84IoPsMvwRfSNKVJce -UQpa4uSKycJVDzIx0qhgnyHKg5nGT1JV+chWE0rHbz8Hs0l0sy0Owv0IWibq2g== ------END CERTIFICATE-----""" - - -@pytest.fixture -def fake_tls_key(): - return """-----BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAoa6/LNqCixPpcfEuOc8aj+OlUBLt8IVcBqtci14LtYaQAAOI -dcHpdZsqcO0PHY3hRuuqbouxMuHYr+5AskjtJ45A6a3Yub4LYVGitWFD4czuooEM -BqOUVa5YvXa9oVsOujlOUN7u4ZeI5nLJ0LD8n2yUJGEXo498AyXfHGPbYcb/tSbm -PI0r63HK5QWRH/CemoMqy1HNWYpALertcW8N3iiGHUTG6Zl4Kuqv8lLNgp4xWMaf -Am2+WEL9CuFyr6Prk2mDojuMktvOq9dHH+596oizEX2c77v8URcRJ5zftFEiPrgQ -pAVlheag79ru8yz0YM/pXV7kdD41wpL8/Nu5CwIDAQABAoIBAQCX5zscJAvEKSgJ -8kOw8oCNMZ8OVUqR0Gm+pl8jXW940/0U1jzuDgqOgQLl6ANsi/FclWuhwsLwADp6 -SEkmd9fAcylPoxLcp82/WFibOs/xJH4L1Vx8HFHwEgazswzEvW1fzxliZ6Fd9+Ya -RTyRQseF7Rhd+Y6hD9y+hGVTIgpqmHMywI6ZBNsIVZ1pCoKu3X2A/jdgFYo4TV2m -CMosfxvynH6m9yb0zaLWcRpj1a4YYxAdiXpVPeEvXuhCtgQFfA1BTZTDQcWiASpC -A/kWZN0B9k2rSqpuzu2+NPNgBrso/bahpcQ4REGGpdxbaC9CY34XwNcfkZfGO4Hm -AKyljsM5AoGBAM343rKRwjunYCsaeDK44uATKWCeZU4iMeVq5D7A/vOekO34EeFx -j0QfYhBuy9B85McdhpA8k/yL97Yv8gExQrfmi4eAOFK8mUQSAYSR+N9rhBxfZ83N -MhX52sc9jKfkolguT2YLzmbAuFUhNGohlVMn/oPMohx0jIZcPTY2sq9fAoGBAMjz -//xhWY36VYc7unfWbKQ2fDwHHDWEnwoLEG1VasZTuuVeLjHCE74TOcHMU+dF+Nec -7Y/T9wq20b7dGr8df1iU1iSsyPPZBG3O7n1GGCnbkxkueQ3Dl7rjb/yk6I+43KMx -TGpkSrp0vaknb2f7oJmapNsuDm+3NDkNxj4oBZHVAoGATA2z9U264ZoI+YF5lokM -RN7ubV2vXG1l7SdOBhnvSfdn3ma1+3+Z/fZ0mErA+UfUle1CDapAnoT0P5JukqAk -2ZDIPo1Kvsoi8a6QXuojciPaETvtMWGuN80dSmpgsHHMvDDFYpHDcc+BgPWUzAeA -gscGxJXf2g/y/325oHYL/pMCgYBZfqlbufNLUtiyYHxcEIfT3lwX08bRYt39eA35 -01e5OeL7caU7DccDGMbZM2mOj1ASnlYCfxD/mYnx6cCWqsljJu3z6WuZheX+DXGT -Ixtx0NNDHLpW0ewKFG50YvEbyOWiXDs/CqlpPsKUyfZIpfzRS9jtsCZHxJyiaCsI -1YQdfQKBgCwlFizsm63tR4dBZRhg6uGwmEPubQtshdVtrSKW084kFFsw4fSNJejV -5H2rPBBrtS205FnnBClIRt+Wx+rKAZxaeJrE5Y+xE6sEoL7aCx/Pt+SjtNhq57i4 -X2wViL+hl304B82EpeKdGjly2YtdRmBCekANPxS24315bU6fGvBr ------END RSA PRIVATE KEY-----""" - - @pytest.fixture def mock_board(settings): settings.ESB_BOARD_CONFIGS = { diff --git a/src/dashboard/apigateway/apigateway/tests/utils/test_crypto.py b/src/dashboard/apigateway/apigateway/tests/utils/test_crypto.py index 074e1c39a..8e2ad58ad 100644 --- a/src/dashboard/apigateway/apigateway/tests/utils/test_crypto.py +++ b/src/dashboard/apigateway/apigateway/tests/utils/test_crypto.py @@ -20,7 +20,6 @@ from django.utils.encoding import smart_bytes, smart_str from apigateway.utils.crypto import ( - CertificateChecker, KeyGenerator, KeyValidator, RSAKeyValidationError, @@ -56,39 +55,3 @@ def test_validate_rsa_key_error(self, fake_rsa_private_key): with pytest.raises(RSAKeyValidationError): KeyValidator().validate_rsa_key(smart_bytes("invalid-private-key"), smart_bytes("invalid-public-key")) - - -class TestCertificateChecker: - def test_check(self, fake_tls_key, fake_tls_cert, fake_tls_cacert): - checker = CertificateChecker(key=fake_tls_key, cert=fake_tls_cert, ca_cert=fake_tls_cacert) - result = checker.check() - assert result["snis"] == ["bkapi.example.com"] - assert result["validity_end"] > result["validity_start"] > 0 - - def test_check_cert_key_matched(self, fake_tls_key, fake_tls_cert): - checker = CertificateChecker(key=fake_tls_key, cert=fake_tls_cert, ca_cert=None) - assert checker._check_cert_key_matched() is None - - def test_check_cert_key_matched_error(self, fake_rsa_private_key, fake_tls_cert): - checker = CertificateChecker(key=fake_rsa_private_key, cert=fake_tls_cert, ca_cert=None) - with pytest.raises(RSAKeyValidationError): - checker._check_cert_key_matched() - - checker = CertificateChecker(key="invalid-private-key", cert=fake_tls_cert, ca_cert=None) - with pytest.raises(ValueError): - checker._check_cert_key_matched() - - with pytest.raises(ValueError): - CertificateChecker(key=fake_rsa_private_key, cert="invalid-cert", ca_cert=None) - - def test_check_cert_is_issued_by_cacert(self, fake_tls_key, fake_tls_cert, fake_tls_cacert): - checker = CertificateChecker(key=fake_tls_key, cert=fake_tls_cert, ca_cert=None) - assert checker._check_cert_is_issued_by_cacert() is None - - checker = CertificateChecker(key=fake_tls_key, cert=fake_tls_cert, ca_cert=fake_tls_cacert) - assert checker._check_cert_is_issued_by_cacert() is None - - # cacert as cert - checker = CertificateChecker(key=fake_tls_key, cert=fake_tls_cacert, ca_cert=fake_tls_cert) - with pytest.raises(RSAKeyValidationError): - checker._check_cert_is_issued_by_cacert() diff --git a/src/dashboard/apigateway/apigateway/tests/utils/test_header.py b/src/dashboard/apigateway/apigateway/tests/utils/test_header.py deleted file mode 100644 index a7cb5bb96..000000000 --- a/src/dashboard/apigateway/apigateway/tests/utils/test_header.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- coding: utf-8 -*- -# -# TencentBlueKing is pleased to support the open source community by making -# 蓝鲸智云 - API 网关(BlueKing - APIGateway) available. -# Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. -# Licensed under the MIT License (the "License"); you may not use this file except -# in compliance with the License. You may obtain a copy of the License at -# -# http://opensource.org/licenses/MIT -# -# Unless required by applicable law or agreed to in writing, software distributed under -# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -# either express or implied. See the License for the specific language governing permissions and -# limitations under the License. -# -# We undertake not to change the open source license (MIT license) applicable -# to the current version of the project delivered to anyone in the future. -# -import pytest - -from apigateway.utils import header - - -@pytest.mark.parametrize( - "key, expected", - [ - ("X-Token", "X-Token"), - ("x-token", "X-Token"), - ("token", "Token"), - ("X-Token-123", "X-Token-123"), - ("x-tokeN", "X-Token"), - ("x-123a", "X-123a"), - ], -) -def test_canonical_header_key(key, expected): - result = header.canonical_header_key(key) - assert result == expected diff --git a/src/dashboard/apigateway/apigateway/tests/utils/test_serializers.py b/src/dashboard/apigateway/apigateway/tests/utils/test_serializers.py deleted file mode 100644 index 242e0348e..000000000 --- a/src/dashboard/apigateway/apigateway/tests/utils/test_serializers.py +++ /dev/null @@ -1,43 +0,0 @@ -# -*- coding: utf-8 -*- -# -# TencentBlueKing is pleased to support the open source community by making -# 蓝鲸智云 - API 网关(BlueKing - APIGateway) available. -# Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. -# Licensed under the MIT License (the "License"); you may not use this file except -# in compliance with the License. You may obtain a copy of the License at -# -# http://opensource.org/licenses/MIT -# -# Unless required by applicable law or agreed to in writing, software distributed under -# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -# either express or implied. See the License for the specific language governing permissions and -# limitations under the License. -# -# We undertake not to change the open source license (MIT license) applicable -# to the current version of the project delivered to anyone in the future. -# -from django.test import TestCase -from rest_framework import serializers - -from apigateway.utils.serializers import CustomFieldsSerializer - - -class UserSerializer(CustomFieldsSerializer): - name = serializers.CharField() - - -class TestCustomFieldsSerializer(TestCase): - def test__init(self): - data = [ - { - "add_fields": {"age": serializers.IntegerField()}, - "expected": ["name", "age"], - }, - { - "add_fields": {"height": serializers.IntegerField()}, - "expected": ["name", "height"], - }, - ] - for test in data: - slz = UserSerializer(add_fields=test["add_fields"]) - self.assertEqual([field_name for field_name, _ in slz.fields.items()], test["expected"]) diff --git a/src/dashboard/apigateway/apigateway/utils/crypto.py b/src/dashboard/apigateway/apigateway/utils/crypto.py index 702fe4cf4..da73e037d 100644 --- a/src/dashboard/apigateway/apigateway/utils/crypto.py +++ b/src/dashboard/apigateway/apigateway/utils/crypto.py @@ -18,19 +18,12 @@ # import base64 import hashlib -import itertools -from dataclasses import dataclass -from typing import List, Optional, Tuple, Union +from typing import Tuple, Union -from cryptography import x509 -from cryptography.exceptions import InvalidSignature from cryptography.hazmat.primitives import serialization -from cryptography.hazmat.primitives.asymmetric import padding, rsa -from cryptography.x509.oid import ExtensionOID, NameOID +from cryptography.hazmat.primitives.asymmetric import rsa from django.utils.encoding import force_bytes -from apigateway.utils.time import timestamp - class RSAKeyValidationError(Exception): """RSA 密钥校验失败""" @@ -82,89 +75,6 @@ def validate_rsa_key(self, private_key: bytes, public_key: bytes): raise RSAKeyValidationError("public key not match") -@dataclass -class CertificateChecker: - key: str - cert: str - ca_cert: Optional[str] = None - - def __post_init__(self): - self._x509_cert = self._load_pem_x509_certificate(self.cert, name="cert") - self._x509_ca_cert = self._load_pem_x509_certificate(self.ca_cert, name="ca_cert") - - def check(self): - self._check_cert_key_matched() - self._check_cert_is_issued_by_cacert() - return self._extract_cert_info() - - def _load_pem_x509_certificate(self, pem_cert: Optional[Union[str, bytes]], name: str) -> x509.Certificate: - if not pem_cert: - return None - - try: - return x509.load_pem_x509_certificate(force_bytes(pem_cert)) - except Exception: - raise ValueError(f"{name} invalid: unable to load certificate") - - def _check_cert_key_matched(self): - public_key_for_cert = self._x509_cert.public_key().public_bytes( - encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo - ) - try: - public_key_for_key = get_public_key_from_private_key(self.key) - except RSAKeyValidationError: - raise ValueError("key invalid: unable to load private key") - - if public_key_for_cert != public_key_for_key: - raise RSAKeyValidationError("key and cert are not matched") - - def _check_cert_is_issued_by_cacert(self): - if not self._x509_ca_cert: - return - - public_key_for_cacert = self._x509_ca_cert.public_key() - try: - # https://cryptography.io/en/latest/x509/reference/#cryptography.x509.Certificate.tbs_certificate_bytes - public_key_for_cacert.verify( - self._x509_cert.signature, - self._x509_cert.tbs_certificate_bytes, - padding.PKCS1v15(), - self._x509_cert.signature_hash_algorithm, - ) - except InvalidSignature: - raise RSAKeyValidationError("cert maybe not issued by cacert") - - def _extract_cert_info(self): - return { - "snis": self._extract_snis(), - "validity_start": timestamp(self._x509_cert.not_valid_before), - "validity_end": timestamp(self._x509_cert.not_valid_after), - } - - def _extract_snis(self): - # https://support.dnsimple.com/articles/what-is-common-name/ - snis = [] - - for name in itertools.chain( - self._extract_common_names(), - self._extract_alternative_names(), - ): - if name not in snis: - snis.append(name) # ruff: noqa: PERF401 - - return snis - - def _extract_common_names(self): - return [attr.value for attr in self._x509_cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME)] - - def _extract_alternative_names(self) -> List[str]: - try: - extensions = self._x509_cert.extensions.get_extension_for_oid(ExtensionOID.SUBJECT_ALTERNATIVE_NAME) - return extensions.value.get_values_for_type(x509.DNSName) - except x509.ExtensionNotFound: - return [] - - def calculate_fingerprint(content): """ For specification, see RFC4716, section 4 diff --git a/src/dashboard/apigateway/apigateway/utils/header.py b/src/dashboard/apigateway/apigateway/utils/header.py deleted file mode 100644 index d7c89c5ac..000000000 --- a/src/dashboard/apigateway/apigateway/utils/header.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -# -# TencentBlueKing is pleased to support the open source community by making -# 蓝鲸智云 - API 网关(BlueKing - APIGateway) available. -# Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. -# Licensed under the MIT License (the "License"); you may not use this file except -# in compliance with the License. You may obtain a copy of the License at -# -# http://opensource.org/licenses/MIT -# -# Unless required by applicable law or agreed to in writing, software distributed under -# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -# either express or implied. See the License for the specific language governing permissions and -# limitations under the License. -# -# We undertake not to change the open source license (MIT license) applicable -# to the current version of the project delivered to anyone in the future. -# - - -def canonical_header_key(header: str) -> str: - return "-".join(s.capitalize() for s in header.split("-")) diff --git a/src/dashboard/apigateway/apigateway/utils/serializers.py b/src/dashboard/apigateway/apigateway/utils/serializers.py deleted file mode 100644 index 3cbe9b0a7..000000000 --- a/src/dashboard/apigateway/apigateway/utils/serializers.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- coding: utf-8 -*- -# -# TencentBlueKing is pleased to support the open source community by making -# 蓝鲸智云 - API 网关(BlueKing - APIGateway) available. -# Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. -# Licensed under the MIT License (the "License"); you may not use this file except -# in compliance with the License. You may obtain a copy of the License at -# -# http://opensource.org/licenses/MIT -# -# Unless required by applicable law or agreed to in writing, software distributed under -# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -# either express or implied. See the License for the specific language governing permissions and -# limitations under the License. -# -# We undertake not to change the open source license (MIT license) applicable -# to the current version of the project delivered to anyone in the future. -# - -from rest_framework import serializers as drf_serializers - - -class CustomFieldsSerializer(drf_serializers.Serializer): - """ - 支持添加`自定义字段`的serializer - """ - - def __init__(self, *args, **kwargs): - # Don't pass the 'add_fields' arg up to the superclass - add_fields = kwargs.pop("add_fields", None) - - # Instantiate the superclass normally - super().__init__(*args, **kwargs) - - if add_fields is not None: - # Add 'add_fields' to fields - self.fields.update(add_fields)