forked from django-extensions/django-extensions
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added encrypted text and char fields.
- Loading branch information
1 parent
e401f82
commit 459276d
Showing
5 changed files
with
128 additions
and
1 deletion.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
from django.db import models | ||
from django.core.exceptions import ImproperlyConfigured | ||
from django import forms | ||
from django.conf import settings | ||
from keyczar import keyczar | ||
|
||
class BaseEncryptedField(models.Field): | ||
prefix = 'enc_str:::' | ||
def __init__(self, *args, **kwargs): | ||
if not hasattr(settings, 'KEYS_DIR'): | ||
raise ImproperlyConfigured('You must set settings.KEYS_DIR to your Keyczar keys directory.') | ||
self.crypt = keyczar.Crypter.Read(settings.KEYS_DIR) | ||
super(BaseEncryptedField, self).__init__(*args, **kwargs) | ||
|
||
def to_python(self, value): | ||
if (value.startswith(self.prefix)): | ||
retval = self.crypt.Decrypt(value[len(self.prefix):]) | ||
else: | ||
retval = value | ||
|
||
return retval | ||
|
||
def get_db_prep_value(self, value): | ||
if not value.startswith(self.prefix): | ||
value = self.prefix + self.crypt.Encrypt(value) | ||
return value | ||
|
||
class EncryptedTextField(BaseEncryptedField): | ||
__metaclass__ = models.SubfieldBase | ||
|
||
def get_internal_type(self): | ||
return 'TextField' | ||
|
||
def formfield(self, **kwargs): | ||
defaults = {'widget': forms.Textarea} | ||
defaults.update(kwargs) | ||
return super(EncryptedTextField, self).formfield(**defaults) | ||
|
||
class EncryptedCharField(BaseEncryptedField): | ||
__metaclass__ = models.SubfieldBase | ||
|
||
def __init__(self, max_length=None, *args, **kwargs): | ||
if max_length: | ||
max_length += len(self.prefix) | ||
|
||
super(EncryptedCharField, self).__init__(max_length=max_length, *args, **kwargs) | ||
|
||
|
||
def get_internal_type(self): | ||
return "CharField" | ||
|
||
def formfield(self, **kwargs): | ||
defaults = {'max_length': self.max_length} | ||
defaults.update(kwargs) | ||
return super(EncryptedCharField, self).formfield(**defaults) |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import unittest | ||
from keyczar import keyczar | ||
|
||
from django.db import connection | ||
from django.conf import settings | ||
from django.core.management import call_command | ||
from django.db.models import loading | ||
|
||
from django_extensions.tests.models import Secret | ||
from django_extensions.db.fields.encrypted import EncryptedTextField, EncryptedCharField | ||
|
||
class EncryptedFieldsTestCase(unittest.TestCase): | ||
|
||
def __init__(self, *args, **kwargs): | ||
self.crypt = keyczar.Crypter.Read(settings.KEYS_DIR) | ||
|
||
super(EncryptedFieldsTestCase, self).__init__(*args, **kwargs) | ||
|
||
def setUp(self): | ||
self.old_installed_apps = settings.INSTALLED_APPS | ||
settings.INSTALLED_APPS.append('django_extensions.tests') | ||
loading.cache.loaded = False | ||
call_command('syncdb', verbosity=0) | ||
|
||
def tearDown(self): | ||
settings.INSTALLED_APPS = self.old_installed_apps | ||
|
||
def testCharFieldCreate(self): | ||
test_val = "Test Secret" | ||
secret = Secret.objects.create(name=test_val) | ||
cursor = connection.cursor() | ||
query = "SELECT name FROM %s WHERE id = %d" % (Secret._meta.db_table, secret.id) | ||
cursor.execute(query) | ||
db_val, = cursor.fetchone() | ||
decrypted_val = self.crypt.Decrypt(db_val[len(EncryptedCharField.prefix):]) | ||
self.assertEqual(test_val, decrypted_val) | ||
|
||
def testCharFieldRead(self): | ||
test_val = "Test Secret" | ||
secret = Secret.objects.create(name=test_val) | ||
retrieved_secret = Secret.objects.get(id=secret.id) | ||
self.assertEqual(test_val, retrieved_secret.name) | ||
|
||
def testTextFieldCreate(self): | ||
test_val = "Test Secret" | ||
secret = Secret.objects.create(text=test_val) | ||
cursor = connection.cursor() | ||
query = "SELECT text FROM %s WHERE id = %d" % (Secret._meta.db_table, secret.id) | ||
cursor.execute(query) | ||
db_val, = cursor.fetchone() | ||
decrypted_val = self.crypt.Decrypt(db_val[len(EncryptedCharField.prefix):]) | ||
self.assertEqual(test_val, decrypted_val) | ||
|
||
def testTextFieldRead(self): | ||
test_val = "Test Secret" | ||
secret = Secret.objects.create(text=test_val) | ||
retrieved_secret = Secret.objects.get(id=secret.id) | ||
self.assertEqual(test_val, retrieved_secret.text) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from django.db import models | ||
|
||
from django_extensions.db.fields.encrypted import EncryptedTextField, EncryptedCharField | ||
|
||
class Secret(models.Model): | ||
name = EncryptedCharField(blank=True, max_length=255) | ||
text = EncryptedTextField(blank=True) |
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