Updated database methodology for everything else.

This commit is contained in:
Michael Woods
2025-12-25 16:06:29 -05:00
parent 5f39349496
commit 5018012dc7
4 changed files with 34 additions and 38 deletions

View File

@@ -1,5 +1,6 @@
# packetserver/http/auth.py # packetserver/http/auth.py
import ax25 import ax25
import transaction
from persistent import Persistent from persistent import Persistent
from argon2 import PasswordHasher from argon2 import PasswordHasher
from argon2.exceptions import VerifyMismatchError from argon2.exceptions import VerifyMismatchError
@@ -7,7 +8,7 @@ import time
from persistent.mapping import PersistentMapping from persistent.mapping import PersistentMapping
from persistent.list import PersistentList from persistent.list import PersistentList
from packetserver.common.util import is_valid_ax25_callsign from packetserver.common.util import is_valid_ax25_callsign
from .database import get_db, get_transaction from .database import ConnectionDependency
ph = PasswordHasher() ph = PasswordHasher()
@@ -51,17 +52,16 @@ class HttpUser(Persistent):
# rf enabled checks.. # rf enabled checks..
# #
def is_rf_enabled(self) -> bool: def is_rf_enabled(self, conn: ConnectionDependency) -> bool:
""" """
Check if RF gateway is enabled (i.e., callsign NOT in global blacklist). Check if RF gateway is enabled (i.e., callsign NOT in global blacklist).
Requires an open ZODB connection. Requires an open ZODB connection.
""" """
with get_transaction() as storage: root = conn.root()
root = storage.root()
blacklist = root.get('config', {}).get('blacklist', []) blacklist = root.get('config', {}).get('blacklist', [])
return self.username not in blacklist return self.username not in blacklist
def set_rf_enabled(self, connection, allow: bool): def set_rf_enabled(self, conn: ConnectionDependency, allow: bool):
""" """
Enable/disable RF gateway by adding/removing from global blacklist. Enable/disable RF gateway by adding/removing from global blacklist.
Requires an open ZODB connection (inside a transaction). Requires an open ZODB connection (inside a transaction).
@@ -69,8 +69,7 @@ class HttpUser(Persistent):
""" """
from packetserver.common.util import is_valid_ax25_callsign # our validator from packetserver.common.util import is_valid_ax25_callsign # our validator
with get_transaction() as storage: root = conn.root()
root = storage.root()
config = root.setdefault('config', PersistentMapping()) config = root.setdefault('config', PersistentMapping())
blacklist = config.setdefault('blacklist', PersistentList()) blacklist = config.setdefault('blacklist', PersistentList())
@@ -89,6 +88,7 @@ class HttpUser(Persistent):
config._p_changed = True config._p_changed = True
root._p_changed = True root._p_changed = True
transaction.commit()
# ------------------------------------------------------------------ # ------------------------------------------------------------------
# Password handling (unchanged) # Password handling (unchanged)

View File

@@ -10,6 +10,7 @@ from pydantic import BaseModel, Field, validator
from packetserver.http.dependencies import get_current_http_user from packetserver.http.dependencies import get_current_http_user
from packetserver.http.auth import HttpUser from packetserver.http.auth import HttpUser
from packetserver.http.database import ConnectionDependency
html_router = APIRouter(tags=["messages-html"]) html_router = APIRouter(tags=["messages-html"])
@@ -28,18 +29,17 @@ class MarkRetrievedRequest(BaseModel):
@router.get("/messages") @router.get("/messages")
async def get_messages( async def get_messages(
conn: ConnectionDependency,
current_user: HttpUser = Depends(get_current_http_user), current_user: HttpUser = Depends(get_current_http_user),
type: str = Query("received", description="received, sent, or all"), type: str = Query("received", description="received, sent, or all"),
limit: Optional[int] = Query(20, le=100, description="Max messages to return (default 20, max 100)"), limit: Optional[int] = Query(20, le=100, description="Max messages to return (default 20, max 100)"),
since: Optional[str] = Query(None, description="ISO UTC timestamp filter (e.g. 2025-12-01T00:00:00Z)") since: Optional[str] = Query(None, description="ISO UTC timestamp filter (e.g. 2025-12-01T00:00:00Z)"),
): ):
if limit is None or limit < 1: if limit is None or limit < 1:
limit = 20 limit = 20
username = current_user.username username = current_user.username
from packetserver.runners.http_server import get_db_connection
conn = get_db_connection()
root = conn.root() root = conn.root()
if 'messages' not in root: if 'messages' not in root:
@@ -81,12 +81,11 @@ async def get_messages(
@router.get("/messages/{msg_id}") @router.get("/messages/{msg_id}")
async def get_message( async def get_message(
conn: ConnectionDependency,
msg_id: str = Path(..., description="UUID of the message (as string)"), msg_id: str = Path(..., description="UUID of the message (as string)"),
mark_retrieved: bool = Query(False, description="If true, mark message as retrieved/read"), mark_retrieved: bool = Query(False, description="If true, mark message as retrieved/read"),
current_user: HttpUser = Depends(get_current_http_user) current_user: HttpUser = Depends(get_current_http_user)
): ):
from packetserver.runners.http_server import get_db_connection
conn = get_db_connection()
root = conn.root() root = conn.root()
username = current_user.username username = current_user.username
@@ -127,12 +126,11 @@ async def get_message(
@router.patch("/messages/{msg_id}") @router.patch("/messages/{msg_id}")
async def mark_message_retrieved( async def mark_message_retrieved(
conn: ConnectionDependency,
msg_id: str = Path(..., description="Message UUID as string"), msg_id: str = Path(..., description="Message UUID as string"),
payload: MarkRetrievedRequest = None, payload: MarkRetrievedRequest = None,
current_user: HttpUser = Depends(get_current_http_user) current_user: HttpUser = Depends(get_current_http_user)
): ):
from packetserver.runners.http_server import get_db_connection
conn = get_db_connection()
root = conn.root() root = conn.root()
username = current_user.username username = current_user.username

View File

@@ -3,16 +3,14 @@ from fastapi import APIRouter, Depends
from packetserver.http.dependencies import get_current_http_user from packetserver.http.dependencies import get_current_http_user
from packetserver.http.auth import HttpUser from packetserver.http.auth import HttpUser
from packetserver.http.database import ConnectionDependency
router = APIRouter(prefix="/api/v1", tags=["auth"]) router = APIRouter(prefix="/api/v1", tags=["auth"])
@router.get("/profile") @router.get("/profile")
async def profile(current_user: HttpUser = Depends(get_current_http_user)): async def profile(conn: ConnectionDependency,current_user: HttpUser = Depends(get_current_http_user)):
username = current_user.username username = current_user.username
from packetserver.runners.http_server import get_db_connection
conn = get_db_connection()
root = conn.root() root = conn.root()
# Get main BBS User and safe dict # Get main BBS User and safe dict

View File

@@ -11,6 +11,7 @@ from packetserver.http.dependencies import get_current_http_user
from packetserver.http.auth import HttpUser from packetserver.http.auth import HttpUser
from packetserver.server.messages import Message from packetserver.server.messages import Message
from packetserver.common.util import is_valid_ax25_callsign from packetserver.common.util import is_valid_ax25_callsign
from packetserver.http.database import ConnectionDependency
router = APIRouter(prefix="/api/v1", tags=["messages"]) router = APIRouter(prefix="/api/v1", tags=["messages"])
@@ -39,11 +40,10 @@ class SendMessageRequest(BaseModel):
@router.post("/messages") @router.post("/messages")
async def send_message( async def send_message(
conn: ConnectionDependency,
payload: SendMessageRequest, payload: SendMessageRequest,
current_user: HttpUser = Depends(get_current_http_user) current_user: HttpUser = Depends(get_current_http_user)
): ):
from packetserver.runners.http_server import get_db_connection
conn = get_db_connection()
root = conn.root() root = conn.root()
if not current_user.is_rf_enabled(conn): if not current_user.is_rf_enabled(conn):