added a rudimentary user page

This commit is contained in:
bacalhau 2026-03-03 23:49:50 +00:00
parent 2f24f28b82
commit cd74903184
3 changed files with 93 additions and 31 deletions

View file

@ -4,21 +4,42 @@ from datetime import date
import gnupg import gnupg
import secrets import secrets
app = Flask(__name__) COUNTRIES = [
"Afghanistan","Albania","Algeria","Andorra","Angola","Antigua and Barbuda","Argentina","Armenia","Australia","Austria",
"Azerbaijan","Bahamas","Bahrain","Bangladesh","Barbados","Belarus","Belgium","Belize","Benin","Bhutan",
"Bolivia","Bosnia and Herzegovina","Botswana","Brazil","Brunei","Bulgaria","Burkina Faso","Burundi","Cabo Verde","Cambodia",
"Cameroon","Canada","Central African Republic","Chad","Chile","China","Colombia","Comoros","Congo (Congo-Brazzaville)","Costa Rica",
"Croatia","Cuba","Cyprus","Czechia (Czech Republic)","Democratic Republic of the Congo","Denmark","Djibouti","Dominica","Dominican Republic","Ecuador",
"Egypt","El Salvador","Equatorial Guinea","Eritrea","Estonia","Eswatini (fmr. Swaziland)","Ethiopia","Fiji","Finland","France",
"Gabon","Gambia","Georgia","Germany","Ghana","Greece","Grenada","Guatemala","Guinea","Guinea-Bissau",
"Guyana","Haiti","Holy See","Honduras","Hungary","Iceland","India","Indonesia","Iran","Iraq",
"Ireland","Israel","Italy","Jamaica","Japan","Jordan","Kazakhstan","Kenya","Kiribati","Kuwait",
"Kyrgyzstan","Laos","Latvia","Lebanon","Lesotho","Liberia","Libya","Liechtenstein","Lithuania","Luxembourg",
"Madagascar","Malawi","Malaysia","Maldives","Mali","Malta","Marshall Islands","Mauritania","Mauritius","Mexico",
"Micronesia","Moldova","Monaco","Mongolia","Montenegro","Morocco","Mozambique","Myanmar (Burma)","Namibia","Nauru",
"Nepal","Netherlands","New Zealand","Nicaragua","Niger","Nigeria","North Korea","North Macedonia","Norway","Oman",
"Pakistan","Palau","Palestine State","Panama","Papua New Guinea","Paraguay","Peru","Philippines","Poland","Portugal",
"Qatar","Romania","Russia","Rwanda","Saint Kitts and Nevis","Saint Lucia","Saint Vincent and the Grenadines","Samoa","San Marino","Sao Tome and Principe",
"Saudi Arabia","Senegal","Serbia","Seychelles","Sierra Leone","Singapore","Slovakia","Slovenia","Solomon Islands","Somalia",
"South Africa","South Korea","South Sudan","Spain","Sri Lanka","Sudan","Suriname","Sweden","Switzerland","Syria",
"Tajikistan","Tanzania","Thailand","Timor-Leste","Togo","Tonga","Trinidad and Tobago","Tunisia","Turkey","Turkmenistan",
"Tuvalu","Uganda","Ukraine","United Arab Emirates","United Kingdom","United States","Uruguay","Uzbekistan","Vanuatu","Venezuela",
"Vietnam","Yemen","Zambia","Zimbabwe"
]
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://love:love@localhost:3309/lovedb' app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://love:love@localhost:3309/lovedb'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SECRET_KEY'] = 'random' app.config['SECRET_KEY'] = 'random'
gpg = gnupg.GPG()
db = SQLAlchemy(app) db = SQLAlchemy(app)
gpg = gnupg.GPG()
class User(db.Model): class User(db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(128), unique=True, nullable=False) username = db.Column(db.String(128), unique=True, nullable=False)
pgp = db.Column(db.String(8128), nullable=False) pgp = db.Column(db.String(4096), nullable=False)
firstname = db.Column(db.String(128), nullable=False) firstname = db.Column(db.String(128), nullable=False)
lastname = db.Column(db.String(128), nullable=False) lastname = db.Column(db.String(128), nullable=False)
@ -55,7 +76,6 @@ def home():
@app.route("/register", methods=["GET", "POST"]) @app.route("/register", methods=["GET", "POST"])
def register(): def register():
if request.method == "POST": if request.method == "POST":
username = request.form.get("username") username = request.form.get("username")
pgp = request.form.get("pgp") pgp = request.form.get("pgp")
firstname = request.form.get("firstname") firstname = request.form.get("firstname")
@ -74,8 +94,7 @@ def register():
race = request.form.get("race") race = request.form.get("race")
prefered_age_range = request.form.get("prefered_age_range") prefered_age_range = request.form.get("prefered_age_range")
if not all([username, pgp, firstname, lastname, sex, if not all([username, pgp, firstname, lastname, sex, date_of_birth, profile_picture, country, xmpp]):
date_of_birth, profile_picture, country, xmpp]):
flash("Please fill all required fields.") flash("Please fill all required fields.")
return redirect(url_for("register")) return redirect(url_for("register"))
@ -128,7 +147,7 @@ def register():
import_result = gpg.import_keys(pgp) import_result = gpg.import_keys(pgp)
if not import_result.fingerprints: if not import_result.fingerprints:
flash("Invalid PGP key. Make sure you pasted the full ASCII-armored public key.") flash("Invalid PGP key.")
return redirect(url_for("register")) return redirect(url_for("register"))
fingerprint = import_result.fingerprints[0] fingerprint = import_result.fingerprints[0]
@ -136,23 +155,15 @@ def register():
random_string = secrets.token_hex(16) random_string = secrets.token_hex(16)
challenge_phrase = f"this is the unencrypted string: {random_string}" challenge_phrase = f"this is the unencrypted string: {random_string}"
encrypted_data = gpg.encrypt( encrypted_data = gpg.encrypt(challenge_phrase, recipients=[fingerprint])
challenge_phrase,
recipients=[fingerprint]
)
if not encrypted_data.ok: if not encrypted_data.ok:
flash("Failed to encrypt challenge. Check your PGP key.") flash("Failed to encrypt challenge.")
return redirect(url_for("register")) return redirect(url_for("register"))
session["pgp_expected_phrase"] = challenge_phrase session["pgp_expected_phrase"] = challenge_phrase
return render_template("verify.html", encrypted_message=str(encrypted_data))
return render_template( return render_template("register.html", countries=COUNTRIES)
"verify.html",
encrypted_message=str(encrypted_data)
)
return render_template("register.html")
@app.route("/verify", methods=["POST"]) @app.route("/verify", methods=["POST"])
def verify(): def verify():
@ -188,7 +199,7 @@ def verify():
weight=int(data["weight"]) if data["weight"] else None, weight=int(data["weight"]) if data["weight"] else None,
race=data["race"] or None, race=data["race"] or None,
prefered_age_range=data["prefered_age_range"] or None, prefered_age_range=data["prefered_age_range"] or None,
is_verified=False is_verified=True
) )
db.session.add(new_user) db.session.add(new_user)
@ -200,7 +211,7 @@ def verify():
session.pop("pending_user", None) session.pop("pending_user", None)
session.pop("pgp_expected_phrase", None) session.pop("pgp_expected_phrase", None)
flash("PGP verification successful!") flash("PGP verification successful! Account created.")
return redirect(url_for("home")) return redirect(url_for("home"))
else: else:
@ -286,6 +297,12 @@ def logout():
flash("Logged out successfully") flash("Logged out successfully")
return redirect(url_for("home")) return redirect(url_for("home"))
@app.route("/user/<username>")
def user_profile(username):
user = User.query.filter_by(username=username).first_or_404()
return render_template("user.html", user=user, date=date)
if __name__ == "__main__": if __name__ == "__main__":
with app.app_context(): with app.app_context():
db.create_all() db.create_all()

View file

@ -6,26 +6,34 @@
<form method="POST"> <form method="POST">
<h3>Identity</h3> <h3>Identity</h3>
<input type="text" name="username" placeholder="Username" required><br> <input type="text" name="username" placeholder="Username" required>*<br>
<textarea name="pgp" placeholder="PGP Public Key" required></textarea><br> <textarea name="pgp" placeholder="PGP Public Key" required></textarea>*<br>
<h3>Personal Info</h3> <h3>Personal Info</h3>
<input type="text" name="firstname" placeholder="First Name" required><br> <input type="text" name="firstname" placeholder="First Name" required>*<br>
<input type="text" name="lastname" placeholder="Last Name" required><br> <input type="text" name="lastname" placeholder="Last Name" required>*<br>
<select name="sex" required> <select name="sex" required>
<option value="">Select Sex</option> <option value="">Select Sex</option>
<option value="male">Male</option> <option value="male">Male</option>
<option value="female">Female</option> <option value="female">Female</option>
</select><br> </select>*<br>
<input type="date" name="date_of_birth" required><br> <input type="date" name="date_of_birth" required>*<br>
<h3>Profile</h3> <h3>Profile Picture</h3>
<input type="text" name="profile_picture" placeholder="Profile Picture URL" required><br> <input type="file" name="profile_picture" accept="image/*" required>*<br>
<h3>Other Pictures</h3>
<input type="file" name="pictures" accept="image/*" multiple><br>
<h3>Location</h3> <h3>Location</h3>
<input type="text" name="country" placeholder="Country" required><br> <select name="country" required>
<option value="">Select Country</option>
{% for c in countries %}
<option value="{{ c }}">{{ c }}</option>
{% endfor %}
</select>*<br>
<input type="text" name="city" placeholder="City"><br> <input type="text" name="city" placeholder="City"><br>
<h3>Physical Attributes</h3> <h3>Physical Attributes</h3>

37
src/templates/user.html Normal file
View file

@ -0,0 +1,37 @@
{% extends "page.html" %}
{% block content %}
<h2>{{ user.firstname }} {{ user.lastname }}</h2>
<img src="{{ user.profile_picture }}" alt="Profile Picture" width="150"><br>
{% if user.pictures %}
<h3>Pictures</h3>
{% for pic in user.pictures %}
<img src="{{ pic }}" width="100">
{% endfor %}
{% endif %}
<h3>Personal Info</h3>
<p>Sex: {{ user.sex }}</p>
<p>Date of Birth: {{ user.date_of_birth }}</p>
<p>Age: {{ (date.today() - user.date_of_birth).days // 365 }}</p>
<p>Race: {{ user.race or 'Not specified' }}</p>
<h3>Location</h3>
<p>Country: {{ user.country }}</p>
<p>City: {{ user.city or 'Not specified' }}</p>
<h3>Physical Attributes</h3>
<p>Height: {{ user.height or 'Not specified' }} m</p>
<p>Weight: {{ user.weight or 'Not specified' }} kg</p>
<h3>Preferences</h3>
<p>Preferred Age Range: {{ user.prefered_age_range or 'Not specified' }}</p>
<p>Likes: {{ user.likes | join(', ') if user.likes else 'Not specified' }}</p>
<p>Dislikes: {{ user.dislikes | join(', ') if user.dislikes else 'Not specified' }}</p>
<h3>Contacts</h3>
<p>XMPP: {{ user.xmpp }}</p>
<p>Email: {{ user.email or 'Not specified' }}</p>
<p>Phone: {{ user.phone or 'Not specified' }}</p>
{% endblock %}