mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-18 13:39:41 -04:00
DRY-up email revalidation check
Previously this was duplicated between the "two_factor" and the "webauthn" views, and required more test setup. This DRYs up the check and tests it once, using mocks to simplify the view tests. As part of DRYing up the check into a util module, I've also moved the "is_less_than_days_ago" function it uses.
This commit is contained in:
@@ -30,11 +30,11 @@ from app.utils import (
|
||||
DELIVERED_STATUSES,
|
||||
FAILURE_STATUSES,
|
||||
REQUESTED_STATUSES,
|
||||
get_current_financial_year,
|
||||
service_has_permission,
|
||||
)
|
||||
from app.utils.csv import Spreadsheet
|
||||
from app.utils.pagination import generate_next_dict, generate_previous_dict
|
||||
from app.utils.time import get_current_financial_year
|
||||
from app.utils.user import user_has_permissions
|
||||
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ from app import user_api_client
|
||||
from app.main import main
|
||||
from app.main.forms import TwoFactorForm
|
||||
from app.models.user import User
|
||||
from app.utils import is_less_than_days_ago
|
||||
from app.utils.login import (
|
||||
email_needs_revalidating,
|
||||
log_in_user,
|
||||
redirect_to_sign_in,
|
||||
redirect_when_logged_in,
|
||||
@@ -79,11 +79,11 @@ def two_factor_sms():
|
||||
redirect_url = request.args.get('next')
|
||||
|
||||
if form.validate_on_submit():
|
||||
if is_less_than_days_ago(user.email_access_validated_at, 90):
|
||||
return log_in_user(user_id)
|
||||
else:
|
||||
if email_needs_revalidating(user):
|
||||
user_api_client.send_verify_code(user.id, 'email', None, redirect_url)
|
||||
return redirect(url_for('.revalidate_email_sent', next=redirect_url))
|
||||
else:
|
||||
return log_in_user(user_id)
|
||||
|
||||
return render_template('views/two-factor-sms.html', form=form, redirect_url=redirect_url)
|
||||
|
||||
|
||||
@@ -9,8 +9,11 @@ from app.main import main
|
||||
from app.models.user import User
|
||||
from app.models.webauthn_credential import RegistrationError, WebAuthnCredential
|
||||
from app.notify_client.user_api_client import user_api_client
|
||||
from app.utils import is_less_than_days_ago
|
||||
from app.utils.login import log_in_user, redirect_to_sign_in
|
||||
from app.utils.login import (
|
||||
email_needs_revalidating,
|
||||
log_in_user,
|
||||
redirect_to_sign_in,
|
||||
)
|
||||
from app.utils.user import user_is_platform_admin
|
||||
|
||||
|
||||
@@ -168,7 +171,7 @@ def _complete_webauthn_login_attempt(user):
|
||||
# user account is locked as too many failed logins
|
||||
abort(403)
|
||||
|
||||
if not is_less_than_days_ago(user.email_access_validated_at, 90):
|
||||
if email_needs_revalidating(user):
|
||||
user_api_client.send_verify_code(user.id, 'email', None, redirect_url)
|
||||
return redirect(url_for('.revalidate_email_sent', next=redirect_url))
|
||||
|
||||
|
||||
@@ -13,8 +13,9 @@ from app.models import JSONModel, ModelList, PaginatedModelList
|
||||
from app.notify_client.job_api_client import job_api_client
|
||||
from app.notify_client.notification_api_client import notification_api_client
|
||||
from app.notify_client.service_api_client import service_api_client
|
||||
from app.utils import is_less_than_days_ago, set_status_filters
|
||||
from app.utils import set_status_filters
|
||||
from app.utils.letters import get_letter_printing_statement
|
||||
from app.utils.time import is_less_than_days_ago
|
||||
|
||||
|
||||
class Job(JSONModel):
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
from datetime import datetime
|
||||
from functools import wraps
|
||||
from itertools import chain
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import pytz
|
||||
from dateutil import parser
|
||||
from flask import abort, current_app, g, make_response, request
|
||||
from flask_login import current_user
|
||||
from notifications_utils.field import Field
|
||||
from notifications_utils.timezones import utc_string_to_aware_gmt_datetime
|
||||
from orderedset._orderedset import OrderedSet
|
||||
from werkzeug.datastructures import MultiDict
|
||||
from werkzeug.routing import RequestRedirect
|
||||
@@ -40,15 +36,6 @@ def get_help_argument():
|
||||
return request.args.get('help') if request.args.get('help') in ('1', '2', '3') else None
|
||||
|
||||
|
||||
def get_current_financial_year():
|
||||
now = utc_string_to_aware_gmt_datetime(
|
||||
datetime.utcnow()
|
||||
)
|
||||
current_month = int(now.strftime('%-m'))
|
||||
current_year = int(now.strftime('%Y'))
|
||||
return current_year if current_month > 3 else current_year - 1
|
||||
|
||||
|
||||
def get_logo_cdn_domain():
|
||||
parsed_uri = urlparse(current_app.config['ADMIN_BASE_URL'])
|
||||
|
||||
@@ -114,12 +101,6 @@ class PermanentRedirect(RequestRedirect):
|
||||
code = 301
|
||||
|
||||
|
||||
def is_less_than_days_ago(date_from_db, number_of_days):
|
||||
return (
|
||||
datetime.utcnow().astimezone(pytz.utc) - parser.parse(date_from_db)
|
||||
).days < number_of_days
|
||||
|
||||
|
||||
def hide_from_search_engines(f):
|
||||
@wraps(f)
|
||||
def decorated_function(*args, **kwargs):
|
||||
|
||||
@@ -3,6 +3,7 @@ from functools import wraps
|
||||
from flask import redirect, request, session, url_for
|
||||
|
||||
from app.models.user import User
|
||||
from app.utils.time import is_less_than_days_ago
|
||||
|
||||
|
||||
def redirect_to_sign_in(f):
|
||||
@@ -41,6 +42,10 @@ def redirect_when_logged_in(platform_admin):
|
||||
return redirect(url_for('main.show_accounts_or_dashboard'))
|
||||
|
||||
|
||||
def email_needs_revalidating(user):
|
||||
return not is_less_than_days_ago(user.email_access_validated_at, 90)
|
||||
|
||||
|
||||
# see http://flask.pocoo.org/snippets/62/
|
||||
def _is_safe_redirect_url(target):
|
||||
from urllib.parse import urljoin, urlparse
|
||||
|
||||
20
app/utils/time.py
Normal file
20
app/utils/time.py
Normal file
@@ -0,0 +1,20 @@
|
||||
from datetime import datetime
|
||||
|
||||
import pytz
|
||||
from dateutil import parser
|
||||
from notifications_utils.timezones import utc_string_to_aware_gmt_datetime
|
||||
|
||||
|
||||
def get_current_financial_year():
|
||||
now = utc_string_to_aware_gmt_datetime(
|
||||
datetime.utcnow()
|
||||
)
|
||||
current_month = int(now.strftime('%-m'))
|
||||
current_year = int(now.strftime('%Y'))
|
||||
return current_year if current_month > 3 else current_year - 1
|
||||
|
||||
|
||||
def is_less_than_days_ago(date_from_db, number_of_days):
|
||||
return (
|
||||
datetime.utcnow().astimezone(pytz.utc) - parser.parse(date_from_db)
|
||||
).days < number_of_days
|
||||
Reference in New Issue
Block a user