feat: Restrict user-status endpoint to department members and chat partners

- Only return users from same department as current user
- Include users with existing private chat conversations
- Remove current user from results for privacy
- Improve performance by limiting user list
This commit is contained in:
DGSoft 2025-12-12 11:29:13 +01:00
parent cfd7068af5
commit 382d4ac3f0

View File

@ -6,7 +6,7 @@ from app.database import create_db_and_tables, get_session
from app.config import get_settings
from app.routers import auth, departments, channels, messages, files, websocket, snippets, admin, direct_messages, kanban
from app.auth import get_current_user
from app.models import User
from app.models import User, DirectMessage, Department
from sqlmodel import Session, select
settings = get_settings()
@ -79,23 +79,36 @@ def health_check():
@app.get("/user-status")
def get_user_statuses(session: Session = Depends(get_session), current_user: User = Depends(get_current_user)):
"""Get online status for all users"""
"""Get online status for users in same department and users with existing private chats"""
from app.websocket import manager
# Get all users
statement = select(User)
users = session.exec(statement).all()
# Get users from same department
department_users = []
if current_user.departments:
dept_ids = [dept.id for dept in current_user.departments]
dept_statement = select(User).where(User.departments.any(Department.id.in_(dept_ids)))
department_users = session.exec(dept_statement).all()
# Get users with existing private chats (either as sender or receiver)
chat_partners_statement = select(User).where(
(User.id == DirectMessage.sender_id) | (User.id == DirectMessage.receiver_id)
).where(
(DirectMessage.sender_id == current_user.id) | (DirectMessage.receiver_id == current_user.id)
).distinct()
chat_partners = session.exec(chat_partners_statement).all()
# Combine and deduplicate users
all_users = list(set(department_users + chat_partners))
# Remove current user from the list
all_users = [user for user in all_users if user.id != current_user.id]
# Get their statuses
statuses = manager.get_all_user_statuses()
# Build response
result = []
for user in users:
for user in all_users:
status = statuses.get(user.id, "offline")
# If user has no WebSocket connection but is the current user, mark as online
if status == "offline" and user.id == current_user.id:
status = "online"
result.append({
"user_id": user.id,
"username": user.username,