Updated user manager.

This commit is contained in:
Michael Woods
2025-12-21 21:25:50 -05:00
parent 95311ece46
commit 1cd7242a7b
2 changed files with 15 additions and 7 deletions

View File

@@ -1,10 +1,12 @@
# packetserver/http/auth.py
import ax25
from persistent import Persistent
from argon2 import PasswordHasher
from argon2.exceptions import VerifyMismatchError
import time
from persistent.mapping import PersistentMapping
from persistent.list import PersistentList
from packetserver.common.util import is_valid_ax25_callsign
ph = PasswordHasher()
@@ -22,6 +24,12 @@ class HttpUser(Persistent):
self.last_login = None
self.failed_attempts = 0
# Check to make sure we're not storing a SSID
if is_valid_ax25_callsign(self.username):
base = ax25.Address(self.username).call
if base.upper() != self.username:
raise ValueError(f"'{self.username}' is a callsign with an SSID appended. Please use base callsign.")
# New fields
self._enabled = True # HTTP access enabled by default
# rf_enabled is a @property no direct storage needed
@@ -30,11 +38,11 @@ class HttpUser(Persistent):
# Simple enabled flag (admin can disable HTTP login entirely)
# ------------------------------------------------------------------
@property
def enabled(self) -> bool:
def http_enabled(self) -> bool:
return getattr(self, '_enabled', True)
@enabled.setter
def enabled(self, value: bool):
@http_enabled.setter
def http_enabled(self, value: bool):
self._enabled = bool(value)
self._p_changed = True
@@ -57,7 +65,7 @@ class HttpUser(Persistent):
Requires an open ZODB connection (inside a transaction).
Only allows enabling if the username is a valid AX.25 callsign.
"""
from packetserver.utils import is_valid_ax25_callsign # our validator
from packetserver.common.util import is_valid_ax25_callsign # our validator
root = connection.root()
config = root.setdefault('config', PersistentMapping())

View File

@@ -214,14 +214,14 @@ def main():
if not users_mapping:
print("No HTTP users configured")
else:
print(f"{'Callsign':<12} {'Enabled':<8} {'RF Enabled':<11} {'Created':<20} Last Login")
print("-" * 70)
print(f"{'Callsign':<12} {'HTTP Enabled':<13} {'RF Enabled':<11} {'Created':<20} Last Login")
print("-" * 75)
for user in sorted(users_mapping.values(), key=lambda u: u.username):
created = time.strftime("%Y-%m-%d %H:%M", time.localtime(user.created_at))
last = (time.strftime("%Y-%m-%d %H:%M", time.localtime(user.last_login))
if user.last_login else "-")
rf_status = "True" if user.is_rf_enabled(connection) else "False"
print(f"{user.username:<12} {str(user.enabled):<8} {rf_status:<11} {created:<20} {last}")
print(f"{user.username:<12} {str(user.http_enabled):<13} {rf_status:<11} {created:<20} {last}")
finally: