mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-02-22 19:34:42 -05:00
Rather than force us to write the decorators in a specific order let’s just have one decorator call the other. This should make fewer lines of code, and fewer annoying test failures. It also means that the same way of raising a `401` (through the `current_app` method) is used everywhere.
226 lines
6.7 KiB
Python
226 lines
6.7 KiB
Python
import json
|
|
|
|
from flask import (
|
|
abort,
|
|
current_app,
|
|
redirect,
|
|
render_template,
|
|
session,
|
|
url_for,
|
|
)
|
|
from flask_login import current_user
|
|
from notifications_utils.url_safe_token import check_token
|
|
|
|
from app import user_api_client
|
|
from app.main import main
|
|
from app.main.forms import (
|
|
ChangeEmailForm,
|
|
ChangeMobileNumberForm,
|
|
ChangeNameForm,
|
|
ChangePasswordForm,
|
|
ConfirmPasswordForm,
|
|
ServiceOnOffSettingForm,
|
|
TwoFactorForm,
|
|
)
|
|
from app.models.user import User
|
|
from app.utils import user_is_gov_user, user_is_logged_in
|
|
|
|
NEW_EMAIL = 'new-email'
|
|
NEW_MOBILE = 'new-mob'
|
|
NEW_MOBILE_PASSWORD_CONFIRMED = 'new-mob-password-confirmed'
|
|
|
|
|
|
@main.route("/user-profile")
|
|
@user_is_logged_in
|
|
def user_profile():
|
|
return render_template(
|
|
'views/user-profile.html',
|
|
can_see_edit=current_user.is_gov_user,
|
|
)
|
|
|
|
|
|
@main.route("/user-profile/name", methods=['GET', 'POST'])
|
|
@user_is_logged_in
|
|
def user_profile_name():
|
|
|
|
form = ChangeNameForm(new_name=current_user.name)
|
|
|
|
if form.validate_on_submit():
|
|
current_user.update(name=form.new_name.data)
|
|
return redirect(url_for('.user_profile'))
|
|
|
|
return render_template(
|
|
'views/user-profile/change.html',
|
|
thing='name',
|
|
form_field=form.new_name
|
|
)
|
|
|
|
|
|
@main.route("/user-profile/email", methods=['GET', 'POST'])
|
|
@user_is_logged_in
|
|
@user_is_gov_user
|
|
def user_profile_email():
|
|
|
|
form = ChangeEmailForm(User.already_registered,
|
|
email_address=current_user.email_address)
|
|
|
|
if form.validate_on_submit():
|
|
session[NEW_EMAIL] = form.email_address.data
|
|
return redirect(url_for('.user_profile_email_authenticate'))
|
|
return render_template(
|
|
'views/user-profile/change.html',
|
|
thing='email address',
|
|
form_field=form.email_address
|
|
)
|
|
|
|
|
|
@main.route("/user-profile/email/authenticate", methods=['GET', 'POST'])
|
|
@user_is_logged_in
|
|
def user_profile_email_authenticate():
|
|
# Validate password for form
|
|
def _check_password(pwd):
|
|
return user_api_client.verify_password(current_user.id, pwd)
|
|
form = ConfirmPasswordForm(_check_password)
|
|
|
|
if NEW_EMAIL not in session:
|
|
return redirect('main.user_profile_email')
|
|
|
|
if form.validate_on_submit():
|
|
user_api_client.send_change_email_verification(current_user.id, session[NEW_EMAIL])
|
|
return render_template('views/change-email-continue.html',
|
|
new_email=session[NEW_EMAIL])
|
|
|
|
return render_template(
|
|
'views/user-profile/authenticate.html',
|
|
thing='email address',
|
|
form=form,
|
|
back_link=url_for('.user_profile_email')
|
|
)
|
|
|
|
|
|
@main.route("/user-profile/email/confirm/<token>", methods=['GET'])
|
|
@user_is_logged_in
|
|
def user_profile_email_confirm(token):
|
|
token_data = check_token(token,
|
|
current_app.config['SECRET_KEY'],
|
|
current_app.config['DANGEROUS_SALT'],
|
|
current_app.config['EMAIL_EXPIRY_SECONDS'])
|
|
token_data = json.loads(token_data)
|
|
user = User.from_id(token_data['user_id'])
|
|
user.update(email_address=token_data['email'])
|
|
session.pop(NEW_EMAIL, None)
|
|
|
|
return redirect(url_for('.user_profile'))
|
|
|
|
|
|
@main.route("/user-profile/mobile-number", methods=['GET', 'POST'])
|
|
@user_is_logged_in
|
|
def user_profile_mobile_number():
|
|
|
|
form = ChangeMobileNumberForm(mobile_number=current_user.mobile_number)
|
|
|
|
if form.validate_on_submit():
|
|
session[NEW_MOBILE] = form.mobile_number.data
|
|
return redirect(url_for('.user_profile_mobile_number_authenticate'))
|
|
|
|
return render_template(
|
|
'views/user-profile/change.html',
|
|
thing='mobile number',
|
|
form_field=form.mobile_number
|
|
)
|
|
|
|
|
|
@main.route("/user-profile/mobile-number/authenticate", methods=['GET', 'POST'])
|
|
@user_is_logged_in
|
|
def user_profile_mobile_number_authenticate():
|
|
|
|
# Validate password for form
|
|
def _check_password(pwd):
|
|
return user_api_client.verify_password(current_user.id, pwd)
|
|
form = ConfirmPasswordForm(_check_password)
|
|
|
|
if NEW_MOBILE not in session:
|
|
return redirect(url_for('.user_profile_mobile_number'))
|
|
|
|
if form.validate_on_submit():
|
|
session[NEW_MOBILE_PASSWORD_CONFIRMED] = True
|
|
current_user.send_verify_code(to=session[NEW_MOBILE])
|
|
return redirect(url_for('.user_profile_mobile_number_confirm'))
|
|
|
|
return render_template(
|
|
'views/user-profile/authenticate.html',
|
|
thing='mobile number',
|
|
form=form,
|
|
back_link=url_for('.user_profile_mobile_number_confirm')
|
|
)
|
|
|
|
|
|
@main.route("/user-profile/mobile-number/confirm", methods=['GET', 'POST'])
|
|
@user_is_logged_in
|
|
def user_profile_mobile_number_confirm():
|
|
|
|
# Validate verify code for form
|
|
def _check_code(cde):
|
|
return user_api_client.check_verify_code(current_user.id, cde, 'sms')
|
|
|
|
if NEW_MOBILE_PASSWORD_CONFIRMED not in session:
|
|
return redirect(url_for('.user_profile_mobile_number'))
|
|
|
|
form = TwoFactorForm(_check_code)
|
|
|
|
if form.validate_on_submit():
|
|
current_user.refresh_session_id()
|
|
mobile_number = session[NEW_MOBILE]
|
|
del session[NEW_MOBILE]
|
|
del session[NEW_MOBILE_PASSWORD_CONFIRMED]
|
|
current_user.update(mobile_number=mobile_number)
|
|
return redirect(url_for('.user_profile'))
|
|
|
|
return render_template(
|
|
'views/user-profile/confirm.html',
|
|
form_field=form.sms_code,
|
|
thing='mobile number'
|
|
)
|
|
|
|
|
|
@main.route("/user-profile/password", methods=['GET', 'POST'])
|
|
@user_is_logged_in
|
|
def user_profile_password():
|
|
|
|
# Validate password for form
|
|
def _check_password(pwd):
|
|
return user_api_client.verify_password(current_user.id, pwd)
|
|
form = ChangePasswordForm(_check_password)
|
|
|
|
if form.validate_on_submit():
|
|
user_api_client.update_password(current_user.id, password=form.new_password.data)
|
|
return redirect(url_for('.user_profile'))
|
|
|
|
return render_template(
|
|
'views/user-profile/change-password.html',
|
|
form=form
|
|
)
|
|
|
|
|
|
@main.route("/user-profile/disable-platform-admin-view", methods=['GET', 'POST'])
|
|
@user_is_logged_in
|
|
def user_profile_disable_platform_admin_view():
|
|
if not current_user.platform_admin and not session.get('disable_platform_admin_view'):
|
|
abort(403)
|
|
|
|
form = ServiceOnOffSettingForm(
|
|
name="Signing in again clears this setting",
|
|
enabled=not session.get('disable_platform_admin_view'),
|
|
truthy='Yes',
|
|
falsey='No',
|
|
)
|
|
|
|
if form.validate_on_submit():
|
|
session['disable_platform_admin_view'] = not form.enabled.data
|
|
return redirect(url_for('.user_profile'))
|
|
|
|
return render_template(
|
|
'views/user-profile/disable-platform-admin-view.html',
|
|
form=form
|
|
)
|