예제 #1
0
 def test_and_or(self):
     text = "(&(objectClass=Person)(|(sn=Jensen)(cn=Babs J*)))"
     filt = pureldap.LDAPFilter_and(
         [
             pureldap.LDAPFilter_equalityMatch(
                 attributeDesc=pureldap.LDAPAttributeDescription(
                     value="objectClass"
                 ),
                 assertionValue=pureldap.LDAPAssertionValue(value="Person"),
             ),
             pureldap.LDAPFilter_or(
                 [
                     pureldap.LDAPFilter_equalityMatch(
                         attributeDesc=pureldap.LDAPAttributeDescription(value="sn"),
                         assertionValue=pureldap.LDAPAssertionValue(value="Jensen"),
                     ),
                     pureldap.LDAPFilter_substrings(
                         type="cn",
                         substrings=[
                             pureldap.LDAPFilter_substrings_initial(value="Babs J")
                         ],
                     ),
                 ]
             ),
         ]
     )
     self.assertEqual(ldapfilter.parseFilter(text), filt)
     self.assertEqual(filt.asText(), text)
예제 #2
0
 def test_andornot(self):
     text = r'(&(!(|(cn=foo)(cn=bar)))(sn=a*b*c*d))'
     filt = pureldap.LDAPFilter_and([
         pureldap.LDAPFilter_not(
             pureldap.LDAPFilter_or([
                 pureldap.LDAPFilter_equalityMatch(
                     attributeDesc=pureldap.LDAPAttributeDescription(
                         value='cn'),
                     assertionValue=pureldap.LDAPAssertionValue(
                         value='foo')),
                 pureldap.LDAPFilter_equalityMatch(
                     attributeDesc=pureldap.LDAPAttributeDescription(
                         value='cn'),
                     assertionValue=pureldap.LDAPAssertionValue(
                         value='bar')),
             ])),
         pureldap.LDAPFilter_substrings(
             type='sn',
             substrings=[
                 pureldap.LDAPFilter_substrings_initial('a'),
                 pureldap.LDAPFilter_substrings_any('b'),
                 pureldap.LDAPFilter_substrings_any('c'),
                 pureldap.LDAPFilter_substrings_final('d'),
             ])
     ])
     self.assertEqual(ldapfilter.parseFilter(text), filt)
     self.assertEqual(filt.asText(), text)
예제 #3
0
 def test_andornot(self):
     text = r"(&(!(|(cn=foo)(cn=bar)))(sn=a*b*c*d))"
     filt = pureldap.LDAPFilter_and(
         [
             pureldap.LDAPFilter_not(
                 pureldap.LDAPFilter_or(
                     [
                         pureldap.LDAPFilter_equalityMatch(
                             attributeDesc=pureldap.LDAPAttributeDescription(
                                 value="cn"
                             ),
                             assertionValue=pureldap.LDAPAssertionValue(value="foo"),
                         ),
                         pureldap.LDAPFilter_equalityMatch(
                             attributeDesc=pureldap.LDAPAttributeDescription(
                                 value="cn"
                             ),
                             assertionValue=pureldap.LDAPAssertionValue(value="bar"),
                         ),
                     ]
                 )
             ),
             pureldap.LDAPFilter_substrings(
                 type="sn",
                 substrings=[
                     pureldap.LDAPFilter_substrings_initial("a"),
                     pureldap.LDAPFilter_substrings_any("b"),
                     pureldap.LDAPFilter_substrings_any("c"),
                     pureldap.LDAPFilter_substrings_final("d"),
                 ],
             ),
         ]
     )
     self.assertEqual(ldapfilter.parseFilter(text), filt)
     self.assertEqual(filt.asText(), text)
    def _cb_testDefaultSetting(self, val, client, o):
        client.assertSent(
            *[

            pureldap.LDAPSearchRequest(
            baseObject='dc=example,dc=com', scope=2,
            derefAliases=0, sizeLimit=1, timeLimit=0, typesOnly=0,
            filter=pureldap.LDAPFilter_equalityMatch(attributeDesc=pureldap.LDAPAttributeDescription(value='uidNumber'),
                                                     assertionValue=pureldap.LDAPAssertionValue(value='1000')),
            attributes=()),

            ] + [
            pureldap.LDAPSearchRequest(
            baseObject='dc=example,dc=com', scope=2,
            derefAliases=0, sizeLimit=1, timeLimit=0, typesOnly=0,
            filter=pureldap.LDAPFilter_equalityMatch(attributeDesc=pureldap.LDAPAttributeDescription(value='gidNumber'),
                                                     assertionValue=pureldap.LDAPAssertionValue(value=str(x))),
            attributes=())
            for x in (1000, 1500, 1250, 1125, 1062, 1031, 1046, 1038, 1042, 1040, 1041)])

        self.failUnless('loginShell' in o)
        self.failUnlessEqual(o['loginShell'], ['/bin/sh'])

        self.failUnless('uidNumber' in o)
        self.failUnlessEqual(o['uidNumber'], ['1000'])
        self.failUnless('gidNumber' in o)
        self.failUnlessEqual(o['gidNumber'], ['1042'])
예제 #5
0
class TestEquality(unittest.TestCase):
    valuesToTest = (
        (pureldap.LDAPFilter_equalityMatch, [
            pureldap.LDAPAttributeDescription(value='cn'),
            pureldap.LDAPAssertionValue(value='foo'),
        ]),
        (pureldap.LDAPFilter_equalityMatch, [
            pureldap.LDAPAttributeDescription(value='cn'),
            pureldap.LDAPAssertionValue(value='bar'),
        ]),
        (pureber.BERInteger, [0]),
    )

    def testEquality(self):
        """LDAP objects equal LDAP objects with same type and content"""
        for class_, args in self.valuesToTest:
            x = class_(*args)
            y = class_(*args)
            self.assertEquals(x, x)
            self.assertEquals(x, y)

    def testInEquality(self):
        """LDAP objects do not equal LDAP objects with different type or content"""
        for i in xrange(len(self.valuesToTest)):
            for j in xrange(len(self.valuesToTest)):
                if i != j:
                    i_class, i_args = self.valuesToTest[i]
                    j_class, j_args = self.valuesToTest[j]
                    x = i_class(*i_args)
                    y = j_class(*j_args)
                    self.assertNotEquals(x, y)
예제 #6
0
    def _tryService(self, services, baseEntry, request, controls, reply):
        try:
            serviceName = services.pop(0)
        except IndexError:
            return None
        timestamp = self.timestamp()
        d = baseEntry.search(
            filterObject=pureldap.LDAPFilter_and([
                pureldap.LDAPFilter_equalityMatch(
                    attributeDesc=pureldap.LDAPAttributeDescription(
                        'objectClass'),
                    assertionValue=pureldap.LDAPAssertionValue(
                        'serviceSecurityObject')),
                pureldap.LDAPFilter_equalityMatch(
                    attributeDesc=pureldap.LDAPAttributeDescription('owner'),
                    assertionValue=pureldap.LDAPAssertionValue(request.dn)),
                pureldap.LDAPFilter_equalityMatch(
                    attributeDesc=pureldap.LDAPAttributeDescription('cn'),
                    assertionValue=pureldap.LDAPAssertionValue(serviceName)),
                pureldap.LDAPFilter_or([
                    # no time
                    pureldap.LDAPFilter_not(
                        pureldap.LDAPFilter_present('validFrom')),
                    # or already valid
                    pureldap.LDAPFilter_lessOrEqual(
                        attributeDesc=pureldap.LDAPAttributeDescription(
                            'validFrom'),
                        assertionValue=pureldap.LDAPAssertionValue(timestamp)),
                ]),
                pureldap.LDAPFilter_or([
                    # no time
                    pureldap.LDAPFilter_not(
                        pureldap.LDAPFilter_present('validUntil')),
                    # or still valid
                    pureldap.LDAPFilter_greaterOrEqual(
                        attributeDesc=pureldap.LDAPAttributeDescription(
                            'validUntil'),
                        assertionValue=pureldap.LDAPAssertionValue(timestamp)),
                ]),
            ]),
            attributes=('1.1', ))

        def _gotEntries(entries):
            if not entries:
                return None
            assert len(entries) == 1  #TODO
            e = entries[0]
            d = e.bind(request.auth)
            return d

        d.addCallback(_gotEntries)
        d.addCallbacks(callback=self._loopIfNone,
                       callbackArgs=(services, baseEntry, request, controls,
                                     reply),
                       errback=self._loopIfBindError,
                       errbackArgs=(services, baseEntry, request, controls,
                                    reply))
        return d
예제 #7
0
 def test_and_item(self):
     text = r'(&(cn=foo)(cn=bar))'
     filt = pureldap.LDAPFilter_and([
         pureldap.LDAPFilter_equalityMatch(
             attributeDesc=pureldap.LDAPAttributeDescription(value='cn'),
             assertionValue=pureldap.LDAPAssertionValue(value='foo')),
         pureldap.LDAPFilter_equalityMatch(
             attributeDesc=pureldap.LDAPAttributeDescription(value='cn'),
             assertionValue=pureldap.LDAPAssertionValue(value='bar')),
     ])
     self.assertEqual(ldapfilter.parseFilter(text), filt)
     self.assertEqual(filt.asText(), text)
예제 #8
0
    def _cb_testDefaultSetting(self, val, client, o):
        client.assertSent(*[
            pureldap.LDAPSearchRequest(
                baseObject="dc=example,dc=com",
                scope=2,
                derefAliases=0,
                sizeLimit=1,
                timeLimit=0,
                typesOnly=0,
                filter=pureldap.LDAPFilter_equalityMatch(
                    attributeDesc=pureldap.LDAPAttributeDescription(
                        value="uidNumber"),
                    assertionValue=pureldap.LDAPAssertionValue(value="1000"),
                ),
                attributes=(),
            ),
        ] + [
            pureldap.LDAPSearchRequest(
                baseObject="dc=example,dc=com",
                scope=2,
                derefAliases=0,
                sizeLimit=1,
                timeLimit=0,
                typesOnly=0,
                filter=pureldap.LDAPFilter_equalityMatch(
                    attributeDesc=pureldap.LDAPAttributeDescription(
                        value="gidNumber"),
                    assertionValue=pureldap.LDAPAssertionValue(value=str(x)),
                ),
                attributes=(),
            ) for x in (
                1000,
                1500,
                1250,
                1125,
                1062,
                1031,
                1046,
                1038,
                1042,
                1040,
                1041,
            )
        ])

        self.failUnless("loginShell" in o)
        self.failUnlessEqual(o["loginShell"], ["/bin/sh"])

        self.failUnless("uidNumber" in o)
        self.failUnlessEqual(o["uidNumber"], ["1000"])
        self.failUnless("gidNumber" in o)
        self.failUnlessEqual(o["gidNumber"], ["1042"])
예제 #9
0
 def test_whitespace_afterEq(self):
     text = r'(cn= foo)'
     filt = pureldap.LDAPFilter_equalityMatch(
         attributeDesc=pureldap.LDAPAttributeDescription(value='cn'),
         assertionValue=pureldap.LDAPAssertionValue(value=' foo'))
     self.assertEqual(ldapfilter.parseFilter(text), filt)
     self.assertEqual(filt.asText(), text)
예제 #10
0
 def test_escape_backslash(self):
     text = r'(filename=C:\5cMyFile)'
     filt = pureldap.LDAPFilter_equalityMatch(
         attributeDesc=pureldap.LDAPAttributeDescription(value='filename'),
         assertionValue=pureldap.LDAPAssertionValue(value=r'C:\MyFile'))
     self.assertEqual(ldapfilter.parseFilter(text), filt)
     self.assertEqual(filt.asText(), text)
예제 #11
0
 def test_cn(self):
     text = '(cn=Babs Jensen)'
     filt = pureldap.LDAPFilter_equalityMatch(
         attributeDesc=pureldap.LDAPAttributeDescription(value='cn'),
         assertionValue=pureldap.LDAPAssertionValue(value='Babs Jensen'))
     self.assertEqual(ldapfilter.parseFilter(text), filt)
     self.assertEqual(filt.asText(), text)
예제 #12
0
 def test_escape_parens(self):
     text = r'(o=Parens R Us \28for all your parenthetical needs\29)'
     filt = pureldap.LDAPFilter_equalityMatch(
         attributeDesc=pureldap.LDAPAttributeDescription(value='o'),
         assertionValue=pureldap.LDAPAssertionValue(value='Parens R Us (for all your parenthetical needs)'))
     self.assertEqual(ldapfilter.parseFilter(text), filt)
     self.assertEqual(filt.asText(), text)
예제 #13
0
 def test_escape_utf8(self):
     text = r"(sn=Lu\c4\8di\c4\87)"
     filt = pureldap.LDAPFilter_equalityMatch(
         attributeDesc=pureldap.LDAPAttributeDescription(value="sn"),
         assertionValue=pureldap.LDAPAssertionValue(value="Lu\xc4\x8di\xc4\x87"),
     )
     self.assertEqual(ldapfilter.parseFilter(text), filt)
예제 #14
0
 def test_or_item(self):
     text = r"(|(cn=foo)(cn=bar))"
     filt = pureldap.LDAPFilter_or(
         [
             pureldap.LDAPFilter_equalityMatch(
                 attributeDesc=pureldap.LDAPAttributeDescription(value="cn"),
                 assertionValue=pureldap.LDAPAssertionValue(value="foo"),
             ),
             pureldap.LDAPFilter_equalityMatch(
                 attributeDesc=pureldap.LDAPAttributeDescription(value="cn"),
                 assertionValue=pureldap.LDAPAssertionValue(value="bar"),
             ),
         ]
     )
     self.assertEqual(ldapfilter.parseFilter(text), filt)
     self.assertEqual(filt.asText(), text)
예제 #15
0
 def test_escape_binary(self):
     text = r"(bin=\00\00\00\04)"
     filt = pureldap.LDAPFilter_equalityMatch(
         attributeDesc=pureldap.LDAPAttributeDescription(value="bin"),
         assertionValue=pureldap.LDAPAssertionValue(value="\00\00\00\04"),
     )
     self.assertEqual(ldapfilter.parseFilter(text), filt)
예제 #16
0
 def test_escape_utf8(self):
     text = r'(sn=Lu\c4\8di\c4\87)'
     filt = pureldap.LDAPFilter_equalityMatch(
         attributeDesc=pureldap.LDAPAttributeDescription(value='sn'),
         assertionValue=pureldap.LDAPAssertionValue(
             value='Lu\xc4\x8di\xc4\x87'))
     self.assertEquals(ldapfilter.parseFilter(text), filt)
예제 #17
0
 def test_escape_simple(self):
     text = r"f\2aoo(bar"
     filt = pureldap.LDAPFilter_equalityMatch(
         attributeDesc=pureldap.LDAPAttributeDescription(value="cn"),
         assertionValue=pureldap.LDAPAssertionValue(value="f*oo(bar"),
     )
     self.assertEqual(ldapfilter.parseMaybeSubstring("cn", text), filt)
예제 #18
0
 def test_and_or(self):
     text = '(&(objectClass=Person)(|(sn=Jensen)(cn=Babs J*)))'
     filt = pureldap.LDAPFilter_and(
         [ pureldap.LDAPFilter_equalityMatch(
         attributeDesc=pureldap.LDAPAttributeDescription(value='objectClass'),
         assertionValue=pureldap.LDAPAssertionValue(value='Person')),
           pureldap.LDAPFilter_or([ pureldap.LDAPFilter_equalityMatch(
         attributeDesc=pureldap.LDAPAttributeDescription(value='sn'),
         assertionValue=pureldap.LDAPAssertionValue(value='Jensen')),
                                    pureldap.LDAPFilter_substrings(
         type='cn',
         substrings=[ pureldap.LDAPFilter_substrings_initial(value='Babs J')
                      ])
                                    ]),
           ])
     self.assertEqual(ldapfilter.parseFilter(text), filt)
     self.assertEqual(filt.asText(), text)
예제 #19
0
 def test_whitespace_beforeCloseParen(self):
     text = r"(cn=foo )"
     filt = pureldap.LDAPFilter_equalityMatch(
         attributeDesc=pureldap.LDAPAttributeDescription(value="cn"),
         assertionValue=pureldap.LDAPAssertionValue(value="foo "),
     )
     self.assertEqual(ldapfilter.parseFilter(text), filt)
     self.assertEqual(filt.asText(), text)
예제 #20
0
 def test_not_cn(self):
     text = '(!(cn=Tim Howes))'
     filt = pureldap.LDAPFilter_not(
         pureldap.LDAPFilter_equalityMatch(
             attributeDesc=pureldap.LDAPAttributeDescription(value='cn'),
             assertionValue=pureldap.LDAPAssertionValue(value='Tim Howes')))
     self.assertEqual(ldapfilter.parseFilter(text), filt)
     self.assertEqual(filt.asText(), text)
예제 #21
0
    def data_servicePasswords(self, ctx, data):
        user = ctx.locate(inevow.ISession).getLoggedInRoot().loggedIn
        config = interfaces.ILDAPConfig(ctx)
        e = ldapsyntax.LDAPEntry(client=user.client, dn=config.getBaseDN())
        d = e.search(filterObject=pureldap.LDAPFilter_and([
            pureldap.LDAPFilter_equalityMatch(
                attributeDesc=pureldap.LDAPAttributeDescription('objectClass'),
                assertionValue=pureldap.LDAPAssertionValue(
                    'serviceSecurityObject')),
            pureldap.LDAPFilter_equalityMatch(
                attributeDesc=pureldap.LDAPAttributeDescription('owner'),
                assertionValue=pureldap.LDAPAssertionValue(str(self.dn))),
            pureldap.LDAPFilter_present('cn'),
        ]),
                     attributes=['cn'])

        return d
예제 #22
0
 def test_not_item(self):
     text = r'(!(cn=foo))'
     filt = pureldap.LDAPFilter_not(
         pureldap.LDAPFilter_equalityMatch(
             attributeDesc=pureldap.LDAPAttributeDescription(value='cn'),
             assertionValue=pureldap.LDAPAssertionValue(value='foo')))
     self.assertEquals(ldapfilter.parseFilter(text), filt)
     self.assertEquals(filt.asText(), text)
예제 #23
0
 def guess(self, num):
     d = self.ldapObject.search(
         filterObject=pureldap.LDAPFilter_equalityMatch(
             attributeDesc=pureldap.LDAPAttributeDescription(
                 value=self.numberType),
             assertionValue=pureldap.LDAPAssertionValue(value=str(num))),
         sizeLimit=1)
     d.addCallback(lambda results: len(results))
     return d
예제 #24
0
 def test_not_item(self):
     text = r"(!(cn=foo))"
     filt = pureldap.LDAPFilter_not(
         pureldap.LDAPFilter_equalityMatch(
             attributeDesc=pureldap.LDAPAttributeDescription(value="cn"),
             assertionValue=pureldap.LDAPAssertionValue(value="foo"),
         )
     )
     self.assertEqual(ldapfilter.parseFilter(text), filt)
     self.assertEqual(filt.asText(), text)
예제 #25
0
    def dict_to_equality_filters(self, d):
        """ Takes a dict of key value pairs and turns them into a list of LDAP equality matches
        Args:
            d: (dict) attribute: value
        Returns:
            List of LDAPFilter_equalityMatch objects
        """
        filters = []
        for attribute, value in d.items():
            attr_obj = pureldap.LDAPAttributeDescription(attribute)
            value_obj = pureldap.LDAPAssertionValue(value)
            filters.append(
                pureldap.LDAPFilter_equalityMatch(attr_obj, value_obj))

        return filters
예제 #26
0
 def _getSearchFilter(self):
     filters = []
     for attr, value in self.data.items():
         if value is not None:
             f = ldapfilter.parseMaybeSubstring(attr, value)
             filters.append(f)
     if not filters:
         return None
     searchFilter = pureldap.LDAPFilter_and([
         pureldap.LDAPFilter_equalityMatch(
             attributeDesc=pureldap.LDAPAttributeDescription('objectClass'),
             assertionValue=pureldap.LDAPAssertionValue(
                 'addressbookPerson'))
     ] + filters)
     return searchFilter
예제 #27
0
def _p_simple(s, l, t):
    attr, filtertype, value = t
    return filtertype(attributeDesc=pureldap.LDAPAttributeDescription(attr),
                      assertionValue=pureldap.LDAPAssertionValue(value))
예제 #28
0
def _p_maybeSubString_simple(s, l, t):
    return (lambda attr: pureldap.LDAPFilter_equalityMatch(
        attributeDesc=pureldap.LDAPAttributeDescription(attr),
        assertionValue=pureldap.LDAPAssertionValue(t[0])))
예제 #29
0
    def try_ranged_search(self, client, base_dn, objs):
        """ So, you are an empty group object or a group with too many members
            to return in one shot.
            Let's try to grab those members a few at a time until we determine
            that the group is empty or we've built up the full list of members.
        """
        for obj in objs:
            member_range = None
            previous_result_empty = False
            # loop until we've exhausted all range segments
            while True:
                # can't help you without a dn. sorry.
                if not obj.get("distinguishedname"):
                    break
                previous_range = member_range
                member_range = next_range(previous_range,
                                          previous_result_empty)

                # create an ldap filter object to search with.
                # pureldap will escape the distinguishedname, making it safe.
                # Since we're reading the distinguishedname from search results,
                # we'll need to unescape it before it gets re-escaped.
                attr_obj = pureldap.LDAPAttributeDescription(
                    "distinguishedname")
                value_obj = pureldap.LDAPAssertionValue(
                    distinguishedname.unescape(obj["distinguishedname"][0]))
                filter_object = pureldap.LDAPFilter_equalityMatch(
                    attr_obj, value_obj)

                attributes = [
                    "member;range={0}-{1}".format(member_range[0],
                                                  member_range[1])
                ]
                try:
                    ranged_res = yield client.perform_search(
                        base_dn, filter_object, attributes=attributes)
                except LDAPOperationsError as e:
                    # searched for a range that exceeds the total number of
                    # elements in the attribute.
                    # if this is the first instance of this error, we may
                    # just need to try again with a '*' as the upper bound
                    # to get the last few members.
                    # if this is the second time (we are using the '*'), then
                    # we already have all of the members and can break.
                    if ldap.client.ERR_AD_CANT_RETRIEVE_ATTS in e.message:
                        if previous_result_empty:
                            break
                        previous_result_empty = True
                        continue
                    # something bad happened... give up
                    else:
                        log.failure("Unexpected error")
                        break

                # no results; we're done here
                if len(ranged_res) == 0:
                    break
                else:
                    # update the result object with the newly discovered
                    # members
                    for k, vs in ranged_res[0].items():
                        k = k.decode().lower()
                        vs = [escape_bytes(v) for v in vs]
                        if k.startswith("member;"):
                            obj["member"].extend(vs)
예제 #30
0
class KnownValues(unittest.TestCase):
    knownValues = (  # class, args, kwargs, expected_result
        (pureldap.LDAPModifyRequest, [], {
            "object":
            'cn=foo, dc=example, dc=com',
            "modification": [
                pureber.BERSequence([
                    pureber.BEREnumerated(0),
                    pureber.BERSequence([
                        pureldap.LDAPAttributeDescription('bar'),
                        pureber.BERSet([
                            pureldap.LDAPString('a'),
                            pureldap.LDAPString('b'),
                        ]),
                    ]),
                ]),
            ],
        }, None, [0x66, 50] +
         ([0x04, 0x1a] + l("cn=foo, dc=example, dc=com") + [0x30, 20] +
          ([0x30, 18] +
           ([0x0a, 0x01, 0x00] + [0x30, 13] +
            ([0x04, len("bar")] + l("bar") + [0x31, 0x06] +
             ([0x04, len("a")] + l("a") + [0x04, len("b")] + l("b"))))))),
        (pureldap.LDAPModifyRequest, [], {
            "object":
            'cn=foo, dc=example, dc=com',
            "modification": [
                pureber.BERSequence([
                    pureber.BEREnumerated(1L),
                    pureber.BERSequence([
                        pureber.BEROctetString('bar'),
                        pureber.BERSet([]),
                    ]),
                ]),
            ],
        }, None, [0x66, 0x2c] +
         ([0x04, 0x1a] + l("cn=foo, dc=example, dc=com") + [0x30, 0x0e] +
          ([0x30, 0x0c] + ([0x0a, 0x01, 0x01] + [0x30, 0x07] +
                           ([0x04, 0x03] + l("bar") + [0x31, 0x00]))))),
        (pureldap.LDAPFilter_not, [], {
            "value": pureldap.LDAPFilter_present("foo"),
        },
         pureldap.LDAPBERDecoderContext_Filter(
             fallback=pureber.BERDecoderContext()),
         [0xa2, 0x05] + [0x87] + [len("foo")] + l("foo")),
        (
            pureldap.LDAPFilter_or,
            [],
            {
                "value": [
                    pureldap.LDAPFilter_equalityMatch(
                        attributeDesc=pureldap.LDAPAttributeDescription(
                            value='cn'),
                        assertionValue=pureldap.LDAPAssertionValue(
                            value='foo')),
                    pureldap.LDAPFilter_equalityMatch(
                        attributeDesc=pureldap.LDAPAttributeDescription(
                            value='uid'),
                        assertionValue=pureldap.LDAPAssertionValue(
                            value='foo')),
                ]
            },
            pureldap.LDAPBERDecoderContext_Filter(
                fallback=pureber.BERDecoderContext()),
            [0xa1, 23] + [0xa3, 9] + [0x04] + [len("cn")] + l("cn") + [0x04] +
            [len("foo")] + l("foo") + [0xa3, 10] + [0x04] + [len("uid")] +
            l("uid") + [0x04] + [len("foo")] + l("foo"),
        ),
        (
            pureldap.LDAPFilter_and,
            [],
            {
                "value": [
                    pureldap.LDAPFilter_equalityMatch(
                        attributeDesc=pureldap.LDAPAttributeDescription(
                            value='cn'),
                        assertionValue=pureldap.LDAPAssertionValue(
                            value='foo')),
                    pureldap.LDAPFilter_equalityMatch(
                        attributeDesc=pureldap.LDAPAttributeDescription(
                            value='uid'),
                        assertionValue=pureldap.LDAPAssertionValue(
                            value='foo')),
                ]
            },
            pureldap.LDAPBERDecoderContext_Filter(
                fallback=pureber.BERDecoderContext()),
            [0xa0, 23] + [0xa3, 9] + [0x04] + [len("cn")] + l("cn") + [0x04] +
            [len("foo")] + l("foo") + [0xa3, 10] + [0x04] + [len("uid")] +
            l("uid") + [0x04] + [len("foo")] + l("foo"),
        ),
        (pureldap.LDAPModifyDNRequest, [], {
            'entry': 'cn=foo,dc=example,dc=com',
            'newrdn': 'uid=bar',
            'deleteoldrdn': 0,
        }, None, [0x6c, 0x26] + [0x04] + [len("cn=foo,dc=example,dc=com")] +
         l("cn=foo,dc=example,dc=com") + [0x04] + [len("uid=bar")] +
         l("uid=bar") + [0x01, 0x01, 0x00]),
        (pureldap.LDAPModifyDNRequest, [], {
            'entry': 'cn=aoue,dc=example,dc=com',
            'newrdn': 'uid=aoue',
            'deleteoldrdn': 0,
            'newSuperior': 'ou=People,dc=example,dc=com',
        }, None, [0x6c, 69] + [0x04] + [len("cn=aoue,dc=example,dc=com")] +
         l("cn=aoue,dc=example,dc=com") + [0x04] + [len("uid=aoue")] +
         l("uid=aoue") + [0x01, 0x01, 0x00] + [0x80] +
         [len("ou=People,dc=example,dc=com")] +
         l("ou=People,dc=example,dc=com")),
        (
            pureldap.LDAPSearchRequest,
            [],
            {
                'baseObject': 'dc=yoja,dc=example,dc=com',
            },
            None,
            [0x63, 57] + [0x04] + [len('dc=yoja,dc=example,dc=com')] +
            l('dc=yoja,dc=example,dc=com')
            # scope
            + [0x0a, 1, 2]
            # derefAliases
            + [0x0a, 1, 0]
            # sizeLimit
            + [0x02, 1, 0]
            # timeLimit
            + [0x02, 1, 0]
            # typesOnly
            + [0x01, 1, 0]
            # filter
            + [135, 11] + l('objectClass')
            # attributes
            + [48, 0]),
        (pureldap.LDAPUnbindRequest, [], {}, None, [0x42, 0x00]),
        (
            pureldap.LDAPSearchResultDone,
            [],
            {
                'resultCode': 0,
            },
            None,
            [0x65, 0x07]
            # resultCode
            + [0x0a, 0x01, 0x00]
            # matchedDN
            + [0x04] + [len('')] + l('')
            # errorMessage
            + [0x04] + [len('')] + l('')
            # referral, TODO
            + []),
        (
            pureldap.LDAPSearchResultDone,
            [],
            {
                'resultCode': 0,
                'matchedDN': 'dc=foo,dc=example,dc=com',
            },
            None,
            [0x65, 31]
            # resultCode
            + [0x0a, 0x01, 0x00]
            # matchedDN
            + [0x04] + [len('dc=foo,dc=example,dc=com')] +
            l('dc=foo,dc=example,dc=com')
            # errorMessage
            + [0x04] + [len('')] + l('')
            # referral, TODO
            + []),
        (
            pureldap.LDAPSearchResultDone,
            [],
            {
                'resultCode': 0,
                'matchedDN': 'dc=foo,dc=example,dc=com',
                'errorMessage': 'the foobar was fubar',
            },
            None,
            [0x65, 51]
            # resultCode
            + [0x0a, 0x01, 0x00]
            # matchedDN
            + [0x04] + [len('dc=foo,dc=example,dc=com')] +
            l('dc=foo,dc=example,dc=com')
            # errorMessage
            + [0x04] + [len('the foobar was fubar')] +
            l('the foobar was fubar', )
            # referral, TODO
            + []),
        (
            pureldap.LDAPSearchResultDone,
            [],
            {
                'resultCode': 0,
                'errorMessage': 'the foobar was fubar',
            },
            None,
            [0x65, 27]
            # resultCode
            + [0x0a, 0x01, 0x00]
            # matchedDN
            + [0x04] + [len('')] + l('')
            # errorMessage
            + [0x04] + [len('the foobar was fubar')] +
            l('the foobar was fubar', )
            # referral, TODO
            + []),
        (
            pureldap.LDAPMessage,
            [],
            {
                'id': 42,
                'value': pureldap.LDAPBindRequest(),
            },
            pureldap.LDAPBERDecoderContext_TopLevel(
                inherit=pureldap.LDAPBERDecoderContext_LDAPMessage(
                    fallback=pureldap.LDAPBERDecoderContext(
                        fallback=pureber.BERDecoderContext()),
                    inherit=pureldap.LDAPBERDecoderContext(
                        fallback=pureber.BERDecoderContext()))),
            [0x30, 12]
            # id
            + [0x02, 0x01, 42]
            # value
            + l(str(pureldap.LDAPBindRequest()))),
        (
            pureldap.LDAPControl,
            [],
            {
                'controlType': '1.2.3.4',
            },
            None,
            [0x30, 9]
            # controlType
            + [0x04, 7] + l("1.2.3.4")),
        (
            pureldap.LDAPControl,
            [],
            {
                'controlType': '1.2.3.4',
                'criticality': True,
            },
            None,
            [0x30, 12]
            # controlType
            + [0x04, 7] + l("1.2.3.4")
            # criticality
            + [0x01, 1, 0xFF]),
        (
            pureldap.LDAPControl,
            [],
            {
                'controlType': '1.2.3.4',
                'criticality': True,
                'controlValue': 'silly',
            },
            None,
            [0x30, 19]
            # controlType
            + [0x04, 7] + l("1.2.3.4")
            # criticality
            + [0x01, 1, 0xFF]
            # controlValue
            + [0x04, len("silly")] + l("silly")),
        (
            pureldap.LDAPMessage,
            [],
            {
                'id':
                42,
                'value':
                pureldap.LDAPBindRequest(),
                'controls': [
                    ('1.2.3.4', None, None),
                    ('2.3.4.5', False),
                    ('3.4.5.6', True, '\x00\x01\x02\xFF'),
                ],
            },
            pureldap.LDAPBERDecoderContext_TopLevel(
                inherit=pureldap.LDAPBERDecoderContext_LDAPMessage(
                    fallback=pureldap.LDAPBERDecoderContext(
                        fallback=pureber.BERDecoderContext()),
                    inherit=pureldap.LDAPBERDecoderContext(
                        fallback=pureber.BERDecoderContext()))),
            [0x30, 59]
            # id
            + [0x02, 0x01, 42]
            # value
            + l(str(pureldap.LDAPBindRequest()))
            # controls
            + l(
                str(
                    pureldap.LDAPControls(value=[
                        pureldap.LDAPControl(controlType='1.2.3.4'),
                        pureldap.LDAPControl(controlType='2.3.4.5',
                                             criticality=False),
                        pureldap.LDAPControl(controlType='3.4.5.6',
                                             criticality=True,
                                             controlValue='\x00\x01\x02\xFF'),
                    ]))),
        ),
        (pureldap.LDAPFilter_equalityMatch, [], {
            'attributeDesc': pureldap.LDAPAttributeDescription('cn'),
            'assertionValue': pureldap.LDAPAssertionValue('foo'),
        },
         pureldap.LDAPBERDecoderContext_Filter(
             fallback=pureldap.LDAPBERDecoderContext(
                 fallback=pureber.BERDecoderContext()),
             inherit=pureldap.LDAPBERDecoderContext(
                 fallback=pureber.BERDecoderContext())),
         [0xa3, 9] + ([0x04, 2] + l('cn') + [0x04, 3] + l('foo'))),
        (pureldap.LDAPFilter_or, [[
            pureldap.LDAPFilter_equalityMatch(
                attributeDesc=pureldap.LDAPAttributeDescription('cn'),
                assertionValue=pureldap.LDAPAssertionValue('foo')),
            pureldap.LDAPFilter_equalityMatch(
                attributeDesc=pureldap.LDAPAttributeDescription('uid'),
                assertionValue=pureldap.LDAPAssertionValue('foo')),
            pureldap.LDAPFilter_equalityMatch(
                attributeDesc=pureldap.LDAPAttributeDescription('mail'),
                assertionValue=pureldap.LDAPAssertionValue('foo')),
            pureldap.LDAPFilter_substrings(
                type='mail',
                substrings=[pureldap.LDAPFilter_substrings_initial('foo@')]),
        ]], {},
         pureldap.LDAPBERDecoderContext_Filter(
             fallback=pureldap.LDAPBERDecoderContext(
                 fallback=pureber.BERDecoderContext()),
             inherit=pureldap.LDAPBERDecoderContext(
                 fallback=pureber.BERDecoderContext())), [0xA1, 52] +
         ([0xa3, 9] +
          ([0x04, 2] + l('cn') + [0x04, 3] + l('foo')) + [0xa3, 10] +
          ([0x04, 3] + l('uid') + [0x04, 3] + l('foo')) + [0xa3, 11] +
          ([0x04, 4] + l('mail') + [0x04, 3] + l('foo')) + [0xa4, 14] +
          ([0x04, 4] + l('mail') + [0x30, 6] + ([0x80, 4] + l('foo@'))))),
        (pureldap.LDAPSearchRequest, [], {
            'baseObject':
            'dc=example,dc=com',
            'scope':
            pureldap.LDAP_SCOPE_wholeSubtree,
            'derefAliases':
            pureldap.LDAP_DEREF_neverDerefAliases,
            'sizeLimit':
            1,
            'timeLimit':
            0,
            'typesOnly':
            False,
            'filter':
            pureldap.LDAPFilter_or([
                pureldap.LDAPFilter_equalityMatch(
                    attributeDesc=pureldap.LDAPAttributeDescription('cn'),
                    assertionValue=pureldap.LDAPAssertionValue('foo')),
                pureldap.LDAPFilter_equalityMatch(
                    attributeDesc=pureldap.LDAPAttributeDescription('uid'),
                    assertionValue=pureldap.LDAPAssertionValue('foo')),
                pureldap.LDAPFilter_equalityMatch(
                    attributeDesc=pureldap.LDAPAttributeDescription('mail'),
                    assertionValue=pureldap.LDAPAssertionValue('foo')),
                pureldap.LDAPFilter_substrings(
                    type='mail',
                    substrings=[
                        pureldap.LDAPFilter_substrings_initial('foo@')
                    ]),
            ]),
            'attributes': [''],
        },
         pureldap.LDAPBERDecoderContext_LDAPMessage(
             fallback=pureldap.LDAPBERDecoderContext(
                 fallback=pureber.BERDecoderContext()),
             inherit=pureldap.LDAPBERDecoderContext(
                 fallback=pureber.BERDecoderContext())), [0x63, 92] +
         ([0x04, 17] + l('dc=example,dc=com') + [0x0a, 1, 0x02] +
          [0x0a, 1, 0x00] + [0x02, 1, 0x01] + [0x02, 1, 0x00] +
          [0x01, 1, 0x00] + [0xA1, 52] +
          ([0xa3, 9] +
           ([0x04, 2] + l('cn') + [0x04, 3] + l('foo')) + [0xa3, 10] +
           ([0x04, 3] + l('uid') + [0x04, 3] + l('foo')) + [0xa3, 11] +
           ([0x04, 4] + l('mail') + [0x04, 3] + l('foo')) + [0xa4, 14] +
           ([0x04, 4] + l('mail') + [0x30, 6] +
            ([0x80, 4] + l('foo@')))) + [0x30, 2] + ([0x04, 0]))),
        (
            pureldap.LDAPMessage,
            [],
            {
                'id':
                1L,
                'value':
                pureldap.LDAPSearchRequest(
                    baseObject='dc=example,dc=com',
                    scope=pureldap.LDAP_SCOPE_wholeSubtree,
                    derefAliases=pureldap.LDAP_DEREF_neverDerefAliases,
                    sizeLimit=1,
                    timeLimit=0,
                    typesOnly=False,
                    filter=pureldap.LDAPFilter_or([
                        pureldap.LDAPFilter_equalityMatch(
                            attributeDesc=pureldap.LDAPAttributeDescription(
                                'cn'),
                            assertionValue=pureldap.LDAPAssertionValue('foo')),
                        pureldap.LDAPFilter_equalityMatch(
                            attributeDesc=pureldap.LDAPAttributeDescription(
                                'uid'),
                            assertionValue=pureldap.LDAPAssertionValue('foo')),
                        pureldap.LDAPFilter_equalityMatch(
                            attributeDesc=pureldap.LDAPAttributeDescription(
                                'mail'),
                            assertionValue=pureldap.LDAPAssertionValue('foo')),
                        pureldap.LDAPFilter_substrings(
                            type='mail',
                            substrings=[
                                pureldap.LDAPFilter_substrings_initial('foo@')
                            ]),
                    ]),
                    attributes=[''],
                ),
            },
            pureldap.LDAPBERDecoderContext_TopLevel(
                inherit=pureldap.LDAPBERDecoderContext_LDAPMessage(
                    fallback=pureldap.LDAPBERDecoderContext(
                        fallback=pureber.BERDecoderContext()),
                    inherit=pureldap.LDAPBERDecoderContext(
                        fallback=pureber.BERDecoderContext()))),
            [0x30, 97]
            # id
            + [0x02, 1, 1]
            # value
            + [0x63, 92] +
            ([0x04, 17] + l('dc=example,dc=com') + [0x0a, 1, 0x02] +
             [0x0a, 1, 0x00] + [0x02, 1, 0x01] + [0x02, 1, 0x00] +
             [0x01, 1, 0x00] + [0xA1, 52] +
             ([0xa3, 9] +
              ([0x04, 2] + l('cn') + [0x04, 3] + l('foo')) + [0xa3, 10] +
              ([0x04, 3] + l('uid') + [0x04, 3] + l('foo')) + [0xa3, 11] +
              ([0x04, 4] + l('mail') + [0x04, 3] + l('foo')) + [0xa4, 14] +
              ([0x04, 4] + l('mail') + [0x30, 6] +
               ([0x80, 4] + l('foo@')))) + [0x30, 2] + ([0x04, 0]))),
        (pureldap.LDAPExtendedRequest, [], {
            'requestName': '42.42.42',
            'requestValue': 'foo',
        }, None, [0x40 | 0x20 | 23, 1 + 1 + 8 + 1 + 1 + 3] +
         ([0x80 | 0] + [len('42.42.42')] + l('42.42.42')) +
         ([0x80 | 1] + [len('foo')] + l('foo'))),
    )

    def testToLDAP(self):
        """str(LDAPClass(...)) should give known result with known input"""
        for klass, args, kwargs, decoder, encoded in self.knownValues:
            result = klass(*args, **kwargs)
            result = str(result)
            result = map(ord, result)
            if result != encoded:
                raise AssertionError, \
                      "Class %s(*%s, **%s) doesn't encode properly: " \
                      "%s != %s" % (klass.__name__,
                                    repr(args), repr(kwargs),
                                    repr(result), repr(encoded))

    def testFromLDAP(self):
        """LDAPClass(encoded="...") should give known result with known input"""
        for klass, args, kwargs, decoder, encoded in self.knownValues:
            if decoder is None:
                decoder = pureldap.LDAPBERDecoderContext(
                    fallback=pureber.BERDecoderContext())
            m = s(*encoded)
            result, bytes = pureber.berDecodeObject(decoder, m)
            self.assertEquals(bytes, len(m))

            shouldBe = klass(*args, **kwargs)
            #TODO shouldn't use str below
            assert str(result)==str(shouldBe), \
                   "Class %s(*%s, **%s) doesn't decode properly: " \
                   "%s != %s" % (klass.__name__,
                                 repr(args), repr(kwargs),
                                 repr(result), repr(shouldBe))

    def testPartial(self):
        """LDAPClass(encoded="...") with too short input should throw BERExceptionInsufficientData"""
        for klass, args, kwargs, decoder, encoded in self.knownValues:
            if decoder is None:
                decoder = pureldap.LDAPBERDecoderContext(
                    fallback=pureber.BERDecoderContext())
            for i in xrange(1, len(encoded)):
                m = s(*encoded)[:i]
                self.assertRaises(pureber.BERExceptionInsufficientData,
                                  pureber.berDecodeObject, decoder, m)
            self.assertEquals((None, 0), pureber.berDecodeObject(decoder, ''))