From 6114ec0f3314013175cc55886f2cd6085d8ae1d0 Mon Sep 17 00:00:00 2001 From: jlaine Date: Wed, 19 May 2010 08:31:51 +0000 Subject: [PATCH] improve LDAP filter escaping git-svn-id: https://svn.bolloretelecom.eu/opensource/django-ldapdb/trunk@849 e071eeec-0327-468d-9b6a-08194a12b294 --- ldapdb/models/fields.py | 13 ------------- ldapdb/models/query.py | 17 ++++++++++++----- ldapdb/tests.py | 18 +++++++++++++----- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/ldapdb/models/fields.py b/ldapdb/models/fields.py index fe91601..78ec1c7 100644 --- a/ldapdb/models/fields.py +++ b/ldapdb/models/fields.py @@ -25,19 +25,6 @@ class CharField(fields.CharField): kwargs['max_length'] = 200 super(CharField, self).__init__(*args, **kwargs) - def get_db_prep_value(self, value): - """Returns field's value prepared for interacting with the database - backend. - - Used by the default implementations of ``get_db_prep_save``and - `get_db_prep_lookup``` - """ - return value.replace('\\', '\\5c') \ - .replace('*', '\\2a') \ - .replace('(', '\\28') \ - .replace(')', '\\29') \ - .replace('\0', '\\00') - class ImageField(fields.Field): pass diff --git a/ldapdb/models/query.py b/ldapdb/models/query.py index f430286..877ea9e 100644 --- a/ldapdb/models/query.py +++ b/ldapdb/models/query.py @@ -21,7 +21,6 @@ from copy import deepcopy import ldap -from django.db.models.fields import Field from django.db.models.query import QuerySet as BaseQuerySet from django.db.models.query_utils import Q from django.db.models.sql import Query as BaseQuery @@ -29,6 +28,14 @@ from django.db.models.sql.where import WhereNode as BaseWhereNode, Constraint as import ldapdb +def escape_ldap_filter(value): + value = str(value) + return value.replace('\\', '\\5c') \ + .replace('*', '\\2a') \ + .replace('(', '\\28') \ + .replace(')', '\\29') \ + .replace('\0', '\\00') + class Constraint(BaseConstraint): """ An object that can be passed to WhereNode.add() and knows how to @@ -43,13 +50,13 @@ class Constraint(BaseConstraint): from django.db.models.base import ObjectDoesNotExist if lookup_type == 'endswith': - params = ["*%s" % value] + params = ["*%s" % escape_ldap_filter(value)] elif lookup_type == 'startswith': - params = ["%s*" % value] + params = ["%s*" % escape_ldap_filter(value)] elif lookup_type == 'exact': - params = [value] + params = [escape_ldap_filter(value)] elif lookup_type == 'in': - params = [v for v in value] + params = [escape_ldap_filter(v) for v in value] else: raise TypeError("Field has invalid lookup: %s" % lookup_type) diff --git a/ldapdb/tests.py b/ldapdb/tests.py index e3c787b..be247fd 100644 --- a/ldapdb/tests.py +++ b/ldapdb/tests.py @@ -22,13 +22,16 @@ from django.test import TestCase from django.db.models.sql.where import Constraint, AND, OR from ldapdb.models.fields import CharField -from ldapdb.models.query import WhereNode - -class FieldTestCase(TestCase): - def test_db_prep(self): - field = CharField() +from ldapdb.models.query import WhereNode, escape_ldap_filter class WhereTestCase(TestCase): + def test_escape(self): + self.assertEquals(escape_ldap_filter('foo*bar'), 'foo\\2abar') + self.assertEquals(escape_ldap_filter('foo(bar'), 'foo\\28bar') + self.assertEquals(escape_ldap_filter('foo)bar'), 'foo\\29bar') + self.assertEquals(escape_ldap_filter('foo\\bar'), 'foo\\5cbar') + self.assertEquals(escape_ldap_filter('foo\\bar*wiz'), 'foo\\5cbar\\2awiz') + def test_single(self): where = WhereNode() where.add((Constraint("cn", "cn", None), 'exact', "test"), AND) @@ -46,6 +49,11 @@ class WhereTestCase(TestCase): where.add((Constraint("cn", "cn", None), 'in', ["foo", "bar"]), AND) self.assertEquals(where.as_sql(), "(|(cn=foo)(cn=bar))") + def test_escaped(self): + where = WhereNode() + where.add((Constraint("cn", "cn", None), 'exact', "(test)"), AND) + self.assertEquals(where.as_sql(), "(cn=\\28test\\29)") + def test_and(self): where = WhereNode() where.add((Constraint("cn", "cn", None), 'exact', "foo"), AND) -- 2.30.2