import logging

from pylons import request, response, session, tmpl_context as c, url, config
from pylons.controllers.util import abort, redirect

from paste.util.converters import aslist

from ppdi.lib.base import BaseController, render
from ppdi.lib import helpers as h
import ldap

log = logging.getLogger(__name__)

class LoginController(BaseController):

    requires_auth = False
    
    def index(self):
        """This is the index landpage"""
        c.domains = []
        for d in config["domains"].split(','):
            c.domains.append(d)
        return render('/component/index.html')

    def login(self):
        username = request.POST['username']
        password = request.POST['password']
        domain = request.POST['domain']
        if username:
            # Authenticate the user!
            Base = config.get('ldap.base')
            
            Scope = ldap.SCOPE_SUBTREE
            Filter = "(&(objectClass=user)(sAMAccountName="+username+"))"
            Attrs = ["displayName", "mail"]

            # Set the LDAP timeout for the connection.
            ldap.set_option(ldap.OPT_NETWORK_TIMEOUT, int(config.get('ldap.timeout')))

            for Server in aslist(config.get('ldap.hosts'), sep=','):
                Server = 'ldap://' + Server
                log.info('Connecting to server: %s' % Server)
                l = ldap.initialize(Server)
                l.protocol_version = 3
                l.set_option(ldap.OPT_REFERRALS, 0)
                try:
                    l.simple_bind_s(username+"@"+domain, password)
                    r = l.search(Base, Scope, Filter, Attrs)
                    Type,user = l.result(r,10)
                    Name,Attrs = user[0]
                    if hasattr(Attrs, 'has_key') and Attrs.has_key('mail'):
                        email = Attrs['mail'][0]
                        session['email'] = email
                    if hasattr(Attrs, 'has_key') and Attrs.has_key('displayName'):
                        displayName = Attrs['displayName'][0]
                        session['displayName'] = displayName

                    session['username'] = username
                    session['domain'] = domain
                    session['logged_in'] = True
                    session.save()
                except ldap.SERVER_DOWN, e:
                    log.warning('Server %s is down!' % Server)

                    if aslist(config.get('ldap.hosts'), sep=',').pop() in Server:
                        # We are the last server, so ...
                        log.critical('All LDAP servers are down. Last server tried was: %s' % Server)
                        msg = 'Active Directory server is down for the moment. Please try again later.'
                        h.flash(msg)
                        location = url(controller='auth/login', action='index')
                        redirect(location)
                    else:
                        continue
                except ldap.INVALID_CREDENTIALS, e:
                    msg = 'Invalid username/password'
                    h.flash(msg)
                    location = url(controller='auth/login', action='index')
                    log.warning('User denied, redirecting to: %s. Error: %s' % (location, e))
                    redirect(location)
                except ldap.LDAPError, e:
                    msg = 'Server error. Try again later.'
                    h.flash(msg)
                    location = url(controller='auth/login', action='index')
                    log.critical('Redirecting to: %s because %s' % (location, e))
                    redirect(location)
                
                # if we get here, user has been authenticated just fine. Break the loop
                break

        else:
            msg = 'Invalid username/password'
            h.flash(msg)
            location = url(controller='auth/login', action='index')

        redirect(session.pop("after_login", url(controller='main/conferences', action='index')))
        
    def logout(self):
        """Log the user out"""
        session.clear()
        session.save()
        h.flash('User logged out.')
        redirect('/')
