From fa098485c4891e51659f1ec4c1d35b47c13c3bc0 Mon Sep 17 00:00:00 2001
From: "Ethan Clay (UWE)" <ethan2.clay@live.uwe.ac.uk>
Date: Fri, 13 Dec 2024 10:52:40 +0000
Subject: [PATCH] Merge auth routes into profile, add login/logout to nav bar
 including adding global context vars into templates

---
 app/__init__.py                  | 21 ++++++++--
 app/auth/__init__.py             |  5 ---
 app/auth/routes.py               | 44 -------------------
 app/profile/routes.py            | 72 +++++++++++++++++++++-----------
 app/templates/base.html          | 11 +++--
 app/templates/profile/login.html |  2 +-
 6 files changed, 74 insertions(+), 81 deletions(-)
 delete mode 100644 app/auth/__init__.py
 delete mode 100644 app/auth/routes.py

diff --git a/app/__init__.py b/app/__init__.py
index a8bae28..fab3143 100644
--- a/app/__init__.py
+++ b/app/__init__.py
@@ -4,7 +4,7 @@ from flask import Flask
 from config import Config
 from flask_sqlalchemy import SQLAlchemy
 from flask_migrate import Migrate
-from flask_login import LoginManager
+from flask_login import LoginManager, current_user
 from dotenv import load_dotenv
 import os
 
@@ -40,6 +40,21 @@ def create_app(config_class=Config):
     # Register blueprints and url prefixes
     register_blueprints(app)
     
+    # Add any vars needed accessible through all templates
+    @app.context_processor
+    def set_global_html_variable_values():
+        try:
+            if current_user.is_authenticated:
+                user_in_session = True
+            else:
+                user_in_session = False
+
+            template_config = {'user_in_session': user_in_session}
+            return template_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.)
+
     
     if __name__ == "__main__":
         app.run(use_reloader=True)
@@ -56,7 +71,6 @@ def load_user(user_id):
 
 def register_blueprints(app):
     blueprints = [
-        ('auth', None),
         ('main', None),
         ('bookings', '/bookings'),
         ('api', '/api'),
@@ -65,4 +79,5 @@ def register_blueprints(app):
     ]
     for module_name, url_prefix in blueprints:
         module = __import__(f'app.{module_name}', fromlist=['bp'])
-        app.register_blueprint(module.bp, url_prefix=url_prefix)
\ No newline at end of file
+        app.register_blueprint(module.bp, url_prefix=url_prefix)
+
diff --git a/app/auth/__init__.py b/app/auth/__init__.py
deleted file mode 100644
index 2834ca1..0000000
--- a/app/auth/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from flask import Blueprint
-
-bp = Blueprint('auth', __name__)
-
-from app.auth import routes
\ No newline at end of file
diff --git a/app/auth/routes.py b/app/auth/routes.py
deleted file mode 100644
index e841d6e..0000000
--- a/app/auth/routes.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#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
-from app.auth import bp
-from werkzeug.security import generate_password_hash, check_password_hash
-from app.models import User
-from app import db
-from flask_login import login_user
-
-@bp.route('/signup')
-def signup():
-    return render_template(url_for('profile.signup'))
-
-@bp.route('/signup', methods=['POST'])
-def signup_post():
-    email = request.form.get('email')
-    username = request.form.get('name')
-    password = request.form.get('password')
-
-    user = User.query.filter_by(email=email).first()
-
-    if user:
-        return redirect(url_for('profile.signup'))
-
-    new_user = User.create_user(username=username, email=email, password=password)
-
-    db.session.add(new_user)
-    db.session.commit()
-
-    return redirect(url_for('profile.login'))
-
-@bp.route('/login', methods=['POST'])
-def login_post():
-    email = request.form.get('email')
-    password = request.form.get('password')
-    remember = True if request.form.get('remember') else False # If checkbox for user is ticked
-
-    user = User.query.filter_by(email=email).first()
-
-    if not user or not check_password_hash(user.password, password):
-        flash('Please check your login details and try again.')
-        return redirect(url_for('profile.login'))
-
-    login_user(user, remember=remember)
-    return redirect(url_for('profile.index'))
\ No newline at end of file
diff --git a/app/profile/routes.py b/app/profile/routes.py
index ebfcbf4..4a32cfa 100644
--- a/app/profile/routes.py
+++ b/app/profile/routes.py
@@ -1,40 +1,62 @@
-from flask import render_template, redirect, url_for
+#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
 from app.profile import bp
-from app.models import User 
-from flask_login import current_user, login_required
+from werkzeug.security import generate_password_hash, check_password_hash
+from app.models import User
+from app import db
+from flask_login import login_user, logout_user, login_required, current_user
 
-@bp.route('/')
-@login_required
-def index():
-    if current_user.is_authenticated:
-        return render_template('profile/index.html', username=current_user.username)
-    else:
-        return redirect(url_for('profile.login'))
-
-@bp.route('/login')
-def login():
-    return render_template('profile/login.html')
+@bp.route('/signup')
+def signup():
+    return render_template(url_for('profile.signup'))
 
 @bp.route('/signup', methods=['POST'])
 def signup_post():
-    return 'hit POST'
     email = request.form.get('email')
-    name = request.form.get('name')
+    username = request.form.get('name')
     password = request.form.get('password')
-    if User.search_user_by_email(email):
-        return redirect('signup.html')
 
-    new_user = User(email=email, name=name, password=generate_password_hash(password, method='sha256'))
+    user = User.query.filter_by(email=email).first()
+
+    if user:
+        return redirect(url_for('profile.signup'))
+
+    new_user = User.create_user(username=username, email=email, password=password)
 
     db.session.add(new_user)
     db.session.commit()
-    
-    return redirect('profile/login.html')
 
-@bp.route('/signup')
-def signup():
-    return render_template('profile/signup.html')
+    return redirect(url_for('profile.login'))
+
+@bp.route('/login', methods=['POST'])
+def login_post():
+    email = request.form.get('email')
+    password = request.form.get('password')
+    remember = True if request.form.get('remember') else False # If checkbox for user is ticked
+
+    user = User.query.filter_by(email=email).first()
+
+    if not user or not check_password_hash(user.password, password):
+        flash('Please check your login details and try again.')
+        return redirect(url_for('profile.login'))
+
+    login_user(user, remember=remember)
+    return redirect(url_for('profile.index'))
 
 @bp.route('/logout')
+@login_required
 def logout():
-    return 'Logout'
+    logout_user()
+    return redirect(url_for('main.index'))
+
+@bp.route('/login')
+def login():
+    return render_template('profile/login.html')
+
+@login_required
+@bp.route('/home')
+def index():
+    if current_user.is_authenticated:
+        return render_template('profile/index.html', username=current_user.username)
+    
+    return redirect(url_for('profile.login'))
\ No newline at end of file
diff --git a/app/templates/base.html b/app/templates/base.html
index c405dd2..8918486 100644
--- a/app/templates/base.html
+++ b/app/templates/base.html
@@ -35,10 +35,15 @@
                                     Account
                                 </a>
                                 <ul class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
-                                    <li><a class="dropdown-item" href="#">Account Details</a></li>
-                                    <li><a class="dropdown-item" href="#">My Bookings</a></li>
-                                    <li><a class="dropdown-item" href="#">Log Out</a></li>
+                                    {% if user_in_session %}
+                                        <li><a class="dropdown-item" href="#">Account Details</a></li>
+                                        <li><a class="dropdown-item" href="#">My Bookings</a></li>
+                                        <li><a class="dropdown-item" href="{{ url_for('profile.logout') }}">Log Out</a></li>
+                                    {% else %}
+                                        <li><a class="dropdown-item" href="{{ url_for('profile.login') }}">Log In</a></li>
+                                    {% endif %}
                                 </ul>
+                                
                                 </li>
                             </ul>
                             </div>
diff --git a/app/templates/profile/login.html b/app/templates/profile/login.html
index 0384d22..ddb577c 100644
--- a/app/templates/profile/login.html
+++ b/app/templates/profile/login.html
@@ -4,7 +4,7 @@
 <div class="column is-4 is-offset-4">
     <h3 class="title">Login</h3>
     <div class="box">
-        <form method="POST" action="/login">
+        <form method="POST" action="{{ url_for ('profile.login_post')}}">
             <div class="field">
                 <div class="control">
                     <input class="input is-large" type="email" name="email" placeholder="Your Email" autofocus="">
-- 
GitLab