Modifications qui seront validées :
modifié : ../app.py nouveau fichier : cloud.py nouveau fichier : common_imports.py nouveau fichier : config.py nouveau fichier : dns.py nouveau fichier : kaz_user.py nouveau fichier : ldap.py nouveau fichier : mattermost.py nouveau fichier : paheko.py nouveau fichier : password.py nouveau fichier : quota.py nouveau fichier : sympa.py nouveau fichier : test.py
This commit is contained in:
341
dockers/apikaz/source/resources/ldap.py
Normal file
341
dockers/apikaz/source/resources/ldap.py
Normal file
@ -0,0 +1,341 @@
|
||||
from resources.common_imports import *
|
||||
|
||||
#les variables globales minimum
|
||||
from resources.config import ldap_admin, ldap_pass, ldap_root, ldap_host
|
||||
|
||||
class Ldap_user(Resource):
|
||||
|
||||
def __init__(self):
|
||||
global ldap_admin, ldap_pass, ldap_root, ldap_host
|
||||
self.ldap_admin = ldap_admin
|
||||
self.ldap_pass = ldap_pass
|
||||
self.ldap_root = ldap_root
|
||||
self.ldap_host = f"ldap://{ldap_host}"
|
||||
|
||||
def _connect_ldap(self):
|
||||
ldap_connection = ldap.initialize(self.ldap_host)
|
||||
ldap_connection.simple_bind_s("cn={},{}".format(self.ldap_admin, self.ldap_root), self.ldap_pass)
|
||||
return ldap_connection
|
||||
|
||||
@classmethod
|
||||
def is_valid_field(cls, field):
|
||||
allowed_fields = ['mailDeSecours', 'mailEnabled', 'nextcloudEnabled', 'mobilizonEnabled', 'agoraEnabled', 'userPassword', 'identifiantKaz', 'mailAlias', 'quota']
|
||||
return field in allowed_fields
|
||||
|
||||
@jwt_required()
|
||||
def get(self, email):
|
||||
"""
|
||||
Vérifier si un utilisateur avec cet email existe dans le LDAP soit comme mail principal soit comme alias
|
||||
---
|
||||
tags:
|
||||
- Ldap
|
||||
security:
|
||||
- Bearer: []
|
||||
parameters:
|
||||
- in: path
|
||||
name: email
|
||||
type: string
|
||||
required: true
|
||||
responses:
|
||||
200:
|
||||
description: Existe
|
||||
400:
|
||||
description: N'existe pas
|
||||
401:
|
||||
description: oops, email invalide
|
||||
402:
|
||||
description: oops, autre erreur
|
||||
|
||||
"""
|
||||
try:
|
||||
|
||||
if not validate_email(email):
|
||||
return "Adresse e-mail non valide", 400
|
||||
|
||||
ldap_connection = self._connect_ldap()
|
||||
|
||||
#result = ldap_connection.search_s("ou=users,{}".format(self.ldap_root), ldap.SCOPE_SUBTREE, "(cn={})".format(email))
|
||||
|
||||
# Créer une chaîne de filtre pour rechercher dans les champs "cn" et "mailAlias"
|
||||
filter_str = "(|(cn={})(mailAlias={}))".format(email, email)
|
||||
result = ldap_connection.search_s("ou=users,{}".format(self.ldap_root), ldap.SCOPE_SUBTREE, filter_str)
|
||||
|
||||
ldap_connection.unbind_s()
|
||||
|
||||
if result:
|
||||
return True, 200
|
||||
else:
|
||||
return False, 400
|
||||
|
||||
except EmailNotValidError as e:
|
||||
return str(e), 401
|
||||
|
||||
except ldap.LDAPError as e:
|
||||
return str(e), 402
|
||||
|
||||
|
||||
#*************************************************
|
||||
@jwt_required()
|
||||
def delete(self, email):
|
||||
"""
|
||||
Supprimer un utilisateur du LDAP par son adresse e-mail
|
||||
---
|
||||
tags:
|
||||
- Ldap
|
||||
security:
|
||||
- Bearer: []
|
||||
parameters:
|
||||
- in: path
|
||||
name: email
|
||||
type: string
|
||||
required: true
|
||||
responses:
|
||||
200:
|
||||
description: Utilisateur supprimé avec succès
|
||||
404:
|
||||
description: Utilisateur non trouvé dans le LDAP
|
||||
400:
|
||||
description: Erreur lors de la suppression de l'utilisateur
|
||||
"""
|
||||
try:
|
||||
if not validate_email(email):
|
||||
return "Adresse e-mail non valide", 400
|
||||
|
||||
ldap_connection = self._connect_ldap()
|
||||
|
||||
# Recherche de l'utilisateur
|
||||
result = ldap_connection.search_s("ou=users,{}".format(self.ldap_root), ldap.SCOPE_SUBTREE, "(cn={})".format(email))
|
||||
|
||||
if not result:
|
||||
return False, 404 # Utilisateur non trouvé
|
||||
|
||||
# Récupération du DN de l'utilisateur
|
||||
dn = result[0][0]
|
||||
|
||||
# Suppression de l'utilisateur
|
||||
ldap_connection.delete_s(dn)
|
||||
ldap_connection.unbind_s()
|
||||
|
||||
return True, 200 # Utilisateur supprimé avec succès
|
||||
|
||||
except ldap.NO_SUCH_OBJECT:
|
||||
return False, 404 # Utilisateur non trouvé
|
||||
except ldap.LDAPError as e:
|
||||
return str(e), 400 # Erreur lors de la suppression
|
||||
except EmailNotValidError as e:
|
||||
return str(e), 400
|
||||
|
||||
|
||||
#*************************************************
|
||||
@jwt_required()
|
||||
def post(self, email):
|
||||
"""
|
||||
Ajouter, supprimer ou modifier un champ pour l'utilisateur LDAP
|
||||
---
|
||||
tags:
|
||||
- Ldap
|
||||
security:
|
||||
- Bearer: []
|
||||
parameters:
|
||||
- in: path
|
||||
name: email
|
||||
type: string
|
||||
required: true
|
||||
- in: query
|
||||
name: action
|
||||
type: string
|
||||
required: true
|
||||
enum: ['add', 'delete', 'modify']
|
||||
- in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
field:
|
||||
type: string
|
||||
enum: ['mailDeSecours', 'mailEnabled', 'nextcloudEnabled', 'mobilizonEnabled', 'agoraEnabled', 'userPassword', 'identifiantKaz', 'mailAlias', 'quota']
|
||||
description: Le champ à ajouter, supprimer ou modifier (par exemple, mailDeSecours, mailAlias, etc.)
|
||||
value:
|
||||
type: string
|
||||
description: La valeur à ajouter, supprimer ou modifier pour le champ spécifié
|
||||
responses:
|
||||
200:
|
||||
description: Opération réussie
|
||||
404:
|
||||
description: Utilisateur non trouvé dans le LDAP
|
||||
400:
|
||||
description: Erreur lors de l'opération
|
||||
"""
|
||||
|
||||
try:
|
||||
if not validate_email(email):
|
||||
return "Adresse e-mail non valide", 400
|
||||
|
||||
action = request.args.get('action')
|
||||
field = request.json.get('field')
|
||||
value = request.json.get('value')
|
||||
|
||||
if not action or not field or not value:
|
||||
return "Action, champ ou valeur manquant", 400
|
||||
|
||||
if not self.is_valid_field(field):
|
||||
return "Champ non autorisé", 400
|
||||
|
||||
ldap_connection = self._connect_ldap()
|
||||
result = ldap_connection.search_s("ou=users,{}".format(self.ldap_root), ldap.SCOPE_SUBTREE, "(cn={})".format(email))
|
||||
|
||||
if not result:
|
||||
return False, 404
|
||||
|
||||
dn = result[0][0]
|
||||
|
||||
if field == 'userPassword' and (action == 'add' or action == 'modify'):
|
||||
password_chiffre = sha512_crypt.hash(value)
|
||||
value = "{{CRYPT}}{}".format(password_chiffre)
|
||||
|
||||
if action == 'add':
|
||||
mod_attrs = [(ldap.MOD_ADD, field, value.encode('utf-8'))]
|
||||
|
||||
elif action == 'delete':
|
||||
mod_attrs = [(ldap.MOD_DELETE, field, value.encode('utf-8'))]
|
||||
|
||||
elif action == 'modify':
|
||||
|
||||
if field == 'quota':
|
||||
mail_quota_value = value + 'G'
|
||||
nextcloud_quota_value = value + " GB"
|
||||
mod_attrs = [
|
||||
(ldap.MOD_REPLACE, 'quota', value.encode('utf-8')),
|
||||
(ldap.MOD_REPLACE, 'mailQuota', mail_quota_value.encode('utf-8')),
|
||||
(ldap.MOD_REPLACE, 'nextcloudQuota', nextcloud_quota_value.encode('utf-8'))
|
||||
]
|
||||
else:
|
||||
mod_attrs = [(ldap.MOD_REPLACE, field, value.encode('utf-8'))]
|
||||
|
||||
else:
|
||||
return "Action non valide", 400
|
||||
|
||||
ldap_connection.modify_s(dn, mod_attrs)
|
||||
ldap_connection.unbind_s()
|
||||
|
||||
return True, 200
|
||||
|
||||
except ldap.NO_SUCH_OBJECT:
|
||||
return False, 404
|
||||
except ldap.LDAPError as e:
|
||||
return str(e), 400
|
||||
except EmailNotValidError as e:
|
||||
return str(e), 400
|
||||
|
||||
#*************************************************
|
||||
@jwt_required()
|
||||
def put(self, email, **kwargs):
|
||||
"""
|
||||
Créer une nouvelle entrée dans le LDAP pour un nouvel utilisateur. QUESTION: A QUOI SERVENT PRENOM/NOM/IDENT_KAZ DANS LE LDAP ? POURQUOI 3 QUOTA ?
|
||||
---
|
||||
tags:
|
||||
- Ldap
|
||||
security:
|
||||
- Bearer: []
|
||||
parameters:
|
||||
- in: path
|
||||
name: email
|
||||
type: string
|
||||
required: true
|
||||
- in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
prenom:
|
||||
type: string
|
||||
description: Prénom de l'utilisateur
|
||||
nom:
|
||||
type: string
|
||||
description: Nom de l'utilisateur
|
||||
password:
|
||||
type: string
|
||||
description: Mot de passe de l'utilisateur
|
||||
email_secours:
|
||||
type: string
|
||||
description: Adresse e-mail de secours
|
||||
quota:
|
||||
type: string
|
||||
description: Quota de l'utilisateur
|
||||
responses:
|
||||
200:
|
||||
description: Utilisateur ajouté avec succès
|
||||
400:
|
||||
description: Erreur lors de l'ajout de l'utilisateur
|
||||
406:
|
||||
description: Erreur utilisateur déjà existant
|
||||
|
||||
"""
|
||||
try:
|
||||
|
||||
if kwargs: # appel depuis une autre api
|
||||
email_secours = kwargs.get('email_secours')
|
||||
prenom = kwargs.get('prenom')
|
||||
nom = kwargs.get('nom')
|
||||
password = kwargs.get('password')
|
||||
quota = kwargs.get('quota')
|
||||
|
||||
else: # appel depuis swagger
|
||||
email_secours = request.json.get('email_secours')
|
||||
nom = request.json.get('nom')
|
||||
prenom = request.json.get('prenom')
|
||||
password = request.json.get('password')
|
||||
quota = request.json.get('quota')
|
||||
|
||||
password_chiffre = sha512_crypt.hash(password)
|
||||
|
||||
if not validate_email(email) or not validate_email(email_secours):
|
||||
return "Adresse e-mail ou secours non valide", 400
|
||||
|
||||
#le user existe t-il déjà ?
|
||||
ldap_connection = self._connect_ldap()
|
||||
result = ldap_connection.search_s("ou=users,{}".format(self.ldap_root), ldap.SCOPE_SUBTREE, "(cn={})".format(email))
|
||||
|
||||
if result:
|
||||
return "User déjà existant", 406
|
||||
|
||||
# Construire le DN
|
||||
dn = f"cn={email},ou=users,{ldap_root}"
|
||||
|
||||
mod_attrs = [
|
||||
('objectClass', [b'inetOrgPerson', b'PostfixBookMailAccount', b'nextcloudAccount', b'kaznaute']),
|
||||
('sn', f'{prenom} {nom}'.encode('utf-8')),
|
||||
('mail', email.encode('utf-8')),
|
||||
('mailEnabled', b'TRUE'),
|
||||
('mailGidNumber', b'5000'),
|
||||
('mailHomeDirectory', f"/var/mail/{email.split('@')[1]}/{email.split('@')[0]}/".encode('utf-8')),
|
||||
('mailQuota', f'{quota}G'.encode('utf-8')),
|
||||
('mailStorageDirectory', f"maildir:/var/mail/{email.split('@')[1]}/{email.split('@')[0]}/".encode('utf-8')),
|
||||
('mailUidNumber', b'5000'),
|
||||
('mailDeSecours', email_secours.encode('utf-8')),
|
||||
('identifiantKaz', f'{prenom.lower()}.{nom.lower()}'.encode('utf-8')),
|
||||
('quota', str(quota).encode('utf-8')),
|
||||
('nextcloudEnabled', b'TRUE'),
|
||||
('nextcloudQuota', f'{quota} GB'.encode('utf-8')),
|
||||
('mobilizonEnabled', b'TRUE'),
|
||||
('agoraEnabled', b'TRUE'),
|
||||
('userPassword', f'{{CRYPT}}{password_chiffre}'.encode('utf-8')),
|
||||
('cn', email.encode('utf-8'))
|
||||
]
|
||||
|
||||
ldap_connection.add_s(dn, mod_attrs)
|
||||
ldap_connection.unbind_s()
|
||||
|
||||
return "Utilisateur créé dand le ldap", 200
|
||||
|
||||
except ldap.LDAPError as e:
|
||||
return str(e), 400
|
||||
except EmailNotValidError as e:
|
||||
return str(e), 400
|
||||
|
||||
#*************************************************
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user