PCv5/app/routes/admin/login_as.py

101 lines
3.3 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, 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)
# 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