This is a pre-production deployment of Warehouse. Changes made here affect the production instance of PyPI (pypi.python.org).
Help us improve Python packaging - Donate today!

Tool for testing code speaking with LDAP server. Allows to easily configure and run an embedded, in-memory LDAP server. Uses UnboundID LDAP SDK through Py4J.

Project Description

Tool for testing code speaking with LDAP server. Allows to easily configure and run an embedded, in-memory LDAP server. Uses UnboundID LDAP SDK through Py4J. Requires Java runtime on the system path to run the server.

Installation

With pip:

pip install python-ldap-test

When installing from source:

git clone https://github.com/zoldar/python-ldap-test
cd python-ldap-test
python setup.py install # you may need root privileges if installing system-wide

Usage

Example library usage with Python ldap client.

import ldap3

from ldap_test import LdapServer

server = LdapServer()

try:
    server.start()

    dn = server.config['bind_dn']
    pw = server.config['password']

    srv = ldap3.Server('localhost', port=server.config['port'])
    conn = ldap3.Connection(srv, user=dn, password=pw, auto_bind=True)

    base_dn = server.config['base']['dn']
    search_filter = '(objectclass=domain)'
    attrs = ['dc']

    conn.search(base_dn, search_filter, attributes=attrs)

    print conn.response
    # [{
    #    'dn': 'dc=example,dc=com',
    #    'raw_attributes': {'dc': [b'example']},
    #    'attributes': {'dc': ['example']},
    #    'type': 'searchResEntry'
    # }]
finally:
    server.stop()

Another example with non-standard settings:

import ldap3

from ldap_test import LdapServer

server = LdapServer({
    'port': 3333,
    'bind_dn': 'cn=admin,dc=zoldar,dc=net',
    'password': 'pass1',
    'base': {'objectclass': ['domain'],
             'dn': 'dc=zoldar,dc=net',
             'attributes': {'dc': 'zoldar'}},
    'entries': [
        {'objectclass': 'domain',
         'dn': 'dc=users,dc=zoldar,dc=net',
         'attributes': {'dc': 'users'}},
        {'objectclass': 'organization',
         'dn': 'o=foocompany,dc=users,dc=zoldar,dc=net',
         'attributes': {'o': 'foocompany'}},
    ]
})

try:
    server.start()

    dn = "cn=admin,dc=zoldar,dc=net"
    pw = "pass1"

    srv = ldap3.Server('localhost', port=3333)
    conn = ldap3.Connection(srv, user=dn, password=pw, auto_bind=True)

    base_dn = 'dc=zoldar,dc=net'
    search_filter = '(objectclass=organization)'
    attrs = ['o']

    conn.search(base_dn, search_filter, attributes=attrs)

    print conn.response
    # [{
    #    'dn': 'o=foocompany,dc=users,dc=zoldar,dc=net',
    #    'raw_attributes': {'o': [b'foocompany']},
    #    'attributes': {'o': ['foocompany']},
    #    'type': 'searchResEntry'
    # }]
finally:
    server.stop()

And, finally, an example of running multiple LDAP servers:

import ldap3

from ldap_test import LdapServer

servers = {}

try:
    for sid in (1, 2):
        domain = 'example{0}'.format(sid)
        servers[sid] = LdapServer({
            'port': 10389 + (sid * 1000),
            'bind_dn': 'cn=admin,dc={0},dc=com'.format(domain),
            'base': {
                'objectclass': ['domain'],
                'dn': 'dc={0},dc=com'.format(domain),
                'attributes': {'dc': domain}
            },
        })
        servers[sid].start()

    search_filter = '(objectclass=domain)'
    attrs = ['dc']

    # server1
    dn = servers[1].config['bind_dn']
    pw = servers[1].config['password']
    base_dn = servers[1].config['base']['dn']
    port = servers[1].config['port']

    srv = ldap3.Server('localhost', port=port)
    conn = ldap3.Connection(srv, user=dn, password=pw, auto_bind=True)
    conn.search(base_dn, search_filter, attributes=attrs)

    print conn.response
    # [{
    #    'dn': 'dc=example1,dc=com',
    #    'raw_attributes': {'dc': [b'example1']},
    #    'attributes': {'dc': ['example1']},
    #    'type': 'searchResEntry'
    # }]

    conn.unbind()

    # server2
    dn = servers[2].config['bind_dn']
    pw = servers[2].config['password']
    base_dn = servers[2].config['base']['dn']
    port = servers[2].config['port']

    srv = ldap3.Server('localhost', port=port)
    conn = ldap3.Connection(srv, user=dn, password=pw, auto_bind=True)
    conn.search(base_dn, search_filter, attributes=attrs)

    print conn.response
    # [{
    #    'dn': 'dc=example2,dc=com',
    #    'raw_attributes': {'dc': [b'example2']},
    #    'attributes': {'dc': ['example2']},
    #    'type': 'searchResEntry'
    # }]

    conn.unbind()
finally:
    for server in servers.values():
        server.stop()

The initial server configuration is represented by a simple dict, which may contain one or more optional parameters:

  • port - a port on which the LDAP server will listen
  • bind_dn - bind DN entry for authentication
  • password - authentication password
  • base - base DN entry
  • entries - a list of dicts representing intially loaded entries in the database. attributes are optional here
  • ldifs - a list of strings representing file paths to the LDIF files to load on start, like ..., 'ldifs': ['path/to/file1.ldif', 'path/to/file2.ldif'], ...

The format of entry in entries as well as base is following:

{'dn': 'o=some,dc=example,dc=com', # DN identifying the entry
 'objectclass': ['top', 'organization'], # objectclass may be either a
                                         # string in case of a single
                                         # class or a list of classes
 'attributes': {        # attributes are optional
    'o': 'some'         # every attribute may have either a single value
                        # or multiple values in a list like
                        # 'ou': ['Value1', 'Value2', ...]
 }
}

Running Java gateway and proxy on non-standard ports

When there’s a necessity to run proxy and gateway on ports different from the default ones (25333 for Java gateway and 25334 for proxy), the LdapServer may be instantiated with custom ones, passed explicitly to the constructor:

server = LdapServer({...}, java_gateway_port=26333, python_proxy_port=26334)

This can be useful when several test runs are done in parallel on a single system.

Reporting issues

Any issues (be it bugs, feature requests or anything else) can be reported through project’s GitHub issues page.

Contributors

License

Copyright © 2016 Adrian Gruntkowski

Distributed under the MIT License.

Release History

Release History

This version
History Node

0.3.0

History Node

0.2.2

History Node

0.2.1

History Node

0.2.0

History Node

0.1.1

History Node

0.1.0

History Node

0.0.9

History Node

0.0.8

History Node

0.0.7

Download Files

Download Files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

File Name & Checksum SHA256 Checksum Help Version File Type Upload Date
python-ldap-test-0.3.0.tar.gz (1.5 MB) Copy SHA256 Checksum SHA256 Source Sep 11, 2016

Supported By

WebFaction WebFaction Technical Writing Elastic Elastic Search Pingdom Pingdom Monitoring Dyn Dyn DNS Sentry Sentry Error Logging CloudAMQP CloudAMQP RabbitMQ Heroku Heroku PaaS Kabu Creative Kabu Creative UX & Design Fastly Fastly CDN DigiCert DigiCert EV Certificate Rackspace Rackspace Cloud Servers DreamHost DreamHost Log Hosting