REFACTOR: Changed blueprints to allow for preprocessing of requests

This commit is contained in:
Luke Else 2024-02-14 14:56:58 +00:00
parent 2f7ba0d963
commit 45d2773f9a
6 changed files with 61 additions and 48 deletions

View File

@ -2,14 +2,27 @@
in the web app in the web app
""" """
from flask import render_template, Blueprint from flask import render_template, Blueprint, redirect, url_for, flash
from controllers.database.user import UserController from controllers.database.user import UserController
from controllers.database.product import ProductController
from utils.user_utils import is_role
# Blueprint to append user endpoints to # Blueprint to append user endpoints to
blueprint = Blueprint("admin", __name__, url_prefix="/admin") blueprint = Blueprint("admin", __name__, url_prefix="/admin")
@blueprint.before_request
def check_admin_user():
""" Preprocess for all admin endpoints to ensure that the requesting
user is logged in as an 'Admin'
"""
if not is_role("Admin"):
flash("You must be logged in as an Admin to view this page.", "error")
return redirect(url_for('main.index'))
@blueprint.route('/') @blueprint.route('/')
def main(): def main():
""" Function responsible for delivering the admin page for the site """ """ Function responsible for delivering the admin page for the site """
@ -24,3 +37,17 @@ def users():
users = db.read_all() users = db.read_all()
return render_template("index.html", content="admin.html", users=users) return render_template("index.html", content="admin.html", users=users)
@blueprint.route('/products/')
def products():
""" Endpoint responsible for managing products on the site """
# Get all products to create admin table on frontend
db = ProductController()
products = db.read_all()
return render_template(
"index.html",
content="admin.html",
products=products
)

View File

@ -11,7 +11,8 @@ from . import admin
blueprint = Blueprint('main', __name__) blueprint = Blueprint('main', __name__)
blueprint.register_blueprint(user.blueprint) blueprint.register_blueprint(user.blueprint)
blueprint.register_blueprint(product.blueprint) blueprint.register_blueprint(product.product_blueprint)
blueprint.register_blueprint(product.seller_blueprint)
blueprint.register_blueprint(stats.blueprint) blueprint.register_blueprint(stats.blueprint)
blueprint.register_blueprint(admin.blueprint) blueprint.register_blueprint(admin.blueprint)

View File

@ -19,7 +19,8 @@ from utils.user_utils import is_role
import os import os
blueprint = Blueprint("products", __name__, url_prefix="/products") product_blueprint = Blueprint("products", __name__, url_prefix="/products")
seller_blueprint = Blueprint("seller", __name__, url_prefix="/products")
# List of available filters for the user to select # List of available filters for the user to select
FILTERS = { FILTERS = {
@ -30,7 +31,7 @@ FILTERS = {
} }
@blueprint.context_processor @product_blueprint.context_processor
def filter_list(): def filter_list():
""" Places a list of all the available filters in the """ Places a list of all the available filters in the
products context products context
@ -49,7 +50,8 @@ def get_filter():
return FILTERS['Relevance'] return FILTERS['Relevance']
@blueprint.context_processor @product_blueprint.context_processor
@seller_blueprint.context_processor
def category_list(): def category_list():
""" Places a list of all categories in the products context """ """ Places a list of all categories in the products context """
database = CategoryController() database = CategoryController()
@ -57,7 +59,15 @@ def category_list():
return dict(categories=categories) return dict(categories=categories)
@blueprint.route('/') @seller_blueprint.before_request
def check_role():
# User must be logged in as seller to view page
if not is_role("Seller") and not is_role("Admin"):
flash("You must be logged in as a seller to view this page!", "error")
return redirect(url_for('main.index'))
@product_blueprint.route('/')
def index(): def index():
""" The front product page """ """ The front product page """
# Returning an empty category acts the same # Returning an empty category acts the same
@ -65,7 +75,7 @@ def index():
return category("") return category("")
@blueprint.route('/<string:category>') @product_blueprint.route('/<string:category>')
def category(category: str): def category(category: str):
""" Loads a given categories page """ """ Loads a given categories page """
database = ProductController() database = ProductController()
@ -92,7 +102,7 @@ def category(category: str):
) )
@blueprint.route('/<int:id>') @product_blueprint.route('/<int:id>')
def product(id: int): def product(id: int):
""" Loads a given product based on ID """ """ Loads a given product based on ID """
db = ProductController() db = ProductController()
@ -116,29 +126,19 @@ def product(id: int):
) )
@blueprint.route('/add') @seller_blueprint.route('/add')
def display_add(): def display_add():
""" Launches the page to add a new product to the site """ """ Launches the page to add a new product to the site """
# User needs to be logged in as a seller to view this page
if not is_role("Seller"):
flash("You must be logged in as a seller to view this page!", "error")
return redirect(url_for('main.index'))
return render_template('index.html', content='new_product.html') return render_template('index.html', content='new_product.html')
@blueprint.post('/add') @seller_blueprint.post('/add')
def add(): def add():
""" Server site processing to handle a request to add a """ Server site processing to handle a request to add a
new product to the site new product to the site
""" """
user_id = session.get('user_id') user_id = session.get('user_id')
# User needs to be logged in as a seller to view this page
if not is_role("Seller"):
flash("You must be logged in as a seller to view this page!", "error")
return redirect(url_for('main.index'))
file = request.files.get('image') file = request.files.get('image')
image_filename = save_image(file) image_filename = save_image(file)
@ -156,26 +156,21 @@ def add():
db = ProductController() db = ProductController()
db.create(product) db.create(product)
return redirect('/products/ownproducts') return redirect(url_for('main.seller.display_own'))
@blueprint.post('/update/<int:id>') @seller_blueprint.post('/update/<int:id>')
def update(id: int): def update(id: int):
""" Processes a request to update a product in place on the site """ """ Processes a request to update a product in place on the site """
# Ensure that the product belongs to the current user # Ensure that the product belongs to the current user
user_id = session.get('user_id') user_id = session.get('user_id')
# User needs to be logged in as a seller to view this page
if not is_role("Seller"):
flash("You must be logged in as a seller to view this page!", "error")
return redirect(url_for('main.index'))
db = ProductController() db = ProductController()
product = db.read_id(id) product = db.read_id(id)
if product.sellerID != user_id: if product.sellerID != user_id:
flash("This product does not belong to you!", "error") flash("This product does not belong to you!", "error")
return redirect(url_for('main.products.own')) return redirect(url_for('main.seller.own'))
# Save new image file # Save new image file
file = request.files.get('image') file = request.files.get('image')
@ -197,39 +192,29 @@ def update(id: int):
return redirect(url_for('main.products.product', id=product.id)) return redirect(url_for('main.products.product', id=product.id))
@blueprint.post('/delete/<int:id>') @seller_blueprint.post('/delete/<int:id>')
def delete(id: int): def delete(id: int):
""" Processes a request to delete a product in place on the site """ """ Processes a request to delete a product in place on the site """
# Ensure that the product belongs to the current user # Ensure that the product belongs to the current user
user_id = session.get('user_id') user_id = session.get('user_id')
# User needs to be logged in as a seller to view this page
if not is_role("Seller"):
flash("You must be logged in as a seller to view this page!", "error")
return redirect(url_for('main.index'))
db = ProductController() db = ProductController()
product = db.read_id(id) product = db.read_id(id)
if product.sellerID != user_id: if product.sellerID != user_id:
flash("This product does not belong to you!", "error") flash("This product does not belong to you!", "error")
return redirect(url_for('main.products.display_own')) return redirect(url_for('main.seller.display_own'))
db.delete(id) db.delete(id)
flash("Product Removed!", "success") flash("Product Removed!", "success")
return redirect(url_for('main.products.display_own')) return redirect(url_for('main.seller.display_own'))
@blueprint.route('/ownproducts') @seller_blueprint.route('/ownproducts')
def display_own(): def display_own():
""" Display products owned by the currently logged in seller """ """ Display products owned by the currently logged in seller """
user_id = session.get('user_id') user_id = session.get('user_id')
# User must be logged in as seller to view page
if not is_role("Seller"):
flash("You must be logged in as a seller to view this page!", "error")
return redirect(url_for('main.index'))
db = ProductController() db = ProductController()
products = db.read_user(user_id) products = db.read_user(user_id)

View File

@ -19,8 +19,8 @@
{% if user.role == "Seller" %} {% if user.role == "Seller" %}
<div class="categories"> <div class="categories">
{# List all available Seller tools #} {# List all available Seller tools #}
<a href="{{ url_for('main.products.display_add') }}" class="category">Create Products</a> <a href="{{ url_for('main.seller.display_add') }}" class="category">Create Products</a>
<a href="{{ url_for('main.products.display_own') }}" class="category">View My Products</a> <a href="{{ url_for('main.seller.display_own') }}" class="category">View My Products</a>
<a href="{{ url_for('main.stats.index') }}" class="category">View Seller Stats</a> <a href="{{ url_for('main.stats.index') }}" class="category">View Seller Stats</a>
</div> </div>
{% elif user.role == "Admin" %} {% elif user.role == "Admin" %}

View File

@ -2,7 +2,7 @@
<div id="input-form-wrap"> <div id="input-form-wrap">
<h2>Create New Product</h2> <h2>Create New Product</h2>
<form class="input-form" method="POST" action="{{ url_for('main.products.add') }}" enctype="multipart/form-data"> <form class="input-form" method="POST" action="{{ url_for('main.seller.add') }}" enctype="multipart/form-data">
<div class="input-form-row"> <div class="input-form-row">
<input type="text" id="name" name="name" placeholder="Product Name" required> <input type="text" id="name" name="name" placeholder="Product Name" required>
<input type="file" id="image" name="image" accept="image/x" required> <input type="file" id="image" name="image" accept="image/x" required>
@ -31,6 +31,6 @@
</form> </form>
<div id="create-account-wrap"> <div id="create-account-wrap">
<p>Want to view all of your products? <a href="{{ url_for('main.products.display_own') }}">Click Here</a><p> <p>Want to view all of your products? <a href="{{ url_for('main.seller.display_own') }}">Click Here</a><p>
</div> </div>
</div> </div>

View File

@ -4,7 +4,7 @@
{% if product != None %} {% if product != None %}
{% if user.id == product.sellerID %} {% if user.id == product.sellerID %}
<!-- Form --> <!-- Form -->
<form class="product-fs" method="POST" action="{{ url_for('main.products.update', id=product.id) }}" enctype="multipart/form-data"> <form class="product-fs" method="POST" action="{{ url_for('main.seller.update', id=product.id) }}" enctype="multipart/form-data">
<img class="product-image" src="{{ url_for('static', filename='assets/img/products/' + product.image) }}" alt="Brake Disks"/> <img class="product-image" src="{{ url_for('static', filename='assets/img/products/' + product.image) }}" alt="Brake Disks"/>
<div class="product-details"> <div class="product-details">
<div class="input-form-row"> <div class="input-form-row">
@ -83,7 +83,7 @@
<label class="modal__close" for="deleteModal"></label> <label class="modal__close" for="deleteModal"></label>
<h2>Confirm Delete</h2> <h2>Confirm Delete</h2>
<p>Are you sure you want to <b>delete {{product.name}}</b> from your products</p> <p>Are you sure you want to <b>delete {{product.name}}</b> from your products</p>
<form method="POST" action="{{ url_for('main.products.delete', id=product.id) }}"> <form method="POST" action="{{ url_for('main.seller.delete', id=product.id) }}">
<div class="input-form-row"> <div class="input-form-row">
<input type="submit" class="modal-btn error" for="deleteModal" value="Delete" /> <input type="submit" class="modal-btn error" for="deleteModal" value="Delete" />
</div> </div>