|
2 | 2 | Flask blueprint for handling identity verification and account recovery. |
3 | 3 | """ |
4 | 4 |
|
| 5 | +import datetime |
5 | 6 | import uuid |
6 | 7 | import logging |
7 | 8 |
|
8 | 9 | from flask import Blueprint, render_template, request, redirect, flash |
9 | 10 | from flask import session as flask_session |
10 | 11 |
|
11 | | -from selfservice.utilities.general import is_expired, email_recovery, phone_recovery |
| 12 | +from selfservice.utilities.general import email_recovery, phone_recovery |
12 | 13 | from selfservice.utilities.reset import ( |
13 | 14 | generate_token, |
14 | 15 | generate_pin, |
@@ -90,7 +91,7 @@ def verify_identity(recovery_id): |
90 | 91 | methods = verif_methods(session.username) |
91 | 92 |
|
92 | 93 | # Make sure it isn't expired. |
93 | | - if is_expired(session.created, 10): |
| 94 | + if session.is_expired(): |
94 | 95 | flash("Sorry, your session has expired.") |
95 | 96 | return redirect("/recovery") |
96 | 97 |
|
@@ -132,7 +133,7 @@ def method_selection(recovery_id, method): |
132 | 133 | methods = verif_methods(session.username) |
133 | 134 |
|
134 | 135 | # Make sure it isn't expired. |
135 | | - if is_expired(session.created, 10): |
| 136 | + if session.is_expired(): |
136 | 137 | flash("Sorry, your session has expired.") |
137 | 138 | return redirect("/recovery") |
138 | 139 |
|
@@ -210,24 +211,23 @@ def reset_password(): |
210 | 211 |
|
211 | 212 | token_data = ResetToken.query.filter_by(token=token).first() |
212 | 213 |
|
213 | | - # Redirect if the token provided isn't valid. |
214 | | - if ( |
215 | | - not token |
216 | | - or not token_data |
217 | | - or is_expired(token_data.created, 30) |
218 | | - or token_data.used |
219 | | - ): |
220 | | - flash( |
221 | | - "Oops! Invalid or expired reset token. Each token is only " |
222 | | - + "valid for 30 minutes after it is issued." |
223 | | - ) |
| 214 | + if not token or not token_data: |
| 215 | + flash("Oops! No reset token provided. Please try again.") |
| 216 | + return redirect("/recovery") |
| 217 | + |
| 218 | + if token_data.used: |
| 219 | + flash("This recovery token has already been used.") |
| 220 | + return redirect("/recovery") |
| 221 | + |
| 222 | + if token_data.is_expired(): |
| 223 | + flash("Oops! Your recovery token expired.") |
224 | 224 | return redirect("/recovery") |
225 | 225 |
|
226 | 226 | # Display the reset page. |
227 | 227 | if request.method == "GET": |
228 | 228 | return render_template("reset.html", token=token_data.token, version=version) |
229 | 229 |
|
230 | | - # Lets actually do the reset. |
| 230 | + # Actually do the reset. |
231 | 231 | if request.form["password"] == request.form["verify"]: |
232 | 232 | if len(request.form["password"]) >= 12: |
233 | 233 | passwd_reset( |
@@ -267,39 +267,47 @@ def admin(): |
267 | 267 | session_id = str(uuid.uuid4()) |
268 | 268 |
|
269 | 269 | # Create the object in the database. |
270 | | - session_data = RecoverySession(id=session_id, username=request.form["username"]) |
| 270 | + session_data = RecoverySession( |
| 271 | + id=session_id, |
| 272 | + username=request.form["username"], |
| 273 | + expires=datetime.datetime.now() |
| 274 | + + datetime.timedelta(hours=int(request.form["expireTime"])), |
| 275 | + ) |
271 | 276 | db.session.add(session_data) |
272 | 277 | db.session.commit() |
273 | 278 |
|
274 | 279 | token = generate_token(session_data) |
275 | 280 |
|
276 | 281 | members = get_members() |
277 | 282 | uid = str(flask_session["userinfo"].get("preferred_username", "")) |
| 283 | + |
| 284 | + last_sessions_query = ( |
| 285 | + RecoverySession.query.join(ResetToken, RecoverySession.id == ResetToken.session) |
| 286 | + .with_entities( |
| 287 | + RecoverySession.username, |
| 288 | + RecoverySession.expires.label("session_expires"), |
| 289 | + ResetToken.id.label("token_id"), |
| 290 | + ResetToken.expires.label("token_expires"), |
| 291 | + ResetToken.used, |
| 292 | + ) |
| 293 | + .order_by(ResetToken.expires.desc()) |
| 294 | + .limit(20) |
| 295 | + .all() |
| 296 | + ) |
| 297 | + |
278 | 298 | last_sessions = [ |
279 | 299 | { |
280 | 300 | "username": s.username, |
281 | | - "session_created": s.session_created, |
282 | 301 | "session_expired": ( |
283 | | - (is_expired(s.session_created, 10) and not s.token_created) |
284 | | - or is_expired(s.token_created, 30) |
| 302 | + s.session_expires < datetime.datetime.now() |
| 303 | + or s.token_expires < datetime.datetime.now() |
285 | 304 | ), |
286 | | - "token_created": s.token_created, |
| 305 | + "token_exists": s.token_id is not None, |
| 306 | + "token_expires": s.token_expires, |
287 | 307 | "used": s.used, |
288 | 308 | } |
289 | | - for s in RecoverySession.query.outerjoin( |
290 | | - ResetToken, RecoverySession.id == ResetToken.session |
291 | | - ) |
292 | | - .with_entities( |
293 | | - RecoverySession.username, |
294 | | - RecoverySession.created.label("session_created"), |
295 | | - ResetToken.created.label("token_created"), |
296 | | - ResetToken.used, |
297 | | - ) |
298 | | - .order_by(RecoverySession.created.desc()) |
299 | | - .limit(20) |
300 | | - .all() |
| 309 | + for s in last_sessions_query |
301 | 310 | ] |
302 | | - |
303 | 311 | return render_template( |
304 | 312 | "admin.html", |
305 | 313 | version=version, |
|
0 commit comments