Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filtering not supported? #44

Open
mflaxman opened this issue Sep 5, 2014 · 7 comments
Open

Filtering not supported? #44

mflaxman opened this issue Sep 5, 2014 · 7 comments

Comments

@mflaxman
Copy link

mflaxman commented Sep 5, 2014

I was getting some strange behavior on my site and traced the problem back to this:

In [1]: from customers.models import *
In [2]: foo = KYCUser.objects.filter(ss_num__isnull=False).last()
In [3]: print foo.ss_num
Out[3]: u'123456789'
In [4]: KYCUser.objects.filter(ss_num='123456789')
Out[4]: []

ss_num looks like this in the model defintion:

ss_num = EncryptedCharField(max_length=10, blank=True, null=True, db_index=True)   

Does this library not support filtering? That'd be understandable, but if so it should make that clear in the docs and not fail silently.

Thanks for putting this out there!

@skatenerd
Copy link

I too am wondering how to query against an encrypted field. I am thinking it could make sense to query using the encrypted value (perhaps with raw sql). In other words, maybe I could figure out what is actually in the DB table, and query for that value.

There doesn't seem to be a clean way to figure out the encrypted value residing in the database.

Any ideas?

@svetlyak40wt
Copy link
Owner

You could do exact filtering against encrypted values. That is it.

@skatenerd
Copy link

I'm trying:
House.objects.filter(color__exact="green")
and coming up empty-handed, even though
House.objects.last().color == "green"

@skatenerd
Copy link

This workaround is working, but it's a litle bit ugly. Note that it basically makes a guess about the mechanics of the random-padding.

color_field = [f for f in House._meta.fields if f.name=='color'][0]
House.objects.filter(color__contains=color_field.get_db_prep_value("green")[:77])

EDIT:
This workaround totally fails

@svetlyak40wt
Copy link
Owner

I belive there should be a way to do it right. But encrypted field's code was contributed and I'm unaware in it's details and don't use encrypted fields.

But will be glad to accept a pull request with fix and a test for it (tests are in the src/django_fields/tests.py).

@svetlyak40wt
Copy link
Owner

Oh, and probably I shoudl setup a travis to run these tests automatically. Will add this in my TODO :)

@danieldai
Copy link

https://github.com/svetlyak40wt/django-fields/blob/master/src/django_fields/fields.py#L55

This is my be the reason why filtering is not supported here.

self.iv = Random.new().read(self.cipher_object.block_size)
            self.cipher = self.cipher_object.new(
                self.secret_key,
                getattr(self.cipher_object, self.block_type),
                self.iv)

self.iv is different on every instantiation of this class, which causes the encrypted value changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants