It looks like I solved it by doing this:
def __set__(self, instance, value):
instance.__dict__[self.field.name] = value
if value != getattr(instance, self.field.attname):
setattr(instance, self.field.attname, self.field.encrypt(value))
I figured I should be checking somewhere if I already encrypted, but
couldn't figure out where. Not sure if this is the best way though...
On Tuesday, September 18, 2012 9:51:23 AM UTC-4, lingrlongr wrote:
>
> I'm trying to make an encrypted field. I'm using some of the code from
> the book Pro Django. Generally speaking, it works, but it fails when using
> Django's admin interface. Here's the code:
>
> class EncryptedTextFieldDescriptor(property):
> def __init__(self, field):
> self.field = field
>
> def __get__(self, instance, owner):
> if instance is None:
> return self
> if self.field.name not in instance.__dict__:
> raw_data = getattr(instance, self.field.attname)
> instance.__dict__[self.field.name] =
> self.field.decrypt(raw_data)
> return instance.__dict__[self.field.name]
>
> def __set__(self, instance, value):
> instance.__dict__[self.field.name] = value
> setattr(instance, self.field.attname, self.field.encrypt(value))
>
> class EncryptedTextField(models.TextField):
> def encrypt(self, data):
> return binascii.b2a_hex(_magic.encrypt(data))
>
> def decrypt(self, data):
> return _magic.decrypt(binascii.a2b_hex(data))
>
> def get_attname(self):
> return '%s_encrypted' % self.name
>
> def get_db_prep_lookup(self, lookup_type, value):
> raise ValueError("Can't make comparisons against encrypted data.")
>
> def contribute_to_class(self, cls, name):
> super(EncryptedTextField, self).contribute_to_class(cls, name)
> setattr(cls, name, EncryptedTextFieldDescriptor (self))
>
> When using a python shell:
>
> >>> obj.enc_field = 'test'
> >>> print obj.enc_field
> 'test'
> >>> print obj.enc_field_encrypted
>
> '4441f5378dbb0be1c5a84e32c8616295b739c0ca82e68sb8f230f0aab2c40c0561d2223c7534a563da727578852db7ac3dd1f9d289ffac34d5492d1c1cefeed771f97b45ad862166e67f2170856fd4bd'
> >>> obj.save()
>
> This all works fine. When this object is loaded in the admin, the value
> for the enc_field will be the encrypted version, not the decrypted version.
> So, if I were to save the object, the encrypted text gets encrypted again,
> then saved.
>
> How can I stop this behavior?
>
>
--
You received this message because you are subscribed to the Google Groups
"Django users" group.
To view this discussion on the web visit
https://groups.google.com/d/msg/django-users/-/G9238VJeRKUJ.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/django-users?hl=en.