Some silly goober left in the Cg=== from the terminal when he ran `echo "password" | base64`. Cute little terminal escape characters.
126 lines
3.2 KiB
Python
126 lines
3.2 KiB
Python
from http import HTTPStatus
|
|
from flask import Flask, Response, request, send_file
|
|
from os import urandom
|
|
from threading import Thread, Event
|
|
from werkzeug.serving import make_server
|
|
from typing import Optional
|
|
from types import FrameType
|
|
import signal
|
|
import sys
|
|
from base64 import b64encode as base64_encode
|
|
|
|
SERVER_IP: str = "0.0.0.0"
|
|
HTTP_HOST: str = "sniphbank.com"
|
|
HTTP_PORT: int = 80
|
|
HTTPS_PORT: int = 443
|
|
DEBUG: bool = False
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = urandom(24)
|
|
|
|
|
|
@app.route("/")
|
|
def index():
|
|
return send_file("./website/index.html")
|
|
|
|
|
|
@app.route("/login", methods=["POST"])
|
|
def login():
|
|
# There isn't really a reason to validate the user for the demo,
|
|
# just decide on a username that might pertain to whomever's
|
|
# personal information
|
|
|
|
user = request.form["username"]
|
|
password = request.form["password"].encode()
|
|
|
|
if user != "ronniej":
|
|
return Response("User not found", HTTPStatus.UNAUTHORIZED)
|
|
if base64_encode(password).decode() != "Z29GQUxDT05TMTIz":
|
|
return Response("Incorrect password", HTTPStatus.UNAUTHORIZED)
|
|
|
|
return send_file("./website/account.html")
|
|
|
|
|
|
@app.route("/css/style.css", methods=["GET"])
|
|
def stylesheet():
|
|
return send_file("./website/css/style.css")
|
|
|
|
|
|
@app.route("/favicon.ico", methods=["GET"])
|
|
def favicon():
|
|
return send_file("./website/favicon.ico")
|
|
|
|
|
|
class ServerThread(Thread):
|
|
def __init__(
|
|
self,
|
|
app: Flask,
|
|
host: str,
|
|
port: int,
|
|
ssl_context: Optional[tuple[str, str]] = None,
|
|
name: str = "ServerThread",
|
|
) -> None:
|
|
super().__init__(name=name, daemon=True)
|
|
self.server = make_server(
|
|
host,
|
|
port,
|
|
app,
|
|
threaded=True,
|
|
ssl_context=ssl_context, # tuple (cert, key) or SSLContext
|
|
)
|
|
|
|
def run(self):
|
|
self.server.serve_forever()
|
|
|
|
def shutdown(self):
|
|
self.server.shutdown()
|
|
|
|
|
|
def _install_signal_handlers(stop_event: Event):
|
|
def handler(signum: signal.Signals, frame: Optional[FrameType]):
|
|
stop_event.set()
|
|
|
|
signal.signal(signal.SIGINT, handler)
|
|
try:
|
|
signal.signal(signal.SIGTERM, handler)
|
|
except AttributeError:
|
|
pass
|
|
|
|
|
|
if __name__ == "__main__":
|
|
stop_event = Event()
|
|
_install_signal_handlers(stop_event)
|
|
|
|
http_server = ServerThread(
|
|
app, SERVER_IP, HTTP_PORT, ssl_context=None, name="HTTP-Thread"
|
|
)
|
|
https_server = ServerThread(
|
|
app,
|
|
SERVER_IP,
|
|
HTTPS_PORT,
|
|
ssl_context=("./certs/cert.pem", "./certs/key.pem"),
|
|
name="HTTPS-Thread",
|
|
)
|
|
|
|
try:
|
|
http_server.start()
|
|
https_server.start()
|
|
print(f"HTTP server running at http://{SERVER_IP}:{HTTP_PORT}")
|
|
print(f"HTTPS server running at https://{SERVER_IP}:{HTTPS_PORT}")
|
|
print("Press Ctrl+C to stop.")
|
|
stop_event.wait()
|
|
except KeyboardInterrupt:
|
|
pass
|
|
finally:
|
|
for srv in (http_server, https_server):
|
|
try:
|
|
srv.shutdown()
|
|
except Exception:
|
|
pass
|
|
|
|
for srv in (http_server, https_server):
|
|
srv.join(timeout=5)
|
|
|
|
print("Servers stopped!")
|
|
sys.exit(0)
|