Repository: zestedesavoir/zds-site

Issue:
La désinscription ne permet pas de supprimer les clées de l'api
Lorsque un membre se désinscrit, il serait bien de supprimer ses clées d'api.



Discussion:
@SpaceFox @andr0 bloquant non? possiblement faille de sécurité?

@artragis Tu peux un peu développer et expliquer en quoi cela pourrait être bloquant et/ou une faille de sécurité ?

C'est pas bloquant, au pire on peut révoquer à la main les clées donc ça serait plus pratique de le faire automatiquement. C'est tout.

C'est pas vraiment une faille de sécurité, tu peux rien accéder de plus. C'est juste que si le mec commence à faire nawak, on lui supprime ses clés manuellement.


Resolving patch:
diff --git a/zds/member/views.py b/zds/member/views.py
--- a/zds/member/views.py
+++ b/zds/member/views.py
@@ -3,6 +3,8 @@
 import uuid
 from datetime import datetime, timedelta
 
+from oauth2_provider.models import AccessToken
+
 from django.conf import settings
 from django.contrib import messages
 from django.contrib.auth import authenticate, login, logout
@@ -432,6 +434,10 @@ def unregister(request):
             anonymous_gallery.save()
         gallery.delete()
 
+    # remove API access (tokens + applications)
+    for token in AccessToken.objects.filter(user=current):
+        token.revoke()
+
     logout(request)
     User.objects.filter(pk=current.pk).delete()
     return redirect(reverse("homepage"))


Test patch:
diff --git a/zds/member/tests/tests_views.py b/zds/member/tests/tests_views.py
--- a/zds/member/tests/tests_views.py
+++ b/zds/member/tests/tests_views.py
@@ -1,7 +1,11 @@
 # coding: utf-8
 
+from datetime import datetime
 import os
 import shutil
+
+from oauth2_provider.models import AccessToken, Application
+
 from django.conf import settings
 from django.contrib.auth.models import User, Group
 from django.core import mail
@@ -412,6 +416,25 @@ def test_unregister(self):
         private_topic.save()
         PrivatePostFactory(author=user.user, privatetopic=private_topic, position_in_topic=1)
 
+        # add API key
+        self.assertEqual(Application.objects.count(), 0)
+        self.assertEqual(AccessToken.objects.count(), 0)
+        api_application = Application()
+        api_application.client_id = 'foobar'
+        api_application.user = user.user
+        api_application.client_type = 'confidential'
+        api_application.authorization_grant_type = 'password'
+        api_application.client_secret = '42'
+        api_application.save()
+        token = AccessToken()
+        token.user = user.user
+        token.token = 'r@d0m'
+        token.application = api_application
+        token.expires = datetime.now()
+        token.save()
+        self.assertEqual(Application.objects.count(), 1)
+        self.assertEqual(AccessToken.objects.count(), 1)
+
         # login and unregister:
         login_check = self.client.login(
             username=user.user.username,
@@ -511,6 +534,10 @@ def test_unregister(self):
         self.assertTrue(Topic.objects.get(pk=beta_content.beta_topic.pk).is_locked)
         self.assertFalse(Topic.objects.get(pk=beta_content_2.beta_topic.pk).is_locked)
 
+        # check API
+        self.assertEqual(Application.objects.count(), 0)
+        self.assertEqual(AccessToken.objects.count(), 0)
+
     def test_forgot_password(self):
         """To test nominal scenario of a lost password."""