Some little python code to visualize an LDAP structure.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

143 lines
4.7 KiB

#!/usr/bin/python
import time
import random
import mmap
import sys, getopt
from struct import pack
from collections import deque
from os.path import dirname, realpath
from sys import argv, path
path.append(dirname(realpath(__file__)) + '/lib')
from Server import Server
from Event.EventHandler import EventHandler
from Event.EventDispatcher import EventDispatcher
from Communication.EndPoint import CommunicationEndPoint
from Protocol.Http.Http import Http
from Protocol.Websocket.Websocket import Websocket
from LdapTree import LdapTree
class Application(EventHandler):
def __init__(self, hosturi, binddn, basedn, password):
super(Application, self).__init__()
self._event_methods = {
EventDispatcher.eventId('heartbeat') : self._heartbeat,
CommunicationEndPoint.eventId('new_msg') : self._handle_data,
CommunicationEndPoint.eventId('close') : self._handle_close,
CommunicationEndPoint.eventId('upgrade') : self._upgrade
}
self._websockets = []
self._wstest = open('websocket.html', 'r+b')
self._wstestmm = mmap.mmap(self._wstest.fileno(), 0)
random.seed()
self.ldaptree = LdapTree(hosturi, binddn, basedn, password, False)
def __del__(self):
self._wstestmm.close()
self._wstest.close()
def _upgrade(self, event):
self._websockets.append(event.subject)
# let other also handle the upgrade .. no return True
def _heartbeat(self, event):
now = pack('!d', time.time())
for event.subject in self._websockets:
self.issueEvent(event.subject, 'send_msg', now)
return True
def _handle_data(self, event):
protocol = event.subject.getProtocol()
if event.subject.hasProtocol(Http):
if event.data.isRequest():
if event.data.getUri() == '/':
resp = protocol.createResponse(event.data, 200, 'OK')
resp.setBody(self._wstestmm[0:])
elif event.data.getUri() == '/ldap':
resp = protocol.createResponse(event.data, 200, 'OK')
resp.setHeader('Content-Type', 'image/svg+xml')
resp.setBody(self.ldaptree.graph())
else:
resp = protocol.createResponse(event.data, 404, 'Not Found')
resp.setBody('<h1>404 - Not Found</h1>')
self.issueEvent(event.subject, 'send_msg', resp)
return True
def _handle_close(self, event):
if event.subject in self._websockets:
print 'websocket closed...'
self._websockets = [w for w in self._websockets if w!=event.subject]
return True
def usage():
print "Usage: " + sys.argv[0] + " ARGUMENT... [OPTIONS]... bindip bindport\n"
print "Start a webserver on the given bindip and bindport. On the page a"
print "tree representation of all DNs starting with a given base DN is"
print "visualized."
print "Only simple binds to the directory with DN and password are supported.\n"
print "ARGUMENTS:\n"
print " {:30s} : {:s}".format('-H, --hosturi=URI', 'The URI to the ldap server to query in the form:')
print " {:30s} {:s}".format('', 'ldap[s]://host.uri[:port]')
print " {:30s} : {:s}".format('-D, --binddn=DN', 'The DN to use for the LDAP bind.')
print " {:30s} : {:s}".format('-p, --password=PASSWORD', 'The password to use for the LDAP bind.')
print " {:30s} : {:s}\n".format('-b, --basedn=DN', 'The DN to start the tree with.')
print "OPTIONS:\n"
print " {:30s} : {:s}".format('-h, --help', 'Show this help page')
def main():
try:
opts, args = getopt.getopt(
sys.argv[1:],
'hH:D:b:p:',
['help', 'hosturi=', 'binddn=', 'basedn=', 'password='])
except getopt.GetoptError as err:
print str(err)
usage()
sys.exit(2)
hosturi = binddn = basedn = password = None
for o, a in opts:
if o in ["-h", "--help"]:
usage()
sys.exit(0)
elif o in ["-H", "--hosturi"]:
hosturi = a
elif o in ["-D", "--binddn"]:
binddn = a
elif o in ["-b", "--basedn"]:
basedn = a
elif o in ["-p", "--password"]:
password = a
else:
print "unknown parameter: " + a
usage()
sys.exit(2)
if not hosturi or not binddn or not basedn or not password:
usage()
sys.exit(2)
server = Server(Application(hosturi, binddn, basedn, password))
server.bindTcp(args[0], int(args[1]), Http())
server.start(1.0)
if __name__ == '__main__':
main()
# vim: set ft=python et ts=8 sw=4 sts=4: