From f23f13557df66e79dfc27cdbc841f5923a1f00ac Mon Sep 17 00:00:00 2001 From: Ethan-clay03 <ethanclay2017@gmail.com> Date: Fri, 3 Jan 2025 21:36:13 +0000 Subject: [PATCH] Continue to complete change password --- app/__init__.py | 13 +++++++--- app/errors/__init__.py | 5 ++++ app/errors/routes.py | 8 ++++++ app/models/user.py | 9 ++++++- app/profile/routes.py | 24 +++++++++++++++--- app/static/base.css | 18 +++++++++++++ app/templates/base.html | 3 ++- app/templates/errors/quandary.html | 28 +++++++++++++++++++++ app/templates/profile/password-reset-3.html | 26 +++++++++++++++++++ 9 files changed, 126 insertions(+), 8 deletions(-) create mode 100644 app/errors/__init__.py create mode 100644 app/errors/routes.py create mode 100644 app/templates/errors/quandary.html create mode 100644 app/templates/profile/password-reset-3.html diff --git a/app/__init__.py b/app/__init__.py index db20977..6a05c0b 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,6 +1,6 @@ # Boilerplate create_app code taken from https://www.digitalocean.com/community/tutorials/how-to-structure-a-large-flask-application-with-flask-blueprints-and-flask-sqlalchemy -from flask import Flask +from flask import Flask, url_for, redirect, session from config import Config from flask_sqlalchemy import SQLAlchemy from flask_migrate import Migrate @@ -60,7 +60,13 @@ def create_app(config_class=Config): except Exception as e: # print(f"Error in context processor: {e}") return {'user_in_session': False} # Fallback, to create logging to record such failures (database corrupted etc.) - + + + @app.errorhandler(Exception) + def handle_exception(e): + app.logger.error(f"Unhandled exception: {e}") + session['error_message'] = str(e) + return redirect(url_for('errors.quandary')) if __name__ == "__main__": app.run(use_reloader=True, debug=True) @@ -81,7 +87,8 @@ def register_blueprints(app): ('bookings', '/bookings'), ('api', '/api'), ('admin', '/admin'), - ('profile', '/profile') + ('profile', '/profile'), + ('errors', '/errors'), ] for module_name, url_prefix in blueprints: module = __import__(f'app.{module_name}', fromlist=['bp']) diff --git a/app/errors/__init__.py b/app/errors/__init__.py new file mode 100644 index 0000000..9e0f7cc --- /dev/null +++ b/app/errors/__init__.py @@ -0,0 +1,5 @@ +from flask import Blueprint + +bp = Blueprint('errors', __name__) + +from app.errors import routes \ No newline at end of file diff --git a/app/errors/routes.py b/app/errors/routes.py new file mode 100644 index 0000000..14aeca0 --- /dev/null +++ b/app/errors/routes.py @@ -0,0 +1,8 @@ +#https://www.digitalocean.com/community/tutorials/how-to-add-authentication-to-your-app-with-flask-login#step-1-installing-packages +from flask import render_template, session +from app.errors import bp + +@bp.route('/quandary') +def quandary(): + error_message = session.pop('error_message') + return render_template("errors/quandary.html", error_message=error_message) diff --git a/app/models/user.py b/app/models/user.py index 87cbab5..40661cf 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -37,4 +37,11 @@ class User(UserMixin, db.Model): def search_user_by_username(cls, user_name): user_exist = cls.query.filter_by(username=user_name).first() - return user_exist \ No newline at end of file + return user_exist + + @classmethod + def change_user_password(cls, email, password): + user = cls.search_user_by_email(email) + + if user is None: + raise ValueError("Error") \ No newline at end of file diff --git a/app/profile/routes.py b/app/profile/routes.py index 998e407..3fa2fa8 100644 --- a/app/profile/routes.py +++ b/app/profile/routes.py @@ -1,5 +1,5 @@ #https://www.digitalocean.com/community/tutorials/how-to-add-authentication-to-your-app-with-flask-login#step-1-installing-packages -from flask import Blueprint, render_template, redirect, url_for, request, flash, jsonify +from flask import render_template, redirect, url_for, request, flash, jsonify, session from app.profile import bp from werkzeug.security import check_password_hash from app.models import User @@ -116,6 +116,7 @@ def check_password_reset_1(): if email_exist is None: return flash('Email does not exist') + session['password-reset-email'] = email return redirect(url_for('profile.password_reset_2')) @bp.route('/password-reset/2FA') @@ -127,8 +128,25 @@ def check_password_reset_2(): code = request.form.get('2fa-code') #Simulate 2FA code being entered - if code == '123456': - pass + if code == '123456' or code == '234567': + return redirect(url_for('profile.password_reset_3')) + + return flash('Invalid 2FA Code') + +@bp.route('/password-reset/reset-password') +def password_reset_3(): + return render_template('profile/password-reset-3.html') + +@bp.route('/password-reset/reset-password', methods=['POST']) +def password_reset_process(): + email = session.get('email') + password1 = session.get('password-1') + password2 = session.get('password-2') + + #Simulate 2FA code being entered + if password1 == password2: + User.change_user_password(email, password1) + return redirect(url_for('profile.password_reset_3')) @login_required @bp.route('/home') diff --git a/app/static/base.css b/app/static/base.css index ad53048..4298542 100644 --- a/app/static/base.css +++ b/app/static/base.css @@ -82,6 +82,24 @@ body { background-color: #90AEAD; } +.button_2 { + background-color: #244855; + border: none; + border-radius: 12px; + color: white; + padding: 15px 32px; + text-align: center; + text-decoration: none; + display: flex; + font-size: 25px; + cursor: pointer; + flex-direction: column; +} + +.button_2:hover { + background-color: #90AEAD; +} + /** Form styling options */ diff --git a/app/templates/base.html b/app/templates/base.html index f1586d9..5bb63ea 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -5,6 +5,7 @@ <meta name="csrf-token" content="{{ csrf_token() }}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='base.css')}}"> <link rel="stylesheet" href="{{ url_for('static', filename='generic.js')}}"> + <script src="https://kit.fontawesome.com/11fd621de6.js" crossorigin="anonymous"></script> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='bootstrap_overrides.css')}}"> @@ -19,7 +20,7 @@ <div class="navigation"> <nav class="navbar navbar-expand-lg navbar-dark nav_background p-3"> <div class="container-fluid"> - <a class="navbar-brand" href="{{ url_for('bookings.index') }}">Horizon Travels</a> + <a class="navbar-brand" href="{{ url_for('main.index') }}">Horizon Travels</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> diff --git a/app/templates/errors/quandary.html b/app/templates/errors/quandary.html new file mode 100644 index 0000000..7cb8f82 --- /dev/null +++ b/app/templates/errors/quandary.html @@ -0,0 +1,28 @@ +{% block content %} +<head> + <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='base.css')}}"> + <script src="https://kit.fontawesome.com/11fd621de6.js" crossorigin="anonymous"></script> +</head> +<div class="quandary-div"> + <h1>500 Server Error</h1> + <div class="container"> + <div style="margin-bottom: 20px;"><span>Something went wrong, if this continues please contact support</span></div> + <div class="button_2"><i class="fa-solid fa-circle-arrow-left"></i><span> Go back</span></div> + </div> +</div> + +<style> + +.quandary-div { + height: 100vh; + display: flex; + flex-direction: row; + justify-content: center; + align-items: baseline; + align-content: center; + font-size: xx-large; + flex-wrap: wrap; +} + +</style> +{% endblock %} \ No newline at end of file diff --git a/app/templates/profile/password-reset-3.html b/app/templates/profile/password-reset-3.html new file mode 100644 index 0000000..e24c164 --- /dev/null +++ b/app/templates/profile/password-reset-3.html @@ -0,0 +1,26 @@ +{% extends 'base.html' %} + +{% block content %} +<div class="form_box_30 background_1"> + {% if get_flashed_messages() %} + <div class="alert alert-danger" role="alert"> + get_flashed_messages() + </div> + {% endif %} + <div class="profile_form_background"> + <h3 class="form_header">Password Reset</h3> + <form method="POST" action="{{ url_for('profile.password_reset_process') }}"> + <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"> + <div class="mb-3"> + <label class="form-label" for="password-1" autofocus="">Enter your new password</label> + <input type="text" id="password-1" class="form-control" name="password-1" required> + </div> + <div class="mb-3"> + <label class="form-label" for="password-2" autofocus="">Re-enter your new password</label> + <input type="text" id="password-2" class="form-control" name="password-2" required> + </div> + <button type="submit" class="btn btn-primary">Update Password</button> + </form> + </div> +</div> +{% endblock %} -- GitLab