Python for Entrepreneurs Transcripts
Chapter: Sending and receiving email
Lecture: Demo: Performing the reset

Login or purchase this course to watch this video and the rest of the course contents.
0:01 So recall from last time, that we has sent a password reset, we generated and sent a password reset email to my test account.
0:09 And here you can see we have exactly what we are looking for, an account/reset_password with some giant, hard to guess number
0:17 or alphanumeric thing here. So what's left to do? Well, we need to actually perform the password reset and that involves adding validation,
0:27 make sure that this is real, active, not used with the right account sort of code here and we are going to actually set the password and use up
0:37 and record that effect that password reset was used, let's start here. So this is the reset password piece, now actually,
0:46 this even the GET requires a little bit of validation. When we see this page, we would like to see a message that says
0:55 something to the effect of "sorry, this password reset code is invalid or expired" or something like that, so let's go here and do vm.validate,
1:05 now we haven't done much of that method yet but we are about to, and then we'll show this back,
1:12 now, in the GET, we are not going to redirect somewhere, we are just going to show them a message,
1:18 this validate will generate a message which will get shown saying "hey, this was already used", something like that.
1:23 So what is happening? Well, we are going to need to restore this from the dictionary,
1:28 so if we run it the way it is now, it's going to give us this message saying
1:32 "reset code not found" and it is going to hide the form to submit the password, because we haven't called from dictionary,
1:42 now you might wonder where is the dictionary coming from, it's coming from the route, not a form, so we'll come over here
1:48 and say vm.from_dict, remember, we have this merge dictionary, it has the routes, it has the query string, it has the forms, all that,
1:56 so if we rerun this, it should revalidate, OK, now it's found the code, that's good,
2:04 so next, now we have a code, let's try to get it from the database, and that's going to come out of the account service,
2:10 I think it's probably the best place, so we'll say AccountService.find_reset_code and we're just going to give it the code.
2:19 And let's store this, we'll say self.reset, I think it's what I called it up here, let's look, yes, self.reset right there.
2:26 So that is going to set the code, and then validate, we can come down here and we are already checking that
2:32 when they are setting the password, when they are actually doing the POST back,
2:35 we are checking for the password, we don't want to check for that on the GET only on the POST,
2:38 so we have this mechanism to indicate whether it's get or not, you can see that happening here on the POST version, this is False
2:52 it defaults to True, OK so the last two things is to add validation around the reset code,
2:57 so we'll say this, actually let's go ahead and use this up here, we'll just say if this query didn't actually set a reset thing,
3:07 we'll say the reset code is not found, OK, so that will do two in one, and then down here we want to say "self.reset_was_used",
3:16 then we'll do a message like so, "This reset code has already been used." Alright, that's good, and then if it's expired,
3:30 what does expired mean, expired means, let's say 24 hours, 7 days, let's go 24 hours, huh?
3:38 So let's just compute the time from when the reset code was created, that was automatically set, to now or reverse rather,
3:46 so now minus when this thing was created, created_date we called it, so that is going to be the change,
3:59 and then let's move this down, right where we are using it, let's say this, if dt.total_days, or total_seconds, so we got to turn that into days,
4:09 let's just do it like that, days=dt.total_seconds divided by 60 to get minutes, divided by 60 to get hours, divided by 24.
4:20 we'll say days is greater than 1, then we are just going to say it's expired, otherwise, if it makes it through all of this, we are going to be golden.
4:28 "This reset code has expired, generate a new one" Let's try this again, OK, if I rerun this, how is everything looking?
4:39 Oh reset code not found. Why was it not found? Because we have not implemented that query yet, let's go do that. Which one am I talking about?
4:49 This one right here, find_reset_code, so let's go write that, so we are going to do a session, right, this is going to be super easy
4:55 so we'll say "reset = session" remember how this goes, query of PasswordReset,
5:06 we'll do a filter, password_reset.id == code, and then what do we want next, first like that, we are just going to return reset,
5:22 so either we are going to find one or not, now let's see if this works again. Oh perfect, so it found it but this one is expired,
5:32 apparently it's been more than 24 hours since I've done that last segment, let's just double check that here.
5:40 This was sent, yes, one day ago, beautiful, OK. So it looks like it's working, I am going to send a new reset code.
5:49 Alright, it was sent, let me check the email, OK we are in good shape, zero minutes ago, let's see if this one works.
5:58 Boom it passes all the validation, it's not been used, it's not expired, things like that,
6:03 OK, so the next step is actually going to perform the password reset, we'll do that in the next video.


Talk Python's Mastodon Michael Kennedy's Mastodon