|
| 1 | +import json |
1 | 2 | from django.core import exceptions |
2 | 3 | from django.db import models |
3 | 4 | from .crypto import Crypto |
4 | 5 | from .exceptions import EncryptedFieldException |
| 6 | +from django.db.models.fields.json import KeyTransform |
5 | 7 |
|
6 | 8 |
|
7 | 9 | class EncryptedMixin(models.Field): |
@@ -36,6 +38,24 @@ def get_internal_type(self): |
36 | 38 | class EncryptedTextField(EncryptedMixin, models.TextField): |
37 | 39 | internal_type = "TextField" |
38 | 40 |
|
| 41 | +class EncryptedJSONField(EncryptedMixin, models.JSONField): |
| 42 | + internal_type = "TextField" |
| 43 | + |
| 44 | + def from_db_value(self, value, expression, connection): |
| 45 | + if value is None: |
| 46 | + return value |
| 47 | + if isinstance(expression, KeyTransform) and not isinstance(value, str): |
| 48 | + return value |
| 49 | + try: |
| 50 | + return json.loads(self.crypto.decrypt(value), cls=self.decoder) |
| 51 | + except json.JSONDecodeError as e: |
| 52 | + return self.crypto.decrypt(value) |
| 53 | + |
| 54 | + def get_prep_value(self, value): |
| 55 | + if value is None: |
| 56 | + return value |
| 57 | + return json.dumps(self.crypto.encrypt(json.dumps(value, cls=self.encoder)), cls=self.encoder) |
| 58 | + |
39 | 59 |
|
40 | 60 | class EncryptedCharField(EncryptedMixin, models.CharField): |
41 | 61 | prepared_max_length = 255 |
|
0 commit comments