diff --git a/cgi-example/README.md b/cgi-example/README.md index 4dc9cc1..53efcf9 100644 --- a/cgi-example/README.md +++ b/cgi-example/README.md @@ -6,7 +6,7 @@ The goal of this project is to give a working example of a basic Gemini CGI appl * (DONE) New TLS certificates automatically create a new user account * (DONE) Users can set data on their own account (a name field for example) -* Users can add additional certificates to the same account by using a special code +* (DONE) Users can add additional certificates to the same account by using a special code ## Files diff --git a/cgi-example/add-cert/index.gmi b/cgi-example/add-cert/index.gmi index 6bf57de..0626a91 100755 --- a/cgi-example/add-cert/index.gmi +++ b/cgi-example/add-cert/index.gmi @@ -5,16 +5,22 @@ import sys sys.path.append('..') # import helpers from modules -from helpers import get_client_cert -from db import check_hash +from helpers import get_client_cert, get_query_string +from db import add_cert_to_user -TLS_CLIENT_HASH = get_client_cert() -user_id = check_hash(TLS_CLIENT_HASH) -user_name = "[Not Set]" -user_cert_count = 1 +tls_client_hash = get_client_cert(False) +key_code = get_query_string("What is your auth code?") +success = add_cert_to_user(key_code, tls_client_hash) -print("# Add another cert") +print("# Add Cert Page") print() -print("This feature coming soon.") + +if success: + print("Your new key has been added to this account. Congratulations!") +else: + print("Either your auth code is incorrect or something else has gone wrong.") +print() +print("=> ../login Back to main page") + #vim:fenc=utf-8:ts=4:sw=4:sta:noet:sts=4:fdm=marker:ai diff --git a/cgi-example/db.py b/cgi-example/db.py index 7aaa853..469e492 100644 --- a/cgi-example/db.py +++ b/cgi-example/db.py @@ -50,7 +50,7 @@ def add_hash(conn, cert_user): :param cert_user: :return: id """ - sql = ''' INSERT INTO certs(hash,user_id) VALUES(?,?) ''' + sql = ''' INSERT OR REPLACE INTO certs(hash,user_id) VALUES(?,?) ''' cur = conn.cursor() cur.execute(sql, cert_user) conn.commit() @@ -73,6 +73,23 @@ def get_user(conn, tls_client_hash): else: return None +def get_user_by_keycode(conn, key_code): + """ + Get user id of tls_client_hash if it exists + :param conn: + :param key_code: + :return: user id + """ + cur = conn.cursor() + cur.execute("SELECT id FROM users WHERE add_key_code=?", (key_code,)) + rows = cur.fetchall() + + if len(rows) > 0: + row = rows[0] + return row[0] # user_id + else: + return None + def check_hash(tls_client_hash): """ Check for existing user with hash or add a new one @@ -110,6 +127,7 @@ def get_name(user_id): def set_name(user_id, user_name): """ Update or set name on user + :param user_id: :param user_name: """ conn = create_connection() @@ -120,5 +138,38 @@ def set_name(user_id, user_name): conn.commit() return cur.lastrowid +def set_add_key_code(user_id, key_code): + """ + Update or set key code on user + :param user_id: + :param key_code: + """ + conn = create_connection() + with conn: + """ There should probably be a check here to ensure no user + has this key_code already + """ + sql = ''' UPDATE users SET add_key_code=(?) WHERE id=? ''' + cur = conn.cursor() + cur.execute(sql, (key_code, user_id)) + conn.commit() + return cur.lastrowid + +def add_cert_to_user(key_code, tls_client_hash): + """ + Check for existing user with hash or add a new one + :param conn: + :param key_code: + :param tls_client_hash: + :return: true if added, false if not found + """ + conn = create_connection() + with conn: + user_id = get_user_by_keycode(conn, key_code) + if (user_id is None): + return False + cert_user = (tls_client_hash, user_id) + add_hash(conn, cert_user) + return True #vim:fenc=utf-8:ts=4:sw=4:sta:noet:sts=4:fdm=marker:ai diff --git a/cgi-example/helpers.py b/cgi-example/helpers.py index 8ad4cf3..1055eda 100644 --- a/cgi-example/helpers.py +++ b/cgi-example/helpers.py @@ -1,4 +1,6 @@ import os +import string +import random def get_client_cert(ok_if_found = True): TLS_CLIENT_HASH = os.getenv('TLS_CLIENT_HASH') @@ -26,4 +28,8 @@ def show_header_cert_required(): def show_query_string_required(msg): print("10 " + msg, end = "\r\n") quit() + +def id_generator(size=12, chars=string.ascii_uppercase + string.digits): + return ''.join(random.choice(chars) for _ in range(size)) + #vim:fenc=utf-8:ts=4:sw=4:sta:noet:sts=4:fdm=marker:ai diff --git a/cgi-example/login/index.gmi b/cgi-example/login/index.gmi index 3fac1b7..0862c24 100755 --- a/cgi-example/login/index.gmi +++ b/cgi-example/login/index.gmi @@ -11,7 +11,6 @@ from db import * TLS_CLIENT_HASH = get_client_cert() user_id = check_hash(TLS_CLIENT_HASH) user_name = get_name(user_id) or "[Not Set]" -user_cert_count = 1 print("# Welcome: User Logged In") print() @@ -25,9 +24,9 @@ print(user_name) print("=> ../change-name Change User Name") print() -print("## Number of TLS Certs associated with account") -print(user_cert_count) -print("=> ../add-cert Add another cert to your account") +print("## TLS Certs associated with account") +print("=> ../update-auth-code Generate an auth code to add another cert to your account") +print("=> ../add-cert Add another cert to your account (with auth code)") print() #vim:fenc=utf-8:ts=4:sw=4:sta:noet:sts=4:fdm=marker:ai diff --git a/cgi-example/update-auth-code/index.gmi b/cgi-example/update-auth-code/index.gmi new file mode 100755 index 0000000..7e111f4 --- /dev/null +++ b/cgi-example/update-auth-code/index.gmi @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 + +# modules are all in the parent directory +import sys +sys.path.append('..') + +# import helpers from modules +from helpers import get_client_cert, id_generator +from db import check_hash, set_add_key_code + +TLS_CLIENT_HASH = get_client_cert() +user_id = check_hash(TLS_CLIENT_HASH) +key_code = id_generator() +set_add_key_code(user_id, key_code) + +print("# Add Cert Page") +print() + +print("Your authorization code to add new client certificates has been updated. Visit the 'Add Cert' page from another device or with another key and enter your authorization code to connect the accounts.") +print() +print("## AUTH CODE") +print(key_code) +print("=> ../add-cert/?" + key_code + " Link to Add Cert page with Auth Code") +print() +print("=> ../login Back to main page") + + +#vim:fenc=utf-8:ts=4:sw=4:sta:noet:sts=4:fdm=marker:ai