|
3 | 3 | """ |
4 | 4 |
|
5 | 5 | import phonenumbers |
| 6 | +import datetime |
6 | 7 | import uuid |
7 | 8 | import logging |
8 | 9 |
|
9 | 10 | from flask import Blueprint, render_template, request, redirect, flash |
10 | 11 | from flask import session as flask_session |
11 | 12 |
|
12 | | -from selfservice.utilities.general import is_expired, email_recovery, phone_recovery |
| 13 | +from selfservice.utilities.general import email_recovery, phone_recovery |
13 | 14 | from selfservice.utilities.reset import ( |
14 | 15 | generate_token, |
15 | 16 | passwd_reset, |
@@ -91,7 +92,7 @@ def verify_identity(recovery_id): |
91 | 92 | methods = verif_methods(session.username) |
92 | 93 |
|
93 | 94 | # Make sure it isn't expired. |
94 | | - if is_expired(session.created, 10): |
| 95 | + if session.is_expired(): |
95 | 96 | flash("Sorry, your session has expired.") |
96 | 97 | return redirect("/recovery") |
97 | 98 |
|
@@ -133,7 +134,7 @@ def method_selection(recovery_id, method): |
133 | 134 | methods = verif_methods(session.username) |
134 | 135 |
|
135 | 136 | # Make sure it isn't expired. |
136 | | - if is_expired(session.created, 10): |
| 137 | + if session.is_expired(): |
137 | 138 | flash("Sorry, your session has expired.") |
138 | 139 | return redirect("/recovery") |
139 | 140 |
|
@@ -230,24 +231,23 @@ def reset_password(): |
230 | 231 |
|
231 | 232 | token_data = ResetToken.query.filter_by(token=token).first() |
232 | 233 |
|
233 | | - # Redirect if the token provided isn't valid. |
234 | | - if ( |
235 | | - not token |
236 | | - or not token_data |
237 | | - or is_expired(token_data.created, 30) |
238 | | - or token_data.used |
239 | | - ): |
240 | | - flash( |
241 | | - "Oops! Invalid or expired reset token. Each token is only " |
242 | | - + "valid for 30 minutes after it is issued." |
243 | | - ) |
| 234 | + if not token or not token_data: |
| 235 | + flash("Oops! No reset token provided. Please try again.") |
| 236 | + return redirect("/recovery") |
| 237 | + |
| 238 | + if token_data.used: |
| 239 | + flash("This recovery token has already been used.") |
| 240 | + return redirect("/recovery") |
| 241 | + |
| 242 | + if token_data.is_expired(): |
| 243 | + flash("Oops! Your recovery token expired.") |
244 | 244 | return redirect("/recovery") |
245 | 245 |
|
246 | 246 | # Display the reset page. |
247 | 247 | if request.method == "GET": |
248 | 248 | return render_template("reset.html", token=token_data.token, version=version) |
249 | 249 |
|
250 | | - # Lets actually do the reset. |
| 250 | + # Actually do the reset. |
251 | 251 | if request.form["password"] == request.form["verify"]: |
252 | 252 | if len(request.form["password"]) >= 12: |
253 | 253 | passwd_reset( |
@@ -287,39 +287,47 @@ def admin(): |
287 | 287 | session_id = str(uuid.uuid4()) |
288 | 288 |
|
289 | 289 | # Create the object in the database. |
290 | | - session_data = RecoverySession(id=session_id, username=request.form["username"]) |
| 290 | + session_data = RecoverySession( |
| 291 | + id=session_id, |
| 292 | + username=request.form["username"], |
| 293 | + expires=datetime.datetime.now() |
| 294 | + + datetime.timedelta(hours=int(request.form["expireTime"])), |
| 295 | + ) |
291 | 296 | db.session.add(session_data) |
292 | 297 | db.session.commit() |
293 | 298 |
|
294 | 299 | token = generate_token(session_data) |
295 | 300 |
|
296 | 301 | members = get_members() |
297 | 302 | uid = str(flask_session["userinfo"].get("preferred_username", "")) |
| 303 | + |
| 304 | + last_sessions_query = ( |
| 305 | + RecoverySession.query.join(ResetToken, RecoverySession.id == ResetToken.session) |
| 306 | + .with_entities( |
| 307 | + RecoverySession.username, |
| 308 | + RecoverySession.expires.label("session_expires"), |
| 309 | + ResetToken.id.label("token_id"), |
| 310 | + ResetToken.expires.label("token_expires"), |
| 311 | + ResetToken.used, |
| 312 | + ) |
| 313 | + .order_by(ResetToken.expires.desc()) |
| 314 | + .limit(20) |
| 315 | + .all() |
| 316 | + ) |
| 317 | + |
298 | 318 | last_sessions = [ |
299 | 319 | { |
300 | 320 | "username": s.username, |
301 | | - "session_created": s.session_created, |
302 | 321 | "session_expired": ( |
303 | | - (is_expired(s.session_created, 10) and not s.token_created) |
304 | | - or is_expired(s.token_created, 30) |
| 322 | + s.session_expires < datetime.datetime.now() |
| 323 | + or s.token_expires < datetime.datetime.now() |
305 | 324 | ), |
306 | | - "token_created": s.token_created, |
| 325 | + "token_exists": s.token_id is not None, |
| 326 | + "token_expires": s.token_expires, |
307 | 327 | "used": s.used, |
308 | 328 | } |
309 | | - for s in RecoverySession.query.outerjoin( |
310 | | - ResetToken, RecoverySession.id == ResetToken.session |
311 | | - ) |
312 | | - .with_entities( |
313 | | - RecoverySession.username, |
314 | | - RecoverySession.created.label("session_created"), |
315 | | - ResetToken.created.label("token_created"), |
316 | | - ResetToken.used, |
317 | | - ) |
318 | | - .order_by(RecoverySession.created.desc()) |
319 | | - .limit(20) |
320 | | - .all() |
| 329 | + for s in last_sessions_query |
321 | 330 | ] |
322 | | - |
323 | 331 | return render_template( |
324 | 332 | "admin.html", |
325 | 333 | version=version, |
|
0 commit comments