Skip to content
Snippets Groups Projects
Commit db69091d authored by ynerant's avatar ynerant
Browse files

When an update is made from the shell, the username of the user connected to the shell is queried

parent 20e2d415
No related branches found
No related tags found
1 merge request!56Corrections
Pipeline #7894 passed with warnings with stages
in 4 minutes and 1 second
......@@ -13,11 +13,6 @@ _thread_locals = local()
def _set_current_user_and_ip(user=None, ip=None):
"""
Sets current user in local thread.
Can be used as a hook e.g. for shell jobs (when request object is not
available).
"""
setattr(_thread_locals, USER_ATTR_NAME, user)
setattr(_thread_locals, IP_ATTR_NAME, ip)
......@@ -38,6 +33,10 @@ def get_current_authenticated_user():
class LogsMiddleware(object):
"""
Ce middleware permet de récupérer l'utilisateur actif ainsi que son adresse IP à chaque connexion.
"""
def __init__(self, get_response):
self.get_response = get_response
......@@ -49,7 +48,7 @@ class LogsMiddleware(object):
ip = request.META.get('REMOTE_ADDR')
_set_current_user_and_ip(user, ip)
response = self.get_response(request)
_set_current_user_and_ip(None, None)
return response
......@@ -5,11 +5,14 @@ from django.contrib.contenttypes.models import ContentType
from django.core import serializers
from django.db.models.signals import pre_save, post_save, post_delete
from django.dispatch import receiver
import getpass
from note.models import NoteUser, Alias
from .middlewares import get_current_authenticated_user, get_current_ip
from .models import Changelog
# Ces modèles ne nécessitent pas de logs
EXCLUDED = [
'admin.logentry',
'authtoken.token',
......@@ -22,13 +25,15 @@ EXCLUDED = [
'note.noteclub',
'note.notespecial',
'sessions.session',
'reversion.revision',
'reversion.version',
]
@receiver(pre_save)
def pre_save_object(sender, instance, **kwargs):
"""
Avant la sauvegarde d'un modèle, on récupère l'ancienne instance actuellement en base de données
que l'on garde en mémoire
"""
qs = sender.objects.filter(pk=instance.pk).all()
if qs.exists():
instance._previous = qs.get()
......@@ -38,26 +43,43 @@ def pre_save_object(sender, instance, **kwargs):
@receiver(post_save)
def save_object(sender, instance, **kwargs):
"""
Dès qu'un modèle est sauvegardé, une entrée dans la table `Changelog` est ajouté dans la base de données
afin de répertorier chaque modification effectuée
"""
# noinspection PyProtectedMember
if instance._meta.label_lower in EXCLUDED:
return
print("LOGGING SOMETHING")
# noinspection PyProtectedMember
previous = instance._previous
# Si un utilisateur est connecté, on récupère l'utilisateur courant ainsi que son adresse IP
user, ip = get_current_authenticated_user(), get_current_ip()
if user is None:
# Si la modification n'a pas été faite via le client Web, on suppose que c'est du à `manage.py`
# On récupère alors l'utilisateur·trice connecté·e à la VM, et on récupère la note associée
# IMPORTANT : l'utilisateur dans la VM doit être un des alias note du respo info
ip = "127.0.0.1"
username = Alias.normalize(getpass.getuser())
note = NoteUser.objects.filter(alias__normalized_name__regex="^" + username + "$")
if not note.exists():
print("WARNING: A model attempted to be saved in the DB, but the actor is unknown: " + username)
else:
user = note.get().user
if user is not None and instance._meta.label_lower == "auth.user" and previous:
# Don't save last login modifications
# On n'enregistre pas les connexions
if instance.last_login != previous.last_login:
return
# Les modèles sont sauvegardés au format JSON
previous_json = serializers.serialize('json', [previous, ])[1:-1] if previous else None
instance_json = serializers.serialize('json', [instance, ])[1:-1]
if previous_json == instance_json:
# No modification
# Pas de log s'il n'y a pas de modification
return
Changelog.objects.create(user=user,
......@@ -72,10 +94,14 @@ def save_object(sender, instance, **kwargs):
@receiver(post_delete)
def delete_object(sender, instance, **kwargs):
"""
Dès qu'un modèle est supprimé, une entrée dans la table `Changelog` est ajouté dans la base de données
"""
# noinspection PyProtectedMember
if instance._meta.label_lower in EXCLUDED:
return
# Si un utilisateur est connecté, on récupère l'utilisateur courant ainsi que son adresse IP
user, ip = get_current_authenticated_user(), get_current_ip()
instance_json = serializers.serialize('json', [instance, ])[1:-1]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment