Skip to content

Instantly share code, notes, and snippets.

@frennkie
Created April 2, 2020 15:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save frennkie/1f0efc9b20186609ee252ba9c91f7b31 to your computer and use it in GitHub Desktop.
Save frennkie/1f0efc9b20186609ee252ba9c91f7b31 to your computer and use it in GitHub Desktop.
# -*- 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