# -*- coding: utf-8 -*-
###########################################################################
# Eole NG - 2007
# Copyright Pole de Competence Eole  (Ministere Education - Academie Dijon)
# Licence CeCill  cf /root/LicenceEole.txt
# eole@ac-dijon.fr
#
# ldap_user.py
#
#  Utilitaire de gestion d'utilisateurs LDAP pour zephir
#
###########################################################################

import sys
from os.path import isfile
import ldap
import hashlib
from creole.utils import print_red
from creole.client import CreoleClient
from pyeole.ssha import ssha_encode

# configuration ldap (adresse serveur)
LDAPCONF = '/etc/eole/eoleldap.conf'
if isfile(LDAPCONF):
    exec(compile(open(LDAPCONF, "rb").read(), LDAPCONF, 'exec'))
else:
    raise Exception("Fichier %s non trouvé" % LDAPCONF)

ldap_server = "ldap://{}".format(ldap_server)

def check_local_ldap_admin_password():
    eoleconf = CreoleClient()
    if eoleconf.get_creole('activer_client_ldap') != 'local':
        return True

    # Login is hardcoded at several places
    # login = eoleconf['admin_zephir']
    login = 'admin'
    base_dn = eoleconf.get_creole('ldap_base_dn')
    admin_dn = 'cn={0},{1}'.format(login, base_dn)
    # vérification de l'authentification
    try:
        l = ldap.initialize(ldap_server)
        l.simple_bind_s(admin_dn, ldap_passwd)
    except:
        print_red("\nLe mot de passe ldap stocké est invalide\nlancez reconfigure pour le réinitialiser\n")
        sys.exit(1)


def encrypt_passwd(passwd):
    return ssha_encode(passwd).decode()

def add_user(login, passwd):
    if isinstance(passwd, bytes):
        passwd = passwd.decode()
    l = ldap.initialize(ldap_server)
    try:
        l.simple_bind_s('cn=admin,o=gouv,c=fr', ldap_passwd)
    except:
        sys.exit("\nerreur d'authentification\n")

    # si la racine n'existe pas, on la crée
    try:
        result = l.search_s("o=gouv, c=fr", ldap.SCOPE_SUBTREE,"(&(objectClass=organization)(o=gouv))")
    except ldap.NO_SUCH_OBJECT:
        result = []
    if result == []:
        l.add_s('o=gouv,c=fr', [('objectClass','organization'),('o','gouv'),('description','Gouvernemental')])
    # si le mot de passe n'est pas chiffré, on lance le chiffrement
    if not passwd.startswith('{SSHA}'):
        passwd = encrypt_passwd(passwd)

    # on regarde si l'utilisateur existe
    result = l.search_s("o=gouv, c=fr", ldap.SCOPE_SUBTREE,"(&(objectClass=OpenLDAPperson)(uid="+login+"))")
    if result == []:
        # si non on le crée
        try:
            if isinstance(passwd, str):
                passwd = passwd.encode()
            l.add_s('uid='+login+',o=gouv,c=fr', [('objectClass',b'OpenLDAPperson'),('uid',login.encode()),('cn',login.encode()),('sn',login.encode()),('UserPassword', passwd)])
        except:
            print("\nerreur d'authentification\n")
    else:
        # si il existe déjà on modifie son mot de passe
        try:
            l.modify_s('uid='+login+',o=gouv,c=fr', [(ldap.MOD_REPLACE,'UserPassword', passwd.encode())])
        except:
            print("\nerreur d'authentification\n")

    l.unbind()

def del_user(login):
    l = ldap.initialize(ldap_server)
    try:
        l.simple_bind_s('cn=admin,o=gouv,c=fr',ldap_passwd)
    except:
        sys.exit("\nerreur d'authentification\n")

    # si la racine n'existe pas, on la crée
    result = l.search_s("o=gouv, c=fr", ldap.SCOPE_SUBTREE,"(&(objectClass=OpenLDAPperson)(uid=%s))" % login)
    if len(result) != 1:
        print("\nerreur, cet utilisateur n'existe pas\n")
        return 0
    else:
        # si il existe, on le supprime
        try:
            l.delete_s(result[0][0])
        except:
            return 0
        else:
            return 1

    l.unbind()

def list_user():
    l = ldap.initialize(ldap_server)
    try:
        l.simple_bind_s('cn=admin,o=gouv,c=fr',ldap_passwd)
    except:
        sys.exit("\nerreur d'authentification\n")

    # si la racine n'existe pas, on la crée
    result = l.search_s("o=gouv, c=fr", ldap.SCOPE_SUBTREE,"(objectClass=OpenLDAPperson)")
    l.unbind()
    if result == []:
        print("\n Aucun utilisateur trouvé dans l'annuaire local\n")
    else:
        # on affiche tous les utilisateurs
        print("\n liste des utilisateurs zephir :\n")
        for user in result:
            print("- " + user[1]['cn'][0].decode("utf-8"))
        print("\n")
