(init): Keys and Prefix Management

This commit is contained in:
2026-06-21 23:56:50 -04:00
commit 80c747226f
50 changed files with 4631 additions and 0 deletions
+27
View File
@@ -0,0 +1,27 @@
import os
from pathlib import Path
import sqlite3
tam_data_dir = os.getenv("TAM_DATA_DIR", "./data")
def session():
data_dir = Path(tam_data_dir)
if not data_dir.is_dir():
data_dir.mkdir(parents=True)
db_file = data_dir / "tam-remote.db"
conn = sqlite3.connect(db_file)
cur = conn.cursor()
return conn, cur
def init_db():
conn, cur = session()
cur.execute("CREATE TABLE IF NOT EXISTS auth_keys (auth_key TEXT PRIMARY KEY, description TEXT)")
cur.execute("CREATE TABLE IF NOT EXISTS prefixes (prefix TEXT PRIMARY KEY, color TEXT, weight INTEGER)")
conn.commit()
conn.close()
class RepoTemplate:
def __init__(self):
self.conn, self.cur = session()
def __del__(self):
self.conn.close()
+31
View File
@@ -0,0 +1,31 @@
from dataclasses import dataclass
from db import init_db
from fastapi import FastAPI, Header
import os
from routers import imp_routers
from system.auth import AuthRepo
tam_env = os.getenv("TAM_ENV", "prod")
@dataclass
class MainRoute:
whoami: str = "TAM Server"
authenticated: bool = False
healthy: bool = True
init_db()
app = FastAPI(
title="TAM Server",
description="Server for Ticket Auction Manager",
version="0.0.1",
docs_url=None if tam_env == "prod" else "/docs",
redoc_url=None,
openapi_url=None if tam_env == "prod" else "/openapi.json"
)
@app.get("/api")
def get_main_route(tam_key: str = Header("")):
return MainRoute(authenticated=AuthRepo().check_key(tam_key))
imp_routers(app)
+7
View File
@@ -0,0 +1,7 @@
from fastapi import FastAPI
from system.auth import auth_router
from system.prefixes import prefix_router
def imp_routers(app: FastAPI):
app.include_router(auth_router)
app.include_router(prefix_router)
Binary file not shown.
Binary file not shown.
+83
View File
@@ -0,0 +1,83 @@
from dataclasses import dataclass
from db import RepoTemplate
from fastapi import APIRouter, Header, HTTPException, status
import os
import random
import string
tam_pwd = os.getenv("TAM_PWD", "dbob16")
ex_pwd = HTTPException(status.HTTP_401_UNAUTHORIZED, "Invalid Password")
ex_key = HTTPException(status.HTTP_401_UNAUTHORIZED, "Invalid Key")
rdm_str_choice = string.ascii_uppercase + string.digits
def check_pw(in_pw: str):
if tam_pwd != in_pw:
raise ex_pwd
def gen_key():
return "".join(random.choice(rdm_str_choice) for _ in range(32))
@dataclass
class AuthReq:
description: str = ""
@dataclass
class AuthKey:
auth_key: str = ""
description: str = ""
class AuthRepo(RepoTemplate):
def get_all_keys(self):
self.cur.execute("SELECT * FROM auth_keys ORDER BY description, auth_key")
results = self.cur.fetchall()
return [AuthKey(*r) for r in results]
def create_key(self, desciption: str = ""):
while True:
new_key = gen_key()
self.cur.execute("SELECT * FROM auth_keys WHERE auth_key = ?", (new_key,))
results = self.cur.fetchall()
if len(results) == 0:
break
self.cur.execute("INSERT INTO auth_keys VALUES (?, ?) RETURNING *", (new_key, desciption))
rtn_key = self.cur.fetchone()
self.conn.commit()
return AuthKey(*rtn_key)
def del_key(self, auth_key: str = ""):
self.cur.execute("DELETE FROM auth_keys WHERE auth_key = ? RETURNING *", (auth_key,))
results = self.cur.fetchall()
self.conn.commit()
if len(results) > 0:
return AuthKey(*results[0])
else:
return AuthKey(auth_key, "")
def check_key(self, auth_key: str = ""):
self.cur.execute("SELECT * FROM auth_keys WHERE auth_key = ?", (auth_key,))
results = self.cur.fetchall()
if results:
return True
else:
return False
def verify_key(self, auth_key: str = ""):
self.cur.execute("SELECT * FROM auth_keys WHERE auth_key = ?", (auth_key,))
results = self.cur.fetchone()
if results:
return True
else:
raise ex_key
auth_router = APIRouter(prefix="/api/auth")
@auth_router.get("")
def get_auth_keys(tam_pw: str = Header("")) -> list[AuthKey]:
check_pw(tam_pw)
return AuthRepo().get_all_keys()
@auth_router.post("")
def create_auth_key(auth_req: AuthReq, tam_pw: str = Header("")) -> AuthKey:
check_pw(tam_pw)
return AuthRepo().create_key(auth_req.description)
@auth_router.delete("")
def delete_auth_key(key_to_del: str, tam_pw: str = Header("")) -> AuthKey:
check_pw(tam_pw)
return AuthRepo().del_key(key_to_del)
+48
View File
@@ -0,0 +1,48 @@
from dataclasses import dataclass
from db import RepoTemplate
from .auth import AuthRepo
from fastapi import APIRouter, Header
@dataclass
class Prefix:
prefix: str
color: str = ""
weight: int = 0
class PrefixRepo(RepoTemplate):
def get_all_prefixes(self):
self.cur.execute("SELECT * FROM prefixes ORDER BY weight, prefix")
results = self.cur.fetchall()
return [Prefix(*r) for r in results]
def post_prefixes(self, ps: list[Prefix]):
for p in ps:
self.cur.execute("""INSERT INTO prefixes VALUES (?, ?, ?)
ON CONFLICT (prefix) DO UPDATE SET
color = EXCLUDED.color, weight = EXCLUDED.weight""", (p.prefix, p.color, p.weight))
self.conn.commit()
return ps
def del_prefix(self, p: str):
self.cur.execute("DELETE FROM prefixes WHERE prefix = ? RETURNING *", (p,))
result = self.cur.fetchone()
self.conn.commit()
if result:
return Prefix(*result)
else:
return Prefix(p, "gray", 1)
prefix_router = APIRouter(prefix="/api/prefixes")
@prefix_router.get("")
def get_all_prefixes(tam_key: str = Header("")):
AuthRepo().verify_key(tam_key)
return PrefixRepo().get_all_prefixes()
@prefix_router.post("")
def post_prefixes(ps: list[Prefix], tam_key: str = Header("")):
AuthRepo().verify_key(tam_key)
return PrefixRepo().post_prefixes(ps)
@prefix_router.delete("")
def delete_prefixes(p: str, tam_key: str = Header("")):
AuthRepo().verify_key(tam_key)
return PrefixRepo().del_prefix(p)