PCv5/app/routes/admin.py

156 lines
5.7 KiB
Python
Raw 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.

from flask import request, flash, redirect, url_for, abort
from flask_login import login_required
from app.utils.priv_required import priv_required
from flask_wtf import FlaskForm
from wtforms import SubmitField
from app.models.users import Member, Group, GroupPrivilege
from app.models.privs import SpecialPrivilege
from app.forms.account import AdminUpdateAccountForm, AdminDeleteAccountForm
from app.utils.render import render
from app import app, db
@app.route('/admin', methods=['GET', 'POST'])
@priv_required('access-admin-panel')
def adm():
return render('admin/index.html')
# Default groups and privileges.
default_groups = [
('Administrateur', 'color: #ee0000',
"Vous voyez Chuck Norris? Pareil."),
('Modérateur', 'color: green',
"Maîtres du kick, ils sont là pour faire respecter un semblant " +
"d'ordre."),
('Développeur', 'color: #4169e1',
"Les développeurs maintiennent et améliorent le code du site."),
('Rédacteur', 'color: blue',
"Rédigent les meilleurs articles de la page d'accueil, rien " +
"que pour vous <3"),
('Responsable communauté', 'color: DarkOrange',
"Anime les pages Twitter et Facebook de Planète Casio et " +
"surveille l'évolution du monde autour de nous !"),
('Partenaire', 'color: purple',
"Membres de l'équipe d'administration des sites partenaires."),
('Compte communautaire', 'background: #d8d8d8; border-radius: ' +
'4px; color:#303030; padding: 1px 2px',
"Compte à usage général de l'équipe de Planète Casio."),
('Robot', 'color: #cf25d0',
"♫ Je suis Nono, le petit robot, l'ami d'Ulysse ♫",
"shoutbox-kick shoutbox-ban".split()),
('Membre de CreativeCalc', 'color: #222222',
"CreativeCalc est l'association qui gère Planète Casio.",
"access-assoc-board".split()),
]
@app.route('/admin/groups', methods=['GET', 'POST'])
@priv_required('access-admin-panel')
def adm_groups():
class GroupRegenerationForm(FlaskForm):
submit = SubmitField('Régénérer les groupes, privilèges, et comptes communs')
form = GroupRegenerationForm()
if form.validate_on_submit():
# Clean up groups
for g in Group.query.all():
g.delete()
# Create base groups
groups = [ Group(g[0], g[1], g[2]) for g in default_groups ]
for g in groups:
db.session.add(g)
db.session.commit()
for g, dg in zip(groups, default_groups):
if len(dg) < 4:
continue
for priv in dg[3]:
db.session.add(GroupPrivilege(g, priv))
db.session.commit()
# Clean up test members
for name in "PlanèteCasio GLaDOS".split():
m = Member.query.filter_by(name=name).first()
if m is not None:
m.delete()
# Create template members
def addgroup(member, group):
g = Group.query.filter_by(name=group).first()
if g is not None:
member.groups.append(g)
m = Member('PlanèteCasio','contact@planet-casio.com','v5-forever')
addgroup(m, "Compte communautaire")
db.session.add(m)
m = Member('GLaDOS', 'glados@aperture.science', 'v5-forever')
addgroup(m, "Robot")
db.session.add(m)
db.session.commit()
db.session.add(SpecialPrivilege(m, "edit-posts"))
db.session.add(SpecialPrivilege(m, "shoutbox-ban"))
db.session.commit()
users = Member.query.all()
groups = Group.query.all()
return render('admin/groups_privileges.html', users=users, groups=groups, form=form)
@app.route('/admin/edit-account/<user_id>', methods=['GET', 'POST'])
@priv_required('edit-account')
def adm_edit_account(user_id):
user = Member.query.filter_by(id=user_id).first()
if not user:
abort(404)
form = AdminUpdateAccountForm()
if request.method == "POST":
if form.validate_on_submit():
if form.avatar.data:
f = form.avatar.data
f.save("./app/static/"+user.avatar)
user.update(
name = form.username.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,
newsletter = form.newsletter.data,
xp = form.xp.data or None,
innovation = form.innovation.data or None
)
db.session.merge(user)
db.session.commit()
flash('Modifications effectuées', 'ok')
else:
flash('Erreur lors de la modification', 'error')
return render('admin/edit_account.html', user=user, form=form)
@app.route('/admin/edit-account/<user_id>/delete', methods=['GET', 'POST'])
@priv_required('delete-account')
def adm_delete_account(user_id):
user = Member.query.filter_by(id=user_id).first_or_404()
# Note: A user deleting their own account will be disconnected.
# TODO: Add an overview of what will be deleted.
# * How many posts will be turned into guest posts
# * Option: purely delete the posts in question
# * How many PMs will be deleted (can't unassign PMs)
# * etc.
del_form = AdminDeleteAccountForm()
if request.method == "POST":
if del_form.validate_on_submit():
user.delete()
flash('Compte supprimé', 'ok')
return redirect(url_for('adm'))
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, del_form=del_form)