diff --git a/apps/audits/handler.py b/apps/audits/handler.py index debe0a068..770ac9661 100644 --- a/apps/audits/handler.py +++ b/apps/audits/handler.py @@ -5,7 +5,7 @@ from django.core.cache import cache from django.db import transaction from django.utils.translation import gettext_lazy as _ -from common.local import encrypted_field_set +from common.local import similar_encrypted_pattern, exclude_encrypted_fields from common.utils import get_request_ip, get_logger from common.utils.encode import Singleton from common.utils.timezone import as_current_tz @@ -109,19 +109,29 @@ class OperatorLogHandler(metaclass=Singleton): return ','.join(value) return json.dumps(value) + @staticmethod + def __similar_check(key): + if not key or key in exclude_encrypted_fields: + return False + + return bool(similar_encrypted_pattern.search(key)) + def __data_processing(self, dict_item, loop=True): encrypt_value = '******' - for key, value in dict_item.items(): + new_data = {} + for label, item in dict_item.items(): + value = item.get('value', '') + field_name = item.get('name', '') if isinstance(value, bool): value = _('Yes') if value else _('No') elif isinstance(value, (list, tuple)): value = self.serialized_value(value) elif isinstance(value, dict) and loop: self.__data_processing(value, loop=False) - if key in encrypted_field_set: + if self.__similar_check(field_name): value = encrypt_value - dict_item[key] = value - return dict_item + new_data[label] = value + return new_data def data_processing(self, before, after): if before: diff --git a/apps/audits/utils.py b/apps/audits/utils.py index 1b1e4b8e6..3618978a2 100644 --- a/apps/audits/utils.py +++ b/apps/audits/utils.py @@ -82,7 +82,9 @@ def _get_instance_field_value( elif isinstance(f, GenericForeignKey): continue try: - data.setdefault(str(f.verbose_name), value) + data.setdefault( + str(f.verbose_name), {'name': getattr(f, 'column', ''), 'value': value} + ) except Exception as e: print(f.__dict__) raise e @@ -106,7 +108,9 @@ def model_to_dict_for_operate_log( return try: field_key = getattr(f, 'verbose_name', None) or f.related_model._meta.verbose_name - data.setdefault(str(field_key), value) + data.setdefault( + str(field_key), {'name': getattr(f, 'column', ''), 'value': value} + ) except: pass diff --git a/apps/common/db/fields.py b/apps/common/db/fields.py index f5b1e4b83..0bbe08f18 100644 --- a/apps/common/db/fields.py +++ b/apps/common/db/fields.py @@ -14,7 +14,6 @@ from django.db.models import Q, Manager, QuerySet from django.utils.translation import gettext_lazy as _ from rest_framework.utils.encoders import JSONEncoder -from common.local import add_encrypted_field_set from common.utils import contains_ip from .utils import Encryptor from .validators import PortRangeValidator @@ -168,7 +167,6 @@ class EncryptTextField(EncryptMixin, models.TextField): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - add_encrypted_field_set(self.verbose_name) class EncryptCharField(EncryptMixin, models.CharField): @@ -184,7 +182,6 @@ class EncryptCharField(EncryptMixin, models.CharField): def __init__(self, *args, **kwargs): self.change_max_length(kwargs) super().__init__(*args, **kwargs) - add_encrypted_field_set(self.verbose_name) def deconstruct(self): name, path, args, kwargs = super().deconstruct() @@ -198,13 +195,11 @@ class EncryptCharField(EncryptMixin, models.CharField): class EncryptJsonDictTextField(EncryptMixin, JsonDictTextField): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - add_encrypted_field_set(self.verbose_name) class EncryptJsonDictCharField(EncryptMixin, JsonDictCharField): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - add_encrypted_field_set(self.verbose_name) class PortField(models.IntegerField): diff --git a/apps/common/local.py b/apps/common/local.py index f5fd01f19..1dc16ad12 100644 --- a/apps/common/local.py +++ b/apps/common/local.py @@ -1,18 +1,14 @@ -from werkzeug.local import Local +import re -from django.utils import translation +from werkzeug.local import Local thread_local = Local() -encrypted_field_set = {'password', 'secret'} +exclude_encrypted_fields = ('secret_type', 'secret_strategy', 'password_rules') +similar_encrypted_pattern = re.compile( + 'password|secret|token|passphrase|private|key|cert', re.IGNORECASE +) def _find(attr): return getattr(thread_local, attr, None) - - -def add_encrypted_field_set(label): - return - if label: - with translation.override('en'): - encrypted_field_set.add(str(label)) diff --git a/apps/common/serializers/fields.py b/apps/common/serializers/fields.py index e53faeb9d..dfe9191df 100644 --- a/apps/common/serializers/fields.py +++ b/apps/common/serializers/fields.py @@ -8,7 +8,6 @@ from rest_framework import serializers from rest_framework.fields import ChoiceField, empty from common.db.fields import TreeChoices, JSONManyToManyField as ModelJSONManyToManyField -from common.local import add_encrypted_field_set from common.utils import decrypt_password __all__ = [ @@ -47,9 +46,7 @@ class EncryptedField(serializers.CharField): if write_only is None: write_only = True kwargs["write_only"] = write_only - encrypted_key = kwargs.pop('encrypted_key', None) super().__init__(**kwargs) - add_encrypted_field_set(encrypted_key or self.label) def to_internal_value(self, value): value = super().to_internal_value(value)