Added user login functionality
This commit is contained in:
parent
ff4336f655
commit
12b902c382
@ -3,7 +3,7 @@
|
||||
A minimal python flask app for inventory management, with some basic functionality:
|
||||
- Fetch and display items from the MySQL db as an html table
|
||||
- Add new items to the db (individually) using a form
|
||||
- Edit existing (individual)items in the db using a for
|
||||
- Edit existing (individual) items in the db using a form
|
||||
- Delete (individual)items in the db
|
||||
- Add a batch of new items from a csv file
|
||||
- Edit a batch of existing items with new data from a csv file
|
||||
|
4
app.py
4
app.py
@ -12,6 +12,7 @@ from sqlalchemy import exc
|
||||
from definitions.models import *
|
||||
|
||||
# Import the Blueprints
|
||||
from routes.homepage import homepage_bp
|
||||
from routes.viewall import viewall_bp
|
||||
from routes.export_csv import export_csv_bp
|
||||
from routes.create import addasset_bp
|
||||
@ -27,6 +28,7 @@ app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
||||
db.init_app(app)
|
||||
|
||||
# Register the Blueprints
|
||||
app.register_blueprint(homepage_bp)
|
||||
app.register_blueprint(viewall_bp)
|
||||
app.register_blueprint(export_csv_bp)
|
||||
app.register_blueprint(addasset_bp)
|
||||
@ -44,9 +46,11 @@ with app.app_context():
|
||||
print(f"Database Error: Failed to create tables. {str(e)}")
|
||||
raise SystemExit("Database connection failed. Please check your configuration.")
|
||||
|
||||
"""
|
||||
@app.route('/')
|
||||
def index():
|
||||
return redirect('/viewall')
|
||||
"""
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='localhost', port=5000)
|
||||
|
10
functions/auth.py
Normal file
10
functions/auth.py
Normal file
@ -0,0 +1,10 @@
|
||||
from functools import wraps # Import wraps
|
||||
from flask import session, redirect, url_for
|
||||
|
||||
def login_required(f):
|
||||
@wraps(f) # Preserve the original function's metadata
|
||||
def decorated_function(*args, **kwargs):
|
||||
if 'username' not in session:
|
||||
return redirect(url_for('homepage.login'))
|
||||
return f(*args, **kwargs)
|
||||
return decorated_function
|
@ -3,10 +3,12 @@ from definitions.models import Asset, db
|
||||
from functions.validate_values import validate_values
|
||||
from config import item_attributes
|
||||
import json
|
||||
from functions.auth import login_required
|
||||
|
||||
confirm_save_bp = Blueprint('confirm_save', __name__)
|
||||
|
||||
@confirm_save_bp.route('/confirm_save', methods=['POST'])
|
||||
@login_required
|
||||
def confirm_save():
|
||||
# Retrieve mode from session
|
||||
mode = session.get('csv_mode')
|
||||
|
@ -3,10 +3,12 @@ from definitions.models import Asset, db
|
||||
from config import item_attributes
|
||||
from sqlalchemy import exc # Import exc for database exceptions
|
||||
from functions.validate_values import validate_values # Form validation
|
||||
from functions.auth import login_required
|
||||
|
||||
addasset_bp = Blueprint('addasset', __name__)
|
||||
|
||||
@addasset_bp.route('/create/', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def create():
|
||||
if request.method == 'GET':
|
||||
# Render the "add item" form
|
||||
|
@ -1,10 +1,12 @@
|
||||
from flask import Blueprint, request, render_template, redirect, flash
|
||||
from definitions.models import Asset, db
|
||||
from config import item_attributes
|
||||
from functions.auth import login_required
|
||||
|
||||
delete_bp = Blueprint('deleteasset', __name__)
|
||||
|
||||
@delete_bp.route('/delete/<path:primary_value>/', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def delete(primary_value):
|
||||
# Identify the primary attribute
|
||||
primary_attrib = next(
|
||||
|
@ -3,10 +3,12 @@ from definitions.models import Asset
|
||||
from config import item_attributes
|
||||
import csv
|
||||
import io
|
||||
from functions.auth import login_required
|
||||
|
||||
export_csv_bp = Blueprint('export_csv', __name__)
|
||||
|
||||
@export_csv_bp.route('/export_csv', methods=['POST'])
|
||||
@login_required
|
||||
def export_csv():
|
||||
# Create an in-memory file-like object
|
||||
output = io.StringIO()
|
||||
|
41
routes/homepage.py
Normal file
41
routes/homepage.py
Normal file
@ -0,0 +1,41 @@
|
||||
# routes/homepage.py
|
||||
from flask import Blueprint, render_template, redirect, url_for, session, request, flash
|
||||
|
||||
homepage_bp = Blueprint('homepage', __name__)
|
||||
|
||||
# Hardcoded credentials for testing (replace with proper authentication in production)
|
||||
VALID_USERNAME = "admin"
|
||||
VALID_PASSWORD = "password"
|
||||
|
||||
@homepage_bp.route('/')
|
||||
def index():
|
||||
# Redirect to /viewall if the user is already logged in
|
||||
if 'username' in session:
|
||||
return redirect(url_for('viewall.view_list'))
|
||||
# Otherwise, redirect to the login page
|
||||
return redirect(url_for('homepage.login'))
|
||||
|
||||
@homepage_bp.route('/login', methods=['GET', 'POST'])
|
||||
def login():
|
||||
# Redirect to /viewall if the user is already logged in
|
||||
if 'username' in session:
|
||||
return redirect(url_for('viewall.view_list'))
|
||||
|
||||
if request.method == 'POST':
|
||||
username = request.form['username']
|
||||
password = request.form['password']
|
||||
|
||||
# Validate credentials (replace with proper authentication logic)
|
||||
if username == VALID_USERNAME and password == VALID_PASSWORD:
|
||||
session['username'] = username # Store username in session
|
||||
return redirect(url_for('viewall.view_list'))
|
||||
else:
|
||||
flash('Invalid username or password', 'error')
|
||||
|
||||
return render_template('login.html')
|
||||
|
||||
@homepage_bp.route('/logout')
|
||||
def logout():
|
||||
# Remove the username from the session
|
||||
session.pop('username', None)
|
||||
return redirect(url_for('homepage.login'))
|
@ -3,10 +3,12 @@ from definitions.models import Asset, db
|
||||
from config import item_attributes
|
||||
from sqlalchemy import exc # Import exc for database exceptions
|
||||
from functions.validate_values import validate_values # Form validation
|
||||
from functions.auth import login_required
|
||||
|
||||
update_bp = Blueprint('editasset', __name__)
|
||||
|
||||
@update_bp.route('/update/<string:primary_value>/', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def update(primary_value):
|
||||
# Identify the primary attribute
|
||||
primary_attrib = next((attrib for attrib in item_attributes if attrib.primary), None)
|
||||
|
@ -3,6 +3,7 @@ from definitions.models import Asset, db
|
||||
from functions.process_csv import get_csv_data
|
||||
from functions.validate_values import validate_values
|
||||
from config import item_attributes
|
||||
from functions.auth import login_required
|
||||
|
||||
upload_bp = Blueprint('uploadcsv', __name__)
|
||||
|
||||
@ -55,6 +56,7 @@ def _process_csv_file(file, mode):
|
||||
}, None
|
||||
|
||||
@upload_bp.route('/import_from_csv', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def import_from_csv():
|
||||
session['csv_mode'] = 'import' # Store mode in session
|
||||
if request.method == 'POST':
|
||||
@ -94,6 +96,7 @@ def import_from_csv():
|
||||
return render_template('upload.html', mode="import")
|
||||
|
||||
@upload_bp.route('/edit_using_csv', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def edit_using_csv():
|
||||
session['csv_mode'] = 'edit' # Store mode in session
|
||||
if request.method == 'POST':
|
||||
|
@ -1,10 +1,12 @@
|
||||
from flask import Blueprint, render_template
|
||||
from definitions.models import Asset
|
||||
from config import item_attributes
|
||||
from functions.auth import login_required
|
||||
|
||||
viewall_bp = Blueprint('viewall', __name__)
|
||||
|
||||
@viewall_bp.route('/viewall/', methods=['GET'])
|
||||
@login_required
|
||||
def view_list():
|
||||
# Fetch all items from the database
|
||||
items = Asset.query.all()
|
||||
|
26
templates/login.html
Normal file
26
templates/login.html
Normal file
@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Login Page</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="left-container">
|
||||
<img src="../images/logo2.png" alt="Company Logo" class="logo">
|
||||
<h1>Inventory Manager</h1>
|
||||
<p>Inventory management system</p>
|
||||
</div>
|
||||
|
||||
<div class="login-container">
|
||||
<h2>Login</h2>
|
||||
<form action="/login" method="post">
|
||||
<input type="text" name="username" placeholder="Username" required>
|
||||
<input type="password" name="password" placeholder="Password" required>
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -49,5 +49,8 @@
|
||||
<form action="/export_csv" method="POST">
|
||||
<button type="submit">Export Data</button>
|
||||
</form>
|
||||
<form action="/logout" method="get">
|
||||
<button type="submit">Logout</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user