Rework invitation system and add qrcode

This commit is contained in:
kitoy 2025-12-27 07:16:39 +01:00
parent 5e54c1d383
commit 51b016aa69
6 changed files with 73 additions and 40 deletions

BIN
base.db.old Normal file

Binary file not shown.

View File

@ -7,10 +7,9 @@
<p> <p>
Si vous voulez vous pouvez inviter une personne à se crée un compte sur ce serveur Si vous voulez vous pouvez inviter une personne à se crée un compte sur ce serveur
pour cela vous devez crée un lien d'inscription. Ce lien restera valable tant pour cela vous devez crée un lien d'inscription. Ce lien restera valable tant que vous ne créez pas un autre lien.
que la personne ne s'est pas inscrite ou tant que vous ne créez pas un autre lien. Les invitations sont limité à 20 personnes pour ne pas surcharger notre petit serveur :).
Les invitations se font une par une et sont limité à 20 personnes pour ne pas surcharger notre petit serveur :). Une fois que la personne s'est inscrite votre nombre d'invitations sera mis à jour
Une fois que la personne s'est incrite votre nombre d'invitations sera mis à jour
</p> </p>
@ -20,8 +19,15 @@
<h3> Votre lien d'inscription en cours: </h3> <h3> Votre lien d'inscription en cours: </h3>
<a href="{{ url_invitation }}"> <a href="{{ url_invitation }}">
{{ url_invitation }} {{ url_invitation }}
</a> </a> <button class="ghost" onclick="navigator.clipboard.writeText('"{{ url_invitation }}');" > Copier le lien </button>
<p> ou faîtes scanner ce qrcode :)</p>
<img src="/invitation.png"/>
{% else %} {% else %}
<h3> Pas d'invitation en attente </h3> <h3> Pas d'invitation en attente </h3>
{% endif %} {% endif %}

View File

@ -43,11 +43,24 @@ def valid_username(username):
valid=True valid=True
# Caractères non autorisés dans la RFC #822 # Caractères non autorisés dans la RFC #822
invalid_char = { '(', ')', '<', '>', ',', ';', ':', '"', '[', ']', '|', 'ç', '%', '&', ' ' } invalid_char = { '(', ')', '<', '>', ',', ';', ':', '"', '[', ']', '|', 'ç', '%', '&', ' ' }
for character in invalid_char: for character in invalid_char:
if character in username: if character in username:
valid=False valid=False
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""SELECT name FROM users WHERE name=?""", (username,))
tmp = cursor.fetchone()
conn.close()
if tmp:
valid = True
else:
valid = False
return valid return valid
def set_mail_domain(): def set_mail_domain():
@ -109,7 +122,7 @@ def valid_token_register(token, token_type):
cursor.execute("""SELECT name FROM users where token=?""", (token,)) cursor.execute("""SELECT name FROM users where token=?""", (token,))
tmp = cursor.fetchone() tmp = cursor.fetchone()
conn.close() conn.close()
print (tmp)
if tmp: if tmp:
valid = True valid = True
else: else:
@ -121,7 +134,6 @@ def valid_token_register(token, token_type):
def get_user_by_token(token, token_type): def get_user_by_token(token, token_type):
if len(token) != 30 and len(token) != 64: if len(token) != 30 and len(token) != 64:
user = "Invalid Token" user = "Invalid Token"

View File

@ -35,13 +35,12 @@ def signin(token) :
mail_domain = set_mail_domain() mail_domain = set_mail_domain()
url_inscription = BASE_URL +'/inscription/'+token url_inscription = BASE_URL +'/'+'inscription/'+token
resp = None resp = None
if valid_token_register(token, "Invitation"): if valid_token_register(token, "Invitation"):
if 'username' in session : if 'username' in session :
resp = redirect(url_for('profil.profile', _external=True)) resp = redirect(url_for('profil.profile', _external=True))
else : else :
# Réponse si la requete est de type GET ou si la requete POST echoue # Réponse si la requete est de type GET ou si la requete POST echoue
resp = render_template('inscription.html', resp = render_template('inscription.html',
signin_enable=app.config['SIGNIN_ENABLE'], signin_enable=app.config['SIGNIN_ENABLE'],
@ -52,6 +51,16 @@ def signin(token) :
if request.method == 'POST': if request.method == 'POST':
# Une fois que tout c'est bien passé pour l'inscription on détruit le jeton.
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""SELECT name, invitations FROM users where Token=?""", (token,))
tmp = cursor.fetchone()
user_invite = tmp[0]
invitations_count=tmp[1]
conn.close()
#On test si aucun champs du formulaire n'est vide. #On test si aucun champs du formulaire n'est vide.
if len(request.form['user']) == 0 or \ if len(request.form['user']) == 0 or \
len(request.form['passwd']) == 0 or \ len(request.form['passwd']) == 0 or \
@ -60,7 +69,7 @@ def signin(token) :
flash(u'Il faut remplir le formulaire en entier, les champs ne peuvent pas etre vide ', 'error') flash(u'Il faut remplir le formulaire en entier, les champs ne peuvent pas etre vide ', 'error')
return render_template('inscription.html', return render_template('inscription.html',
signin_enable=app.config['SIGNIN_ENABLE'], signin_enable=app.config['SIGNIN_ENABLE'],
token=token, hostname=hostname, token=token, hostname=mail_domain,
url_inscription=url_inscription, url_inscription=url_inscription,
MAIL_SERVER=MAIL_SERVER, XMPP_SERVER=XMPP_SERVER) MAIL_SERVER=MAIL_SERVER, XMPP_SERVER=XMPP_SERVER)
@ -73,16 +82,11 @@ def signin(token) :
not_error = True not_error = True
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée if invitations_count < 1 :
cursor = conn.cursor() # Création de l'objet "curseur" flash(u'Votre lien d\'inscription est invalide', 'error')
not_error=False
cursor.execute("""SELECT name FROM users WHERE name=?""", (user,))
testuser = cursor.fetchone() if not_error and valid_username(user):
conn.close()
print("user :" +user)
print ("passwd: "+ passwd)
if testuser and valid_username(user):
flash(u'Le Nom d\'utilisateur déjà utilisé ou contient des caractères invalides, merci d\'en choisir un autre', 'error') flash(u'Le Nom d\'utilisateur déjà utilisé ou contient des caractères invalides, merci d\'en choisir un autre', 'error')
flash(u'Les caractères espaces et \' ( ) < > , ; : " [ ] | ç % & ne sont pas autorisés', 'error') flash(u'Les caractères espaces et \' ( ) < > , ; : " [ ] | ç % & ne sont pas autorisés', 'error')
not_error = False not_error = False
@ -131,17 +135,16 @@ def signin(token) :
with open(log_file, 'x') as file: with open(log_file, 'x') as file:
file.write(log) file.write(log)
except FileExistsError: except FileExistsError:
print('The file '+log_file +' already exists') print('The file '+log_file +' already exists')
# Une fois que tout c'est bien passé pour l'inscription on détruit le jeton.
cursor.execute("""SELECT name, invitations FROM users where Token=?""", (token,)) if user_invite == "pywallter":
tmp = cursor.fetchone() cursor.execute("""DELETE from users where name = ?""", (user_invite,))
username = tmp[0] elif invitations_count > 0:
invitations_count=tmp[1] - 1 invitations_count= invitations_count - 1
if username == "pywallter": cursor.execute("""UPDATE users set invitations=? where name=?""", (invitations_count, user_invite,))
cursor.execute("""DELETE from users where name = ?""", (username,))
else: else:
cursor.execute("""UPDATE users set invitations=?, Token='' where name=?""", (invitations_count, username,)) cursor.execute("""UPDATE users set invitations=?, Token='' where name=?""", (invitations_count, user_invite,))
conn.commit() conn.commit()
flash(u'Inscription réalisée avec succés !', 'success') flash(u'Inscription réalisée avec succés !', 'success')
@ -149,7 +152,7 @@ def signin(token) :
else: else:
return render_template('inscription.html', return render_template('inscription.html',
signin_enable=app.config['SIGNIN_ENABLE'], signin_enable=app.config['SIGNIN_ENABLE'],
token=token, hostname=hostname, token=token, hostname=mail_domain,
url_inscription=url_inscription, url_inscription=url_inscription,
MAIL_SERVER=MAIL_SERVER, XMPP_SERVER=XMPP_SERVER) MAIL_SERVER=MAIL_SERVER, XMPP_SERVER=XMPP_SERVER)
else: else:

View File

@ -50,7 +50,7 @@ def index():
else : else :
if token: if token:
hostname = gethostname() hostname = gethostname()
url_inscription = BASE_URL+'inscription/'+token url_inscription = BASE_URL+'/inscription/'+token
return render_template('inscription.html', signin_enable=app.config['SIGNIN_ENABLE'], return render_template('inscription.html', signin_enable=app.config['SIGNIN_ENABLE'],
token=token, hostname=hostname, token=token, hostname=hostname,
url_inscription=url_inscription, url_inscription=url_inscription,

View File

@ -349,39 +349,51 @@ def deltoken_passwd_lost(token) :
@profil.route('/invitation/', methods=['GET']) @profil.route('/invitation/', methods=['GET'])
@login_required @login_required
def invitation(): def invitation():
UTILISATEUR='%s' % escape(session['username']) user='%s' % escape(session['username'])
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur" cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""SELECT Token, invitations FROM users WHERE name=?""", (UTILISATEUR,)) cursor.execute("""SELECT Token, invitations FROM users WHERE name=?""", (user,))
tmp = cursor.fetchone() tmp = cursor.fetchone()
token = tmp[0] token = tmp[0]
if token: nb_invitations = tmp[1]
url_invitation = BASE_URL + 'inscription/' + token if token and nb_invitations > 0:
url_invitation = BASE_URL + '/inscription/' + token
img = qrcode.make(url_invitation)
img.save(os.path.join(DOSSIER_PERSO, user, "invitation.png"))
else: else:
url_invitation = "" url_invitation = ""
invitations_count = tmp[1]
conn.close() conn.close()
return render_template('invitation.html', return render_template('invitation.html',
section='Profil', section='Profil',
nb_invitation=invitations_count, nb_invitation=nb_invitations,
token=token, token=token,
url_invitation=url_invitation) url_invitation=url_invitation)
@profil.route('/invitation.png', methods=['GET'])
@login_required
def invitation_qrcode():
user='%s' % escape(session['username'])
return send_file(
os.path.join(DOSSIER_PERSO, user, "invitation.png"))
@profil.route('/gen_token/', methods=['GET']) @profil.route('/gen_token/', methods=['GET'])
@login_required @login_required
def generate_token(): def generate_token():
user='%s' % escape(session['username']) user='%s' % escape(session['username'])
conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée conn = sqlite3.connect(DATABASE) # Connexion à la base de donnée
cursor = conn.cursor() # Création de l'objet "curseur" cursor = conn.cursor() # Création de l'objet "curseur"
cursor.execute("""SELECT invitations FROM users WHERE name=?""", (user,))
tmp = cursor.fetchone()
token = tmp[0]
token = gen_token("Invitation") token = gen_token("Invitation")
cursor.execute("UPDATE users SET Token=? WHERE name=?", cursor.execute("UPDATE users SET Token=? WHERE name=?",
(token, user)) (token, user))
conn.commit() conn.commit()
conn.close() conn.close()
return redirect(BASE_URL+'invitation/') return redirect(BASE_URL+'/invitation/')
@profil.route( '/delete_me/', methods=['GET','POST']) @profil.route( '/delete_me/', methods=['GET','POST'])