From 11234a520bfc15ba3e76524c88f58c92f76fb434 Mon Sep 17 00:00:00 2001
From: Ethan Nguyen <etnguyen03@hotmail.com>
Date: Fri, 30 Jul 2021 18:37:22 -0400
Subject: [PATCH] feat(authentication): add ability to lock login

---
 tjdests/apps/authentication/tests.py | 13 +++++++++++++
 tjdests/apps/authentication/views.py |  7 +++++++
 tjdests/settings/__init__.py         |  1 +
 tjdests/settings/secret.sample.py    |  3 +++
 4 files changed, 24 insertions(+)

diff --git a/tjdests/apps/authentication/tests.py b/tjdests/apps/authentication/tests.py
index 3d2fb80..343731e 100644
--- a/tjdests/apps/authentication/tests.py
+++ b/tjdests/apps/authentication/tests.py
@@ -33,6 +33,19 @@ class AuthenticationTest(TJDestsTestCase):
         self.assertEqual(302, response.status_code)
         self.assertNotIn("_auth_user_id", self.client.session)
 
+        # Test login lock
+        self.login(make_student=True, make_superuser=False)
+        with self.settings(LOGIN_LOCKED=True):
+            response = self.client.get(reverse("authentication:tos"))
+            self.assertEqual(302, response.status_code)
+            self.assertNotIn("_auth_user_id", self.client.session)
+
+        # but superusers should be fine
+        self.login(make_student=True, make_superuser=True)
+        with self.settings(LOGIN_LOCKED=True):
+            response = self.client.get(reverse("authentication:tos"))
+            self.assertEqual(200, response.status_code)
+
         # Make us a student and try again
         user = self.login(make_student=True)
         response = self.client.get(reverse("authentication:tos"))
diff --git a/tjdests/apps/authentication/views.py b/tjdests/apps/authentication/views.py
index a8d8bfa..899c70c 100644
--- a/tjdests/apps/authentication/views.py
+++ b/tjdests/apps/authentication/views.py
@@ -1,3 +1,4 @@
+from django.conf import settings
 from django.contrib import messages
 from django.contrib.auth import login, logout
 from django.contrib.auth.decorators import login_required
@@ -17,6 +18,12 @@ class IndexView(TemplateView):
 def accept_tos_view(request: HttpRequest) -> HttpResponse:
     assert request.user.is_authenticated
 
+    if settings.LOGIN_LOCKED:
+        if not request.user.is_superuser:
+            logout(request)
+            messages.error(request, "Login is restricted to administrators only.")
+            return redirect(reverse("authentication:index"))
+
     if not request.user.is_student:
         logout(request)
         messages.error(request, "You must be a student to access this site.")
diff --git a/tjdests/settings/__init__.py b/tjdests/settings/__init__.py
index dfc538e..131ec30 100644
--- a/tjdests/settings/__init__.py
+++ b/tjdests/settings/__init__.py
@@ -167,6 +167,7 @@ MESSAGE_TAGS = {
 SENIOR_GRAD_YEAR: int = -1
 BRANDING_NAME: str = "UNDEFINED"
 GLOBAL_MESSAGE: Optional[str] = None
+LOGIN_LOCKED = False
 
 try:
     from .secret import *  # noqa  # pylint: disable=unused-import
diff --git a/tjdests/settings/secret.sample.py b/tjdests/settings/secret.sample.py
index 3b1c90e..76d5c1b 100644
--- a/tjdests/settings/secret.sample.py
+++ b/tjdests/settings/secret.sample.py
@@ -21,3 +21,6 @@ SOCIAL_AUTH_ION_SECRET = "ionsecret"
 # Message blast - treated as HTML safe text
 # type is str
 GLOBAL_MESSAGE = None
+
+# Login lock: if True, restrict login to superusers only
+LOGIN_LOCKED = False