open-webui/backend/open_webui/routers/notes.py

236 lines
6.6 KiB
Python
Raw Normal View History

2025-05-03 22:16:32 +08:00
import json
import logging
from typing import Optional
from fastapi import APIRouter, Depends, HTTPException, Request, status, BackgroundTasks
from pydantic import BaseModel
2025-07-17 21:36:06 +08:00
from open_webui.socket.main import sio
2025-05-03 22:52:13 +08:00
from open_webui.models.users import Users, UserResponse
2025-05-03 22:16:32 +08:00
from open_webui.models.notes import Notes, NoteModel, NoteForm, NoteUserResponse
from open_webui.config import ENABLE_ADMIN_CHAT_ACCESS, ENABLE_ADMIN_EXPORT
from open_webui.constants import ERROR_MESSAGES
from open_webui.env import SRC_LOG_LEVELS
from open_webui.utils.auth import get_admin_user, get_verified_user
2025-05-06 03:29:40 +08:00
from open_webui.utils.access_control import has_access, has_permission
2025-05-03 22:16:32 +08:00
log = logging.getLogger(__name__)
log.setLevel(SRC_LOG_LEVELS["MODELS"])
router = APIRouter()
############################
# GetNotes
############################
@router.get("/", response_model=list[NoteUserResponse])
2025-05-04 21:22:51 +08:00
async def get_notes(request: Request, user=Depends(get_verified_user)):
if user.role != "admin" and not has_permission(
user.id, "features.notes", request.app.state.config.USER_PERMISSIONS
):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=ERROR_MESSAGES.UNAUTHORIZED,
)
2025-05-03 22:16:32 +08:00
notes = [
NoteUserResponse(
**{
**note.model_dump(),
2025-05-03 22:52:13 +08:00
"user": UserResponse(**Users.get_user_by_id(note.user_id).model_dump()),
2025-05-03 22:16:32 +08:00
}
)
2025-09-26 02:47:43 +08:00
for note in Notes.get_notes_by_permission(user.id, "write")
2025-05-03 22:16:32 +08:00
]
return notes
2025-07-09 05:17:25 +08:00
class NoteTitleIdResponse(BaseModel):
id: str
title: str
updated_at: int
created_at: int
@router.get("/list", response_model=list[NoteTitleIdResponse])
async def get_note_list(
request: Request, page: Optional[int] = None, user=Depends(get_verified_user)
):
2025-05-04 21:22:51 +08:00
if user.role != "admin" and not has_permission(
user.id, "features.notes", request.app.state.config.USER_PERMISSIONS
):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=ERROR_MESSAGES.UNAUTHORIZED,
)
limit = None
skip = None
if page is not None:
limit = 60
skip = (page - 1) * limit
2025-05-03 22:16:32 +08:00
notes = [
2025-07-09 05:17:25 +08:00
NoteTitleIdResponse(**note.model_dump())
2025-09-26 02:47:43 +08:00
for note in Notes.get_notes_by_permission(
user.id, "write", skip=skip, limit=limit
)
2025-05-03 22:16:32 +08:00
]
return notes
############################
# CreateNewNote
############################
@router.post("/create", response_model=Optional[NoteModel])
2025-05-04 21:22:51 +08:00
async def create_new_note(
request: Request, form_data: NoteForm, user=Depends(get_verified_user)
):
if user.role != "admin" and not has_permission(
user.id, "features.notes", request.app.state.config.USER_PERMISSIONS
):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=ERROR_MESSAGES.UNAUTHORIZED,
)
2025-05-03 22:16:32 +08:00
try:
note = Notes.insert_new_note(form_data, user.id)
return note
except Exception as e:
log.exception(e)
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT()
)
############################
# GetNoteById
############################
@router.get("/{id}", response_model=Optional[NoteModel])
2025-05-04 21:22:51 +08:00
async def get_note_by_id(request: Request, id: str, user=Depends(get_verified_user)):
if user.role != "admin" and not has_permission(
user.id, "features.notes", request.app.state.config.USER_PERMISSIONS
):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=ERROR_MESSAGES.UNAUTHORIZED,
)
2025-05-03 22:16:32 +08:00
note = Notes.get_note_by_id(id)
if not note:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND
)
2025-06-16 15:35:01 +08:00
if user.role != "admin" and (
2025-06-05 05:05:33 +08:00
user.id != note.user_id
2025-06-16 15:35:01 +08:00
and (not has_access(user.id, type="read", access_control=note.access_control))
2025-05-03 22:16:32 +08:00
):
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT()
)
return note
############################
# UpdateNoteById
############################
@router.post("/{id}/update", response_model=Optional[NoteModel])
async def update_note_by_id(
2025-05-04 21:22:51 +08:00
request: Request, id: str, form_data: NoteForm, user=Depends(get_verified_user)
2025-05-03 22:16:32 +08:00
):
2025-05-04 21:22:51 +08:00
if user.role != "admin" and not has_permission(
user.id, "features.notes", request.app.state.config.USER_PERMISSIONS
):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=ERROR_MESSAGES.UNAUTHORIZED,
)
2025-05-03 22:16:32 +08:00
note = Notes.get_note_by_id(id)
if not note:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND
)
2025-06-16 15:35:01 +08:00
if user.role != "admin" and (
2025-06-05 05:05:33 +08:00
user.id != note.user_id
and not has_access(user.id, type="write", access_control=note.access_control)
2025-05-03 22:16:32 +08:00
):
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT()
)
try:
note = Notes.update_note_by_id(id, form_data)
2025-07-17 21:36:06 +08:00
await sio.emit(
"note-events",
note.model_dump(),
to=f"note:{note.id}",
)
2025-05-03 22:16:32 +08:00
return note
except Exception as e:
log.exception(e)
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT()
)
############################
# DeleteNoteById
############################
@router.delete("/{id}/delete", response_model=bool)
2025-05-04 21:22:51 +08:00
async def delete_note_by_id(request: Request, id: str, user=Depends(get_verified_user)):
if user.role != "admin" and not has_permission(
user.id, "features.notes", request.app.state.config.USER_PERMISSIONS
):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=ERROR_MESSAGES.UNAUTHORIZED,
)
2025-05-03 22:16:32 +08:00
note = Notes.get_note_by_id(id)
if not note:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND
)
2025-06-16 15:35:01 +08:00
if user.role != "admin" and (
2025-06-05 05:05:33 +08:00
user.id != note.user_id
and not has_access(user.id, type="write", access_control=note.access_control)
2025-05-03 22:16:32 +08:00
):
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT()
)
try:
note = Notes.delete_note_by_id(id)
return True
except Exception as e:
log.exception(e)
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT()
)