Assignment 7

A basic HTML + Python app, using Common Gateway Interface and the Apache HTTP Server.

htdocs/form.html

A screenshot of the main form page

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<title>Form for Python</title>
<link rel="Stylesheet" type="text/css" href="styles.css" />
<meta name="viewport" content="width=device-width, initial-scale=0.875">
<style>
form fieldset {
border: 1px solid gray;
padding: 1rem;
margin-bottom: 1rem;
}

form fieldset[disabled] {
background: rgba(0, 0, 0, )
}

form legend {
background: var(--font-color);
color: var(--bg-color);
text-shadow: none;
font-size: 1em;
font-weight: bold;
font-family: 'Times New Roman', Times, serif;
text-transform: uppercase;
display: inline-block;
width: unset;
margin: 0 -1ch;
padding: 0 1ch;
}

form label {
display: block;
}

form input[type="text"] {
display: block;
}
</style>
</head>

<body>
<h1>Python CGI Form Example</h1>
<form method="POST" action="/cgi-bin/submit.py">
<fieldset>
<legend>Shipping information</legend>
<label>Name
<input name="shipping-name" type="text" autocomplete="name" required />
</label>
<label>Zip code
<input name="shipping-zip" type="text" autocomplete="postal-code" required>
</label>
</fieldset>
<fieldset id="billing-info">
<legend>Billing information</legend>
<label>Billing information is the same? <input name="billing-info-same" type="checkbox" checked /></label>
<label>Name
<input name="billing-name" type="text" autocomplete="name" required />
</label>
<label>Zip code
<input name="billing-zip" type="text" autocomplete="postal-code" required />
</label>
</fieldset>
<input type="submit" value="Calculate" />
</form>
<script>
{ // closure
// select elements
const { "shipping-name": shippingNameEl, "shipping-zip": shippingZipEl, "billing-name": billingNameEl,
"billing-zip": billingZipEl,
"billing-info-same": billingInfoSameEl
} = document.querySelector("form").elements;

function updateBillingInfo() {
// change placeholder text
billingNameEl.placeholder = shippingNameEl.value;
billingZipEl.placeholder = shippingZipEl.value;
// disable inputs if checkbox checked
billingNameEl.disabled = billingInfoSameEl.checked;
billingZipEl.disabled = billingInfoSameEl.checked;
}
document.querySelector("form")
.addEventListener("input", updateBillingInfo);
document.querySelector("form")
.addEventListener("change", updateBillingInfo);
updateBillingInfo();
} // end closure
</script>
</body>

</html>

htdocs/cgi-bin/submit.py

A screenshot of the form after submission

#!/usr/bin/env python

import os
import cgi
import io
import cgitb
import random
cgitb.enable(True) # uncomment for debugging

OUTFILE_NAME = "address.csv"

# create CGI header
print ("Content-Type: text/html; charset=UTF-8")
print()


# get data from form submission
form = cgi.FieldStorage()
order_num = random.randrange(100000, 999999)
shipping_name = form.getfirst("shipping-name", None)
shipping_zip = form.getfirst("shipping-zip", None)
billing_name = form.getfirst("billing-name", shipping_name)
billing_zip = form.getfirst("billing-zip", shipping_zip)

if not shipping_name and billing_name:
print(f"<h1>Error: Invalid data</h1>")
print(f"<p>Your order could not be completed.</p>")
exit(1)

# Create a file, if it
try:
with open(OUTFILE_NAME, "x") as outfile:
# write header
print("OrderNumber,ShippingName,ShippingZip,BillingName,BillingZip", file=outfile)
except (FileExistsError):
pass

with open(OUTFILE_NAME, "a+") as outfile:

print(order_num, shipping_name, shipping_zip, billing_name, billing_zip, sep=",", file=outfile)

print("")
# print to user
print(f"<h1>Your order #{order_num} was confirmed!</h1>")
print("<h2>Shipping info</h2>")
print(f"<address>{shipping_name}<br>{shipping_zip}</address>")
print("<h2>Billing info</h2>")
print(f"<address>{billing_name}<br>{billing_zip}</address>")

htdocs/cgi-bin/dump_data.py

A screenshot of the data dump

#!/usr/bin/env python

import cgi
import cgitb

cgitb.enable(True) # uncomment for debugging

SUPER_SECRET_ADMIN_PASSWORD = "admin123"
OUTFILE_NAME = "address.csv"

# create CGI header
print("Content-Type: text/plain; charset=UTF-8")
print()


# get data from form submission
form = cgi.FieldStorage()

if (form.getfirst("password") == SUPER_SECRET_ADMIN_PASSWORD):
with open(OUTFILE_NAME, "r") as address_file:
print(address_file.read())
else:
print("Invalid password.")