|
# retoor <retoor@molodetz.nl>
|
|
|
|
import logging
|
|
from typing import Annotated
|
|
from fastapi import Depends, APIRouter, Request
|
|
from fastapi.responses import RedirectResponse
|
|
from fastapi.responses import JSONResponse
|
|
from devplacepy.database import get_table, resolve_object_url
|
|
from devplacepy.content import (
|
|
is_owner,
|
|
create_comment_record,
|
|
delete_comment_record,
|
|
edit_comment_record,
|
|
)
|
|
from devplacepy.utils import require_user, is_admin
|
|
from devplacepy.models import CommentForm, CommentEditForm
|
|
from devplacepy.responses import action_result, wants_json, json_error
|
|
from devplacepy.schemas import CommentEditOut
|
|
from devplacepy.services.audit import record as audit
|
|
from devplacepy.dependencies import json_or_form
|
|
|
|
logger = logging.getLogger(__name__)
|
|
router = APIRouter()
|
|
|
|
@router.post("/create")
|
|
async def create_comment(request: Request, data: Annotated[CommentForm, Depends(json_or_form(CommentForm))]):
|
|
user = require_user(request)
|
|
target_uid = data.target_uid or data.post_uid
|
|
comment_uid, comment_url = create_comment_record(
|
|
request,
|
|
user,
|
|
data.target_type,
|
|
target_uid,
|
|
data.content.strip(),
|
|
data.parent_uid,
|
|
data.attachment_uids,
|
|
)
|
|
return action_result(
|
|
request, comment_url, data={"uid": comment_uid, "url": comment_url}
|
|
)
|
|
|
|
@router.post("/edit/{comment_uid}")
|
|
async def edit_comment(
|
|
request: Request, comment_uid: str, data: Annotated[CommentEditForm, Depends(json_or_form(CommentEditForm))]
|
|
):
|
|
user = require_user(request)
|
|
comments = get_table("comments")
|
|
comment = comments.find_one(uid=comment_uid, deleted_at=None)
|
|
if not comment or not is_owner(comment, user):
|
|
target_type = comment.get("target_type", "post") if comment else "post"
|
|
target_uid = (
|
|
(comment.get("target_uid") or comment.get("post_uid", "")) if comment else ""
|
|
)
|
|
audit.record(
|
|
request,
|
|
"comment.edit",
|
|
user=user,
|
|
result="denied",
|
|
target_type="comment",
|
|
target_uid=comment_uid,
|
|
summary=f"{user['username']} denied editing comment {comment_uid}",
|
|
)
|
|
if wants_json(request):
|
|
return json_error(403, "Not allowed")
|
|
return RedirectResponse(
|
|
url=resolve_object_url(target_type, target_uid), status_code=302
|
|
)
|
|
content = data.content.strip()
|
|
updated_at = edit_comment_record(request, user, comment, content)
|
|
target_type = comment.get("target_type", "post")
|
|
target_uid = comment.get("target_uid") or comment.get("post_uid", "")
|
|
comment_url = f"{resolve_object_url(target_type, target_uid)}#comment-{comment_uid}"
|
|
if wants_json(request):
|
|
return JSONResponse(
|
|
CommentEditOut(
|
|
uid=comment_uid,
|
|
content=content,
|
|
url=comment_url,
|
|
updated_at=updated_at,
|
|
).model_dump(mode="json")
|
|
)
|
|
return RedirectResponse(url=comment_url, status_code=302)
|
|
|
|
@router.post("/delete/{comment_uid}")
|
|
async def delete_comment(request: Request, comment_uid: str):
|
|
user = require_user(request)
|
|
comments = get_table("comments")
|
|
comment = comments.find_one(uid=comment_uid, deleted_at=None)
|
|
if not comment or not (is_owner(comment, user) or is_admin(user)):
|
|
audit.record(
|
|
request,
|
|
"comment.delete",
|
|
user=user,
|
|
result="denied",
|
|
target_type="comment",
|
|
target_uid=comment_uid,
|
|
summary=f"{user['username']} denied deleting comment {comment_uid}",
|
|
)
|
|
if wants_json(request):
|
|
return json_error(403, "Not allowed")
|
|
return RedirectResponse(url="/feed", status_code=302)
|
|
target_type, target_uid = delete_comment_record(request, user, comment)
|
|
redirect_url = resolve_object_url(target_type, target_uid)
|
|
return action_result(
|
|
request,
|
|
redirect_url,
|
|
data={
|
|
"deleted_uid": comment_uid,
|
|
"target_type": target_type,
|
|
"target_uid": target_uid,
|
|
},
|
|
)
|