[CalendarServer-changes] [12399] twext/trunk/twext/who/ldap/test/test_service.py

source_changes at macosforge.org source_changes at macosforge.org
Wed Mar 12 11:16:27 PDT 2014


Revision: 12399
          http://trac.calendarserver.org//changeset/12399
Author:   wsanchez at apple.com
Date:     2014-01-20 12:10:14 -0800 (Mon, 20 Jan 2014)
Log Message:
-----------
Patch mockldap to handle some wild cards.

Modified Paths:
--------------
    twext/trunk/twext/who/ldap/test/test_service.py

Modified: twext/trunk/twext/who/ldap/test/test_service.py
===================================================================
--- twext/trunk/twext/who/ldap/test/test_service.py	2014-01-20 04:35:14 UTC (rev 12398)
+++ twext/trunk/twext/who/ldap/test/test_service.py	2014-01-20 20:10:14 UTC (rev 12399)
@@ -25,6 +25,11 @@
 import ldap
 from mockldap import MockLdap
 
+from mockldap.filter import (
+    Test as MockLDAPFilterTest,
+    UnsupportedOp as MockLDAPUnsupportedOp,
+)
+
 from twisted.python.constants import NamedConstant, ValueConstant
 from twisted.python.filepath import FilePath
 from twisted.internet.defer import inlineCallbacks
@@ -71,6 +76,32 @@
 
 
     def setUp(self):
+        def parse_expression(
+            self, upcall=MockLDAPFilterTest._parse_expression
+        ):
+            try:
+                # Try the stock implementation first.
+                return upcall(self)
+
+            except MockLDAPUnsupportedOp as e:
+                if (
+                    len(e.args) == 1 and
+                    e.args[0].startswith(u"Wildcard matches are not supported")
+                ):
+                    return mockldap_parse_wildcard_expression(self)
+
+                raise
+
+        def matches(self, dn, attrs, upcall=MockLDAPFilterTest.matches):
+            if upcall(self, dn, attrs):
+                return True
+            else:
+                return mockldap_matches(self, dn, attrs)
+
+
+        self.patch(MockLDAPFilterTest, "_parse_expression", parse_expression)
+        self.patch(MockLDAPFilterTest, "matches", matches)
+
         self.xmlSeedService = xmlService(self.mktemp())
         self.mockData = mockDirectoryDataFromXMLService(self.xmlSeedService)
 
@@ -141,23 +172,6 @@
     test_queryCaseInsensitiveNoIndex.todo = "?"
 
 
-    def test_queryStartsWith(self):
-        return (
-            BaseDirectoryServiceQueryTestMixIn.test_queryStartsWith(self)
-        )
-
-    test_queryStartsWith.todo = "?"
-
-
-    def test_queryStartsWithNoIndex(self):
-        return (
-            BaseDirectoryServiceQueryTestMixIn
-            .test_queryStartsWithNoIndex(self)
-        )
-
-    test_queryStartsWithNoIndex.todo = "?"
-
-
     def test_queryStartsWithNot(self):
         return BaseDirectoryServiceQueryTestMixIn.test_queryStartsWithNot(self)
 
@@ -425,3 +439,88 @@
             data[dn] = recordData
 
     return data
+
+
+
+#
+# mockldap patches
+#
+
+class WildcardExpression(object):
+    first = None
+    middle = []
+    last = None
+
+
+def mockldap_parse_wildcard_expression(self):
+    match = self.TEST_RE.match(self.content)
+
+    if match is None:
+        raise ldap.FILTER_ERROR(
+            u"Failed to parse filter item %r at pos %d"
+            % (self.content, self.start)
+        )
+
+    self.attr, self.op, valueExpression = match.groups()
+
+    if self.op != "=":
+        raise MockLDAPUnsupportedOp(
+            u"Operation %r is not supported" % (self.op,)
+        )
+
+    if (u"*" not in valueExpression):
+        raise NotImplementedError(u"I only deal with wild cards")
+
+    values = []
+
+    for value in valueExpression.split(u"*"):
+        # Resolve all escaped characters
+        values.append(self.UNESCAPE_RE.sub(
+            lambda m: chr(int(m.group(1), 16)),
+            value
+        ))
+
+    exp = WildcardExpression()
+
+    if not valueExpression.startswith(u"*"):
+        exp.first = values.pop(0)
+
+    if not valueExpression.endswith(u"*"):
+        exp.last = values.pop(-1)
+
+    exp.middle = values
+
+    self.value = exp
+
+
+def mockldap_matches(self, dn, attrs):
+    exp = self.value
+
+    if not isinstance(exp, WildcardExpression):
+        return False
+
+    values = attrs.get(self.attr)
+
+    if values is None:
+        return False
+
+    for value in values:
+        if exp.first is not None:
+            if not value.startswith(exp.first):
+                continue
+            value = value[len(exp.first):]
+
+        if exp.last is not None:
+            if not value.endswith(exp.last):
+                continue
+            value = value[:-len(exp.last)]
+
+        if exp.middle:
+            for substr in exp.middle:
+                if not substr:
+                    continue
+                raise NotImplementedError("middle: {0}".format(exp.middle))
+
+        return True
+
+    return False
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20140312/48598f1c/attachment.html>


More information about the calendarserver-changes mailing list