| 
									
										
										
										
											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-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
										 |  |  |             } | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         for note in Notes.get_notes_by_user_id(user.id, "write") | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return notes | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @router.get("/list", response_model=list[NoteUserResponse]) | 
					
						
							| 
									
										
										
										
											2025-05-04 21:22:51 +08:00
										 |  |  | async def get_note_list(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
										 |  |  |             } | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         for note in Notes.get_notes_by_user_id(user.id, "read") | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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) | 
					
						
							|  |  |  |         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() | 
					
						
							|  |  |  |         ) |