From 09eabe35fae8260e7d4971f3c1f8d2e85f6460ed Mon Sep 17 00:00:00 2001
From: Monty Dawson <wgd23@cam.ac.uk>
Date: Tue, 15 Mar 2022 11:29:30 +0000
Subject: [PATCH] Add tests for permissions spec methods

---
 .../tests/mocks/permissions_spec.py           | 23 +++++++++
 apigatewayauth/tests/test_permissions.py      | 50 ++++++++++++++++++-
 2 files changed, 72 insertions(+), 1 deletion(-)
 create mode 100644 apigatewayauth/tests/mocks/permissions_spec.py

diff --git a/apigatewayauth/tests/mocks/permissions_spec.py b/apigatewayauth/tests/mocks/permissions_spec.py
new file mode 100644
index 0000000..b0d66a8
--- /dev/null
+++ b/apigatewayauth/tests/mocks/permissions_spec.py
@@ -0,0 +1,23 @@
+from typing import Dict
+from functools import wraps
+from tempfile import NamedTemporaryFile
+import yaml
+
+from django.test import override_settings
+
+
+def override_permission_spec(permissions_spec: Dict[str, Dict[str, str]]):
+    """
+    A decorator which allows the permissions specification to be mocked, allowing a
+    permission to only be enabled for the given identities.
+
+    """
+    def decorator(func):
+        @wraps(func)
+        def wrapped_function(*args, **kwargs):
+            with NamedTemporaryFile('w+') as temp_file:
+                yaml.dump(permissions_spec, temp_file.file)
+                with override_settings(PERMISSIONS_SPECIFICATION_URL=temp_file.name):
+                    func(*args, **kwargs)
+        return wrapped_function
+    return decorator
diff --git a/apigatewayauth/tests/test_permissions.py b/apigatewayauth/tests/test_permissions.py
index 6c53499..6a2fa46 100644
--- a/apigatewayauth/tests/test_permissions.py
+++ b/apigatewayauth/tests/test_permissions.py
@@ -4,6 +4,7 @@ from identitylib.identifiers import Identifier, IdentifierSchemes
 from rest_framework.test import APIRequestFactory
 from ucamlookup.ibisclient import IbisException
 
+from .mocks.permissions_spec import override_permission_spec
 from .mocks.mock_ibis import MockIbisGroup
 from .mocks.models import TestModel
 
@@ -13,7 +14,8 @@ from apigatewayauth.permissions import (
     Disallowed,
     HasAnyScope,
     SpecifiedPermission,
-    IsResourceOwningPrincipal
+    IsResourceOwningPrincipal,
+    get_permissions_for_request
 )
 
 
@@ -337,3 +339,49 @@ class PermissionsTestCase(TestCase):
         get_groups_mock.assert_called_with(
             scheme='crsid', identifier=self.client_auth_details.principal_identifier.value
         )
+
+    @override_permission_spec({
+        'DATA_READER': {
+            'principals': {
+                str(Identifier('abc44', IdentifierSchemes.CRSID)),
+                str(Identifier('abc55', IdentifierSchemes.CRSID))
+            }
+        },
+        'DATA_OWNER': {
+            'principals': {
+                str(Identifier('abc44', IdentifierSchemes.CRSID))
+            }
+        }
+    })
+    def test_get_permissions_for_request(self):
+        """
+        Test that `get_permissions_for_request` returns correctly based on the user authenticated
+        on the request.
+
+        """
+
+        mock_request = APIRequestFactory().get('/')
+        setattr(mock_request, 'auth', None)
+
+        # expect an empty list to be returned if no auth details provided
+        self.assertListEqual(get_permissions_for_request(mock_request), [])
+
+        # if we have a principal not in our permissions spec we should get an empty list
+        mock_request.auth = APIGatewayAuthenticationDetails(
+            Identifier('abc123', IdentifierSchemes.CRSID), []
+        )
+        self.assertListEqual(get_permissions_for_request(mock_request), [])
+
+        # abc55 should be shown as a `DATA_READER`
+        mock_request.auth = APIGatewayAuthenticationDetails(
+            Identifier('abc55', IdentifierSchemes.CRSID), []
+        )
+        self.assertListEqual(get_permissions_for_request(mock_request), ['DATA_READER'])
+
+        # abc44 should be shown as a `DATA_READER` and `DATA_WRITER`
+        mock_request.auth = APIGatewayAuthenticationDetails(
+            Identifier('abc44', IdentifierSchemes.CRSID), []
+        )
+        self.assertListEqual(
+            get_permissions_for_request(mock_request), ['DATA_OWNER', 'DATA_READER']
+        )
-- 
GitLab