103 lines
3.8 KiB
Python
Raw Normal View History

import logging
from datetime import datetime
from fastapi import APIRouter, Request
from fastapi.responses import HTMLResponse, RedirectResponse
from devplacepy.database import get_table
from devplacepy.templating import templates
from devplacepy.utils import require_admin, hash_password, generate_uid, time_ago
logger = logging.getLogger(__name__)
router = APIRouter()
@router.get("", response_class=HTMLResponse)
async def admin_index(request: Request):
require_admin(request)
return RedirectResponse(url="/admin/users", status_code=302)
@router.get("/users", response_class=HTMLResponse)
async def admin_users(request: Request):
admin = require_admin(request)
users_table = get_table("users")
all_users = list(users_table.all())
for u in all_users:
posts_count = len(list(get_table("posts").find(user_uid=u["uid"])))
u["posts_count"] = posts_count
return templates.TemplateResponse("admin_users.html", {
"request": request,
"user": admin,
"users": all_users,
"admin_section": "users",
})
@router.post("/users/{uid}/role")
async def admin_user_role(request: Request, uid: str):
admin = require_admin(request)
form = await request.form()
role = form.get("role", "").strip().capitalize()
if role not in ("Member", "Admin"):
return RedirectResponse(url="/admin/users", status_code=302)
if uid == admin["uid"]:
return RedirectResponse(url="/admin/users", status_code=302)
users = get_table("users")
users.update({"uid": uid, "role": role}, ["uid"])
logger.info(f"Admin {admin['username']} set user {uid} role to {role}")
return RedirectResponse(url="/admin/users", status_code=302)
@router.post("/users/{uid}/password")
async def admin_user_password(request: Request, uid: str):
admin = require_admin(request)
form = await request.form()
password = form.get("password", "")
if len(password) < 6:
return RedirectResponse(url="/admin/users", status_code=302)
users = get_table("users")
users.update({"uid": uid, "password_hash": hash_password(password)}, ["uid"])
logger.info(f"Admin {admin['username']} changed password for user {uid}")
return RedirectResponse(url="/admin/users", status_code=302)
@router.post("/users/{uid}/toggle")
async def admin_user_toggle(request: Request, uid: str):
admin = require_admin(request)
if uid == admin["uid"]:
return RedirectResponse(url="/admin/users", status_code=302)
users = get_table("users")
user = users.find_one(uid=uid)
if user:
new_state = not user.get("is_active", True)
users.update({"uid": uid, "is_active": new_state}, ["uid"])
logger.info(f"Admin {admin['username']} {'disabled' if not new_state else 'enabled'} user {uid}")
return RedirectResponse(url="/admin/users", status_code=302)
@router.get("/settings", response_class=HTMLResponse)
async def admin_settings(request: Request):
admin = require_admin(request)
settings = get_table("site_settings")
all_settings = {s["key"]: s["value"] for s in settings.all()}
return templates.TemplateResponse("admin_settings.html", {
"request": request,
"user": admin,
"settings": all_settings,
"admin_section": "settings",
})
@router.post("/settings")
async def admin_settings_save(request: Request):
admin = require_admin(request)
form = await request.form()
settings = get_table("site_settings")
for key, value in form.multi_items():
existing = settings.find_one(key=key)
if existing:
settings.update({"id": existing["id"], "key": key, "value": value}, ["id"])
else:
settings.insert({"uid": generate_uid(), "key": key, "value": value})
logger.info(f"Admin {admin['username']} updated settings")
return RedirectResponse(url="/admin/settings", status_code=302)