diff --git a/private_gpt/users/api/v1/routers/audits.py b/private_gpt/users/api/v1/routers/audits.py index 2be00bf3..cffe86aa 100644 --- a/private_gpt/users/api/v1/routers/audits.py +++ b/private_gpt/users/api/v1/routers/audits.py @@ -46,6 +46,39 @@ def list_auditlog( return logs +@router.get("filter/", response_model=List[schemas.Audit]) +def filter_auditlog( + db: Session = Depends(deps.get_db), + filter_in= Depends(schemas.AuditFilter), + current_user: models.User = Security( + deps.get_current_user, + scopes=[Role.SUPER_ADMIN["name"]], + ), +) -> List[schemas.Audit]: + """ + Retrieve a list of audit logs with pagination support. + """ + def get_fullname(id): + user = crud.user.get_by_id(db, id=id) + if user: + return user.username + return "" + + logs = crud.audit.filter(db, obj_in=filter_in) + logs = [ + schemas.Audit( + id=dep.id, + model=dep.model, + username=get_fullname(dep.user_id), + details=dep.details, + action=dep.action, + timestamp=dep.timestamp, + ip_address=dep.ip_address, + ) + for dep in logs + ] + return logs + @router.post("", response_model=schemas.Audit) def get_auditlog( diff --git a/private_gpt/users/crud/audit_crud.py b/private_gpt/users/crud/audit_crud.py index 188a7117..f430d3f7 100644 --- a/private_gpt/users/crud/audit_crud.py +++ b/private_gpt/users/crud/audit_crud.py @@ -1,8 +1,9 @@ from typing import Optional, List +from private_gpt.users import crud from private_gpt.users.crud.base import CRUDBase from private_gpt.users.models.audit import Audit -from private_gpt.users.schemas.audit import AuditCreate, AuditUpdate +from private_gpt.users.schemas.audit import AuditCreate, AuditUpdate, AuditFilter from sqlalchemy import desc from sqlalchemy.orm import Session @@ -13,6 +14,29 @@ class CRUDAudit(CRUDBase[Audit, AuditCreate, AuditUpdate]): ) -> List[Audit]: return db.query(self.model).order_by(desc(self.model.timestamp)).offset(skip).limit(limit).all() + def filter( + self, db: Session, *, obj_in : AuditFilter + ) -> List[Audit]: + + def get_id(username): + user = crud.user.get_by_name(db, name=username) + if user: + return user.id + return None + query = db.query(Audit) + if obj_in.model: + query = query.filter(Audit.model == obj_in.model) + if obj_in.username: + query = query.filter(Audit.user_id == get_id(obj_in.username)) + if obj_in.action: + query = query.filter(Audit.action == obj_in.action) + if obj_in.start_date: + query = query.filter(Audit.timestamp >= obj_in.start_date) + if obj_in.end_date: + query = query.filter(Audit.timestamp <= obj_in.end_date) + + return query.order_by(desc(self.model.timestamp)).offset(obj_in.skip).limit(obj_in.limit).all() + def get_by_id(self, db: Session, *, id: str) -> Optional[Audit]: return db.query(self.model).filter(Audit.id == id).first() diff --git a/private_gpt/users/crud/chat_crud.py b/private_gpt/users/crud/chat_crud.py index 6c709755..15b94c9c 100644 --- a/private_gpt/users/crud/chat_crud.py +++ b/private_gpt/users/crud/chat_crud.py @@ -11,12 +11,20 @@ from private_gpt.users.schemas.chat import ChatHistoryCreate, ChatHistoryCreate, class CRUDChat(CRUDBase[ChatHistory, ChatHistoryCreate, ChatHistoryCreate]): def get_by_id(self, db: Session, *, id: uuid.UUID) -> Optional[ChatHistory]: - return ( - db.query(self.model) - .filter(ChatHistory.conversation_id == id) - .order_by(asc(getattr(ChatHistory, 'created_at'))) - .first() + chat_history = ( + db.query(self.model) + .filter(ChatHistory.conversation_id == id) + .order_by(asc(getattr(ChatHistory, 'created_at'))) + .first() + ) + if chat_history: + chat_history.chat_items = ( + db.query(ChatItem) + .filter(ChatItem.conversation_id == id) + .order_by(asc(getattr(ChatItem, 'index'))) + .all() ) + return chat_history def get_chat_history( self, db: Session, *,user_id:int, skip: int = 0, limit: int = 100 diff --git a/private_gpt/users/schemas/__init__.py b/private_gpt/users/schemas/__init__.py index 5d88d1d7..462328db 100644 --- a/private_gpt/users/schemas/__init__.py +++ b/private_gpt/users/schemas/__init__.py @@ -18,7 +18,7 @@ from .documents import ( from .department import ( Department, DepartmentCreate, DepartmentUpdate, DepartmentAdminCreate, DepartmentDelete ) -from .audit import AuditBase, AuditCreate, AuditUpdate, Audit, GetAudit +from .audit import AuditBase, AuditCreate, AuditUpdate, Audit, GetAudit, AuditFilter from .chat import ( ChatHistory, ChatHistoryBase, ChatHistoryCreate, ChatHistoryUpdate, ChatDelete, ChatItem, ChatItemBase, ChatItemCreate, ChatItemUpdate, CreateChatHistory diff --git a/private_gpt/users/schemas/audit.py b/private_gpt/users/schemas/audit.py index 48b0b543..2ad11bb8 100644 --- a/private_gpt/users/schemas/audit.py +++ b/private_gpt/users/schemas/audit.py @@ -38,4 +38,14 @@ class Audit(BaseModel): class GetAudit(BaseModel): - id: int \ No newline at end of file + id: int + + +class AuditFilter(BaseModel): + skip: Optional[int], + limit: Optional[int], + model: Optional[str] = None + username: Optional[str] = None + action: Optional[str] = None + start_date: Optional[datetime] = None + end_date: Optional[datetime] = None \ No newline at end of file diff --git a/private_gpt/users/schemas/chat.py b/private_gpt/users/schemas/chat.py index 148509a3..b7783d38 100644 --- a/private_gpt/users/schemas/chat.py +++ b/private_gpt/users/schemas/chat.py @@ -20,6 +20,7 @@ class ChatItem(ChatItemBase): id: int created_at: datetime updated_at: datetime + index: int class Config: orm_mode = True @@ -28,6 +29,7 @@ class ChatItem(ChatItemBase): class ChatHistoryBase(BaseModel): user_id: int title: Optional[str] + class ChatHistoryCreate(ChatHistoryBase): @@ -46,9 +48,15 @@ class ChatHistory(ChatHistoryBase): updated_at: datetime chat_items: List[ChatItem] + @property + def ordered_chat_items(self): + return sorted(self.chat_items, key=lambda x: x.index) + class Config: orm_mode = True + + class ChatDelete(BaseModel): conversation_id: uuid.UUID diff --git a/private_gpt/users/utils/export.py b/private_gpt/users/utils/export.py new file mode 100644 index 00000000..e69de29b