@@ -91,6 +91,7 @@ but this is just a fun toy project so let's give it a go.
9191To get this Magic Links project set up, the first thing I did was take a look at existing Python and Django authentication
9292packages, like https://docs.allauth.org/en/latest/[django-allauth]
9393and https://github.com/omab/python-social-auth[python-social-auth],
94+ // CSANAD: python-social-auth looks abandoned
9495but both of them looked overcomplicated for this stage
9596(and besides, it'll be more fun to code our own!).
9697
@@ -109,6 +110,11 @@ and convince yourself that it really does work.
109110
110111==== Starting a Branch for the Spike
111112
113+ // CSANAD: although we introduced to expression "spike" in the 17th chapter, I
114+ // would still mention more explicitly that this is a quick and dirty hacking
115+ // around, which is not production code, and this is the reason we are not
116+ // writing tests just yet - we still need to see what and how to test.
117+
112118((("spiking and de-spiking", "branching your VCS")))
113119((("Git", "creating branches")))
114120This spike is going to be a bit more involved than the last one,
@@ -182,12 +188,20 @@ The login in theory will be something like this:
182188
183189- When someone wants to log in, we generate a unique secret token for them,
184190 store it in the database linked to their email, and send it to them.
191+ // CSANAD: although it should be obvious there is no "database linked to their
192+ // email", still, I suggest different order of words for clarity:
193+ // "store it linked to their email in the database, (...)"
194+ // or
195+ // "store it linked in the database to their email, (...)"
185196
186197- The user then checks their email,
187198 which will have a link to a URL that includes that token.
188199
189200- When they click that link, we check whether the token exists in the database,
190201 and if so, they are logged in as the associated user.
202+ // CSANAD: what do you think about rephrasing it a little:
203+ // "...and if so, we authorize/approve the request to authenticate/log in as the
204+ // associated user"
191205
192206// https://docs.djangoproject.com/en/5.0/topics/auth/customizing/
193207
@@ -334,7 +348,9 @@ TIP: If you want to use Gmail as well,
334348((("", startref="DFemail18")))
335349((("", startref="SDemail18")))
336350
337-
351+ // CSANAD: I was only able to make it work with 2FA enabled and the
352+ // app-specific password set. If I have time, I'll try again with allowing
353+ // less secure apps too.
338354
339355==== Another Secret, Another Environment Variable
340356
@@ -461,6 +477,14 @@ OK so we've done the first half of "generate and recognise unique tokens":
461477
462478Before we can move on to recognising them and making the login work end-to-end though,
463479we need to sort out user authentication in Django.
480+ // CSANAD: not sure if it's clear for the readers why we need to sort out the
481+ // authn first. Maybe we could just rephrase:
482+ //
483+ // "In order to move on to recognising them and making the login work end-to-end,
484+ // we need to sort out user authentication in Django.
485+ //
486+ // This way we aren't just stating what needs to be done first, but also the
487+ // reason behind it.
464488The first thing we'll need is a user model.
465489I took a dive into the
466490https://docs.djangoproject.com/en/5.0/topics/auth/customizing[Django
@@ -523,6 +547,12 @@ class ListUserManager(BaseUserManager):
523547----
524548====
525549
550+ // CSANAD: ListUserManager has to be defined before ListUser, since its
551+ // reference to ListUser isn't evaluated until `create_user` is called. This is
552+ // not the case the other way around, ListUser's reference to ListUserManager
553+ // is instantiated in the class definition. Maybe we could leave a note about
554+ // this?
555+
526556
527557No need to worry about what a model manager is at this stage;
528558for now we just need it because we need it, and it works.
@@ -608,6 +638,9 @@ def login(request):
608638
609639The `authenticate()` function invokes Django's authentication framework,
610640which we configure using a "custom authentication backend",
641+ // CSANAD: why the quote marks? If it's because this is a reference to the
642+ // official Django docs, we could just make it a link instead to
643+ // https://docs.djangoproject.com/en/5.1/topics/auth/customizing/#writing-an-authentication-backend
611644whose job it is to validate the UID and return a user with the right email.
612645
613646We could have done this stuff directly in the view,
@@ -971,6 +1004,8 @@ what information you want to track about users,
9711004from explicitly recording first name and last namefootnote:[
9721005A decision which you'll find prominent Django maintainers
9731006saying they now regret. Not everyone has a first name and a last name.]
1007+ // CSANAD: also, profile-related information has no business in auth-related
1008+ // models.
9741009to forcing you to use a username.
9751010I'm a great believer in not storing information about users
9761011unless you absolutely must,
0 commit comments