This commit is contained in:
2025-07-25 14:49:46 +02:00
parent 27ca4dfce3
commit b4eee312df
5 changed files with 222 additions and 86 deletions

View File

@@ -1,6 +1,7 @@
import ldap import ldap
from passlib.hash import sha512_crypt from passlib.hash import sha512_crypt
from email_validator import validate_email, EmailNotValidError from email_validator import validate_email, EmailNotValidError
import subprocess
from .config import getDockersConfig, getSecretConfig from .config import getDockersConfig, getSecretConfig
@@ -11,7 +12,8 @@ class Ldap:
self.ldap_root = getDockersConfig("ldap_root") self.ldap_root = getDockersConfig("ldap_root")
self.ldap_admin_username = getSecretConfig("ldapServ", "LDAP_ADMIN_USERNAME") self.ldap_admin_username = getSecretConfig("ldapServ", "LDAP_ADMIN_USERNAME")
self.ldap_admin_password = getSecretConfig("ldapServ", "LDAP_ADMIN_PASSWORD") self.ldap_admin_password = getSecretConfig("ldapServ", "LDAP_ADMIN_PASSWORD")
self.ldap_host = "10.0.0.146" cmd="docker inspect -f '{{.NetworkSettings.Networks.ldapNet.IPAddress}}' ldapServ"
self.ldap_host = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT).strip().decode()
def __enter__(self): def __enter__(self):
self.ldap_connection = ldap.initialize(f"ldap://{self.ldap_host}") self.ldap_connection = ldap.initialize(f"ldap://{self.ldap_host}")

122
bin/lib/mattermost.py Normal file
View File

@@ -0,0 +1,122 @@
import subprocess
from .config import getDockersConfig, getSecretConfig
mattermost_user = getSecretConfig("mattermostServ", "MM_ADMIN_USER")
mattermost_pass = getSecretConfig("mattermostServ", "MM_ADMIN_PASSWORD")
mattermost_url = f"https://{getDockersConfig('matterHost')}.{getDockersConfig('domain')}"
mmctl = "docker exec -i mattermostServ bin/mmctl"
class Mattermost:
def __init__(self):
self.authenticate()
def authenticate(self):
# Authentification sur MM
cmd = f"{mmctl} auth login {mattermost_url} --name local-server --username {mattermost_user} --password {mattermost_pass}"
subprocess.run(cmd, shell=True, stderr=subprocess.STDOUT, check=True)
def post_message(self, message, equipe="kaz", canal="creation-comptes"):
"""
Envoyer un message dans une Equipe/Canal de MM
"""
cmd = f"{mmctl} post create {equipe}:{canal} --message \"{message}\""
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
return output.decode()
def get_user(self, user):
"""
Le user existe t-il sur MM ?
"""
try:
cmd = f"{mmctl} user search {user} --json"
user_list_output = subprocess.check_output(cmd, shell=True)
return True # Le nom d'utilisateur existe
except subprocess.CalledProcessError:
return False
def create_user(self, user, email, password):
"""
Créer un utilisateur sur MM
"""
cmd = f"{mmctl} user create --email {email} --username {user} --password {password}"
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
return output.decode()
def delete_user(self, email):
"""
Supprimer un utilisateur sur MM
"""
cmd = f"{mmctl} user delete {email} --confirm"
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
return output.decode()
def update_password(self, email, new_password):
"""
Changer un password pour un utilisateur de MM
"""
cmd = f"{mmctl} user change-password {email} --password {new_password}"
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
return output.decode()
def add_user_to_team(self, email, equipe):
"""
Affecte un utilisateur à une équipe MM
"""
cmd = f"{mmctl} team users add {equipe} {email}"
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
return output.decode()
def add_user_to_channel(self, email, equipe, canal):
"""
Affecte un utilisateur à un canal MM
"""
cmd = f'{mmctl} channel users add {equipe}:{canal} {email}'
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
return output.decode()
def get_teams(self):
"""
Lister les équipes sur MM
"""
cmd = f"{mmctl} team list --disable-pager"
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
data_list = output.decode("utf-8").strip().split('\n')
data_list.pop()
return data_list
def create_team(self, equipe, email):
"""
Créer une équipe sur MM et affecter un admin si email est renseigné (set admin marche pô)
"""
#DANGER: l'option --email ne rend pas le user admin de l'équipe comme c'est indiqué dans la doc :(
cmd = f"{mmctl} team create --name {equipe} --display-name {equipe} --private --email {email}"
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
#Workaround: on récup l'id du user et de l'équipe pour affecter le rôle "scheme_admin": true, "scheme_user": true avec l'api MM classique.
#TODO:
return output.decode()
def delete_tem(self, equipe):
"""
Supprimer une équipe sur MM
"""
cmd = f"{mmctl} team delete {equipe} --confirm"
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
return output.decode()

37
bin/lib/sympa.py Normal file
View File

@@ -0,0 +1,37 @@
import subprocess
from .config import getDockersConfig, getSecretConfig
sympa_user = getSecretConfig("sympaServ", "SOAP_USER")
sympa_pass = getSecretConfig("sympaServ", "SOAP_PASSWORD")
sympa_listmaster = getSecretConfig("sympaServ", "ADMINEMAIL")
sympa_url = f"https://{getDockersConfig('sympaHost')}.{getDockersConfig('domain')}"
sympa_soap = "docker exec -i sympaServ /usr/lib/sympa/bin/sympa_soap_client.pl"
sympa_liste_info = f"info@{getDockersConfig('domain_sympa')}"
# docker exec -i sympaServ /usr/lib/sympa/bin/sympa_soap_client.pl --soap_url=${httpProto}://${URL_LISTE}/sympasoap --trusted_application=${sympa_SOAP_USER} --trusted_application_password=${sympa_SOAP_PASSWORD} --proxy_vars=\"USER_EMAIL=${LISTMASTER}\" --service=add --service_parameters=\"${NL_LIST},${EMAIL_SOUHAITE}\"" | tee -a "${CMD_SYMPA}"
class Sympa:
def _execute_sympa_command(self, email, liste, service):
if validate_email(email) and validate_email(liste):
cmd = f'{sympa_soap} --soap_url={sympa_url}/sympasoap --trusted_application={sympa_user} --trusted_application_password={sympa_pass} --proxy_vars=USER_EMAIL={sympa_listmaster} --service={service} --service_parameters="{liste},{email}" && echo $?'
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
return output.decode()
def add_email_to_list(self, email, liste=sympa_liste_info):
"""
Ajouter un email dans une liste sympa
"""
output = self._execute_sympa_command(email, liste, 'add')
return output
def delete_email_from_list(self, email, liste=sympa_liste_info):
"""
Supprimer un email dans une liste sympa
"""
output = self._execute_sympa_command(email, liste, 'del')
return output

View File

@@ -1,37 +1,27 @@
from email_validator import validate_email, EmailNotValidError from email_validator import validate_email, EmailNotValidError
from glob import glob from glob import glob
import tempfile import tempfile
import subprocess
import re import re
from .paheko import Paheko from .paheko import Paheko
from .ldap import Ldap from .ldap import Ldap
from .utils import generate_password from .mattermost import Mattermost
DEFAULT_FILE = "/kaz/tmp/createUser.txt" DEFAULT_FILE = "/kaz/tmp/createUser.txt"
#class Kaz_user: def _generate_password(self):
cmd="apg -n 1 -m 10 -M NCL -d"
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
new_password="_"+output.decode("utf-8")+"_"
return new_password
# def __init__(self):
# self.paheko = Paheko()
# self.ldap = Ldap()
# global sympa_liste_info
#
# self.paheko_users_action_resource = Paheko_users_action()
# self.paheko_user_resource=Paheko_user()
# self.ldap_user_resource = Ldap_user()
# self.password_create_resource = Password_create()
# self.mattermost_message_resource=Mattermost_message()
# self.mattermost_user_resource=Mattermost_user()
# self.mattermost_user_team_resource=Mattermost_user_team()
# self.mattermost_user_channel_resource=Mattermost_user_channel()
# self.mattermost_team_resource=Mattermost_team()
# self.sympa_user_resource=Sympa_user()
def create_user(email, email_secours, admin_orga, nom_orga, quota_disque, nom, prenom, nc_orga, garradin_orga, wp_orga, agora_orga, wiki_orga, nc_base, groupe_nc_base, equipe_agora, password=None): def create_user(email, email_secours, admin_orga, nom_orga, quota_disque, nom, prenom, nc_orga, garradin_orga, wp_orga, agora_orga, wiki_orga, nc_base, groupe_nc_base, equipe_agora, password=None):
with Ldap() as ldap:
email = email.lower() email = email.lower()
with Ldap() as ldap:
# est-il déjà dans le ldap ? (mail ou alias) # est-il déjà dans le ldap ? (mail ou alias)
if ldap.get_email(email): if ldap.get_email(email):
print(f"ERREUR 1: {email} déjà existant dans ldap. on arrête tout") print(f"ERREUR 1: {email} déjà existant dans ldap. on arrête tout")
@@ -59,7 +49,7 @@ def create_user(email, email_secours, admin_orga, nom_orga, quota_disque, nom, p
return return
#on génère un password #on génère un password
password = password or generate_password() password = password or _generate_password()
#on créé dans le ldap #on créé dans le ldap
#à quoi servent prenom/nom dans le ldap ? #à quoi servent prenom/nom dans le ldap ?
@@ -74,45 +64,34 @@ def create_user(email, email_secours, admin_orga, nom_orga, quota_disque, nom, p
print("Erreur LDAP") print("Erreur LDAP")
return return
# #on créé dans MM with Mattermost() as mm:
# user = email.split('@')[0] #on créé dans MM
# res, status_code = self.mattermost_user_resource.post(user,email,password) user = email.split('@')[0]
# if status_code != 200: raise ValueError(f"ERREUR 4 sur MM: {email} : {res}, on arrête tout ") mm.create_user(user, email, password)
# mm.add_user_to_team(email, "kaz")
# # et on affecte à l'équipe kaz
# res, status_code = self.mattermost_user_team_resource.post(email,"kaz") #et aux 2 canaux de base
# if status_code != 200: raise ValueError(f"ERREUR 5 sur MM: {email} : {res}, on arrête tout ") mm.add_user_to_channel(email, "kaz", "une-question--un-soucis")
# mm.add_user_to_channel(email, "kaz", "cafe-du-commerce--ouvert-2424h")
# #et aux 2 canaux de base
# res, status_code = self.mattermost_user_channel_resource.post(email,"kaz","une-question--un-soucis") #on créé une nouvelle équipe ds MM si besoin
# if status_code != 200: raise ValueError(f"ERREUR 6 sur MM: {email} : {res}, on arrête tout ") if admin_orga == 1:
# res, status_code = self.mattermost_user_channel_resource.post(email,"kaz","cafe-du-commerce--ouvert-2424h") mm.create_team(nom_orga, email)
# if status_code != 200: raise ValueError(f"ERREUR 7 sur MM: {email} : {res}, on arrête tout ") #BUG: créer la nouvelle équipe n'a pas rendu l'email admin, on le rajoute comme membre simple
# mm.add_user_to_team(email, nom_orga)
# #on créé une nouvelle équipe ds MM si besoin
# if tab['admin_orga'] == 1: sympa = Sympa()
# res, status_code = self.mattermost_team_resource.post(tab['nom_orga'],email)
# if status_code != 200: raise ValueError(f"ERREUR 8 sur MM: {email} : {res}, on arrête tout ")
# #BUG: créer la nouvelle équipe n'a pas rendu l'email admin, on le rajoute comme membre simple
# res, status_code = self.mattermost_user_team_resource.post(email,tab['nom_orga'])
# if status_code != 200: raise ValueError(f"ERREUR 8.1 sur MM: {email} : {res}, on arrête tout ")
#
# #on créé dans le cloud genéral
# #inutile car tous les user du ldap sont user du cloud général.
#
# #on inscrit email et email_secours à la nl sympa_liste_info # #on inscrit email et email_secours à la nl sympa_liste_info
# res, status_code = self.sympa_user_resource.post(email,sympa_liste_info) sympa.add_email_to_list(email)
# if status_code != 200: raise ValueError(f"ERREUR 9 sur Sympa: {email} : {res}, on arrête tout ") sympa.add_email_to_list(email_secours)
# res, status_code = self.sympa_user_resource.post(email_secours,sympa_liste_info)
# if status_code != 200: raise ValueError(f"ERREUR 10 sur Sympa: {email_secours} : {res}, on arrête tout ") #on construit/envoie le mail
#
# #on construit/envoie le mail
# context = { # context = {
# 'ADMIN_ORGA': tab['admin_orga'], # 'ADMIN_ORGA': admin_orga,
# 'NOM': tab['nom'], # 'NOM': nom,
# 'EMAIL_SOUHAITE': email, # 'EMAIL_SOUHAITE': email,
# 'PASSWORD': password, # 'PASSWORD': password,
# 'QUOTA': tab['quota_disque'], # 'QUOTA': quota_disque,
# 'URL_WEBMAIL': webmail_url, # 'URL_WEBMAIL': webmail_url,
# 'URL_AGORA': mattermost_url, # 'URL_AGORA': mattermost_url,
# 'URL_MDP': mdp_url, # 'URL_MDP': mdp_url,
@@ -120,20 +99,21 @@ def create_user(email, email_secours, admin_orga, nom_orga, quota_disque, nom, p
# 'URL_SITE': site_url, # 'URL_SITE': site_url,
# 'URL_CLOUD': cloud_url # 'URL_CLOUD': cloud_url
# } # }
# subject="KAZ: confirmation d'inscription !" # subject = "KAZ: confirmation d'inscription !"
# sender=app.config['MAIL_USERNAME'] # sender = "contact@kaz.bzh"
# reply_to = app.config['MAIL_REPLY_TO'] # reply_to = "contact@kaz.bzh"
# msg = Message(subject=subject, sender=sender, reply_to=reply_to, recipients=[email,email_secours]) # msg = Message(subject=subject, sender=sender, reply_to=reply_to, recipients=[email,email_secours])
# msg.html = render_template('email_inscription.html', **context) # msg.html = render_template('email_inscription.html', **context)
# mail.send(msg) # mail.send(msg)
#
# #on met le flag paheko action à Aucune #on met le flag paheko action à Aucune
# res, status_code = self.paheko_user_resource.put(email,"action_auto","Aucune") paheko = Paheko()
# if status_code != 200: raise ValueError(f"ERREUR 12 sur paheko: {email} : {res}, on arrête tout ") paheko.set_user(email, "action_auto", "Aucune")
#
# #on post sur MM pour dire ok #on post sur MM pour dire ok
# msg=f"**POST AUTO** Inscription réussie pour {email} avec le secours {email_secours} Bisou!" with Mattermost() as mm:
# self.mattermost_message_resource.post(message=msg) msg=f"**POST AUTO** Inscription réussie pour {email} avec le secours {email_secours} Bisou!"
mm.post_message(message=msg)
def create_waiting_users(): def create_waiting_users():

View File

@@ -1,5 +0,0 @@
def generate_password(self):
cmd="apg -n 1 -m 10 -M NCL -d"
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
new_password="_"+output.decode("utf-8")+"_"
return new_password