Add user login form

This commit is contained in:
2026-08-24 15:18:45 +02:00
parent 0b262c83ab
commit 21bce2da64
3 changed files with 80 additions and 4 deletions
+42 -3
View File
@@ -1,11 +1,12 @@
import sqlite3 import sqlite3
from hashlib import sha256
def init_db(path: str) -> None: def init_db(path: str) -> None:
with sqlite3.connect(path) as connection: with sqlite3.connect(path) as connection:
cursor = connection.cursor() cursor = connection.cursor()
cursor.execute(''' cursor.execute('''
CREATE TABLE IF NOT EXISTS Tokens ( CREATE TABLE IF NOT EXISTS Tokens (
TOKEN TEXT PRIMARY KEY NOT NULL, TKHASH TEXT PRIMARY KEY NOT NULL,
USERID INTEGER NOT NULL, USERID INTEGER NOT NULL,
NAME TEXT NOT NULL NAME TEXT NOT NULL
) )
@@ -18,17 +19,55 @@ def init_db(path: str) -> None:
) )
''') ''')
cursor.execute('''
CREATE TABLE IF NOT EXISTS Users (
USERID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
USERNAME TEXT NOT NULL UNIQUE,
PWHASH TEXT NOT NULL,
PWSALT TEXT NOT NULL,
EMAIL TEXT
IS_ADMIN INTEGER NOT NULL DEFAULT 0
)
''')
connection.commit() connection.commit()
cursor.close() cursor.close()
def check_token_domain(db_path: str, token: str, domain: str) -> bool: def check_token_domain(db_path: str, token: str, domain: str) -> bool:
with sqlite3.connect(db_path) as connection: with sqlite3.connect(db_path) as connection:
cursor = connection.cursor() cursor = connection.cursor()
token_hash = sha256(token.encode('utf-8')).hexdigest()
cursor.execute(''' cursor.execute('''
SELECT COUNT(*) FROM Tokens SELECT COUNT(*) FROM Tokens
JOIN Domains ON Tokens.userid = Domains.userid JOIN Domains ON Tokens.userid = Domains.userid
WHERE token = ? WHERE tkhash = ?
AND domain = ? AND domain = ?
''', (token,domain)) ''', (token_hash, domain))
return cursor.fetchone()[0] == 1 return cursor.fetchone()[0] == 1
def user_login(db_path: str, username: str, password: str) -> bool:
with sqlite3.connect(db_path) as connection:
cursor = connection.cursor()
cursor.execute('''
SELECT pwsalt FROM Users
WHERE username = ?
''', (username,))
password_salt = cursor.fetchone()
if password_salt is None:
return False
password_salt = password_salt[0]
password_hash = sha256( (password_salt + password).encode('utf-8') ).hexdigest()
cursor.execute('''
SELECT COUNT(*) FROM Users
WHERE username = ?
AND pwhash = ?
''', (username, password_hash))
return cursor.fetchone()[0] == 1
+23 -1
View File
@@ -1,4 +1,4 @@
from flask import Flask, jsonify, request from flask import Flask, jsonify, request, render_template, redirect
import auth import auth
import re import re
@@ -8,6 +8,7 @@ HOSTS_PATH = "/app/hosts.d/izbi"
DB_PATH = "/app/sqlite.db" DB_PATH = "/app/sqlite.db"
app = Flask(__name__) app = Flask(__name__)
hosts = {} hosts = {}
@@ -36,6 +37,27 @@ def validate_ip(ip: str) -> bool:
@app.route('/', methods=["GET"]) @app.route('/', methods=["GET"])
def homepage():
return render_template("index.html")
@app.route('/login', methods=["POST"])
def login():
if "user" not in request.form or "pass" not in request.form:
return redirect("/"), 400
if request.form["user"].strip() == "" or request.form["pass"].strip() == "":
return redirect("/"), 400
if not auth.user_login(DB_PATH, request.form["user"], request.form["pass"]):
return redirect("/")
return redirect("/dashboard", code=302)
@app.route('/health', methods=["GET"])
def health(): def health():
return jsonify({"status": "healthy", "comment": ""}) return jsonify({"status": "healthy", "comment": ""})
+15
View File
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<title>IZBI DNS</title>
</head>
<body>
<p>Dynamic DNS service for <span style="font-family: monospace">.izbi</span> domains <span style="font-family: monospace">:3</span></p>
<form method="POST" action="/login">
<input type="text" name="user" placeholder="username" required /><br />
<input type="password" name="pass" placeholder="password" required /><br />
<button type="submit">Log in</button>
</form>
</body>
</html>