# -*- coding: UTF-8 -* import re from flask import render_template, current_app from app import ScoValueError from app.email import send_email # Fonctions de manipulation des adresses mail # Objectif: traiter puis élminier les adresses mail doublonnées # pour pouvoir , à terme, les utilisaer commen identifiant pour inclusion d'un LDAP comme outil d'identification # principe: les adresses mails doublonnées superflues(note) sont transformées/numérotées sous une forme non autorisée # * les comptes ainsi modifiés seront désactivés et déclencheront une demande d'action auprès de l'utilisateur et/ou # administrateur # * une notice est ajouté à la page des utlisateurs pour indiquer à l administrateur l'existence (et # la liste) de doublons. Un bouton qui traite ces doublons est ajouté à cette liste. # note: une des adresses doublonnée sera conservée sous sa forme initiale (heuristique: on prend l'adresse du compte # actif utilisé le plus récement) # transformation proposée: * un marqueur ( '.' initial normalement interdit dans les adresses mail est ajouté un # numéro d'ordre (+xxx) est ajouté à la partie locale de l'adresse # ainsi les trois adresses identiques u@domaine.org seront renommés en: # u@domaine.org, .u+2@domaine.org et .u@domaine+3.org (la numérotation commence à 2) # cette transformation peut être redéfinie en remplaçant les fonctions check_email, transform_email et initial_email initial_re = re.compile(r"([^@]*)@(.*)") processes_re = re.compile(r"\.(.*)\+([0-9]*)@(.*)") def is_disabled_email_addr(email: str) -> bool: """ Indique si un email a été transformé :param email: l'adresse mail testée :return: True si l'adresse a été transformée """ return email[0] == '.' def disable_email_addr(email: str, rang: int) -> str: """transformation de l adresse. ajoute un '.' initial et ajoute le rang l'email ne doit pas avoir été déjà transformée. hypothèse: l'adresse mail ne comporte qu'un seul @ (en vrai un @ peut être utilisé autrement que comme séparateur si quoté comme dans '"abc@def"@dom.org'). :param email: l'adresse mail à modifier :param rang: le rang à ajouter :return: l'adresse mail transformée. """ if is_disabled_email_addr(email): raise ScoValueError("Tentative de traitement d'une adresse déjà traitée") decomposition = initial_re.match(email) if decomposition is None: # adresse mail non conforme raise ScoValueError("tentative de traitement de l\'adresse email non reconnue '%s' % email") return ".%s+%s@%s" % (decomposition.group(1), rang, decomposition.group(2)) def initial_email_address(email) -> (str, int): """récupération de la valeur initiale de l'adresse (transformation reciproque de transform_email_adr. enlève le '.' initial et supprime la terminaison '+xxx' de la partie locale. Attention: il peut y avoir un autre + dans l'adresse. :param email: l'adresse après transformation :return: l'adresse email initiale et le rang """ if not is_disabled_email_addr(email): return email, 1 # l'adresse n'a pas été transformée. on la retourne à l'identique (avec l'indice 1) decomposition = processes_re.match(email) if decomposition is None: # l'adresse a été transformée mais n'est pas reconnue raise ScoValueError("Adresse mail transformée non reconnue'%s'" % email) rang = int(decomposition.group(2)) return "%s@%s" % (decomposition.group(1), decomposition.group(3)), rang def send_password_reset_email(user): token = user.get_reset_password_token() send_email( "[ScoDoc] Réinitialisation de votre mot de passe", sender=current_app.config["ADMINS"][0], recipients=[user.email], text_body=render_template("email/reset_password.txt", user=user, token=token), html_body=render_template("email/reset_password.html", user=user, token=token), )