From d159f4ec68cc766c4925e8901309d97ce0dfa952 Mon Sep 17 00:00:00 2001 From: bacalhau Date: Tue, 3 Mar 2026 23:07:59 +0000 Subject: [PATCH] =?UTF-8?q?adiciondo=20/register=20e=20verifica=C3=A7?= =?UTF-8?q?=C3=A3o=20pgp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 1 + src/main.py | 172 +++++++++++++++++++++++++++++++++++- src/templates/page.html | 14 ++- src/templates/register.html | 65 +++++++++++--- src/templates/verify.html | 17 ++++ 5 files changed, 254 insertions(+), 15 deletions(-) create mode 100644 src/templates/verify.html diff --git a/requirements.txt b/requirements.txt index d185f9d..9524e22 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,4 @@ Flask Flask-SQLAlchemy SQLAlchemy PyMySQL +python-gnupg diff --git a/src/main.py b/src/main.py index 2f7d027..0b0a06c 100644 --- a/src/main.py +++ b/src/main.py @@ -1,11 +1,16 @@ -from flask import Flask, render_template +from flask import Flask, render_template, request, redirect, url_for, flash, session from flask_sqlalchemy import SQLAlchemy from datetime import date +import gnupg +import secrets app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://love:love@localhost:3309/lovedb' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False +app.config['SECRET_KEY'] = 'random' + +gpg = gnupg.GPG() db = SQLAlchemy(app) @@ -13,7 +18,7 @@ class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(128), unique=True, nullable=False) - password = db.Column(db.String(128), nullable=False) + pgp = db.Column(db.String(4096), nullable=False) firstname = db.Column(db.String(128), nullable=False) lastname = db.Column(db.String(128), nullable=False) @@ -47,14 +52,175 @@ class User(db.Model): def home(): return render_template("index.html") -@app.route("/register") +@app.route("/register", methods=["GET", "POST"]) def register(): + if request.method == "POST": + + username = request.form.get("username") + pgp = request.form.get("pgp") + firstname = request.form.get("firstname") + lastname = request.form.get("lastname") + sex = request.form.get("sex") + date_of_birth = request.form.get("date_of_birth") + profile_picture = request.form.get("profile_picture") + country = request.form.get("country") + xmpp = request.form.get("xmpp") + + email = request.form.get("email") + phone = request.form.get("phone") + city = request.form.get("city") + height = request.form.get("height") + weight = request.form.get("weight") + race = request.form.get("race") + prefered_age_range = request.form.get("prefered_age_range") + + if not all([username, pgp, firstname, lastname, sex, + date_of_birth, profile_picture, country, xmpp]): + flash("Please fill all required fields.") + return redirect(url_for("register")) + + if User.query.filter_by(username=username).first(): + flash("Username already exists.") + return redirect(url_for("register")) + + if User.query.filter_by(xmpp=xmpp).first(): + flash("XMPP already exists.") + return redirect(url_for("register")) + + if email and User.query.filter_by(email=email).first(): + flash("Email already exists.") + return redirect(url_for("register")) + + if phone and User.query.filter_by(phone=phone).first(): + flash("Phone already exists.") + return redirect(url_for("register")) + + try: + dob = date.fromisoformat(date_of_birth) + except ValueError: + flash("Invalid date format.") + return redirect(url_for("register")) + + today = date.today() + age = today.year - dob.year - ((today.month, today.day) < (dob.month, dob.day)) + if age < 18: + flash("You must be at least 18 years old to register.") + return redirect(url_for("register")) + + session["pending_user"] = { + "username": username, + "pgp": pgp, + "firstname": firstname, + "lastname": lastname, + "sex": sex, + "date_of_birth": date_of_birth, + "profile_picture": profile_picture, + "country": country, + "xmpp": xmpp, + "email": email, + "phone": phone, + "city": city, + "height": height, + "weight": weight, + "race": race, + "prefered_age_range": prefered_age_range + } + + import_result = gpg.import_keys(pgp) + if not import_result.fingerprints: + flash("Invalid PGP key. Make sure you pasted the full ASCII-armored public key.") + return redirect(url_for("register")) + + fingerprint = import_result.fingerprints[0] + + random_string = secrets.token_hex(16) + challenge_phrase = f"this is the unencrypted string: {random_string}" + + encrypted_data = gpg.encrypt( + challenge_phrase, + recipients=[fingerprint] + ) + + if not encrypted_data.ok: + flash("Failed to encrypt challenge. Check your PGP key.") + return redirect(url_for("register")) + + session["pgp_expected_phrase"] = challenge_phrase + + return render_template( + "verify.html", + encrypted_message=str(encrypted_data) + ) + return render_template("register.html") +@app.route("/verify", methods=["POST"]) +def verify(): + + expected_phrase = session.get("pgp_expected_phrase") + data = session.get("pending_user") + + if not expected_phrase or not data: + flash("Verification session expired.") + return redirect(url_for("register")) + + submitted = request.form.get("decrypted_message") + + if not submitted: + flash("You must paste the decrypted message.") + return redirect(url_for("register")) + + if submitted.strip() != expected_phrase: + flash("Verification failed.") + return redirect(url_for("register")) + + dob = date.fromisoformat(data["date_of_birth"]) + + new_user = User( + username=data["username"], + pgp=data["pgp"], + firstname=data["firstname"], + lastname=data["lastname"], + sex=data["sex"], + date_of_birth=dob, + profile_picture=data["profile_picture"], + country=data["country"], + xmpp=data["xmpp"], + email=data["email"] or None, + phone=data["phone"] or None, + city=data["city"] or None, + height=float(data["height"]) if data["height"] else None, + weight=int(data["weight"]) if data["weight"] else None, + race=data["race"] or None, + prefered_age_range=data["prefered_age_range"] or None, + is_verified=True + ) + + db.session.add(new_user) + db.session.commit() + + # Clear session + session.pop("pending_user", None) + session.pop("pgp_expected_phrase", None) + + flash("PGP verification successful!") + + session['user_id'] = user.id + session['username'] = user.username + + return redirect(url_for("login")) + @app.route("/login") def login(): return render_template("login.html") +@app.route("/logout") +def logout(): + session.pop('user_id', None) + session.pop('username', None) + flash("Logged out successfully") + return redirect(url_for("home")) + if __name__ == "__main__": with app.app_context(): db.create_all() diff --git a/src/templates/page.html b/src/templates/page.html index 20cb983..0f95a01 100644 --- a/src/templates/page.html +++ b/src/templates/page.html @@ -5,7 +5,19 @@

Dating Website

- + + {% block content %}{% endblock %} diff --git a/src/templates/register.html b/src/templates/register.html index bf4f7a5..8e19d76 100644 --- a/src/templates/register.html +++ b/src/templates/register.html @@ -1,15 +1,58 @@ {% extends "page.html" %} {% block content %} -

Register

-

Page text

-

Page text

-

Page text

-

Page text

-

Page text

-

Page text

-

Page text

-

Page text

-

Page text

-

Page text

+

Register

+ +
+ +

Identity

+
+
+ +

Personal Info

+
+
+ +
+ +
+ +

Profile

+
+ +

Location

+
+
+ +

Physical Attributes

+
+
+
+ +

Preferences

+
+ +

Contacts

+
+
+

+ + + +
+ +{% with messages = get_flashed_messages() %} + {% if messages %} + + {% endif %} +{% endwith %} + {% endblock %} diff --git a/src/templates/verify.html b/src/templates/verify.html new file mode 100644 index 0000000..7064963 --- /dev/null +++ b/src/templates/verify.html @@ -0,0 +1,17 @@ +{% extends "page.html" %} + +{% block content %} +

PGP Verification

+ +

Decrypt the message below using your private key and paste the result.

+ + + +
+
+ +
+ +{% endblock %}