#!/usr/bin/python2.3

from ldaptor.apps import webui
from ldaptor.apps.webui import gadget
from ldaptor import cred

from twisted.internet import main, app
from twisted.web import server, guard
from ldaptor import usage
from twisted.python import log

class MyOptions(usage.Options, usage.Options_service_location, usage.Options_base):
    """LDAPtor Web User Interface"""

    def __init__(self, *args, **kwargs):
	usage.Options.__init__(self, *args, **kwargs)
	self.opts['search-field']=None

    optParameters = (
	('http-port', None, '38980', # think "ldap and http"
	 "listen on this port"),
	('identity-search', None,
	 '(|(cn=%(name)s)(uid=%(name)s))',
	 "unknown identities are searched with this filter"),
	('identity-base', None,
	 None,
	 "unknown identities are searched with this base (defaults to the --base value)"),
	)

    def opt_search_field(self, s):
	"""
	Add extra search fields to search page. Value is of type
	fieldname=ldapfilter, where ldapfilter is expanded according
	to Python %(var)s convention, e.g. name=(cn=%(input)s).
	"""

	try:
	    field, filter = s.split('=', 1)
	except ValueError:
	    raise usage.UsageError, 'search-field value must be of form field=filter'

	if self.opts['search-field'] is None:
	    self.opts['search-field']=[]
	self.opts['search-field'].append((field, filter))

    def postOptions_search_field(self):
	if self.opts['search-field'] is None:
	    self.opts['search-field']=()

    def postOptions_httpport(self):
	try:
	    val = int(self.opts['http-port'])
	except ValueError:
	    raise usage.UsageError, "%s value must be numeric" % 'http-port'
	self.opts['http-port'] = val

if __name__ == '__main__':
    import sys
    try:
	config = MyOptions()
	config.parseOptions()
    except usage.UsageError, ue:
	sys.stderr.write('%s: %s\n' % (sys.argv[0], ue))
	sys.exit(1)
    log.startLogging(sys.stderr, setStdout=0)
    auth = cred.LDAPAuthorizer(
	ldapbase=config.opts['base'],
	serviceLocationOverride=config.opts['service-location'],
	ldapFilterTemplate=config.opts['identity-search'],
	ldapFilterBase=config.opts['identity-base'],
	)
    application = app.Application('ldaptor-webui', authorizer=auth)
    svc = cred.LDAPService("edit", serviceParent=application, authorizer=auth)
    svc.perspectiveClass = cred.LDAPPerspective
    gdgt = gadget.LdaptorWebUIGadget(
	svc,
	serviceLocationOverride=config.opts['service-location'],
	searchFields=config.opts['search-field'],
	)

    sit = server.Site(gdgt)
    sit.application = application
    application.listenTCP(config.opts['http-port'], sit)
    application.run(save=0)
