aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/api/admin.py
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/api/admin.py')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/api/admin.py39
1 files changed, 30 insertions, 9 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/api/admin.py b/packages/meshbay-hub/src/meshbay_hub/api/admin.py
index 087c221..397b4d9 100644
--- a/packages/meshbay-hub/src/meshbay_hub/api/admin.py
+++ b/packages/meshbay-hub/src/meshbay_hub/api/admin.py
@@ -40,20 +40,25 @@ class SettingsPatchRequest(BaseModel):
allow_public_groups: bool | None = None
# Every mail bound, each optional: the panel sends only what changed.
mail: dict[str, int] | None = None
+ # The sign-in lockout's two numbers, each optional, as for mail.
+ login: dict[str, int] | None = None
# ── Instance settings ────────────────────────────────────────────────────────
-def _settings_payload(allow_public_groups: bool, mail: dict) -> dict:
+async def _settings_payload(db: AsyncSession) -> dict:
return {
- "allow_public_groups": allow_public_groups,
- "mail": mail,
+ "allow_public_groups": await hub_settings.public_groups_allowed(db),
+ "mail": await hub_settings.mail_limits(db),
# So the panel can show what a field falls back to, and label the
# bounds it will refuse — rather than the operator finding out by
# having a value silently clamped.
"mail_defaults": {k: hub_settings.mail_default(k)
for k in hub_settings.MAIL_KEYS},
"mail_bounds": {k: list(v) for k, v in hub_settings.MAIL_BOUNDS.items()},
+ "login": await hub_settings.login_limits(db),
+ "login_defaults": dict(hub_settings.LOGIN_DEFAULTS),
+ "login_bounds": {k: list(v) for k, v in hub_settings.LOGIN_BOUNDS.items()},
}
@@ -63,9 +68,7 @@ async def admin_get_settings(
db: AsyncSession = Depends(get_db),
):
"""Instance-wide policy an admin controls from the panel. Moderators may read."""
- return _settings_payload(
- await hub_settings.public_groups_allowed(db),
- await hub_settings.mail_limits(db))
+ return await _settings_payload(db)
@router.patch("/settings")
@@ -115,9 +118,27 @@ async def admin_patch_settings(
))
await db.commit()
- return _settings_payload(
- await hub_settings.public_groups_allowed(db),
- await hub_settings.mail_limits(db))
+ if body.login:
+ unknown = sorted(set(body.login) - set(hub_settings.LOGIN_KEYS))
+ if unknown:
+ raise HTTPException(
+ status_code=422, detail=f"Unknown login setting(s): {unknown}")
+ changed = []
+ for key, value in body.login.items():
+ clamped = hub_settings.clamp_login_value(key, value)
+ await hub_settings.set_raw(db, f"login.{key}", str(clamped))
+ changed.append(f"{key}={clamped}")
+ log.info("Sign-in lockout changed by %s: %s",
+ current_user.username, ", ".join(changed))
+ db.add(IPLog(
+ user_id=current_user.id,
+ event="admin_login_lockout_update",
+ ip_address="admin",
+ detail=", ".join(changed)[:255],
+ ))
+ await db.commit()
+
+ return await _settings_payload(db)
@router.get("/mail")