From bc97eb1eb4bb3943ad60bf3569c05255386953d0 Mon Sep 17 00:00:00 2001
From: Yohann D'ANELLO <yohann.danello@gmail.com>
Date: Wed, 11 Mar 2020 10:08:28 +0100
Subject: [PATCH] Add logs to the API (this right should only be given to
 superusers)

---
 apps/api/urls.py             |  2 ++
 apps/logs/api/__init__.py    |  0
 apps/logs/api/serializers.py | 17 +++++++++++++++++
 apps/logs/api/urls.py        | 11 +++++++++++
 apps/logs/api/views.py       | 17 +++++++++++++++++
 apps/logs/models.py          |  6 ++++++
 apps/logs/signals.py         |  7 ++++---
 note_kfet/settings/base.py   |  1 +
 8 files changed, 58 insertions(+), 3 deletions(-)
 create mode 100644 apps/logs/api/__init__.py
 create mode 100644 apps/logs/api/serializers.py
 create mode 100644 apps/logs/api/urls.py
 create mode 100644 apps/logs/api/views.py

diff --git a/apps/api/urls.py b/apps/api/urls.py
index c1b6bf48..bb1fdce2 100644
--- a/apps/api/urls.py
+++ b/apps/api/urls.py
@@ -7,6 +7,7 @@ from rest_framework import routers, serializers, viewsets
 from activity.api.urls import register_activity_urls
 from member.api.urls import register_members_urls
 from note.api.urls import register_note_urls
+from logs.api.urls import register_logs_urls
 
 
 class UserSerializer(serializers.ModelSerializer):
@@ -41,6 +42,7 @@ router.register('user', UserViewSet)
 register_members_urls(router, 'members')
 register_activity_urls(router, 'activity')
 register_note_urls(router, 'note')
+register_logs_urls(router, 'logs')
 
 app_name = 'api'
 
diff --git a/apps/logs/api/__init__.py b/apps/logs/api/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/apps/logs/api/serializers.py b/apps/logs/api/serializers.py
new file mode 100644
index 00000000..7de7bc1a
--- /dev/null
+++ b/apps/logs/api/serializers.py
@@ -0,0 +1,17 @@
+# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from rest_framework import serializers
+
+from ..models import Changelog
+
+
+class ChangelogSerializer(serializers.ModelSerializer):
+    """
+    REST API Serializer for Changelog types.
+    The djangorestframework plugin will analyse the model `Changelog` and parse all fields in the API.
+    """
+
+    class Meta:
+        model = Changelog
+        fields = '__all__'
diff --git a/apps/logs/api/urls.py b/apps/logs/api/urls.py
new file mode 100644
index 00000000..9a0ceaa8
--- /dev/null
+++ b/apps/logs/api/urls.py
@@ -0,0 +1,11 @@
+# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from .views import ChangelogViewSet
+
+
+def register_logs_urls(router, path):
+    """
+    Configure router for Activity REST API.
+    """
+    router.register(path, ChangelogViewSet)
diff --git a/apps/logs/api/views.py b/apps/logs/api/views.py
new file mode 100644
index 00000000..60da612b
--- /dev/null
+++ b/apps/logs/api/views.py
@@ -0,0 +1,17 @@
+# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from rest_framework import viewsets
+
+from .serializers import ChangelogSerializer
+from ..models import Changelog
+
+
+class ChangelogViewSet(viewsets.ModelViewSet):
+    """
+    REST API View set.
+    The djangorestframework plugin will get all `Changelog` objects, serialize it to JSON with the given serializer,
+    then render it on /api/logs/
+    """
+    queryset = Changelog.objects.all()
+    serializer_class = ChangelogSerializer
diff --git a/apps/logs/models.py b/apps/logs/models.py
index 9ab3cf6a..10e2651f 100644
--- a/apps/logs/models.py
+++ b/apps/logs/models.py
@@ -56,6 +56,12 @@ class Changelog(models.Model):
         max_length=16,
         null=False,
         blank=False,
+        choices=[
+            ('create', _('create')),
+            ('edit', _('edit')),
+            ('delete', _('delete')),
+        ],
+        default='edit',
         verbose_name=_('action'),
     )
 
diff --git a/apps/logs/signals.py b/apps/logs/signals.py
index 1cd74067..41f87cda 100644
--- a/apps/logs/signals.py
+++ b/apps/logs/signals.py
@@ -69,6 +69,7 @@ def save_object(sender, instance, **kwargs):
         else:
             user = note.get().user
 
+    # noinspection PyProtectedMember
     if user is not None and instance._meta.label_lower == "auth.user" and previous:
         # On n'enregistre pas les connexions
         if instance.last_login != previous.last_login:
@@ -80,8 +81,8 @@ def save_object(sender, instance, **kwargs):
             model = instance.__class__
             fields = '__all__'
 
-    previous_json = JSONRenderer().render(CustomSerializer(previous).data)
-    instance_json = JSONRenderer().render(CustomSerializer(instance).data)
+    previous_json = JSONRenderer().render(CustomSerializer(previous).data).decode("UTF-8")
+    instance_json = JSONRenderer().render(CustomSerializer(instance).data).decode("UTF-8")
 
     if previous_json == instance_json:
         # Pas de log s'il n'y a pas de modification
@@ -115,7 +116,7 @@ def delete_object(sender, instance, **kwargs):
             model = instance.__class__
             fields = '__all__'
 
-    instance_json = JSONRenderer().render(CustomSerializer(instance).data)
+    instance_json = JSONRenderer().render(CustomSerializer(instance).data).decode("UTF-8")
 
     Changelog.objects.create(user=user,
                              ip=ip,
diff --git a/note_kfet/settings/base.py b/note_kfet/settings/base.py
index 737350e2..84f07b6c 100644
--- a/note_kfet/settings/base.py
+++ b/note_kfet/settings/base.py
@@ -140,6 +140,7 @@ REST_FRAMEWORK = {
         'rest_framework.permissions.DjangoModelPermissions'
     ],
     'DEFAULT_AUTHENTICATION_CLASSES': [
+        'rest_framework.authentication.SessionAuthentication',
         'rest_framework.authentication.TokenAuthentication',
     ]
 }
-- 
GitLab