Skip to content

Instantly share code, notes, and snippets.

@brylie
Created November 4, 2023 18:10
Show Gist options
  • Save brylie/5f1cb4ce8a811498ecfb2da73ac14395 to your computer and use it in GitHub Desktop.
Save brylie/5f1cb4ce8a811498ecfb2da73ac14395 to your computer and use it in GitHub Desktop.
Code with Brylie - e33
(...) Hello and welcome to another live code hangout. Today we will be working on the Western Friend website.
(...)
Source code is here on GitHub,(...) github.com slash Western Friend.
(...)
Got an issue here co-assigned to protect our registration and possibly other forms such as our contact form.
(...)
Today I will be looking at the registration process.
(...)
We've got a plugin called Django registration that's doing the heavy lifting for us.
(...)
So mainly I will just be following these instructions.
(...)
We'll see how that goes.
(...)
And optionally we might look at using some sort of a capture like Django.
(...)
Capture plugin or the Wagtail recapture.
(...)
Which GT coder is working on in a separate pull request. So I kind of want to align with their work.(...) But they're focused on the contact form. I'll focus on the registration form.
(...)
So I've got a branch here and I believe we I'm just checking our user registration form here. I think if we were to add a capture you would just add the field here.
(...)
But for now we're not going to do that.
(...)
So here's our core URLs.
(...)
We have a registration form where we implement the registration view and use that custom user form.
(...)
The rest of it,(...) the registration flow that is handled by these two paths where we've got overlapping accounts. This is per the documentation so there shouldn't be any collisions.
(...)
Django registration back end. Currently one step URL. You just register and you're already signed in and your account is activated. That's good for prototyping and quick development getting out of the beta stage. But now we're ready to have actual users register. We should verify their email at the very least and if possible verify that they're not a bot. You know not only by the email method but probably by adding a capture.(...) For better or for worse. That's just what we kind of have to settle on.
(...)
So I think the only change we need is to use activation URLs instead of one step URLs.
(...)
It's a very small change. Let's see. So let's make sure the database is running.
(...)
And run the development server.
(...)
We'll hop over into the development server now.
(...)
There may be some templates I need to implement.
(...)
But it looks like I'm already logged in so let's hop out of that and register.
(...)
Okay, so this is using our same registration form.
(...)
One issue. Hopefully it should use the console back in for our email.
(...)
So let's say test user.
(...)
I have created a few of those.
(...)
Number two. Oh wait, can't click in there.
(...)
Hmm.
(...)
Interesting.
(...)
And logged in. So unfortunately that didn't work. Just switching.
(...)
Let me check this form a little closer.
(...)
I think.
(...)
Let's use a registration form.
(...)
Okay, this is pretty much.
(...)
Yeah, that's correct.
(...)
Okay,(...) we just need to subclass the right view. No problem.
(...)
So one step. All right, so there we go. Backends.
(...)
Activation and views. Okay.
(...)
Registration view.
(...)
Two step.
(...)
So it's also called registration view. I think if I just change the import.
(...)
Backends activation.
(...)
And then we'll have the right flow. All right. It's pretty cool that you can override it as easily as that. It's just the documentation is not super clear.
(...)
And then we've had to customize like how to customize it. It says you can, but it would be nice if it had more holistic documentation about examples. This is more reference documentation, but it's not very good tutorial.
(...)
Yeah, or example.
(...)
What is that called the C for documentation framework? No, that's how you diagram application.
(...)
This is diet, text, data taxes.
(...)
Yeah. So it doesn't really have much of this. It's got almost completely a reference.
(...)
This is a bit of a, okay, it's a bit down here. Explanation and reference. I'm looking for this oftentimes.(...) I've been doing Django for a while, but I still need tutorials like anybody. Right.
(...)
Tutorials are helpful in how to do specific things like how to implement this or override it. That'd be cool. Now granted,(...) I could also contribute to the documentation efforts in that regard. So I'm not trying to complain, but just kind of realizing the difference between these types of documentations and how the fully fledged project should try to balance, try to find their selves balanced within here. So we've got a little bit of everything and not leaning too much into the theoretical knowledge.
(...)
A lot of practical steps. In fact, if you're going to lean one way or the other, probably lean to the practical side and then supplement with theoretical knowledge to kind of balance yourself.
(...)
That'd be my philosophy. Okay. So I am going to register again and we'll just see if we're missing some templates now.
(...)
Okay. It did mention the settings.
(...)
So I should be reading docs.
(...)
I was kind of assuming that these would have defaults,(...) but that was not a good assumption.
(...)
You know, if you're going to have a configuration variable, give a default.
(...)
I know the number of days for registration could be a sensitive one, count activation days,(...) but a default value of like three.
(...)
That's pretty good.
(...)
All right. So core settings.
(...)
Now these are relating to registration.
(...)
In...
(...)
Registration. Salt.
(...)
Now it does have a default registration salt, so I'm just going to use that in any case.
(...)
Now we've got our variables, so I should be able to try again.
(...)
Interesting.
(...)
There we go.
(...)
Now, probably just read the docs on this one.
(...)
Quick start guide has required templates.
(...)
Here's a registration form where we can add the capture later.
(...)
I'm going to refresh my tonic and lime. I'll be right back.
(...)
Camera's not frozen.
(...)
Tonic lime refreshed.
(...)
However, we've got registration form, registration complete,(...) registration closed.
(...)
(clicking)
(...)
(clicking)
(...)
(clicking) - Okay, here's our activation failed template. Just a message of an error was encountered when activating this account. We'll display the activation error to dictionary. Well, I'm not sure how that'll print out, but hopefully it'll be useful. Please contact the site administrator.
(...)
(clicking)
(...)
(clicking)
(...)
Okay, activation complete is fairly simple.
(...)
Activation complete. Your account has been activated.
(...)
I'm not sure if at this point they'll need to log in. I might add a little bit more detail there after I test this out.
(...)
So the activation email subject text.
(...)
(clicking) Must be a single line. (clicking)
(...)
(clicking)
(...)
(clicking)
(...)
So activation email subject. We can use this expiration days.
(...)
Please activate your westernfriend.org account within expiration days,(...) days.
(...)
And then the body will have more information.
(...)
(clicking)
(...)
(clicking)
(...)
I will need to construct a URL for this. This is an example of how this documentation is lacking the pragmatic or practical steps.(...) It's giving me the information.
(...)
The explanation and reference. Here we're more in the reference zone, but it's not telling me how to do it.
(...)
I really just would like to know how to do it.
(...)
I know it differs between sites, but a simple example.
(...)
Particularly since I'm not deviating from the documentation. I'm using the same URL structure and everything. So if you don't deviate from the documentation, then an example is easier to give an example here. So how to... (clicking) How to figure out which URL, which route to send them to.
(...)
Right. (clicking)
(...)
I'll leave this open.
(...)
And what I might be able to do is use co-pilot.
(...)
(clicking)
(...)
(clicking)
(...)
So I'll see if co-pilot has this tacit knowledge. Please generate a link for the user to copy and paste into their browser that uses the activation key and correct URL for the registration, Django registration's account activation view
(...)
for the given. (clicking)
(...)
(clicking)
(...)
Scheme in sight. Essentially all this should be able to...
(...)
Or I can get the reverse for it. Reverse would probably be better.
(...)
(clicking)(...) Correction URLs.
(...)
(clicking) (clicking) (clicking) (clicking) (clicking) (clicking)
(...)
So we'll try to use Django reverse URL.
(...)
All right, let's send that.
(...)
It's thinking about it.
(...)
I'm sure somebody, there's an open source project out here that's done this.
(...)
There we are.
(...)
It's a plain text.
(...)
So unfortunately it won't be something that they can click on.
(...)
Registration activate activation key. Okay.
(...)
Request ghettos, request scheme.
(...)
I don't know if that's gonna work.
(...)
(clicking)
(...)
Because we're not handling a request.
(...)
Man, see this, I just have a simple tutorial here.
(...)
Would be really helpful here.
(...)
I could use an email body.txt.
(...)
Django registration. So they have an example.
(...)
Hmm, interesting.
(...)
This must be the...
(...)
(clicking) Context variables.
(...)
Well dang.
(...)
(clicking)
(...)
Oh, I just noticed these are the same URL registration activate activation key.
(...)
Without, oh it's a relative URL. Okay. Well, this is not super cool, but it's essentially...
(...)
I just, dude. (clicking)
(...)
I just highlight here.
(...)
Go western friend hard code this.
(...)
And we're gonna use HTTPS.
(...)
So,(...) yeah, I'm liking this.
(...)
Copy and paste it and take off the western friend part.
(...)
I sort of disagree here. I think we should be using the HTML. It could be people, something to click on. I don't think people have a widespread antipathy(...) towards all this.
(...)
You know, most browser, most email clients support links and I think people like to click links.
(...)
So...
(...)
Browser interoper...
(...)
What did they say?
(...)
The interoperability aside, I think using a minimal subset of HTML, like anchor tags is fairly common and easy to do. I don't think we should completely disallow HTML. This is kind of a weird decision. (clicking)
(...)
All right, so we'll see if that works. We'll continue down.
(...)
I guess that's it, we've made it down the list.
(...)
All right, so...
(...)
Cancel that, we'll go back.
(...)
All right.
(...)
All right.
(...)
We'll just check our URL structures here.
(...)
There we go.
(...)
(clicking)
(...)
All right.
(...)
Mm, so it's trying to send an email to the user but...
(...)
Apparently that's a...
(...)
Either something I need to implement or something that's been deprecated from Django.
(...)
Mm...
(...)
Hmm.
(...)
Now it could be that...
(...)
We're inheriting from the user model,(...) abstract based user or something.
(...)
All right, let's close a bunch of things out.
(...)
Everything out.
(...)
Counts, models...
(...)
And perhaps...
(...)
We should inherit from a more rich user model but the abstract based user seemed to be pretty good. Django, so we would look for Django email user or...
(...)
Yeah.
(...)
See where that's defined, contrib auth. (clicking)
(...)
Yeah, and a custom user model, okay.
(...)
Ah, there we go. So Google is sort of...
(...)
Quality is diminishing.
(...)
(clicking) So...
(...)
(chuckling)
(...)
(clicking)
(...)
It's a bit old answer, 2016.
(...)
Let's try it.
(...)
Let's check out the other models here.
(...)
Models...
(...)
Permission.
(...)
(clicking) (clicking)
(...)
(clicking)
(...)
So I'm thinking...
(...)
Because most of this is not necessary. We don't need a short name, full name.
(...)
Hmm...
(...)
Clean could be useful.
(...)
The reason is we're only collecting the email.
(...)
We're not asking for a username. We don't need a username validator.
(...)
Maybe I'll add this date join.
(...)
So I can either just inherit from this and set things to null. Or not.
(...)
Or copy and paste, I don't really like that, but okay.
(...)
Let's bring some of this over though.
(...)
So yeah.
(...)
And Django has its own sort of time zone.(...) I think time zone handle. Let's see where it got the time zone from.
(...)
Jango utils.
(...)
(clicking) (clicking)
(...)
(clicking)
(...)
(clicking) (sighing) (clicking) (clicking) (clicking) (clicking)
(...)
(clicking)
(...)
Well.
(...)
Well, when I did this, it knew
(...)
I don't need that get text.
(...)
Oh yeah, yeah.
(...)
(clicking)
(...)
I do like this clean method.
(...)
Oops.
(...)
Let's see.
(...)
Well, yeah, open that here.
(...)
And yeah, it's still complaining.
(...)
Cannot override class variable previously declared on base class abstract base user with instance variable my_py. Okay.
(...)
I don't know.
(...)
(clicking)
(...)
And the thing is now we can implement the email user.
(...)
(clicking)
(...)
Give my import. (clicking)
(...)
Yeah.
(...)
(sighing)
(...)
(clicking) Okay, so the, we don't need the email to be marked as required, which I think is why I overrode that.
(...)
(clicking) (clicking)
(...)
So I will just. (clicking)
(...)
Commit the migrations separately. I guess it doesn't.
(...)
(clicking)
(...)
Quite matter.
(...)
(clicking) (clicking) (clicking)
(...)
(clicking) Yeah, I didn't wanna,
(...)
didn't wanna stage everything.
(...)
Kinda weird.
(...)
(clicking)
(...)
(clicking) Hmm.
(...)
All right.
(...)
(clicking)
(...)
(clicking) All right.
(...)
(clicking)
(...)
Add the user clean and email user methods.
(...)
(clicking) Now we can.
(...)
(clicking)(...) Log in here real quick and see if I can answer this.
(...)
(clicking)
(...)
(clicking) (sighing)
(...)
(clicking)
(...)
(clicking)
(...)
Ah, that's old.
(...)
(clicking) (clicking)
(...)
(sniffling)
(...)
And we're in the class abstract user.
(...)
(clicking) (clicking) (sniffling)
(...)
(clicking)
(...)
And yeah, just have a quick.
(...)
(clicking)
(...)
(clicking)
(...)
So we need the send mail and abstract user imports.
(...)
Whoa.
(...)
(clicking) (clicking) (clicking) (clicking)
(...)
(clicking)
(...)
All right, let's try again.
(...)
(clicking)
(...)
Forgot to migrate.
(...)
(clicking) Now we're on the server.
(...)
Try again.
(...)
(clicking)
(...)
Okay, now we get this text email in our console. (clicking)
(...)
Oh,(...) but it says registration successful.
(...)
Ah,(...) yeah, yeah, okay, that's...
(...)
True,(...) except they need to check their email. So I just need to update this text.
(...)
(clicking)
(...)
So first, let me refresh my tonic and lime.
(...)
(clicking)
(...)
Got the fizzy.
(...)
(clicking) (clicking)
(...)
So yes, the registration,
(...)
it was successful in that
(...)
there's a user account, but the account is not active, so. (clicking)
(...)
Or activate your account.
(...)
(clicking)
(...)
(clicking) All right, activate your account. We have emailed you instructions to activate your account. So it comes like this.
(...)
And we get a link that I can copy and paste.
(...)
Let's just copy it and paste it.
(...)
The only problem, because I'm copying and pasting, is the hero is hard coded. I'm also noticing two slashes there.
(...)
Ah,(...) yeah, that makes sense.
(...)
So with just HTTP and local development,
(...)
activation complete. Am I logged in?
(...)
No. So that's the other thing we can tell them. They can now log in.
(...)
All right, so just some more minor changes to the texts.
(...)
(clicking)
(...)
(clicking)
(...)
Yeah, so I have to find the URL for login.
(...)
Mm,(...) that's under our core template.
(...)
Navbar, for example.
(...)
(clicking) Log in. Ah. (clicking) Yeah.
(...)
Let's try that.
(...)
You can now log in, verb.
(...)
Punctuation.
(...)
You can now log in, log in, log in. Yes.
(...)
And I guess this is okay, it's kind of narrow.
(...)
However, on the login form,
(...)
for small screens,
(...)
it should be all the way across.
(...)
For example, if I view this on a mobile device,
(...)
yeah, here we go. I like that.
(...)
And if I'm on a, let's see, a tablet or like an iPad,
(...)
oh.
(...)
I don't like that.
(...)
Hmm.
(...)
(clicking)
(...)
Let's try that.
(...)
Medium 12.
(...)
So basically, it is a little bit better. I don't need the medium here.
(...)
The break point will automatically handle that.
(...)
But just for whatever reason, so we're on the iPhone, and then I switch to just a responsive mode.
(...)
Yeah, that's pretty good, email, password.
(...)
I don't know, they're super long. You know, actually what would be nice is if it was centered.
(...)
That's not what I'm here for.
(...)
Yeah.
(...)
Okay, so let's test this out one more time.
(...)
I need to change, need to change
(...)
the text for the email body.
(...)
So I don't need that slash,
(...)
and I can use the hard coded URL.
(...)
Yeah.
(...)
Register.
(...)
Got email.
(...)
Okay, so now we've got another email here.(...) I'll copy and paste it so that I can edit, oops.
(...)
(keyboard clicking)
(...)
And we'll edit the URL here.
(...)
Okay.
(...)
Activation complete. Your account has been activated. You can now log in, take the login page. All right, you know, it's first pass.
(...)
So we're at minimum usable at this point. I could publish this and people could use it. So let's see.
(...)
We will commit the changes in a kind of meaningful order.
(...)
(keyboard clicking)
(...)
So we'll publish the branch, create a pull request. And for now, (keyboard clicking)
(...)
(keyboard clicking)
(...)
Try and think if I should close or just relate it.(...) (keyboard clicking)
(...)
817.
(...)
Because if I close it, then we haven't done the other protection. Now the registration flow is a decent first step protection. I think bots can still abuse it.
(...)
At least in terms of generating a bunch of spam users that never get activated,
(...)
but maybe also in activating users.
(...)
So I believe the CAPTCHA
(...)
is going to be a necessary addition here.(...) We'll take a break here at about one hour in.(...) I'll do some research offline
(...)
and see how we can merge GT coders, pull requests that they've opened. We'll look at it in another session and then see if I can kind of align our CAPTCHA usage.
(...)
So we're leveraging what GT coders added
(...)
and then I can add it to the registration form.(...) Okay.
(...)
So this has been another live code hangout.
(...)
If you'd like to check out
(...)
the changes we made during today's session, you can check this pull request.
(...)
Number 928.
(...)
If you'd like to get involved with this project, we have a bunch of issues where we could use a little bit of help. Most of these are fairly small. A lot of them are good first issues(...) and we're also participating in Hacktober Fest every year, although that's now passed. But yeah, you can hop by our GitHub repository
(...)
and look for these good first issues.
(...)
All right. Well, thanks for checking out the live stream.(...) I hope you're doing well and have a great day.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment