103 lines
3.8 KiB
Python
103 lines
3.8 KiB
Python
|
|
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)
|