PCv5/app/routes/account/account.py

199 lines
7.1 KiB
Python
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from flask import redirect, url_for, request, flash, abort
from flask_login import login_required, current_user, logout_user
from app import app, db
from app.forms.account import UpdateAccountForm, RegistrationForm, \
DeleteAccountForm, AskResetPasswordForm, ResetPasswordForm
from app.models.user import Guest, Member
from app.models.trophy import Title
from app.utils.render import render
from app.utils.send_mail import send_validation_mail, send_reset_password_mail
from app.utils.priv_required import guest_only
from app.utils.glados import say, BOLD
import app.utils.ldap as ldap
import app.utils.validators as vd
from itsdangerous import URLSafeTimedSerializer
from config import V5Config
@app.route('/compte', methods=['GET', 'POST'])
@login_required
def edit_account():
form = UpdateAccountForm()
titles = [(t.id, t.name) for t in current_user.trophies if isinstance(t, Title)]
titles.insert(0, (-1, "Membre"))
form.title.choices = titles
extra_vd = {
"email": [vd.password.old_password],
"password": [vd.password.old_password],
"title": [vd.own_title],
}
if form.submit.data:
if form.is_submitted() and form.validate(extra_validators=extra_vd):
old_username = current_user.norm
current_user.update(
avatar=form.avatar.data or None,
email=form.email.data or None,
password=form.password.data or None,
birthday=form.birthday.data,
signature=form.signature.data,
bio=form.biography.data,
title=form.title.data,
newsletter=form.newsletter.data,
theme=form.theme.data
)
ldap.edit(old_username, current_user)
current_user.update(password=form.password.data or None)
db.session.merge(current_user)
db.session.commit()
current_user.update_trophies("on-profile-update")
flash('Modifications effectuées', 'ok')
app.v5logger.info(f"<{current_user.name}> has edited their account")
return redirect(request.url)
else:
flash('Erreur lors de la modification', 'error')
else:
form.theme.data = current_user.theme or 'default_theme'
return render('account/account.html', scripts=["+scripts/entropy.js"],
form=form)
@app.route('/compte/reinitialiser', methods=['GET', 'POST'])
@guest_only
def ask_reset_password():
form = AskResetPasswordForm()
if form.submit.data:
m = Member.query.filter_by(email=form.email.data).first()
if m is not None:
send_reset_password_mail(m.name, m.email)
app.v5logger.info(f"<{m.name}> has asked a password reset token")
flash('Un email a été envoyé à l\'adresse renseignée', 'ok')
return redirect(url_for('login'))
elif request.method == "POST":
flash('Une erreur est survenue', 'error')
return render('account/ask_reset_password.html', form=form)
@app.route('/compte/reinitialiser/<token>', methods=['GET', 'POST'])
@guest_only
def reset_password(token):
try:
ts = URLSafeTimedSerializer(app.config["SECRET_KEY"])
email = ts.loads(token, salt="email-confirm-key", max_age=86400)
except Exception as e:
print(f"Error: {e}")
abort(404)
form = ResetPasswordForm()
if form.submit.data:
if form.validate_on_submit():
m = Member.query.filter_by(email=email).first_or_404()
m.set_password(form.password.data)
db.session.merge(m)
db.session.commit()
flash('Modifications effectuées', 'ok')
app.v5logger.info(f"<{m.name}> has reset their password")
return redirect(url_for('login'))
else:
flash('Erreur lors de la modification', 'error')
return render('account/reset_password.html',
scripts=["+scripts/entropy.js"], form=form)
@app.route('/compte/supprimer', methods=['GET', 'POST'])
@login_required
def delete_account():
del_form = DeleteAccountForm()
if del_form.submit.data:
if del_form.validate_on_submit():
name = current_user.name
if del_form.transfer.data:
guest = Guest(current_user.generate_guest_name())
db.session.add(guest)
db.session.commit()
current_user.transfer_posts(guest)
db.session.commit()
else:
current_user.delete_posts()
db.session.commit()
if (V5Config.USE_LDAP):
ldap.delete_member(current_user)
current_user.delete()
logout_user()
db.session.commit()
flash('Compte supprimé', 'ok')
app.v5logger.info(f"<{name}> has deleted their account ({'with' if del_form.transfer.data else 'without'} guest transfer)")
return redirect(url_for('index'))
else:
flash('Erreur lors de la suppression du compte', 'error')
del_form.delete.data = False # Force to tick to delete the account
return render('account/delete_account.html', del_form=del_form)
@app.route('/inscription', methods=['GET', 'POST'])
@guest_only
def register():
form = RegistrationForm()
if form.validate_on_submit():
member = Member(form.username.data, form.email.data, form.password.data)
member.newsletter = form.newsletter.data
db.session.add(member)
db.session.commit()
# Workflow with LDAP is User → Postgresql → LDAP → Change password
if V5Config.USE_LDAP:
ldap.add_member(member)
ldap.set_password(member, form.password.data)
flash('Inscription réussie', 'ok')
# Email validation message
send_validation_mail(member.name, member.email)
app.v5logger.info(f"<{member.name}> registered")
return redirect(url_for('validation') + "?email=" + form.email.data)
return render('account/register.html', title='Register',
scripts=["+scripts/entropy.js"], form=form)
@app.route('/inscription/validation', methods=['GET'])
@guest_only
def validation():
try:
mail = request.args['email']
except Exception as e:
print(f"Error: {e}")
abort(404)
if current_user.is_authenticated:
return redirect(url_for('index'))
return render('account/validation.html', mail=mail)
@app.route('/inscription/validation/<token>', methods=['GET'])
@guest_only
def activate_account(token):
try:
ts = URLSafeTimedSerializer(app.config["SECRET_KEY"])
email = ts.loads(token, salt="email-confirm-key", max_age=86400)
except Exception as e:
# TODO: add proper login
print(f"Error: {e}")
abort(404)
m = Member.query.filter_by(email=email).first_or_404()
m.email_confirmed = True
db.session.add(m)
db.session.commit()
flash("L'email a bien été confirmé", "ok")
app.v5logger.info(f"<{m.name}> has activated their account")
say(f"Un nouveau membre sest inscrit ! Il sagit de {BOLD}{m.name}{BOLD}.")
say(url_for('user', username=m.name, _external=True))
return redirect(url_for('login'))