#!/usr/bin/python # -*- coding: utf8 -*- import sys, os, cgi appbase = os.path.dirname(os.path.abspath(__file__)) sys.path.append(appbase) import threading import cherrypy from tmpl import expose, render from lxml import etree from lxml.html import formfill from StringIO import StringIO import ldap import mx.DateTime, urllib from accountservice import accountservice import ticket tgt_sites = ['wiki'] class ldapobj(object): def __init__(s, data): if len(data) != 1: raise ValueError, "invalid number of results" dn, fields = data[0] s._keys = fields.keys() for k, v in fields.iteritems(): s.__dict__[k] = v s.dn = dn def __getitem__(s, key): l = s.__dict__[key] if len(l) != 1: raise IndexError, "invalid number of attributes" return l[0] def keys(s): return s._keys class LoginError(Exception): pass class SubdapSite(object): def __init__(s): cherrypy.config.update({'error_page.404': s.http_404}) @expose('error.html') def http_404(s, status, message, **kwargs): return render(details = status + ' - ' + message) @expose('login.html') def index(s): return render(errors = {}) def login_perform(s, username, password): dn = "cn=%s,ou=people,dc=sublab,dc=org" % (username) try: l = ldap.initialize('ldaps://taifun.local.sublab.org/') l.simple_bind_s(dn, password) except ldap.INVALID_CREDENTIALS: raise LoginError('Login incorrect') except ldap.LDAPError, e: raise LoginError('Login incorrect') # e.message['info'] return (l, dn) @expose('login.html') def login(s, username = None, password = None): if username == None or password == None: return render(errors = {'password': 'Login incorrect'}) if username == '' or password == '': return render(errors = {'password': 'Login incorrect'}) try: l, dn = s.login_perform(username, password) except LoginError, e: return render(errors = {'password': str(e)}) user = ldapobj(l.search_s(dn, ldap.SCOPE_BASE, '(objectclass=*)', [])) tgts = {} for site in tgt_sites: tgts[site] = urllib.urlencode(ticket.tgt_create(site, user['cn'])) return render('select.html', user = user, tgts = tgts) ## x = '' # for r in data: # if r[0] != dn: # continue ## x += '%s\n' % (r[0]) # for k, v in r[1].iteritems(): # for value in v: # details.append([k, value]) ## x += '%s
%s
\n' % (k, "
".join(v)) def params_validate(s, errors, username, password, password2): errors = {} if username == None or username == '': errors['username'] = 'please specify an user name' elif accountservice.name_valid(username) != 'valid': errors['username'] = 'username invalid or taken' if password == None or len(password) < 6: errors['password'] = 'please specify a password of at least 6 characters' if password2 != password: errors['password2'] = 'passwords did not match' if len(errors) > 0: return errors return None @expose('create.html') def create(s, username = None, password = None, password2 = None): if cherrypy.request.method.upper() == 'GET': return render(errors = {}, username = '') errors = s.params_validate(errors, username, password, password2) if errors is not None: return render(errors = errors, username = username) accountservice.name_create(username, password) return s.login(username, password) @cherrypy.expose def kill(s): import sys sys.exit(0) config = { 'global': { 'server.socket_port': 8080, 'server.socket_host': '127.0.0.1', # 'server.socket_host': '::1', 'tools.staticdir.root': appbase, }, '/': { 'tools.decode.on': True, 'tools.encode.on': True, 'tools.gzip.on': True, 'tools.proxy.on': True, # 'tools.caching.on': False, # 'tools.expires.secs': 0, # 'tools.expires.force': True, }, '/static': { 'tools.staticdir.on': True, 'tools.staticdir.dir': 'static', }, } if len(sys.argv) >= 2 and sys.argv[1] == 'standalone': cherrypy.quickstart(SubdapSite(), "/", config) else: cherrypy.config.update({'environment': 'embedded'}) application = cherrypy.Application(SubdapSite(), script_name = None, config = config)