2019-02-06 12:44:44 +01:00
|
|
|
|
from flask import request, flash, redirect, url_for, abort
|
2019-02-04 16:41:29 +01:00
|
|
|
|
from flask_login import login_required
|
2019-02-06 12:44:44 +01:00
|
|
|
|
from app.utils.priv_required import priv_required
|
2019-02-04 16:41:29 +01:00
|
|
|
|
from flask_wtf import FlaskForm
|
|
|
|
|
from wtforms import SubmitField
|
|
|
|
|
from app.models.users import Member, Group, GroupPrivilege
|
|
|
|
|
from app.models.privs import SpecialPrivilege
|
2019-02-06 12:44:44 +01:00
|
|
|
|
from app.forms.account import AdminUpdateAccountForm, AdminDeleteAccountForm
|
2019-02-04 16:41:29 +01:00
|
|
|
|
from app.utils.render import render
|
|
|
|
|
from app import app, db
|
|
|
|
|
|
|
|
|
|
@app.route('/admin', methods=['GET', 'POST'])
|
2019-02-09 11:32:08 +01:00
|
|
|
|
@priv_required('admin-panel')
|
2019-02-10 15:46:53 +01:00
|
|
|
|
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('admin-manel')
|
|
|
|
|
def adm_groups():
|
|
|
|
|
class GroupRegenerationForm(FlaskForm):
|
2019-02-09 21:18:12 +01:00
|
|
|
|
submit = SubmitField('Régénérer les groupes, privilèges, et comptes communs')
|
2019-02-04 16:41:29 +01:00
|
|
|
|
|
2019-02-10 15:46:53 +01:00
|
|
|
|
form = GroupRegenerationForm()
|
2019-02-04 16:41:29 +01:00
|
|
|
|
if form.validate_on_submit():
|
|
|
|
|
# Clean up groups
|
|
|
|
|
for g in Group.query.all():
|
2019-02-10 18:51:53 +01:00
|
|
|
|
g.delete()
|
2019-02-04 16:41:29 +01:00
|
|
|
|
|
|
|
|
|
# Create base groups
|
2019-02-10 15:46:53 +01:00
|
|
|
|
groups = [ Group(g[0], g[1], g[2]) for g in default_groups ]
|
2019-02-09 21:18:12 +01:00
|
|
|
|
for g in groups:
|
2019-02-10 15:46:53 +01:00
|
|
|
|
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()
|
2019-02-04 16:41:29 +01:00
|
|
|
|
|
|
|
|
|
# Clean up test members
|
|
|
|
|
for name in "PlanèteCasio GLaDOS".split():
|
|
|
|
|
m = Member.query.filter_by(name=name).first()
|
|
|
|
|
if m is not None:
|
2019-02-10 18:51:53 +01:00
|
|
|
|
m.delete()
|
2019-02-04 16:41:29 +01:00
|
|
|
|
|
|
|
|
|
# Create template members
|
2019-02-09 21:18:12 +01:00
|
|
|
|
|
|
|
|
|
def addgroup(member, group):
|
|
|
|
|
g = Group.query.filter_by(name=group).first()
|
|
|
|
|
if g is not None:
|
|
|
|
|
member.groups.append(g)
|
|
|
|
|
|
2019-02-04 16:41:29 +01:00
|
|
|
|
m = Member('PlanèteCasio','contact@planet-casio.com','v5-forever')
|
2019-02-09 21:18:12 +01:00
|
|
|
|
addgroup(m, "Compte communautaire")
|
2019-02-04 16:41:29 +01:00
|
|
|
|
db.session.add(m)
|
|
|
|
|
|
|
|
|
|
m = Member('GLaDOS', 'glados@aperture.science', 'v5-forever')
|
2019-02-09 21:18:12 +01:00
|
|
|
|
addgroup(m, "Robot")
|
2019-02-04 16:41:29 +01:00
|
|
|
|
db.session.add(m)
|
2019-02-10 15:46:53 +01:00
|
|
|
|
db.session.commit()
|
|
|
|
|
|
2019-02-04 16:41:29 +01:00
|
|
|
|
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()
|
2019-02-10 15:46:53 +01:00
|
|
|
|
return render('admin/groups_privileges.html', users=users, groups=groups, form=form)
|
2019-02-06 12:44:44 +01:00
|
|
|
|
|
|
|
|
|
@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(
|
|
|
|
|
email = form.email.data or None,
|
|
|
|
|
password = form.password.data or None,
|
|
|
|
|
birthday = form.birthday.data,
|
|
|
|
|
signature = form.signature.data,
|
|
|
|
|
bio = form.biography.data,
|
2019-02-06 13:12:03 +01:00
|
|
|
|
newsletter = form.newsletter.data,
|
|
|
|
|
xp = form.xp.data or None,
|
|
|
|
|
innovation = form.innovation.data or None
|
2019-02-06 12:44:44 +01:00
|
|
|
|
)
|
|
|
|
|
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):
|
2019-02-10 15:46:53 +01:00
|
|
|
|
user = Member.query.filter_by(id=user_id).first_or_404()
|
2019-02-09 21:18:12 +01:00
|
|
|
|
|
|
|
|
|
# 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.
|
2019-02-06 12:44:44 +01:00
|
|
|
|
del_form = AdminDeleteAccountForm()
|
|
|
|
|
if request.method == "POST":
|
|
|
|
|
if del_form.validate_on_submit():
|
2019-02-10 18:51:53 +01:00
|
|
|
|
user.delete()
|
2019-02-06 12:44:44 +01:00
|
|
|
|
flash('Compte supprimé', 'ok')
|
2019-02-10 15:46:53 +01:00
|
|
|
|
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, del_form=del_form)
|