diff --git a/ela_user_account.py b/ela_user_account.py index 39bba37..ea0fd1f 100644 --- a/ela_user_account.py +++ b/ela_user_account.py @@ -16,6 +16,8 @@ La fonction effectue les operations suivantes : from pymongo import MongoClient import json from bson import ObjectId + +import email_mgt import email_mgt as mail from datetime import datetime import prj_common as mycommon @@ -731,6 +733,10 @@ def change_user_pwd(diction): return False, "Le mot de passe est vide" + if ( len(str(new_pwd)) <= 0): + mycommon.myprint(str(inspect.stack()[0][3]) + " Le nouveau mot de passe est vide") + return False, "Le nouveau mot de passe est vide" + if (str(new_pwd) != str(conf_new_pwd)): mycommon.myprint(str(inspect.stack()[0][3]) + " - Les mots de passe ne sont pas identiques. nouveau pass :'"+str(new_pwd) +"', la oonfirmation envoyées est "''+str(conf_new_pwd)+"' ") return False, " Les mots de passe ne sont pas identiques " @@ -776,6 +782,117 @@ def change_user_pwd(diction): return False, "Impossible de mettre à jour le mot de passe de l'utilisateur" +''' +Changement du mot de passe d'un user +avec un token de reinitialisation ''' +def Reset_user_pwd_by_token(diction): + try: + # Dictionnaire des champs utilisables + field_list = ['token', 'new_pwd', 'conf_new_pwd'] + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list: + mycommon.myprint(" Le champ '" + val + "' n'est pas autorisé, requete annulée") + return False, " Impossible de recuperer le user account" + + ''' + Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente, + On controle que les champs obligatoires sont presents dans la liste + ''' + field_list_obligatoire = ['token', 'new_pwd', 'conf_new_pwd'] + for val in field_list_obligatoire: + if val not in diction: + mycommon.myprint(" La valeur '" + val + "' n'est pas presente dans liste ") + return False, " Impossible de mettre à jour le mot de passe" + + + # recuperation des paramettre + email_value = "" + token_value = "" + pwd = "" + new_pwd = "" + conf_new_pwd = "" + + mydata ={} + + if ("conf_new_pwd" in diction.keys()): + if diction['conf_new_pwd']: + conf_new_pwd = diction['conf_new_pwd'] + + if ("token" in diction.keys()): + if diction['token']: + token_value = diction['token'] + + if ("new_pwd" in diction.keys()): + if diction['new_pwd']: + new_pwd = diction['new_pwd'] + mydata['pwd'] = diction['new_pwd'] + + + # Verification de la validité du token/mail dans le cas des user en mode connecté + if ( len(str(token_value)) <= 0): + mycommon.myprint(str(inspect.stack()[0][3]) + " Le token est vide") + return False, "Le token est vide" + + if ( len(str(new_pwd)) <= 0): + mycommon.myprint(str(inspect.stack()[0][3]) + " Le mot de passe est vide") + return False, "Le mot de passe est vide" + + + if (str(new_pwd) != str(conf_new_pwd)): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Les mots de passe ne sont pas identiques. nouveau pass :'"+str(new_pwd) +"', la oonfirmation envoyées est "''+str(conf_new_pwd)+"' ") + return False, " Les mots de passe ne sont pas identiques " + + retval = mycommon.check_token_validity("", token_value) + + if retval is False: + mycommon.myprint(str(inspect.stack()[0][3]) + " Le token est invalide") + return False, "Le token est invalide" + + + # Recuperation du recid du user + user_recid = mycommon.get_user_recid_from_token(token_value) + if user_recid is False : + mycommon.myprint(str(inspect.stack()[0][3]) + " Impossible de recuperer le recid du user. Le token envoyé est :"+str(token_value)) + return False, " Impossible de mettre à jour le mot de passe" + + + mydata['date_update'] = str(datetime.now()) + client = MongoClient(CONNECTION_STRING) + dbname = client['cherifdb'] + coll_name = dbname['user_account'] + + print(" le recid = "+user_recid+" mydata = "+str(mydata)) + ret_val = coll_name.find_one_and_update({'recid': user_recid, 'locked': '0', 'active':'1'}, + {"$set": mydata}, + return_document=ReturnDocument.AFTER + ) + + if (ret_val and ret_val['_id']): + # Apres avoir changer le mot passe, desactivation tu token + + coll_name = dbname['user_token'] + ret_val = coll_name.update_many({'recid': user_recid, 'valide': '1'}, + {"$set": {'valide': '0', 'date_update': str(datetime.now())}}, + ) + + if( ret_val.matched_count <= 0 ): + mycommon.myprint(str(inspect.stack()[0][3]) + " WARNING : Attention à la mise à jour du mot de passe de" + " du user avec le recid = "+user_recid) + else: + mycommon.myprint(str(inspect.stack()[0][3]) + " Le mot de passe de l'utilisateur (recid) =" + str(user_recid)+" a été modifié") + return True, "Le mot de passe a bien été mise à jour " + else: + mycommon.myprint(str(inspect.stack()[0][3]) + " Impossible de mettre à jour le password du user : recid = "+str(user_recid)) + return False, "Impossible de mettre à jour le password" + + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exc_info() + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) + return False, "Impossible de mettre à jour le mot de passe de l'utilisateur" + + @@ -1227,9 +1344,9 @@ def InitUserPasswd(diction): myemail = "" myquery = {} if ("email" in diction.keys()): - if diction['source']: - myemail = diction['source'] - myquery['email'] = diction['source'] + if diction['email']: + myemail = diction['email'] + myquery['email'] = diction['email'] myquery['active'] = '1' @@ -1238,18 +1355,17 @@ def InitUserPasswd(diction): coll_name = dbname['user_account'] - tmp = coll_name.count_documents(myquery) + #print(" myquery ="+str(myquery)) + tmp = coll_name.count_documents(myquery) if (tmp <= 0): mycommon.myprint(str(inspect.stack()[0][3]) + " Aucun resultat trouvé pour " + str(myquery)) - return False, "Impossible de reinitialiser le mot de passe de l'utiilisateur" + return True, "La demande de reinitiation à été prise en compte" - RetObject = [] - local_id = 0 retVal = coll_name.find(myquery, {"_id": 0, "valide": 0, "user_recid": 0}) - print(" le recid = "+retVal['recid']) + #print(" le recid = "+str(retVal[0]['recid'])) ''' Desactivation des tocken actifs @@ -1258,37 +1374,93 @@ def InitUserPasswd(diction): coll_name_token = dbname['user_token'] - ret_val_user_rech = coll_name_token.find_one_and_update( - {'recid': retVal['recid']}, - {"$set": update_field}, - return_document=ReturnDocument.AFTER + ret_val_user_rech = coll_name_token.update_many( + {'recid': retVal[0]['recid']}, + {"$set": update_field} ) - if (ret_val_user_rech is False): - mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de mettre à jour la table 'user_token' " - return False, "Impossible de reinitialiser le mot de passe de l'utiilisateur " + if (ret_val_user_rech.matched_count <= 0): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de desactivier les token actifs dans table 'user_token' ") + return True, "La demande de reinitiation à été prise en compte" ''' Insertion du nouveau token ''' new_token = {} - new_token['email'] = retVal['email'] - new_token['recid'] = retVal['recid'] + new_token['email'] = retVal[0]['email'] + new_token['recid'] = retVal[0]['recid'] new_token['date_update'] = str(datetime.now()) new_token['valide'] = '1' + # Creation du token + mynewtoken = mycommon.create_token_urlsafe() + new_token['token'] = mynewtoken + #print(" new token to insert = "+str(new_token)) ret_val_tmp = coll_name_token.insert_one(new_token) if (ret_val_tmp is False): mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de créer le nouveau toek") - return False, "Impossible de reinitialiser le mot de passe de l'utiilisateur " + return True, "La demande de reinitiation à été prise en compte" -send email a faire + # envoi de l'email + email_mgt.send_user_init_pwd_mail(mynewtoken, retVal[0]['email']) - return True, "RetObject" + return True, "La demande de reinitiation à été prise en compte" except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) return False, "Impossible de reinitialiser le mot de passe de l'utiilisateur" + + +''' +Cette fonction verifie si le token d'un utilisateur est valide +''' +def IsUserTokenValide(diction): + try: + ''' + # Verification que les champs reçus dans l'API sont bien dans la liste des champs autorisés + # Cela evite le cas ou une entité tierce ajouter les valeurs inconnu dans l'API + # Ici on doit mettre tous les champs possible (obligatoire ou non) de la BDD dans la liste + # field_list. + ''' + field_list = ['token'] + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list: + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé, opération annulée") + return False, "Impossible de reinitialiser le mot de passe de l'utiilisateur" + + ''' + Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente, + On controle que les champs obligatoires sont presents dans la liste + ''' + field_list_obligatoire = ['token'] + for val in field_list_obligatoire: + if val not in diction: + mycommon.myprint(str(inspect.stack()[0][3]) + " La valeur '" + val + "' n'est pas presente dans liste ") + return False, "Impossible de reinitialiser le mot de passe de l'utiilisateur" + + myquery = {} + if ("token" in diction.keys()): + if diction['token']: + myquery['token'] = diction['token'] + + myquery['valide'] = '1' + coll_name_token = dbname['user_token'] + + + tmp = coll_name_token.count_documents(myquery) + if (tmp <= 0): + mycommon.myprint(str(inspect.stack()[0][3]) + " Aucun resultat trouvé pour " + str(myquery)) + return False, "Le token n'est pas valide" + + return True, "Le token est valdie" + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exc_info() + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) + return False, "Impossible de verifier la validité du token" + diff --git a/email_mgt.py b/email_mgt.py index 8cb1436..f470db3 100644 --- a/email_mgt.py +++ b/email_mgt.py @@ -194,3 +194,95 @@ def send_partner_account_mail(message, account_mail): +''' +Envoie de l'email de reinitialisation du mot de passe du user +''' + + +def send_user_init_pwd_mail(token, account_mail): + try: + tomorrow = datetime.date.today() + datetime.timedelta(days=1) + tomorrow_day = tomorrow.strftime("%A") + + print("debut envoi mail de test ") + # on rentre les renseignements pris sur le site du fournisseur + + msg = MIMEMultipart("alternative") + + msg['Subject'] = '[MySy Training] : Reinitialisez votre mot de passe' + msg['From'] = 'billardman01@hotmail.com' + msg['To'] = str(account_mail) + + html = ''' + + + + +
+

+ Mysy Training Logo

+
+
+
+
+ Bonjour +
+ + Nous avons reçu une demande de réinitialisation du mot de passe de votre compte MySy-Training.
+ Veuillez cliquer sur le bouton ci-dessous pour le réinitialiser. + .
+ +
+
+ + Changez de mot de passe + + + +
+ +
+ + + CLIQUEZ ICI ==> LOCALHOST + + + +

Cordialement
+ L'equipe informatique de MySy +

+

+
+ +
+ + + + '''.format(code=tomorrow_day, objId=token) + + html_mime = MIMEText(html, 'html') + + # msg.attach(texte_mime) + msg.attach(html_mime) + + print("html_mime =" + str(html)) + + toaddr = str(account_mail) + cc = ['billardman01@hotmail.com'] + toaddrs = [toaddr] + cc + + # msg.attach(MIMEText(open(filename).read())) + + with smtplib.SMTP(smtp_address, port) as server: + server.starttls() # Secure the connection + + server.login(user, password) + server.sendmail(sender, toaddrs, msg.as_string()) + mycommon.myprint("mail successfully sent to " + str(toaddrs)) + + return True + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exc_info() + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) + return False, " Impossible d'envoyer l'email de notification " diff --git a/main.py b/main.py index ecb4183..7d6ea66 100644 --- a/main.py +++ b/main.py @@ -917,6 +917,43 @@ def get_article_avis_alaune(): return jsonify(status=status, message=result) +''' +Cette API reinitialise le mot de passe d'un utilisation +depuis le front office''' +@app.route('/myclass/api/InitUserPasswd/', methods=['GET','POST']) +@crossdomain(origin='*') +def InitUserPasswd(): + # On recupere le corps (payload) de la requete + payload = request.form.to_dict() + print(" ### payload = ", payload) + status, result = eua.InitUserPasswd(payload) + return jsonify(status=status, message=result) + +''' +Cette API verifie la validité d'un token +''' +@app.route('/myclass/api/IsUserTokenValide/', methods=['GET','POST']) +@crossdomain(origin='*') +def IsUserTokenValide(): + # On recupere le corps (payload) de la requete + payload = request.form.to_dict() + print(" ### payload = ", payload) + status, result = eua.IsUserTokenValide(payload) + return jsonify(status=status, message=result) + +''' +Cette API, modifie le pwd d'un user +en partant d'un token. +l'api est utilisé dans le cas d'un process de reinitialisation du pwd +par le user meme''' +@app.route('/myclass/api/Reset_user_pwd_by_token/', methods=['GET','POST']) +@crossdomain(origin='*') +def Reset_user_pwd_by_token(): + # On recupere le corps (payload) de la requete + payload = request.form.to_dict() + print(" ### payload = ", payload) + status, result = eua.Reset_user_pwd_by_token(payload) + return jsonify(status=status, message=result) if __name__ == '__main__': print(" debut api")