PCv5/app/routes/admin/account.py

161 lines
6.1 KiB
Python
Raw Normal View History

from flask import flash, redirect, url_for, request
2019-09-01 12:30:41 +02:00
from flask_login import current_user
from wtforms import BooleanField
2019-02-06 12:44:44 +01:00
from app.utils.priv_required import priv_required
from app.models.user import Guest, Member
from app.models.trophy import Trophy, Title
from app.models.priv import Group
from app.forms.account import AdminUpdateAccountForm, AdminDeleteAccountForm, \
AdminAccountEditTrophyForm, AdminAccountEditGroupForm
from app.utils.render import render
2019-09-01 12:30:41 +02:00
from app.utils.notify import notify
from app import app, db
2019-12-09 23:24:05 +01:00
from config import V5Config
2019-02-06 12:44:44 +01:00
2019-12-16 23:57:50 +01:00
@app.route('/admin/compte/<user_id>/editer', methods=['GET', 'POST'])
review of privileges and forum permissions * Sorted privileges into categories, similar to the v4.3 style Added privilege check utilities: * Forum: is_news(), is_default_accessible() and is_default_postable() * Member: can_access_forum(), can_post_in_forum(), can_edit_post(), and can_delete_post() Unfortunately current_user is not a Guest when logged out, so one cannot usually write current_user.can_*() without checking for authentication first, so the checks are still somewhat verbose. Reviewed forum permissions; the following permission issues have been fixed (I have tested most but not all of them prior to fixing): * app/routes/forum/index.py: Users that were not meant to access a forum could still obtain a listing of the topics * app/routes/forum/topic.py: Users that were not meant to see topics could still read them by browsing the URL * app/routes/forum/topic.py: Authenticated users could post in any topic, including ones that they should not have access to * app/routes/posts/edit.py: Users with edit.posts (eg. mods) could edit and delete messages in forums they can't access (eg. creativecalc) * app/templates/account/user.html: Users with admin panel access would see account editing links they can't use (affects developers) * app/templates/base/navbar/forum.html: The "Forum" tab would list all forums including ones the user doesn't have access to * app/templates/forum/index.html: Users would see every single forum, including ones they can't access * app/template/widgets/thread.html: Anyone would see Edit/Delete links on every message, even though most were unusable Miscellaneous changes: * app/routes/forum/topic.py: Ordered comments by date as intended, which I assume worked by chance until now * Removed the old assets/privs.txt files which is now superseded by the list implemented in app/data/groups.yaml This commit changes group and forum information, run master.py with: @> forums update @> groups update
2021-02-26 18:29:25 +01:00
@priv_required('misc.admin-panel', 'edit.accounts')
2019-02-06 12:44:44 +01:00
def adm_edit_account(user_id):
2019-03-30 22:37:57 +01:00
user = Member.query.filter_by(id=user_id).first_or_404()
form = AdminUpdateAccountForm(prefix="user")
class TrophyForm(AdminAccountEditTrophyForm):
pass
class GroupForm(AdminAccountEditGroupForm):
pass
for t in Trophy.query.all():
setattr(TrophyForm, f't{t.id}', BooleanField(t.name))
setattr(TrophyForm, "trophies", {f't{t.id}': t for t in Trophy.query.all()})
setattr(TrophyForm, "user_trophies", [f't{t.id}' for t in user.trophies])
trophy_form = TrophyForm(prefix="trophies")
for g in Group.query.all():
setattr(GroupForm, f'g{g.id}', BooleanField(g.name))
2021-02-27 11:50:40 +01:00
setattr(GroupForm, "groups", {f'g{g.id}': g for g in Group.query.all()})
setattr(GroupForm, "user_groups", [f'g{g.id}' for g in user.groups])
group_form = GroupForm(prefix="group")
titles = [(t.id, t.name) for t in Title.query.all()]
titles.insert(0, (-1, "Membre"))
form.title.choices = titles
if form.submit.data:
2019-02-06 12:44:44 +01:00
if form.validate_on_submit():
2019-03-30 22:37:57 +01:00
newname = form.username.data
names = list(Member.query.filter(Member.id != user.id).values(Member.name))
if newname in names:
# TODO: avoid this exception
# You cannot user vd.name_available because name will always be
# invalid! Maybe you can add another validator with arguments
raise Exception(f'{newname} is not available')
2019-02-06 12:44:44 +01:00
user.update(
avatar=form.avatar.data or None,
name=form.username.data or None,
email=form.email.data or None,
email_confirmed=form.email_confirmed.data,
password=form.password.data or None,
birthday=form.birthday.data,
signature=form.signature.data,
title=form.title.data,
bio=form.biography.data,
newsletter=form.newsletter.data,
xp=form.xp.data or None,
2019-02-06 12:44:44 +01:00
)
db.session.merge(user)
db.session.commit()
# TODO: send an email to member saying his account has been modified
2019-09-01 12:30:41 +02:00
user.notify(f"Vos informations personnelles ont été modifiées par {current_user.name}.")
2019-02-06 12:44:44 +01:00
flash('Modifications effectuées', 'ok')
return redirect(request.url)
2019-02-06 12:44:44 +01:00
else:
flash('Erreur lors de la modification', 'error')
# Trophies
if trophy_form.submit.data:
if trophy_form.validate_on_submit():
for id, field in trophy_form.__dict__.items():
if id[0] == "t":
if field.data:
user.add_trophy(int(id[1:]))
else:
user.del_trophy(int(id[1:]))
db.session.merge(user)
db.session.commit()
flash('Modifications effectuées', 'ok')
return redirect(request.url)
else:
flash("Erreur lors de la modification des trophées", 'error')
# Groups
if group_form.submit.data:
if group_form.validate_on_submit():
for id, field in group_form.__dict__.items():
if id[0] == "g":
if field.data:
user.add_group(int(id[1:]))
else:
user.del_group(int(id[1:]))
db.session.merge(user)
db.session.commit()
flash('Modifications effectuées', 'ok')
return redirect(request.url)
else:
flash("Erreur lors de la modification des groupes", 'error')
trophies_owned = set()
for t in user.trophies:
trophies_owned.add(f"t{t.id}")
groups_owned = set()
for g in user.groups:
groups_owned.add(f"g{g.id}")
return render('admin/edit_account.html', scripts=["+scripts/entropy.js"],
user=user, form=form, trophy_form=trophy_form,
trophies_owned=trophies_owned, group_form=group_form,
groups_owned=groups_owned)
2019-02-06 12:44:44 +01:00
2019-12-16 23:57:50 +01:00
@app.route('/admin/compte/<user_id>/supprimer', methods=['GET', 'POST'])
review of privileges and forum permissions * Sorted privileges into categories, similar to the v4.3 style Added privilege check utilities: * Forum: is_news(), is_default_accessible() and is_default_postable() * Member: can_access_forum(), can_post_in_forum(), can_edit_post(), and can_delete_post() Unfortunately current_user is not a Guest when logged out, so one cannot usually write current_user.can_*() without checking for authentication first, so the checks are still somewhat verbose. Reviewed forum permissions; the following permission issues have been fixed (I have tested most but not all of them prior to fixing): * app/routes/forum/index.py: Users that were not meant to access a forum could still obtain a listing of the topics * app/routes/forum/topic.py: Users that were not meant to see topics could still read them by browsing the URL * app/routes/forum/topic.py: Authenticated users could post in any topic, including ones that they should not have access to * app/routes/posts/edit.py: Users with edit.posts (eg. mods) could edit and delete messages in forums they can't access (eg. creativecalc) * app/templates/account/user.html: Users with admin panel access would see account editing links they can't use (affects developers) * app/templates/base/navbar/forum.html: The "Forum" tab would list all forums including ones the user doesn't have access to * app/templates/forum/index.html: Users would see every single forum, including ones they can't access * app/template/widgets/thread.html: Anyone would see Edit/Delete links on every message, even though most were unusable Miscellaneous changes: * app/routes/forum/topic.py: Ordered comments by date as intended, which I assume worked by chance until now * Removed the old assets/privs.txt files which is now superseded by the list implemented in app/data/groups.yaml This commit changes group and forum information, run master.py with: @> forums update @> groups update
2021-02-26 18:29:25 +01:00
@priv_required('misc.admin-panel', 'delete.accounts')
2019-02-06 12:44:44 +01:00
def adm_delete_account(user_id):
# A user deleting their own account will be disconnected
user = Member.query.filter_by(id=user_id).first_or_404()
# TODO: Number of comments by *other* members which will be deleted
stats = {
'comments': len(user.comments()),
'topics': len(user.topics()),
'programs': len(user.programs()),
'groups': len(user.groups),
'privs': len(user.special_privileges()),
}
2019-02-06 12:44:44 +01:00
del_form = AdminDeleteAccountForm()
if del_form.submit.data:
2019-02-06 12:44:44 +01:00
if del_form.validate_on_submit():
if del_form.transfer.data:
guest = Guest(user.generate_guest_name())
db.session.add(guest)
db.session.commit()
user.transfer_posts(guest)
db.session.commit()
else:
user.delete_posts()
db.session.commit()
user.delete()
db.session.commit()
2019-02-06 12:44:44 +01:00
flash('Compte supprimé', 'ok')
return redirect(url_for('adm'))
2019-02-06 12:44:44 +01:00
else:
flash('Erreur lors de la suppression du compte', 'error')
del_form.delete.data = False # Force to tick to delete the account
return render('admin/delete_account.html', user=user, stats=stats,
del_form=del_form)