import ldap
import config
import db
from model import User


class LDAP:
    def __init__(self, server, base, dn):
        self.server = server
        self.base = base
        self.dn = dn

    def auth(self, username, pw, admin=False):
        self.ldap = ldap.open(self.server)

        if admin:
            dn = "cn=admin" + base
            self.username = ""
        else:
            dn = self.dn % username
            self.username = username

        try:
            self.ldap.simple_bind_s(dn, pw)
        except ldap.INVALID_CREDENTIALS:
            print "[LDAP] '%s' username or password is incorrect." % dn
            return False

        return True

    def _getattr(self, filter):
        return self.ldap.search_s(self.base, ldap.SCOPE_SUBTREE, filterstr=filter) 

    def get_attrs(self, username=""):
        if not username:
            username = self.username

        return self._getattr('uid=' + username)[0][1]

    def set_attr(self, attr, newv, username=""):
        if not username:
            username = self.username

        m = [(ldap.MOD_REPLACE, attr, newv)]
        self.ldap.modify_s(self.dn % username, m)

    def change_passwd(self, oldp, newp, username=""):
        if not username:
            username = self.username

        self.ldap.passwd_s(self, self.dn % username, oldp, newp)


def auth(username, password):
    '''
    Authenticated in LDAP (configured in config) an username with password and
    returns a db user. If user doesn't exists in db it will be created.

    If not auth in LDAP None is return
    '''

    user_mail = ldap_auth(username, password)
    if not user_mail:
        return None

    s = db.connect()
    query = s.query(User).filter(User.name == username)
    if not query.count():
        # user doesn't exists, I'm going to create it
        user = User(name=username, password=password, email=user_mail)
        user.validate_temp_token(user.temp_token)
        s.add(user)
        s.commit()
    else:
        user = query.one()

    return user


def ldap_auth(username, password):
    '''
    Authenticates a user in ldap and returns his email. If user doesn't
    authenticated returns empty string.
    '''
    ld = LDAP(config.LDAP_SERVER, config.LDAP_BASE, config.LDAP_DN)
    if ld.auth(username, password):
        return ld.get_attrs()['mail'][0]
    return ''
