perf(auth): Make aiohttp auth server read-only
Refactored the aiohttp authentication server to be a purely read-only service. Removed all file write operations from the authentication logic to eliminate disk I/O and reduce CPU overhead during connection attempts. The responsibility for persistently blocking users by writing to `users.json` is now fully delegated to the external scheduler service, allowing the auth server to function as a faster, more efficient gatekeeper.
This commit is contained in:
@ -14,18 +14,16 @@ async def load_users(app):
|
|||||||
global users_data
|
global users_data
|
||||||
async with users_lock:
|
async with users_lock:
|
||||||
if os.path.exists(USERS_FILE):
|
if os.path.exists(USERS_FILE):
|
||||||
async with aiofiles.open(USERS_FILE, 'r') as f:
|
try:
|
||||||
content = await f.read()
|
async with aiofiles.open(USERS_FILE, 'r') as f:
|
||||||
users_data = json.loads(content)
|
content = await f.read()
|
||||||
|
users_data = json.loads(content)
|
||||||
|
except (IOError, json.JSONDecodeError):
|
||||||
|
users_data = {}
|
||||||
else:
|
else:
|
||||||
users_data = {}
|
users_data = {}
|
||||||
app['users_data'] = users_data
|
app['users_data'] = users_data
|
||||||
|
|
||||||
async def save_users():
|
|
||||||
async with users_lock:
|
|
||||||
async with aiofiles.open(USERS_FILE, 'w') as f:
|
|
||||||
await f.write(json.dumps(users_data, indent=4))
|
|
||||||
|
|
||||||
async def authenticate(request):
|
async def authenticate(request):
|
||||||
global users_data
|
global users_data
|
||||||
try:
|
try:
|
||||||
@ -50,7 +48,6 @@ async def authenticate(request):
|
|||||||
if user.get("password") != password:
|
if user.get("password") != password:
|
||||||
return web.json_response({"ok": False, "msg": "Invalid password"}, status=401)
|
return web.json_response({"ok": False, "msg": "Invalid password"}, status=401)
|
||||||
|
|
||||||
should_save = False
|
|
||||||
expiration_days = user.get("expiration_days", 0)
|
expiration_days = user.get("expiration_days", 0)
|
||||||
if expiration_days > 0:
|
if expiration_days > 0:
|
||||||
creation_date_str = user.get("account_creation_date")
|
creation_date_str = user.get("account_creation_date")
|
||||||
@ -58,20 +55,14 @@ async def authenticate(request):
|
|||||||
creation_date = datetime.strptime(creation_date_str, "%Y-%m-%d")
|
creation_date = datetime.strptime(creation_date_str, "%Y-%m-%d")
|
||||||
expiration_date = creation_date + timedelta(days=expiration_days)
|
expiration_date = creation_date + timedelta(days=expiration_days)
|
||||||
if datetime.now() >= expiration_date:
|
if datetime.now() >= expiration_date:
|
||||||
user["blocked"] = True
|
return web.json_response({"ok": False, "msg": "Account expired"}, status=401)
|
||||||
should_save = True
|
|
||||||
|
|
||||||
max_bytes = user.get("max_download_bytes", 0)
|
max_bytes = user.get("max_download_bytes", 0)
|
||||||
if max_bytes > 0:
|
if max_bytes > 0:
|
||||||
current_up = user.get("upload_bytes", 0)
|
current_up = user.get("upload_bytes", 0)
|
||||||
current_down = user.get("download_bytes", 0)
|
current_down = user.get("download_bytes", 0)
|
||||||
if (current_up + current_down) >= max_bytes:
|
if (current_up + current_down) >= max_bytes:
|
||||||
user["blocked"] = True
|
return web.json_response({"ok": False, "msg": "Data limit exceeded"}, status=401)
|
||||||
should_save = True
|
|
||||||
|
|
||||||
if should_save:
|
|
||||||
await save_users()
|
|
||||||
return web.json_response({"ok": False, "msg": "User blocked due to limits"}, status=401)
|
|
||||||
|
|
||||||
return web.json_response({"ok": True, "id": username})
|
return web.json_response({"ok": True, "id": username})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user