mirror of
https://git.victorphan.net/basketballcantho/ten-project.git
synced 2026-08-05 18:33:11 +07:00
thực hiện phân quyền admin giáo viên và học sinh xong
This commit is contained in:
@@ -6,10 +6,50 @@ from sqlalchemy.orm import Session
|
||||
|
||||
from ..database import get_db
|
||||
from ..dependencies import get_current_user
|
||||
from ..models import Annotation, PDF, User
|
||||
from ..models import Annotation, PDF, User, UserRole
|
||||
from ..redis_client import ANN_TTL, ann_temp_key, ann_temp_page_pattern, get_redis
|
||||
from ..schemas import AnnotationIn, AnnotationOut
|
||||
|
||||
|
||||
def _do_delete_annotation(ann: Annotation, current_user: User, db: Session) -> None:
|
||||
"""Shared RBAC + delete logic, used by both delete endpoints."""
|
||||
from ..models import UserRole # avoid circular at module level
|
||||
|
||||
ann_owner = db.get(User, ann.user_id)
|
||||
|
||||
if current_user.role == UserRole.admin:
|
||||
pass # full access
|
||||
elif current_user.role == UserRole.teacher:
|
||||
if ann.user_id == current_user.id:
|
||||
pass # own annotation
|
||||
elif ann_owner and ann_owner.role == UserRole.admin:
|
||||
raise HTTPException(
|
||||
status_code=http_status.HTTP_403_FORBIDDEN,
|
||||
detail="Teachers cannot delete annotations belonging to an admin.",
|
||||
)
|
||||
else:
|
||||
pass # can delete student annotations (or annotations of deleted users)
|
||||
else: # student
|
||||
if ann.user_id != current_user.id:
|
||||
raise HTTPException(
|
||||
status_code=http_status.HTTP_403_FORBIDDEN,
|
||||
detail="You can only delete your own annotations.",
|
||||
)
|
||||
|
||||
pdf_id = ann.pdf_id
|
||||
page_number = ann.page_number
|
||||
user_id = ann.user_id
|
||||
db.delete(ann)
|
||||
db.commit()
|
||||
|
||||
# Remove Redis temp entry so /all doesn't serve stale data
|
||||
r = get_redis()
|
||||
if r is not None:
|
||||
try:
|
||||
r.delete(ann_temp_key(pdf_id, page_number, user_id))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
router = APIRouter(prefix="/annotations", tags=["annotations"])
|
||||
|
||||
|
||||
@@ -211,3 +251,56 @@ def upsert_annotation(
|
||||
pass
|
||||
|
||||
return ann
|
||||
|
||||
|
||||
# ── DELETE /api/annotations/{annotation_id} ───────────────────────────────────
|
||||
|
||||
@router.delete("/{annotation_id}", status_code=http_status.HTTP_204_NO_CONTENT)
|
||||
def delete_annotation(
|
||||
annotation_id: int,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""Delete annotation by primary key (RBAC enforced)."""
|
||||
ann = db.get(Annotation, annotation_id)
|
||||
if not ann:
|
||||
raise HTTPException(status_code=404, detail="Annotation not found.")
|
||||
_do_delete_annotation(ann, current_user, db)
|
||||
|
||||
|
||||
# ── DELETE /api/annotations/{pdf_id}/{page_number}/user/{target_user_id} ──────
|
||||
|
||||
@router.delete("/{pdf_id}/{page_number}/user/{target_user_id}", status_code=http_status.HTTP_204_NO_CONTENT)
|
||||
def delete_user_page_annotation(
|
||||
pdf_id: int,
|
||||
page_number: int,
|
||||
target_user_id: int,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Delete a specific user's annotation on a given page (RBAC enforced).
|
||||
Useful for teachers clearing a student's page without knowing the annotation id.
|
||||
Returns 204 even when no annotation exists (idempotent).
|
||||
"""
|
||||
_any_pdf_or_404(db, pdf_id)
|
||||
ann = (
|
||||
db.query(Annotation)
|
||||
.filter(
|
||||
Annotation.pdf_id == pdf_id,
|
||||
Annotation.page_number == page_number,
|
||||
Annotation.user_id == target_user_id,
|
||||
)
|
||||
.first()
|
||||
)
|
||||
if ann is None:
|
||||
# Nothing in DB — still clean up any Redis temp entry
|
||||
r = get_redis()
|
||||
if r is not None:
|
||||
try:
|
||||
r.delete(ann_temp_key(pdf_id, page_number, target_user_id))
|
||||
except Exception:
|
||||
pass
|
||||
return
|
||||
_do_delete_annotation(ann, current_user, db)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user