Skip to content
Snippets Groups Projects
Commit f23f1355 authored by Ethan-clay03's avatar Ethan-clay03
Browse files

Continue to complete change password

parent ed105da3
No related branches found
No related tags found
No related merge requests found
# 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 # 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 config import Config
from flask_sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate from flask_migrate import Migrate
...@@ -60,7 +60,13 @@ def create_app(config_class=Config): ...@@ -60,7 +60,13 @@ def create_app(config_class=Config):
except Exception as e: except Exception as e:
# print(f"Error in context processor: {e}") # print(f"Error in context processor: {e}")
return {'user_in_session': False} # Fallback, to create logging to record such failures (database corrupted etc.) 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__": if __name__ == "__main__":
app.run(use_reloader=True, debug=True) app.run(use_reloader=True, debug=True)
...@@ -81,7 +87,8 @@ def register_blueprints(app): ...@@ -81,7 +87,8 @@ def register_blueprints(app):
('bookings', '/bookings'), ('bookings', '/bookings'),
('api', '/api'), ('api', '/api'),
('admin', '/admin'), ('admin', '/admin'),
('profile', '/profile') ('profile', '/profile'),
('errors', '/errors'),
] ]
for module_name, url_prefix in blueprints: for module_name, url_prefix in blueprints:
module = __import__(f'app.{module_name}', fromlist=['bp']) module = __import__(f'app.{module_name}', fromlist=['bp'])
......
from flask import Blueprint
bp = Blueprint('errors', __name__)
from app.errors import routes
\ No newline at end of file
#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)
...@@ -37,4 +37,11 @@ class User(UserMixin, db.Model): ...@@ -37,4 +37,11 @@ class User(UserMixin, db.Model):
def search_user_by_username(cls, user_name): def search_user_by_username(cls, user_name):
user_exist = cls.query.filter_by(username=user_name).first() user_exist = cls.query.filter_by(username=user_name).first()
return user_exist return user_exist
\ No newline at end of file
@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
#https://www.digitalocean.com/community/tutorials/how-to-add-authentication-to-your-app-with-flask-login#step-1-installing-packages #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 app.profile import bp
from werkzeug.security import check_password_hash from werkzeug.security import check_password_hash
from app.models import User from app.models import User
...@@ -116,6 +116,7 @@ def check_password_reset_1(): ...@@ -116,6 +116,7 @@ def check_password_reset_1():
if email_exist is None: if email_exist is None:
return flash('Email does not exist') return flash('Email does not exist')
session['password-reset-email'] = email
return redirect(url_for('profile.password_reset_2')) return redirect(url_for('profile.password_reset_2'))
@bp.route('/password-reset/2FA') @bp.route('/password-reset/2FA')
...@@ -127,8 +128,25 @@ def check_password_reset_2(): ...@@ -127,8 +128,25 @@ def check_password_reset_2():
code = request.form.get('2fa-code') code = request.form.get('2fa-code')
#Simulate 2FA code being entered #Simulate 2FA code being entered
if code == '123456': if code == '123456' or code == '234567':
pass 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 @login_required
@bp.route('/home') @bp.route('/home')
......
...@@ -82,6 +82,24 @@ body { ...@@ -82,6 +82,24 @@ body {
background-color: #90AEAD; 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 Form styling options
*/ */
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
<meta name="csrf-token" content="{{ csrf_token() }}"> <meta name="csrf-token" content="{{ csrf_token() }}">
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='base.css')}}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='base.css')}}">
<link rel="stylesheet" href="{{ url_for('static', filename='generic.js')}}"> <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"> <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> <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')}}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='bootstrap_overrides.css')}}">
...@@ -19,7 +20,7 @@ ...@@ -19,7 +20,7 @@
<div class="navigation"> <div class="navigation">
<nav class="navbar navbar-expand-lg navbar-dark nav_background p-3"> <nav class="navbar navbar-expand-lg navbar-dark nav_background p-3">
<div class="container-fluid"> <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"> <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> <span class="navbar-toggler-icon"></span>
</button> </button>
......
{% 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
{% 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 %}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment