def update_password(token): form = auth_forms.ChangePasswordForm(request.form) decoded = decode_password_reset_token(token.encode(), data_api_client) if decoded.get('error', None): flash(decoded['error'], 'error') return redirect(url_for('.request_password_reset')) user_id = decoded["user"] email_address = decoded["email"] password = form.password.data if form.validate(): if data_api_client.update_user_password(user_id, password, email_address): current_app.logger.info( "User {user_id} ({hashed_email}) successfully changed their password", extra={ 'user_id': user_id, 'hashed_email': hash_email(email_address) }) flash('password_updated') else: flash('password_not_updated', 'error') return redirect(url_for('.render_login')) else: return render_template_with_csrf("auth/reset-password.html", status_code=400, email_address=email_address, form=form, token=token)
def update_password(token): form = PasswordResetForm() decoded = decode_password_reset_token(token, data_api_client) if 'error' in decoded: flash(EXPIRED_PASSWORD_RESET_TOKEN_MESSAGE, "error") return redirect(url_for('.request_password_reset')) user_id = decoded["user"] email_address = decoded["email"] password = form.password.data if form.validate_on_submit(): if data_api_client.update_user_password(user_id, password, email_address): current_app.logger.info( "User {user_id} successfully changed their password", extra={'user_id': user_id}) flash(PASSWORD_UPDATED_MESSAGE, "success") else: flash(PASSWORD_NOT_UPDATED_MESSAGE, "error") return redirect(url_for('.render_login')) else: return render_template("auth/reset-password.html", email_address=email_address, form=form, errors=get_errors_from_wtform(form), token=token), 400
def test_decode_password_reset_token_ok_for_good_token(email_app, user): user['users']['passwordChangedAt'] = "2016-01-01T12:00:00.30Z" data_api_client = mock.Mock() data_api_client.get_user.return_value = user with email_app.app_context(): data = {'user': '******'} token = generate_token(data, TEST_SECRET_KEY, 'PassSalt') assert decode_password_reset_token(token, data_api_client) == data
def test_decode_password_reset_token_ok_for_good_token(email_app): user = user_json() user['users']['passwordChangedAt'] = "2016-01-01T12:00:00.30Z" data_api_client = mock.Mock() data_api_client.get_user.return_value = user with email_app.app_context(): data = {'user': '******'} token = generate_token(data, 'Secret', 'PassSalt') assert decode_password_reset_token(token, data_api_client) == data
def test_decode_password_reset_token_does_not_work_if_bad_token(email_app): user = user_json() user['users']['passwordChangedAt'] = "2016-01-01T12:00:00.30Z" data_api_client = mock.Mock() data_api_client.get_user.return_value = user data = {'user': '******'} token = generate_token(data, 'Secret', 'PassSalt')[1:] with email_app.app_context(): assert decode_password_reset_token(token, data_api_client) == {'error': 'token_invalid'}
def test_decode_password_reset_token_does_not_work_if_bad_token(email_app): user = user_json() user['users']['passwordChangedAt'] = "2016-01-01T12:00:00.30Z" data_api_client = mock.Mock() data_api_client.get_user.return_value = user data = {'user': '******'} token = generate_token(data, TEST_SECRET_KEY, 'PassSalt')[1:] with email_app.app_context(): assert decode_password_reset_token(token, data_api_client) == {'error': 'token_invalid'}
def reset_password(token): decoded = decode_password_reset_token(token.encode(), data_api_client) if decoded.get('error', None): flash(decoded['error'], 'error') return redirect(url_for('.request_password_reset')) email_address = decoded['email'] return render_template_with_csrf("auth/reset-password.html", email_address=email_address, form=auth_forms.ChangePasswordForm(), token=token)
def test_decode_password_reset_token_does_not_work_if_token_expired(email_app): user = user_json() user['users']['passwordChangedAt'] = "2016-01-01T12:00:00.30Z" data_api_client = mock.Mock() data_api_client.get_user.return_value = user with freeze_time('2015-01-02 03:04:05'): # Token was generated a year before current time data = {'user': '******'} token = generate_token(data, 'Secret', 'PassSalt') with freeze_time('2016-01-02 03:04:05'): with email_app.app_context(): assert decode_password_reset_token(token, data_api_client) == {'error': 'token_expired'}
def test_decode_password_reset_token_does_not_work_if_token_expired(email_app): user = user_json() user['users']['passwordChangedAt'] = "2016-01-01T12:00:00.30Z" data_api_client = mock.Mock() data_api_client.get_user.return_value = user with freeze_time('2015-01-02 03:04:05'): # Token was generated a year before current time data = {'user': '******'} token = generate_token(data, TEST_SECRET_KEY, 'PassSalt') with freeze_time('2016-01-02 03:04:05'): with email_app.app_context(): assert decode_password_reset_token(token, data_api_client) == {'error': 'token_invalid'}
def test_decode_password_reset_token_does_not_work_if_password_changed_later_than_token(email_app): user = user_json() user['users']['passwordChangedAt'] = "2016-01-01T13:00:00.30Z" data_api_client = mock.Mock() data_api_client.get_user.return_value = user with freeze_time('2016-01-01T12:00:00.30Z'): # Token was generated an hour earlier than password was changed data = {'user': '******'} token = generate_token(data, 'Secret', 'PassSalt') with freeze_time('2016-01-01T14:00:00.30Z'): # Token is two hours old; password was changed an hour ago with email_app.app_context(): assert decode_password_reset_token(token, data_api_client) == {'error': 'token_invalid'}
def test_decode_password_reset_token_does_not_work_if_password_changed_later_than_token(email_app): user = user_json() user['users']['passwordChangedAt'] = "2016-01-01T13:00:00.30Z" data_api_client = mock.Mock() data_api_client.get_user.return_value = user with freeze_time('2016-01-01T12:00:00.30Z'): # Token was generated an hour earlier than password was changed data = {'user': '******'} token = generate_token(data, TEST_SECRET_KEY, 'PassSalt') with freeze_time('2016-01-01T14:00:00.30Z'): # Token is two hours old; password was changed an hour ago with email_app.app_context(): assert decode_password_reset_token(token, data_api_client) == {'error': 'token_invalid'}
def reset_password(token): decoded = decode_password_reset_token(token, data_api_client) if 'error' in decoded: flash(EXPIRED_PASSWORD_RESET_TOKEN_MESSAGE, "error") return redirect(url_for('.request_password_reset')) email_address = decoded['email'] form = PasswordResetForm() errors = get_errors_from_wtform(form) return render_template("auth/reset-password.html", email_address=email_address, form=form, errors=errors, token=token), 200