Add server-side input validation

- Validate that first_name, last_name, email, and location are provided
- Add regex-based email format validation in app.py
- Display error messages on the guestbook form if validation fails

These changes help ensure that only properly formatted data is stored.
This commit is contained in:
Steve Dogiakos 2025-04-01 18:01:58 -06:00
parent e18fd5fffa
commit 83775b716f
2 changed files with 40 additions and 13 deletions

50
app.py
View File

@ -1,5 +1,6 @@
from flask import Flask, render_template, request, redirect, url_for from flask import Flask, render_template, request, redirect, url_for
import sqlite3 import sqlite3
import re
app = Flask(__name__) app = Flask(__name__)
DATABASE = 'guestbook.db' DATABASE = 'guestbook.db'
@ -20,30 +21,53 @@ def init_db():
conn.commit() conn.commit()
conn.close() conn.close()
def is_valid_email(email):
# A simple regex for basic email validation
pattern = r'^[\w\.-]+@[\w\.-]+\.\w+$'
return re.match(pattern, email)
@app.route('/', methods=['GET', 'POST']) @app.route('/', methods=['GET', 'POST'])
def index(): def index():
error = None
if request.method == 'POST': if request.method == 'POST':
first_name = request.form.get('first_name') first_name = request.form.get('first_name', '').strip()
last_name = request.form.get('last_name') last_name = request.form.get('last_name', '').strip()
email = request.form.get('email') email = request.form.get('email', '').strip()
location = request.form.get('location') location = request.form.get('location', '').strip()
if first_name and last_name and email and location:
# Basic validation checks
if not (first_name and last_name and email and location):
error = "All fields are required."
elif not is_valid_email(email):
error = "Invalid email address."
if error:
# Retrieve guest entries to display on the page.
conn = sqlite3.connect(DATABASE) conn = sqlite3.connect(DATABASE)
c = conn.cursor() c = conn.cursor()
c.execute( c.execute('SELECT first_name, location FROM guests ORDER BY id DESC')
'INSERT INTO guests (first_name, last_name, email, location) VALUES (?, ?, ?, ?)', guests = c.fetchall()
(first_name, last_name, email, location)
)
conn.commit()
conn.close() conn.close()
return redirect(url_for('index')) return render_template('index.html', error=error, guests=guests)
# Retrieve guest entries to display only first name and location.
# If all validations pass, insert the data into the database.
conn = sqlite3.connect(DATABASE)
c = conn.cursor()
c.execute(
'INSERT INTO guests (first_name, last_name, email, location) VALUES (?, ?, ?, ?)',
(first_name, last_name, email, location)
)
conn.commit()
conn.close()
return redirect(url_for('index'))
# For GET requests, retrieve guest entries to display.
conn = sqlite3.connect(DATABASE) conn = sqlite3.connect(DATABASE)
c = conn.cursor() c = conn.cursor()
c.execute('SELECT first_name, location FROM guests ORDER BY id DESC') c.execute('SELECT first_name, location FROM guests ORDER BY id DESC')
guests = c.fetchall() guests = c.fetchall()
conn.close() conn.close()
return render_template('index.html', guests=guests) return render_template('index.html', error=error, guests=guests)
if __name__ == '__main__': if __name__ == '__main__':
init_db() init_db()

View File

@ -8,6 +8,9 @@
<body> <body>
<h1>Museum Visitor Guestbook</h1> <h1>Museum Visitor Guestbook</h1>
{% if error %}
<div style="color: red;">{{ error }}</div>
{% endif %}
<form method="post" action="/"> <form method="post" action="/">
<label for="first_name">First Name(s):</label><br> <label for="first_name">First Name(s):</label><br>
<input type="text" id="first_name" name="first_name" required><br><br> <input type="text" id="first_name" name="first_name" required><br><br>