From fbf64db16e193b9a89617a5a238fc9436c5a1fd1 Mon Sep 17 00:00:00 2001
From: Yohann D'ANELLO <ynerant@crans.org>
Date: Thu, 17 Jun 2021 22:29:57 +0200
Subject: [PATCH] Simple test to check permissions with the new OAuth2
 implementation

Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
---
 apps/permission/backends.py          |  2 +-
 apps/permission/tests/test_oauth2.py | 94 ++++++++++++++++++++++++++++
 2 files changed, 95 insertions(+), 1 deletion(-)
 create mode 100644 apps/permission/tests/test_oauth2.py

diff --git a/apps/permission/backends.py b/apps/permission/backends.py
index 40bfb085..af071455 100644
--- a/apps/permission/backends.py
+++ b/apps/permission/backends.py
@@ -48,7 +48,7 @@ class PermissionBackend(ModelBackend):
             user = request.user
 
             def permission_filter(membership_obj):
-                return Q(mask__rank__lte=request.session.get("permission_mask", -1))
+                return Q(mask__rank__lte=request.session.get("permission_mask", 42))
 
         if user.is_anonymous:
             # Unauthenticated users have no permissions
diff --git a/apps/permission/tests/test_oauth2.py b/apps/permission/tests/test_oauth2.py
new file mode 100644
index 00000000..4593b35a
--- /dev/null
+++ b/apps/permission/tests/test_oauth2.py
@@ -0,0 +1,94 @@
+# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from datetime import timedelta
+
+from django.contrib.auth.models import User
+from django.test import TestCase
+from django.urls import reverse
+from django.utils import timezone
+from django.utils.crypto import get_random_string
+from member.models import Membership, Club
+from note.models import NoteUser
+from oauth2_provider.models import Application, AccessToken
+
+from ..models import Role, Permission
+
+
+class OAuth2TestCase(TestCase):
+    fixtures = ('initial', )
+
+    def setUp(self):
+        self.user = User.objects.create(
+            username="toto",
+        )
+        self.application = Application.objects.create(
+            name="Test",
+            client_type=Application.CLIENT_PUBLIC,
+            authorization_grant_type=Application.GRANT_AUTHORIZATION_CODE,
+            user=self.user,
+        )
+
+    def test_oauth2_access(self):
+        """
+        Create a simple OAuth2 access token that only has the right to see data of the current user
+        and check that this token has required access, and nothing more.
+        """
+
+        bde = Club.objects.get(name="BDE")
+        view_user_perm = Permission.objects.get(pk=1)  # View own user detail
+
+        # Create access token that has access to our own user detail
+        token = AccessToken.objects.create(
+            user=self.user,
+            application=self.application,
+            scope=f"{view_user_perm.pk}_{bde.pk}",
+            token=get_random_string(64),
+            expires=timezone.now() + timedelta(days=365),
+        )
+
+        # No access without token
+        resp = self.client.get(f'/api/user/{self.user.pk}/')
+        self.assertEqual(resp.status_code, 403)
+
+        # Valid token but user has no membership, so the query is not returning the user object
+        resp = self.client.get(f'/api/user/{self.user.pk}/', **{'Authorization': f'Bearer {token.token}'})
+        self.assertEqual(resp.status_code, 404)
+
+        # Create membership to validate permissions
+        NoteUser.objects.create(user=self.user)
+        membership = Membership.objects.create(user=self.user, club_id=bde.pk)
+        membership.roles.add(Role.objects.get(name="Adhérent BDE"))
+        membership.save()
+
+        # User is now a member and can now see its own user detail
+        resp = self.client.get(f'/api/user/{self.user.pk}/', **{'Authorization': f'Bearer {token.token}'})
+        self.assertEqual(resp.status_code, 200)
+
+        # Token is not granted to see profile detail
+        resp = self.client.get(f'/api/members/profile/{self.user.profile.pk}/',
+                               **{'Authorization': f'Bearer {token.token}'})
+        self.assertEqual(resp.status_code, 404)
+
+    def test_scopes(self):
+        """
+        Ensure that the scopes page is loading.
+        """
+        self.client.force_login(self.user)
+
+        resp = self.client.get(reverse('permission:scopes'))
+        self.assertEqual(resp.status_code, 200)
+        self.assertIn(self.application, resp.context['scopes'])
+        self.assertNotIn('1_1', resp.context['scopes'][self.application])  # The user has not this permission
+
+        # Create membership to validate permissions
+        bde = Club.objects.get(name="BDE")
+        NoteUser.objects.create(user=self.user)
+        membership = Membership.objects.create(user=self.user, club_id=bde.pk)
+        membership.roles.add(Role.objects.get(name="Adhérent BDE"))
+        membership.save()
+
+        resp = self.client.get(reverse('permission:scopes'))
+        self.assertEqual(resp.status_code, 200)
+        self.assertIn(self.application, resp.context['scopes'])
+        self.assertIn('1_1', resp.context['scopes'][self.application])  # Now the user has this permission
-- 
GitLab