PCv5/app/routes/admin/login_as.py

101 lines
3.3 KiB
Python
Raw Normal View History

from flask import request, flash, make_response, redirect, url_for, abort
from flask_login import current_user, login_user, logout_user, login_required
from itsdangerous import Serializer
from itsdangerous.exc import BadSignature
from app import app
from app.utils.render import render
from app.utils.login_as import is_vandal
from app.utils.unicode_names import normalize
from app.models.user import Member
from app.models.priv import Group
from app.forms.login_as import LoginAsForm
@app.route("/admin/vandalisme", methods=['GET', 'POST'])
@login_required
def adm_login_as():
""" Show a basic form and login as arbitrary user when asked """
# Basic permission
if (not current_user.priv("misc.arbitrary-login") and
not current_user.priv("misc.community-login")):
abort(403)
if is_vandal():
flash("Vous êtes déjà authentifié", "error")
return redirect(url_for('index'))
# Handle form
form = LoginAsForm()
if form.validate_on_submit():
norm = normalize(form.username.data)
user = Member.query.filter_by(norm=norm).one()
if user is None:
flash("Utilisateur invalide", "error")
return render('admin/login_as.html', form=form)
# Apply for community login
g = Group.query.filter_by(name="Compte communautaire").one()
is_community = g in user.groups
if not is_community and not current_user.priv("misc.arbitrary-login"):
abort(403)
# Create a safe token to flee when needed
s = Serializer(app.config["SECRET_KEY"])
vandal_token = s.dumps(current_user.id)
vandal_name = current_user.name
# Login and display some messages
login_user(user)
if user.name == "GLaDOS":
flash("Vous espérez quoi exactement? Survivre? "
"Dans ce cas, évitez de me faire du mal.")
else:
flash(f"Connecté en tant que {user.name}")
app.v5logger.info(f"[admin] <{vandal_name}> has logged in as <{user.name}>")
# Return the response
resp = make_response(redirect(url_for('index')))
resp.set_cookie('vandale', vandal_token, path='/')
return resp
# Else return form
return render('admin/login_as.html', form=form)
@app.route("/admin/vandalisme/fuir")
@login_required
def adm_logout_as():
""" Log out as a vandalized user, login back as admin """
s = Serializer(app.config["SECRET_KEY"])
vandal_token = request.cookies.get('vandale')
if vandal_token is None:
abort(403)
try:
id = s.loads(vandal_token)
except BadSignature:
flash("Vous avez vraiment agi de manière stupide.", "error")
abort(403)
user = Member.query.get(id)
2023-06-20 19:38:04 +02:00
# Send a notification to vandalized user
current_user.notify(f"{user.name} a accédé à ce compte à des fins de modération",
url_for('user', username=user.name))
# Switch back to admin
victim_name = current_user.name
logout_user()
login_user(user)
app.v5logger.info(f"[admin] <{user.name}> has logged out from <{victim_name}>'s account")
if request.referrer:
resp = make_response(redirect(request.referrer))
else:
resp = make_response(redirect(url_for('index')))
resp.set_cookie('vandale', '', expires=0, path='/')
return resp