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 import yaml import os @app.route('/admin', methods=['GET', 'POST']) @priv_required('access-admin-panel') def adm(): return render('admin/index.html') @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 = [] with open(os.path.join(app.root_path, "data", "groups.yaml")) as fp: groups = yaml.load(fp.read()) for g in groups: g["obj"] = Group(g["name"], g["css"], g["descr"]) db.session.add(g["obj"]) db.session.commit() for g in groups: for priv in g.get("privs", "").split(): db.session.add(GroupPrivilege(g["obj"], 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/', 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//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)