addd password recovery
This commit is contained in:
parent
39574a2c06
commit
f7d2e8563b
Binary file not shown.
BIN
__pycache__/mail.cpython-310.pyc
Normal file
BIN
__pycache__/mail.cpython-310.pyc
Normal file
Binary file not shown.
@ -1 +1,14 @@
|
||||
{"users": {"1": {"camille@chauvet.pro": "b'$2b$12$AMuNu9CU/lUyaQjDmyWypeVg8beyRA795lrldMGAmHMXaeyfNnke.'"}}}
|
||||
{
|
||||
"users": {
|
||||
"1": {
|
||||
"email": "camille@chauvet.pro",
|
||||
"password": "b'$2b$12$FVOKVF9p/SlSv9ANVNDW.eOmv1f3qtB0WU86g4ED4B8J2fMBPZu7.'"
|
||||
},
|
||||
"2": {
|
||||
"email": "spam@camille.chauvet.pro",
|
||||
"password": "b'$2b$12$D2DexgunhMTbYWkXmEQKw.Aa13W9QZE4CjsNUyaU5bSaZ8ZpdJ2hO'"
|
||||
}
|
||||
},
|
||||
"resets": {},
|
||||
"_default": {}
|
||||
}
|
46
database.py
46
database.py
@ -1,27 +1,59 @@
|
||||
from tinydb import TinyDB, Query
|
||||
from tinydb import TinyDB, where, Query
|
||||
import uuid
|
||||
import hasher
|
||||
|
||||
db = TinyDB("./database.json")
|
||||
db = TinyDB("./database.json", indent=4)
|
||||
query = Query()
|
||||
|
||||
users = db.table("users");
|
||||
|
||||
def get_users():
|
||||
return (users.all())
|
||||
|
||||
def get_user_by_email(email: str):
|
||||
for user in get_users():
|
||||
if (list(user.keys())[0] == email):
|
||||
return (user);
|
||||
user_lst = users.search(query.email == email)
|
||||
if (user_lst == []):
|
||||
return (None)
|
||||
return (user_lst[0])
|
||||
|
||||
def email_exist(email: str) -> bool:
|
||||
return (get_user_by_email(email) != None)
|
||||
|
||||
def user_exist(email: str):
|
||||
return (get_user_by_email(email) != None)
|
||||
|
||||
def add_user(email: str, password: str):
|
||||
password_hashed = hasher.hash_text(password)
|
||||
users.insert({email: str(password_hashed)});
|
||||
users.insert({"email": email, "password": str(password_hashed)});
|
||||
|
||||
def check_password(email: str, password: str):
|
||||
password_hashed = get_user_by_email(email).get(email)
|
||||
password_hashed = get_user_by_email(email).get("password")
|
||||
password_hashed = bytes(password_hashed[2:-1], "utf-8")
|
||||
return (hasher.is_same(password, password_hashed))
|
||||
|
||||
def change_user_password(email: str, password: str):
|
||||
password_hashed = hasher.hash_text(password)
|
||||
db.update({"password": password_hashed}, query.email == email)
|
||||
|
||||
resets = db.table("resets")
|
||||
|
||||
def get_email_by_reset_code(code: str):
|
||||
user_lst = resets.search(query.code == code)
|
||||
if (user_lst == []):
|
||||
return (None)
|
||||
return (user_lst[0])
|
||||
|
||||
def reset_code_exist(code: str) -> bool:
|
||||
return (get_email_by_reset_code(code) != None)
|
||||
|
||||
def remove_reset_code_by_email(email: str):
|
||||
resets.remove(query.email == email)
|
||||
|
||||
def remove_reset_code_by_code(code: str):
|
||||
resets.remove(query.code == code)
|
||||
|
||||
def create_reset_code_by_email(email: str):
|
||||
code = str(uuid.uuid4());
|
||||
remove_reset_code_by_email(email);
|
||||
resets.insert({"email": email, "code": code})
|
||||
return (code)
|
||||
|
Binary file not shown.
Binary file not shown.
8
mail.py
8
mail.py
@ -1,6 +1,7 @@
|
||||
import ssl
|
||||
import smtplib
|
||||
from email.message import EmailMessage
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
|
||||
config = {
|
||||
"server": "ssl0.ovh.net",
|
||||
@ -11,11 +12,11 @@ config = {
|
||||
}
|
||||
|
||||
def send_mail(mail_add:str, subject:str, mail_content:str):
|
||||
email = EmailMessage()
|
||||
email = MIMEMultipart()
|
||||
email['From'] = config["display_name"]
|
||||
email["To"] = mail_add;
|
||||
email["subject"] = subject;
|
||||
email.set_content(mail_content);
|
||||
email.attach(MIMEText(mail_content, "html"))
|
||||
|
||||
context = ssl.create_default_context();
|
||||
|
||||
@ -23,4 +24,3 @@ def send_mail(mail_add:str, subject:str, mail_content:str):
|
||||
smtp.login(config["email"], config["password"]);
|
||||
smtp.sendmail(config["email"], mail_add, email.as_string());
|
||||
|
||||
send_mail("camille@chauvet.pro", "test", "text")
|
||||
|
40
main.py
40
main.py
@ -2,6 +2,7 @@ from flask import Flask, render_template, request, redirect, session
|
||||
from flask_session import Session
|
||||
import utils
|
||||
import database
|
||||
import mail
|
||||
|
||||
app = Flask(__name__);
|
||||
app.config["SESSION_PERMANENT"] = False
|
||||
@ -12,7 +13,6 @@ Session(app)
|
||||
def home():
|
||||
return (render_template("home.html"));
|
||||
|
||||
|
||||
@app.route("/connected")
|
||||
def connected():
|
||||
if (not session.get("email")):
|
||||
@ -21,12 +21,12 @@ def connected():
|
||||
|
||||
@app.route("/login")
|
||||
def login():
|
||||
if (session.get("email")):
|
||||
return (redirect("/connected"))
|
||||
return (render_template("login.html"));
|
||||
|
||||
@app.route('/login', methods=['POST'])
|
||||
def login_post():
|
||||
if (not session.get("email")):
|
||||
return (redirect("/connected"))
|
||||
email = request.form.get('email')
|
||||
password = request.form.get('password')
|
||||
if (not database.user_exist(email)):
|
||||
@ -43,12 +43,12 @@ def logout():
|
||||
|
||||
@app.route("/signin")
|
||||
def signin():
|
||||
if (session.get("email")):
|
||||
return (redirect("/connected"))
|
||||
return (render_template("signin.html"));
|
||||
|
||||
@app.route('/signin', methods=['POST'])
|
||||
def signup_post():
|
||||
if (not session.get("email")):
|
||||
return (redirect("/connected"))
|
||||
def signin_post():
|
||||
email = request.form.get('email')
|
||||
password = request.form.get('password')
|
||||
repassword = request.form.get('repassword')
|
||||
@ -65,9 +65,35 @@ def signup_post():
|
||||
def forgot():
|
||||
return (render_template("forgot.html"));
|
||||
|
||||
@app.route("/forgot", methods=["POST"])
|
||||
def forgot_post():
|
||||
email = request.form.get('email')
|
||||
if (not database.email_exist(email)):
|
||||
return (render_template("forgot.html", error="Ce compte n'existe pas'"))
|
||||
uuid = database.create_reset_code_by_email(email);
|
||||
mail.send_mail(email, "Password recovery", render_template("mails/password_recovery.html", code=uuid))
|
||||
return (redirect(f"/reset/{uuid}"))
|
||||
|
||||
@app.route("/reset/<uuid>")
|
||||
def reset(uuid):
|
||||
return ("bozo")
|
||||
if (not database.reset_code_exist(uuid)):
|
||||
return (render_template("error.html", error="code inconnu"))
|
||||
email = database.get_email_by_reset_code(uuid)
|
||||
email = email["email"]
|
||||
return (render_template("reset.html", email=email))
|
||||
|
||||
@app.route("/reset/<uuid>", methods=['POST'])
|
||||
def reset_post(uuid):
|
||||
if (not database.reset_code_exist(uuid)):
|
||||
return (render_template("error.html", error="code inconnu"))
|
||||
email = database.get_email_by_reset_code(uuid)
|
||||
password = request.form.get('password')
|
||||
repassword = request.form.get('repassword')
|
||||
if (password != repassword):
|
||||
return (render_template("reset.html", error="Les deux mots de passe sont differents"))
|
||||
database.change_user_password(email, password);
|
||||
database.remove_reset_code_by_code(uuid);
|
||||
return (redirect("/login"))
|
||||
|
||||
@app.route("/join/<uuid>")
|
||||
def join(uuid):
|
||||
|
14
templates/connected.html
Normal file
14
templates/connected.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>PyMenu</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>connected</h1>
|
||||
<h2>Welcome to FlaskApp!</h2>
|
||||
<a href="/logout">
|
||||
<input type="button" value="logout">
|
||||
</a>
|
||||
</body>
|
||||
</html>
|
16
templates/error.html
Normal file
16
templates/error.html
Normal file
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>PyMenu</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Error</h1>
|
||||
{% if error %}
|
||||
<h2>{{error}}</h2>
|
||||
{% endif %}
|
||||
<a href="/">
|
||||
<input type="button" value="Revenir a l'acceuil">
|
||||
</a>
|
||||
</body>
|
||||
</html>
|
83
templates/forgot.html
Normal file
83
templates/forgot.html
Normal file
@ -0,0 +1,83 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="index.css" />
|
||||
<title>Beyond School</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<form method="post">
|
||||
<h2>Mot de passe oublié ?</h2>
|
||||
<label><b>Email :</b></label>
|
||||
<input type="email" name="email" placeholder="Insérez votre email" required>
|
||||
<br>
|
||||
{% if error %}
|
||||
<p>{{error}}</p>
|
||||
{% endif %}
|
||||
<input type="submit" value="Valider">
|
||||
<a href="/login">
|
||||
<input type="button" value="connection">
|
||||
</a>
|
||||
</form>
|
||||
</div>
|
||||
<style>
|
||||
body{
|
||||
background: #67BE4B;
|
||||
}
|
||||
#container{
|
||||
width:400px;
|
||||
margin:0 auto;
|
||||
margin-top:10%;
|
||||
}
|
||||
/* Bordered form */
|
||||
form {
|
||||
width:100%;
|
||||
padding: 40px;
|
||||
border: 1px solid #f1f1f1;
|
||||
background: #fff;
|
||||
box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);
|
||||
}
|
||||
#container h2{
|
||||
width: 38%;
|
||||
margin: 0 auto;
|
||||
padding-bottom: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Full-width inputs */
|
||||
input[type=email], input[type=password], input[type=number] {
|
||||
width: 100%;
|
||||
padding: 12px 20px;
|
||||
margin: 8px 0;
|
||||
display: inline-block;
|
||||
border: 1px solid #ccc;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Set a style for all buttons */
|
||||
input[type=submit], input[type=button] {
|
||||
background-color: #53af57;
|
||||
color: white;
|
||||
padding: 14px 20px;
|
||||
margin: 8px 0;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
}
|
||||
input[type=submit]:hover {
|
||||
background-color: white;
|
||||
color: #53af57;
|
||||
border: 1px solid #53af57;
|
||||
}
|
||||
h6 {
|
||||
float: right;
|
||||
}
|
||||
p {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
76
templates/mails/password_recovery.html
Normal file
76
templates/mails/password_recovery.html
Normal file
@ -0,0 +1,76 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="index.css" />
|
||||
<title>Beyond School</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<form method="post">
|
||||
<h2>Mot de passe oublié ?</h2>
|
||||
<a href="http://localhost:5000/reset/{{code}}">
|
||||
<input type="button" value="connection">
|
||||
</a>
|
||||
</form>
|
||||
</div>
|
||||
<style>
|
||||
body{
|
||||
background: #67BE4B;
|
||||
}
|
||||
#container{
|
||||
width:400px;
|
||||
margin:0 auto;
|
||||
margin-top:10%;
|
||||
}
|
||||
/* Bordered form */
|
||||
form {
|
||||
width:100%;
|
||||
padding: 40px;
|
||||
border: 1px solid #f1f1f1;
|
||||
background: #fff;
|
||||
box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);
|
||||
}
|
||||
#container h2{
|
||||
width: 38%;
|
||||
margin: 0 auto;
|
||||
padding-bottom: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Full-width inputs */
|
||||
input[type=email], input[type=password], input[type=number] {
|
||||
width: 100%;
|
||||
padding: 12px 20px;
|
||||
margin: 8px 0;
|
||||
display: inline-block;
|
||||
border: 1px solid #ccc;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Set a style for all buttons */
|
||||
input[type=submit], input[type=button] {
|
||||
background-color: #53af57;
|
||||
color: white;
|
||||
padding: 14px 20px;
|
||||
margin: 8px 0;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
}
|
||||
input[type=submit]:hover {
|
||||
background-color: white;
|
||||
color: #53af57;
|
||||
border: 1px solid #53af57;
|
||||
}
|
||||
h6 {
|
||||
float: right;
|
||||
}
|
||||
p {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
83
templates/reset.html
Normal file
83
templates/reset.html
Normal file
@ -0,0 +1,83 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="index.css" />
|
||||
<title>Beyond School</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<form name="signin" method="post">
|
||||
<h2>Connection</h2>
|
||||
<label><b>Email :</b></label>
|
||||
<input type="email" name="email" placeholder={{email}} disabled=true>
|
||||
<br>
|
||||
<label><b>Mot de passe :</b></label>
|
||||
<input type="password" name="password" placeholder="Insérez votre mot de passe" required>
|
||||
<br>
|
||||
<label><b>Mot de passe :</b></label>
|
||||
<input type="password" name="repassword" placeholder="Insérez votre mot de passe" required>
|
||||
<br>
|
||||
<input type="submit" value="Changer de mot de passe">
|
||||
</form>
|
||||
</div>
|
||||
<style>
|
||||
body{
|
||||
background: #67BE4B;
|
||||
}
|
||||
#container{
|
||||
width:400px;
|
||||
margin:0 auto;
|
||||
margin-top:10%;
|
||||
}
|
||||
/* Bordered form */
|
||||
form {
|
||||
width:100%;
|
||||
padding: 40px;
|
||||
border: 1px solid #f1f1f1;
|
||||
background: #fff;
|
||||
box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);
|
||||
}
|
||||
#container h2{
|
||||
width: 38%;
|
||||
margin: 0 auto;
|
||||
padding-bottom: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Full-width inputs */
|
||||
input[type=email], input[type=password], input[type=number] {
|
||||
width: 100%;
|
||||
padding: 12px 20px;
|
||||
margin: 8px 0;
|
||||
display: inline-block;
|
||||
border: 1px solid #ccc;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Set a style for all buttons */
|
||||
input[type=submit], input[type=button] {
|
||||
background-color: #53af57;
|
||||
color: white;
|
||||
padding: 14px 20px;
|
||||
margin: 8px 0;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
}
|
||||
input[type=submit]:hover {
|
||||
background-color: white;
|
||||
color: #53af57;
|
||||
border: 1px solid #53af57;
|
||||
}
|
||||
h6 {
|
||||
float: right;
|
||||
}
|
||||
p {
|
||||
color: red
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user