Просмотр исходного кода

Tweak settings/middleware to support testing; improve tests

Jeremy Stretch 6 лет назад
Родитель
Сommit
7ffc00159e

+ 2 - 4
netbox/netbox/settings.py

@@ -277,13 +277,12 @@ MIDDLEWARE = [
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
     'django.middleware.security.SecurityMiddleware',
     'utilities.middleware.ExceptionHandlingMiddleware',
+    'utilities.middleware.RemoteUserMiddleware',
     'utilities.middleware.LoginRequiredMiddleware',
     'utilities.middleware.APIVersionMiddleware',
     'extras.middleware.ObjectChangeMiddleware',
     'django_prometheus.middleware.PrometheusAfterMiddleware',
 ]
-if REMOTE_AUTH_ENABLED:
-    MIDDLEWARE.append('utilities.middleware.RemoteUserMiddleware')
 
 ROOT_URLCONF = 'netbox.urls'
 
@@ -308,10 +307,9 @@ TEMPLATES = [
 
 # Set up authentication backends
 AUTHENTICATION_BACKENDS = [
+    REMOTE_AUTH_BACKEND,
     'utilities.auth_backends.ViewExemptModelBackend',
 ]
-if REMOTE_AUTH_ENABLED:
-    AUTHENTICATION_BACKENDS.insert(0, REMOTE_AUTH_BACKEND)
 
 # Internationalization
 LANGUAGE_CODE = 'en-us'

+ 66 - 31
netbox/netbox/tests/test_authentication.py

@@ -1,4 +1,5 @@
-from django.contrib.auth.models import Group, Permission, User
+from django.conf import settings
+from django.contrib.auth.models import Group, User
 from django.test import Client, TestCase
 from django.test.utils import override_settings
 from django.urls import reverse
@@ -6,11 +7,36 @@ from django.urls import reverse
 
 class ExternalAuthenticationTestCase(TestCase):
 
+    @classmethod
+    def setUpTestData(cls):
+        cls.user = User.objects.create(username='remoteuser1')
+
+    def setUp(self):
+        self.client = Client()
+
+    @override_settings(
+        LOGIN_REQUIRED=True
+    )
+    def test_remote_auth_disabled(self):
+        """
+        Test enabling remote authentication with the default configuration.
+        """
+        headers = {
+            'HTTP_REMOTE_USER': 'remoteuser1',
+        }
+
+        self.assertFalse(settings.REMOTE_AUTH_ENABLED)
+        self.assertEqual(settings.REMOTE_AUTH_HEADER, 'HTTP_REMOTE_USER')
+
+        # Client should not be authenticated
+        response = self.client.get(reverse('home'), follow=True, **headers)
+        self.assertNotIn('_auth_user_id', self.client.session)
+
     @override_settings(
         REMOTE_AUTH_ENABLED=True,
         LOGIN_REQUIRED=True
     )
-    def test_remote_auth(self):
+    def test_remote_auth_enabled(self):
         """
         Test enabling remote authentication with the default configuration.
         """
@@ -18,12 +44,12 @@ class ExternalAuthenticationTestCase(TestCase):
             'HTTP_REMOTE_USER': 'remoteuser1',
         }
 
-        self.client = Client()
+        self.assertTrue(settings.REMOTE_AUTH_ENABLED)
+        self.assertEqual(settings.REMOTE_AUTH_HEADER, 'HTTP_REMOTE_USER')
+
         response = self.client.get(reverse('home'), follow=True, **headers)
         self.assertEqual(response.status_code, 200)
-
-        user = User.objects.get(username='remoteuser1')
-        self.assertEqual(int(self.client.session['_auth_user_id']), user.pk, msg='Authentication failed')
+        self.assertEqual(int(self.client.session.get('_auth_user_id')), self.user.pk, msg='Authentication failed')
 
     @override_settings(
         REMOTE_AUTH_ENABLED=True,
@@ -38,40 +64,40 @@ class ExternalAuthenticationTestCase(TestCase):
             'HTTP_FOO': 'remoteuser1',
         }
 
-        self.client = Client()
+        self.assertTrue(settings.REMOTE_AUTH_ENABLED)
+        self.assertEqual(settings.REMOTE_AUTH_HEADER, 'HTTP_FOO')
+
         response = self.client.get(reverse('home'), follow=True, **headers)
         self.assertEqual(response.status_code, 200)
-
-        user = User.objects.get(username='remoteuser1')
-        self.assertEqual(int(self.client.session['_auth_user_id']), user.pk, msg='Authentication failed')
+        self.assertEqual(int(self.client.session.get('_auth_user_id')), self.user.pk, msg='Authentication failed')
 
     @override_settings(
         REMOTE_AUTH_ENABLED=True,
-        REMOTE_AUTH_AUTO_CREATE_USER=False,
+        REMOTE_AUTH_AUTO_CREATE_USER=True,
         LOGIN_REQUIRED=True
     )
-    def test_remote_auth_no_auto_create(self):
+    def test_remote_auth_auto_create(self):
         """
         Test enabling remote authentication with automatic user creation disabled.
         """
         headers = {
-            'HTTP_REMOTE_USER': 'remoteuser1',
+            'HTTP_REMOTE_USER': 'remoteuser2',
         }
 
-        self.client = Client()
+        self.assertTrue(settings.REMOTE_AUTH_ENABLED)
+        self.assertTrue(settings.REMOTE_AUTH_AUTO_CREATE_USER)
+        self.assertEqual(settings.REMOTE_AUTH_HEADER, 'HTTP_REMOTE_USER')
 
-        # First attempt should fail as the user does not exist
-        self.client.get(reverse('home'), **headers)
-        self.assertNotIn('_auth_user_id', self.client.session)
-
-        # Create the user locally and try again
-        user = User.objects.create(username='remoteuser1')
         response = self.client.get(reverse('home'), follow=True, **headers)
         self.assertEqual(response.status_code, 200)
-        self.assertEqual(int(self.client.session['_auth_user_id']), user.pk, msg='Authentication failed')
+
+        # Local user should have been automatically created
+        new_user = User.objects.get(username='remoteuser2')
+        self.assertEqual(int(self.client.session.get('_auth_user_id')), new_user.pk, msg='Authentication failed')
 
     @override_settings(
         REMOTE_AUTH_ENABLED=True,
+        REMOTE_AUTH_AUTO_CREATE_USER=True,
         REMOTE_AUTH_DEFAULT_GROUPS=['Group 1', 'Group 2'],
         LOGIN_REQUIRED=True
     )
@@ -80,9 +106,14 @@ class ExternalAuthenticationTestCase(TestCase):
         Test enabling remote authentication with the default configuration.
         """
         headers = {
-            'HTTP_REMOTE_USER': 'remoteuser1',
+            'HTTP_REMOTE_USER': 'remoteuser2',
         }
 
+        self.assertTrue(settings.REMOTE_AUTH_ENABLED)
+        self.assertTrue(settings.REMOTE_AUTH_AUTO_CREATE_USER)
+        self.assertEqual(settings.REMOTE_AUTH_HEADER, 'HTTP_REMOTE_USER')
+        self.assertEqual(settings.REMOTE_AUTH_DEFAULT_GROUPS, ['Group 1', 'Group 2'])
+
         # Create required groups
         groups = (
             Group(name='Group 1'),
@@ -91,19 +122,19 @@ class ExternalAuthenticationTestCase(TestCase):
         )
         Group.objects.bulk_create(groups)
 
-        self.client = Client()
         response = self.client.get(reverse('home'), follow=True, **headers)
         self.assertEqual(response.status_code, 200)
 
-        user = User.objects.get(username='remoteuser1')
-        self.assertEqual(int(self.client.session['_auth_user_id']), user.pk, msg='Authentication failed')
+        new_user = User.objects.get(username='remoteuser2')
+        self.assertEqual(int(self.client.session.get('_auth_user_id')), new_user.pk, msg='Authentication failed')
         self.assertListEqual(
             [groups[0], groups[1]],
-            list(user.groups.all())
+            list(new_user.groups.all())
         )
 
     @override_settings(
         REMOTE_AUTH_ENABLED=True,
+        REMOTE_AUTH_AUTO_CREATE_USER=True,
         REMOTE_AUTH_DEFAULT_PERMISSIONS=['dcim.add_site', 'dcim.change_site'],
         LOGIN_REQUIRED=True
     )
@@ -112,13 +143,17 @@ class ExternalAuthenticationTestCase(TestCase):
         Test enabling remote authentication with the default configuration.
         """
         headers = {
-            'HTTP_REMOTE_USER': 'remoteuser1',
+            'HTTP_REMOTE_USER': 'remoteuser2',
         }
 
-        self.client = Client()
+        self.assertTrue(settings.REMOTE_AUTH_ENABLED)
+        self.assertTrue(settings.REMOTE_AUTH_AUTO_CREATE_USER)
+        self.assertEqual(settings.REMOTE_AUTH_HEADER, 'HTTP_REMOTE_USER')
+        self.assertEqual(settings.REMOTE_AUTH_DEFAULT_PERMISSIONS, ['dcim.add_site', 'dcim.change_site'])
+
         response = self.client.get(reverse('home'), follow=True, **headers)
         self.assertEqual(response.status_code, 200)
 
-        user = User.objects.get(username='remoteuser1')
-        self.assertEqual(int(self.client.session['_auth_user_id']), user.pk, msg='Authentication failed')
-        self.assertTrue(user.has_perms(['dcim.add_site', 'dcim.change_site']))
+        new_user = User.objects.get(username='remoteuser2')
+        self.assertEqual(int(self.client.session.get('_auth_user_id')), new_user.pk, msg='Authentication failed')
+        self.assertTrue(new_user.has_perms(['dcim.add_site', 'dcim.change_site']))

+ 1 - 1
netbox/utilities/auth_backends.py

@@ -37,7 +37,7 @@ class RemoteUserBackend(ViewExemptModelBackend, RemoteUserBackend_):
     """
     @property
     def create_unknown_user(self):
-        return bool(settings.REMOTE_AUTH_AUTO_CREATE_USER)
+        return settings.REMOTE_AUTH_AUTO_CREATE_USER
 
     def configure_user(self, request, user):
         logger = logging.getLogger('netbox.authentication.RemoteUserBackend')

+ 8 - 0
netbox/utilities/middleware.py

@@ -42,6 +42,14 @@ class RemoteUserMiddleware(RemoteUserMiddleware_):
     def header(self):
         return settings.REMOTE_AUTH_HEADER
 
+    def process_request(self, request):
+
+        # Bypass middleware if remote authentication is not enabled
+        if not settings.REMOTE_AUTH_ENABLED:
+            return
+
+        return super().process_request(request)
+
 
 class APIVersionMiddleware(object):
     """