Created
April 2, 2020 15:01
-
-
Save frennkie/1f0efc9b20186609ee252ba9c91f7b31 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
import string | |
from django import forms | |
from django.conf import settings | |
from django.core.exceptions import ImproperlyConfigured | |
from django.db import models | |
class BaseEncryptedField(models.Field): | |
_internal_type = None | |
prefix = 'enc_str:::' | |
L2I = dict(zip(string.ascii_uppercase, range(26))) | |
l2i = dict(zip(string.ascii_lowercase, range(26))) | |
I2L = dict(zip(range(26), string.ascii_uppercase)) | |
i2l = dict(zip(range(26), string.ascii_lowercase)) | |
def __init__(self, *args, **kwargs): | |
if kwargs.get('primary_key'): | |
raise ImproperlyConfigured( | |
"%s does not support primary_key=True." | |
% self.__class__.__name__ | |
) | |
if kwargs.get('unique'): | |
raise ImproperlyConfigured( | |
"%s does not support unique=True." | |
% self.__class__.__name__ | |
) | |
if kwargs.get('db_index'): | |
raise ImproperlyConfigured( | |
"%s does not support db_index=True." | |
% self.__class__.__name__ | |
) | |
# if not getattr(settings, 'DJANGO_SMAIL_CAESAR_VALUE', None): | |
# raise ImproperlyConfigured('You must set the settings.DJANGO_SMAIL_CAESAR_VALUE ' | |
# 'setting to an integer value.') | |
self.caesar_value = getattr(settings, 'DJANGO_SMAIL_CAESAR_VALUE', 13) | |
super(BaseEncryptedField, self).__init__(*args, **kwargs) | |
def to_python(self, value): | |
if value and value.startswith(self.prefix): | |
try: | |
retval = "" | |
for c in value[len(self.prefix):]: | |
if c.isalpha(): | |
if c in string.ascii_uppercase: | |
retval += self.I2L[(self.L2I[c] + self.caesar_value) % 26] | |
else: | |
retval += self.i2l[(self.l2i[c] + self.caesar_value) % 26] | |
else: | |
retval += c | |
except KeyError as err: | |
print("failed to decode") | |
print(err) | |
return "" | |
else: | |
retval = value | |
return retval | |
def from_db_value(self, value, expression, connection, *args): | |
return self.to_python(value) | |
def get_db_prep_value(self, value, connection, prepared=False): | |
if value and not value.startswith(self.prefix): | |
retval = self.prefix | |
for c in value: | |
if c.isalpha(): | |
if c in string.ascii_uppercase: | |
retval += self.I2L[(self.L2I[c] - self.caesar_value) % 26] | |
else: | |
retval += self.i2l[(self.l2i[c] - self.caesar_value) % 26] | |
else: | |
retval += c | |
return retval | |
return value | |
# https://github.com/orcasgit/django-fernet-fields/blob/master/fernet_fields/fields.py | |
# def get_db_prep_save(self, value, connection): | |
# value = super( | |
# EncryptedField, self | |
# ).get_db_prep_save(value, connection) | |
# if value is not None: | |
# retval = self.fernet.encrypt(force_bytes(value)) | |
# return connection.Database.Binary(retval) | |
def get_internal_type(self): | |
return self._internal_type | |
def deconstruct(self): | |
name, path, args, kwargs = super(BaseEncryptedField, self).deconstruct() | |
return name, path, args, kwargs | |
class EncryptedTextField(BaseEncryptedField): | |
_internal_type = 'TextField' | |
def formfield(self, **kwargs): | |
defaults = {'widget': forms.Textarea} | |
defaults.update(kwargs) | |
return super(EncryptedTextField, self).formfield(**defaults) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment