Add lost password recovery

This commit is contained in:
2025-05-12 16:37:30 +02:00
parent c91fdad70b
commit 15c0f4fd79
38 changed files with 1299 additions and 397 deletions

View File

@@ -29,7 +29,9 @@ def init_db():
prenom TEXT,
age TEXT,
website TEXT,
Token CHAR(30),
blog_theme TEXT,
Token CHAR(64),
Lost_password_token CHAR(128),
invitations INTEGER DEFAULT (20),
Mail_rescue TEXT )
""")
@@ -47,10 +49,27 @@ def init_db():
status TEXT
)
""")
cursor.execute("""
CREATE TABLE IF NOT EXISTS Blog_posts(
title TEXT NOT NULL,
subtitle TEXT,
comments TEXT,
filename TEXT,
time TEXT,
last_updated TEXT,
category TEXT,
author TEXT,
status TEXT,
PRIMARY KEY(title, author)
)
""")
conn.commit()
cursor.execute("""select * from users""")
accounts = cursor.fetchall()
# Si aucun account n'est crée on créé l'utilisateur
# Si aucun compte utilisateur existe on créé l'utilisateur
# pywallter qui permet la première inscription
if not(accounts) :
user = "pywallter"
@@ -73,12 +92,50 @@ def db_migrate():
cursor.execute("""SELECT name FROM PRAGMA_TABLE_INFO('users');""")
db_columns = cursor.fetchall()
present = False
invitations_col = False
blog_theme_col = False
updated_col = False
lost_password_token_col = False
for col in db_columns:
if "invitations" == col[0]:
present = True
invitations_col = True
if "Lost_password_token" == col[0]:
lost_password_token_col = True
if not(present):
cursor.execute("""SELECT name FROM PRAGMA_TABLE_INFO('Blog_posts');""")
db_columns = cursor.fetchall()
for col in db_columns:
if "blog_theme" == col[0]:
blog_theme_col = True
if "last_updated" == col[0]:
updated_col = True
if not(invitations_col):
cursor.execute("""ALTER TABLE users ADD COLUMN invitations INTEGER DEFAULT (20);""")
conn.commit()
print ("Ajout du champ invitations")
print ("Ajout du champ invitations dans la table users")
if not(lost_password_token_col):
cursor.execute("""ALTER TABLE Users ADD COLUMN Lost_password_token CHAR(64);""")
conn.commit()
print ("Ajout du champ Lost_password_token dans la table Users")
if not(blog_theme_col):
cursor.execute("""ALTER TABLE Blog_posts ADD COLUMN blog_theme TEXT;""")
conn.commit()
print ("Ajout du champ blog_theme dans la table Blog")
if not(updated_col):
cursor.execute("""ALTER TABLE Blog_posts ADD COLUMN last_updated TEXT;""")
conn.commit()
print ("Ajout du champ updated dans la table BLog")
conn.close()

12
tools/filesutils.py Normal file
View File

@@ -0,0 +1,12 @@
import os
from math import floor
def getFileSizeMo(filename): # Prend un nom de fichier en arguments renvoie la taille en Mo
tmp = os.path.getsize(filename)
size = floor (tmp / 1024) / 1000
return size
def getFileSizeKo(filename): # Prend un nom de fichier en arguments renvoie la taille en Mo
tmp = os.path.getsize(filename)
size = floor(tmp / 1024)
return size

65
tools/mailer.py Normal file
View File

@@ -0,0 +1,65 @@
from flask import Flask
import os, smtplib, ssl
from email.message import EmailMessage
app = Flask( 'pywallter' )
app.config.from_pyfile('config.py')
class Mailer:
def __init__(self):
self._smtp_server = app.config['SMTP_SERVER']
self._smtp_port = app.config['SMTP_PORT']
self._smtp_user = app.config['SMTP_USER']
self._smtp_passwd = app.config['SMTP_PASSWD']
self._sender_address = app.config['SENDER_ADDRESS']
def get_smtp_conf(self):
print ("Serveur SMTP: _smtp_server")
return self._smtp_server
def send_email(self, receiver_email, subject, message):
mail = EmailMessage()
mail['Subject'] = subject
mail['From'] = self._sender_address
mail['To'] = receiver_email
mail.set_content(message)
match self._smtp_port:
case "465":
self._send_ssl_mail(receiver_email, mail)
case "587":
self._send_starttls_mail(receiver_email, mail)
case "25":
with smtplib.SMTP(self._smtp_server, self._smtp_port) as server:
server.login(self._smtp_user, self._smtp_password)
server.sendmail(self._sender_address, receiver_email, mail.as_string())
case _:
print ("There are problem with mail port configuration ")
def _send_starttls_mail(self, receiver_email, mail):
context = ssl.create_default_context()
with smtplib.SMTP(self._smtp_server, self._smtp_port) as server:
server.ehlo() # Can be omitted
server.starttls(context=context)
server.ehlo() # Can be omitted
server.login(self._smtp_user, self._smtp_passwd)
server.sendmail(self._sender_address, receiver_email, mail.as_string())
def _send_ssl_mail(receiver_email, mail):
context = ssl.create_default_context()
with smtplib.SMTP(self._smtp_server, self._smtp_port) as server:
server.login(sender_email, password)
server.sendmail(self._sender_address, receiver_email, mail.as_string())

View File

@@ -55,9 +55,6 @@ def email_disp(email):
if alias:
if email in alias:
disp=False
else:
disp = False
@@ -72,16 +69,20 @@ def valid_passwd(password):
def valid_token_register(token):
def valid_token_register(token, token_type):
valid = True
print(token)
if len(token) != 30:
if len(token) != 30 and len(token) != 64 :
valid = False
if valid:
conn = sqlite3.connect(DATABASE)
cursor = conn.cursor()
cursor.execute("""SELECT name, invitations FROM users where Token=?""", (token,))
match token_type:
case "Lost password":
cursor.execute("""SELECT name FROM users where Lost_password_token=?""", (token,))
case "Invitation":
cursor.execute("""SELECT name FROM users where token=?""", (token,))
tmp = cursor.fetchone()
conn.close()
print (tmp)
@@ -89,13 +90,42 @@ def valid_token_register(token):
valid = True
else:
valid = False
print(valid)
return valid
#Génère un token de 30 caratères aléatoires
def gen_token():
letters = random.choices(string.ascii_letters, k=20)
digits = random.choices(string.digits, k=10)
sample = ''.join(random.sample(digits + letters, 30))
def get_user_by_token(token, token_type):
if len(token) != 30 and len(token) != 64:
user = "Invalid Token"
conn = sqlite3.connect(DATABASE)
cursor = conn.cursor()
match token_type:
case "Lost password":
cursor.execute("""SELECT name FROM users where Lost_password_token=?""", (token,))
case "Invitation":
cursor.execute("""SELECT name FROM users where token=?""", (token,))
user = cursor.fetchone()[0]
conn.close()
print ("User: " + user)
if not(user):
user = "Invalid Token"
return user
#Génère un token de 30 ou 64 caratères aléatoires
def gen_token(token_type):
letters = random.choices(string.ascii_letters, k=128)
digits = random.choices(string.digits, k=30)
match token_type:
case "Invitation":
sample = ''.join(random.sample(digits + letters, 30))
case "Lost password":
sample = ''.join(random.sample(digits + letters, 64))
return sample