diff --git a/schon/fields.py b/schon/fields.py index 8e5dc8d5..33dfa3cd 100644 --- a/schon/fields.py +++ b/schon/fields.py @@ -1,5 +1,5 @@ -import json - +import orjson +from cryptography.fernet import InvalidToken from encrypted_fields.fields import EncryptedTextField @@ -18,16 +18,20 @@ class EncryptedJSONTextField(EncryptedTextField): def get_prep_value(self, value): if value is not None and not isinstance(value, str): - value = json.dumps(value, default=str) + value = orjson.dumps(value, default=str).decode("utf-8") return super().get_prep_value(value) def from_db_value(self, value, expression, connection): - value = super().from_db_value(value, expression, connection) if value is None: return None if isinstance(value, str): try: - return json.loads(value) + value = self.f.decrypt(value.encode("utf-8")).decode("utf-8") + except (InvalidToken, UnicodeEncodeError): + pass + if isinstance(value, str): + try: + return orjson.loads(value) except (ValueError, TypeError): pass return value @@ -35,9 +39,16 @@ class EncryptedJSONTextField(EncryptedTextField): def to_python(self, value): if isinstance(value, (dict, list)): return value + if value is None: + return value if isinstance(value, str): + if not hasattr(self, "_already_decrypted"): + try: + value = self.f.decrypt(value.encode("utf-8")).decode("utf-8") + except (InvalidToken, UnicodeEncodeError): + pass try: - return json.loads(value) + return orjson.loads(value) except (ValueError, TypeError): pass return value