Skip to content

Commit c0ce515

Browse files
authored
fix: auth flow (#120)
* update paths * try entrypoint script * remove manage script * load fixtures command * fix: backends * allow anyone to get a CSRF cookie * rename session cookie * rename cookie
1 parent e79403a commit c0ce515

File tree

7 files changed

+68
-24
lines changed

7 files changed

+68
-24
lines changed

codeforlife/settings/django.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,11 @@ def get_databases(base_dir: Path): # pragma: no cover
6666
# https://docs.djangoproject.com/en/3.2/ref/settings/#authentication-backends
6767

6868
AUTHENTICATION_BACKENDS = [
69-
"codeforlife.user.auth.backends.EmailAndPasswordBackend",
69+
"codeforlife.user.auth.backends.EmailBackend",
7070
"codeforlife.user.auth.backends.OtpBackend",
7171
"codeforlife.user.auth.backends.OtpBypassTokenBackend",
72-
"codeforlife.user.auth.backends.UserIdAndLoginIdBackend",
73-
"codeforlife.user.auth.backends.FirstNameAndPasswordAndClassIdBackend",
72+
"codeforlife.user.auth.backends.StudentBackend",
73+
"codeforlife.user.auth.backends.StudentAutoBackend",
7474
]
7575

7676
# Sessions
@@ -79,7 +79,7 @@ def get_databases(base_dir: Path): # pragma: no cover
7979
SESSION_ENGINE = "codeforlife.user.models.session"
8080
SESSION_SAVE_EVERY_REQUEST = True
8181
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
82-
SESSION_COOKIE_NAME = "sessionid_httponly_true"
82+
SESSION_COOKIE_NAME = "session_key"
8383
SESSION_COOKIE_HTTPONLY = True
8484
SESSION_COOKIE_AGE = 60 * 60
8585
SESSION_COOKIE_SECURE = True
@@ -144,12 +144,12 @@ def get_databases(base_dir: Path): # pragma: no cover
144144
# URLs
145145
# https://docs.djangoproject.com/en/3.2/ref/settings/#root-urlconf
146146

147-
ROOT_URLCONF = "src.service.urls"
147+
ROOT_URLCONF = "src.urls"
148148

149149
# App
150150
# https://docs.djangoproject.com/en/3.2/ref/settings/#wsgi-application
151151

152-
WSGI_APPLICATION = "src.service.wsgi.application"
152+
WSGI_APPLICATION = "main.app"
153153

154154
# Password validation
155155
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators

codeforlife/user/auth/backends/__init__.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22
© Ocado Group
33
Created on 01/02/2024 at 14:48:57(+00:00).
44
"""
5+
56
# TODO: Create a custom auth backend for Django admin permissions
6-
from .email_and_password import EmailAndPasswordBackend
7-
from .first_name_and_password_and_class_id import (
8-
FirstNameAndPasswordAndClassIdBackend,
9-
)
7+
from .email import EmailBackend
108
from .otp import OtpBackend
119
from .otp_bypass_token import OtpBypassTokenBackend
12-
from .user_id_and_login_id import UserIdAndLoginIdBackend
10+
from .student import StudentBackend
11+
from .student_auto import StudentAutoBackend

codeforlife/user/auth/backends/email_and_password.py renamed to codeforlife/user/auth/backends/email.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from .base import BaseBackend
1010

1111

12-
class EmailAndPasswordBackend(BaseBackend):
12+
class EmailBackend(BaseBackend):
1313
"""Authenticate a user by checking their email and password."""
1414

1515
def authenticate( # type: ignore[override]

codeforlife/user/auth/backends/first_name_and_password_and_class_id.py renamed to codeforlife/user/auth/backends/student.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from .base import BaseBackend
1111

1212

13-
class FirstNameAndPasswordAndClassIdBackend(BaseBackend):
13+
class StudentBackend(BaseBackend):
1414
"""Authenticate a student using their first name, password and class ID."""
1515

1616
user_class = StudentUser

codeforlife/user/auth/backends/user_id_and_login_id.py renamed to codeforlife/user/auth/backends/student_auto.py

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,30 +17,34 @@
1717
from .base import BaseBackend
1818

1919

20-
class UserIdAndLoginIdBackend(BaseBackend):
20+
class StudentAutoBackend(BaseBackend):
2121
"""Authenticate a student using their ID and auto-generated password."""
2222

2323
user_class = StudentUser
2424

2525
def authenticate( # type: ignore[override]
2626
self,
2727
request: t.Optional[HttpRequest],
28-
user_id: t.Optional[int] = None,
29-
login_id: t.Optional[str] = None,
28+
student_id: t.Optional[int] = None,
29+
auto_gen_password: t.Optional[str] = None,
3030
**kwargs
3131
):
32-
if user_id is None or login_id is None:
32+
if student_id is None or auto_gen_password is None:
3333
return None
3434

35-
user = self.get_user(user_id)
36-
if user:
35+
try:
36+
student = Student.objects.get(id=student_id)
37+
except Student.DoesNotExist:
38+
student = None
39+
40+
if student:
41+
# TODO: refactor this
3742
# Check the url against the student's stored hash.
38-
student = Student.objects.get(new_user=user)
3943
if (
40-
student.login_id
41-
# TODO: refactor this
42-
and get_hashed_login_id(login_id) == student.login_id
44+
student.new_user
45+
and student.login_id
46+
and get_hashed_login_id(auto_gen_password) == student.login_id
4347
):
44-
return user
48+
return student.new_user
4549

4650
return None
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""
2+
© Ocado Group
3+
Created on 10/06/2024 at 10:44:45(+01:00).
4+
"""
5+
6+
import os
7+
import typing as t
8+
9+
from django.apps import apps
10+
from django.core.management import call_command
11+
from django.core.management.base import BaseCommand
12+
13+
14+
# pylint: disable-next=missing-class-docstring
15+
class Command(BaseCommand):
16+
help = "Loads all the fixtures of the specified apps."
17+
18+
def add_arguments(self, parser):
19+
parser.add_argument("app_labels", nargs="*", type=str)
20+
21+
def handle(self, *args, **options):
22+
fixture_labels: t.List[str] = []
23+
for app_label in {*options["app_labels"], "user"}:
24+
app_config = apps.app_configs[app_label]
25+
fixtures_path = os.path.join(app_config.path, "fixtures")
26+
27+
self.stdout.write(f"{app_label} fixtures ({fixtures_path}):")
28+
for fixture_label in os.listdir(fixtures_path):
29+
if fixture_label in fixture_labels:
30+
self.stderr.write(f"Duplicate fixture: {fixture_label}")
31+
return
32+
33+
self.stdout.write(f" - {fixture_label}")
34+
fixture_labels.append(fixture_label)
35+
36+
self.stdout.write()
37+
38+
call_command("loaddata", *fixture_labels)

codeforlife/views/csrf.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@
99
from rest_framework.response import Response
1010
from rest_framework.views import APIView
1111

12+
from ..permissions import AllowAny
13+
1214

1315
class CookieView(APIView):
1416
"""A view to get a CSRF cookie."""
1517

1618
http_method_names = ["get"]
19+
permission_classes = [AllowAny]
1720

1821
@method_decorator(ensure_csrf_cookie)
1922
def get(self, request: Request):

0 commit comments

Comments
 (0)