Files
nanobot-auth/app/manual_review.py
2026-03-23 14:18:24 +08:00

111 lines
3.4 KiB
Python

from __future__ import annotations
import os
import sqlite3
from datetime import datetime, timezone
from pathlib import Path
DB_PATH = Path(os.getenv("AUTH_DB_PATH", "auth_service.sqlite3")).expanduser()
def now_iso() -> str:
return datetime.now(timezone.utc).isoformat()
def connect() -> sqlite3.Connection:
conn = sqlite3.connect(DB_PATH)
conn.row_factory = sqlite3.Row
return conn
def approve(conn: sqlite3.Connection, request_id: int) -> None:
row = conn.execute(
"SELECT id, phone, password_hash, salt, status FROM registration_requests WHERE id = ?",
(request_id,),
).fetchone()
if row is None:
print(f"request #{request_id} not found")
return
if row["status"] != "pending":
print(f"request #{request_id} already {row['status']}")
return
try:
conn.execute(
"INSERT INTO users(phone, password_hash, salt, created_at) VALUES(?, ?, ?, ?)",
(row["phone"], row["password_hash"], row["salt"], now_iso()),
)
conn.execute(
"UPDATE registration_requests SET status='approved', reviewed_at=?, review_note=? WHERE id=?",
(now_iso(), "approved in manual_review", request_id),
)
conn.commit()
print(f"approved request #{request_id} ({row['phone']})")
except sqlite3.IntegrityError:
conn.execute(
"UPDATE registration_requests SET status='rejected', reviewed_at=?, review_note=? WHERE id=?",
(now_iso(), "phone already exists", request_id),
)
conn.commit()
print(f"rejected request #{request_id}: phone already exists")
def reject(conn: sqlite3.Connection, request_id: int, note: str) -> None:
row = conn.execute(
"SELECT id, status, phone FROM registration_requests WHERE id = ?",
(request_id,),
).fetchone()
if row is None:
print(f"request #{request_id} not found")
return
if row["status"] != "pending":
print(f"request #{request_id} already {row['status']}")
return
conn.execute(
"UPDATE registration_requests SET status='rejected', reviewed_at=?, review_note=? WHERE id=?",
(now_iso(), note, request_id),
)
conn.commit()
print(f"rejected request #{request_id} ({row['phone']})")
def main() -> None:
if not DB_PATH.exists():
print(f"db not found: {DB_PATH}")
return
with connect() as conn:
rows = conn.execute(
"""
SELECT id, phone, invite_code, created_at
FROM registration_requests
WHERE status='pending'
ORDER BY id ASC
"""
).fetchall()
if not rows:
print("no pending requests")
return
print(f"pending requests: {len(rows)}")
for row in rows:
print("-" * 64)
print(
f"#{row['id']} phone={row['phone']} invite={row['invite_code']} "
f"created_at={row['created_at']}"
)
answer = input("approve this request? [y/N/r]: ").strip().lower()
if answer == "y":
approve(conn, int(row["id"]))
elif answer == "r":
note = input("reject reason: ").strip() or "rejected manually"
reject(conn, int(row["id"]), note)
else:
print("skip")
if __name__ == "__main__":
main()