From 6eaf5397bce48f7678b3507b6d1dbcd367a572f4 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 29 Jun 2024 12:14:46 -0400 Subject: [PATCH] add dependencies --- catalog/common/jsondata.py | 43 ++++++++++++++++++++++++++++++++++---- catalog/tests.py | 7 +++++++ pyproject.toml | 1 + requirements-dev.lock | 1 + requirements.lock | 1 + 5 files changed, 49 insertions(+), 4 deletions(-) diff --git a/catalog/common/jsondata.py b/catalog/common/jsondata.py index 74afe267..659fecd6 100644 --- a/catalog/common/jsondata.py +++ b/catalog/common/jsondata.py @@ -1,13 +1,18 @@ # pyright: reportIncompatibleMethodOverride=false, reportFunctionMemberAccess=false import copy +from base64 import b64decode, b64encode from datetime import date, datetime from functools import partialmethod +from hashlib import sha256 from importlib import import_module import django +from cryptography.fernet import Fernet, MultiFernet +from django.conf import settings from django.core.exceptions import FieldError -from django.db.models import fields +from django.db.models import Value, fields from django.utils import dateparse, timezone +from django.utils.encoding import force_bytes from django.utils.translation import gettext_lazy as _ # from django.db.models import JSONField as DJANGO_JSONField @@ -16,6 +21,28 @@ from django.utils.translation import gettext_lazy as _ from django_jsonform.models.fields import ArrayField as DJANGO_ArrayField from django_jsonform.models.fields import JSONField as DJANGO_JSONField + +def _get_crypter(): + configured_keys = [settings.SECRET_KEY] + settings.SECRET_KEY_FALLBACKS + keys = [Fernet(b64encode(sha256(force_bytes(k)).digest())) for k in configured_keys] + if len(keys) == 0: + raise ValueError("No keys defined") + return MultiFernet(keys) + + +CRYPTER = _get_crypter() + + +def encrypt_str(s: str) -> str: + # be sure to encode the string to bytes + return CRYPTER.encrypt(s.encode("utf-8")).decode("utf-8") + + +def decrypt_str(t: str) -> str: + # be sure to decode the bytes to a string + return CRYPTER.decrypt(t.encode("utf-8")).decode("utf-8") + + __all__ = ( "BooleanField", "CharField", @@ -29,6 +56,7 @@ __all__ = ( "IPAddressField", "GenericIPAddressField", "NullBooleanField", + "EncryptedTextField", "TextField", "TimeField", "URLField", @@ -81,9 +109,6 @@ class JSONFieldDescriptor(object): setattr(instance, self.field.json_field_name, json_value) -fields.CharField - - class JSONFieldMixin(object): """ Override django.db.model.fields.Field.contribute_to_class @@ -226,6 +251,16 @@ class TextField(JSONFieldMixin, fields.TextField): pass +class EncryptedTextField(JSONFieldMixin, fields.TextField): + def to_json(self, value): + if value: + return encrypt_str(str(value)) + + def from_json(self, value): + if value: + return decrypt_str(value) + + class TimeField(JSONFieldMixin, fields.TimeField): def to_json(self, value): if value: diff --git a/catalog/tests.py b/catalog/tests.py index 6935f405..a623b25f 100644 --- a/catalog/tests.py +++ b/catalog/tests.py @@ -1,6 +1,7 @@ from django.test import TestCase from catalog.book.tests import * +from catalog.common.jsondata import decrypt_str, encrypt_str from catalog.game.tests import * from catalog.movie.tests import * from catalog.music.tests import * @@ -39,3 +40,9 @@ class CatalogCase(TestCase): self.hyperion_print.merge_to(self.hyperion_ebook) resloved = Item.get_by_url(self.hyperion_hardcover.url, True) self.assertEqual(resloved, self.hyperion_ebook) + + def test_encypted_field(self): + o = "Hello, World!" + e = encrypt_str(o) + d = decrypt_str(e) + self.assertEqual(o, d) diff --git a/pyproject.toml b/pyproject.toml index d73740c7..637f64b4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,6 +55,7 @@ dependencies = [ "urlman", "validators", "deepmerge>=1.1.1", + "django-typed-models>=0.14.0", ] [tool.rye] diff --git a/requirements-dev.lock b/requirements-dev.lock index a8d1ff4f..4dffda81 100644 --- a/requirements-dev.lock +++ b/requirements-dev.lock @@ -103,6 +103,7 @@ django-slack==5.19.0 django-stubs==5.0.2 django-stubs-ext==5.0.2 # via django-stubs +django-typed-models==0.14.0 django-tz-detect==0.5.0 django-user-messages==1.0.0 djlint==1.34.1 diff --git a/requirements.lock b/requirements.lock index e4178c6f..4d1e392b 100644 --- a/requirements.lock +++ b/requirements.lock @@ -82,6 +82,7 @@ django-rq==2.10.2 django-sass-processor==1.4.1 django-simple-history==3.7.0 django-slack==5.19.0 +django-typed-models==0.14.0 django-tz-detect==0.5.0 django-user-messages==1.0.0 dnspython==2.6.1