Fix: исправлена проверка доступа к чату при загрузке файлов
- Добавлена поддержка разных типов чатов (private, global, department, group) - Для личных чатов проверяется участие через participants - Для чатов отдела проверяется принадлежность к отделу - Для глобального чата проверяется только is_active - Для групповых/канальных чатов используется ChatMembership Настройки CSRF: - CSRF_COOKIE_HTTPONLY = False - CSRF_COOKIE_SAMESITE = 'Lax' - CSRF_USE_SESSIONS = False
This commit is contained in:
parent
3f5c7a8e31
commit
1c040a2c9f
@ -5,7 +5,7 @@ from django.contrib.auth.decorators import login_required
|
||||
from django.db import transaction
|
||||
from django.http import JsonResponse
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.views.decorators.csrf import ensure_csrf_cookie
|
||||
from django.views.decorators.csrf import csrf_protect
|
||||
from django.views.decorators.http import require_POST
|
||||
|
||||
from communications.models import (
|
||||
@ -16,9 +16,9 @@ from communications.models import (
|
||||
)
|
||||
|
||||
|
||||
@csrf_protect
|
||||
@login_required
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
def upload_message_with_attachments(request):
|
||||
"""Отправка сообщения с вложениями"""
|
||||
chat_id = request.POST.get('chat_id')
|
||||
@ -33,18 +33,48 @@ def upload_message_with_attachments(request):
|
||||
chat = get_object_or_404(Chat, pk=chat_id)
|
||||
|
||||
# Проверка доступа к чату
|
||||
membership = ChatMembership.objects.filter(
|
||||
chat=chat,
|
||||
user=request.user,
|
||||
is_active=True,
|
||||
can_send_messages=True
|
||||
).first()
|
||||
|
||||
if not membership:
|
||||
return JsonResponse(
|
||||
{'ok': False, 'error': 'Cannot send messages to this chat'},
|
||||
status=403
|
||||
)
|
||||
# Для групповых, канальных и объявлений проверяем ChatMembership
|
||||
if chat.type in ['group', 'channel', 'announcement']:
|
||||
membership = ChatMembership.objects.filter(
|
||||
chat=chat,
|
||||
user=request.user,
|
||||
is_active=True,
|
||||
can_send_messages=True
|
||||
).first()
|
||||
|
||||
if not membership:
|
||||
return JsonResponse(
|
||||
{'ok': False, 'error': 'Cannot send messages to this chat'},
|
||||
status=403
|
||||
)
|
||||
# Для личных чатов проверяем, что пользователь - участник
|
||||
elif chat.type == 'private':
|
||||
if not chat.participants.filter(id=request.user.id).exists():
|
||||
return JsonResponse(
|
||||
{'ok': False, 'error': 'You are not a participant'},
|
||||
status=403
|
||||
)
|
||||
# Для чатов отдела проверяем принадлежность к отделу
|
||||
elif chat.type == 'department':
|
||||
if chat.department:
|
||||
from employees.models import EmployeeDepartment
|
||||
is_member = EmployeeDepartment.objects.filter(
|
||||
department=chat.department,
|
||||
employee=request.user,
|
||||
is_active=True
|
||||
).exists()
|
||||
if not is_member and chat.department.head_id != request.user.id:
|
||||
return JsonResponse(
|
||||
{'ok': False, 'error': 'Not a department member'},
|
||||
status=403
|
||||
)
|
||||
# Глобальный чат доступен всем активным пользователям
|
||||
elif chat.type == 'global':
|
||||
if not request.user.is_active:
|
||||
return JsonResponse(
|
||||
{'ok': False, 'error': 'User is not active'},
|
||||
status=403
|
||||
)
|
||||
|
||||
# Если нет ни текста, ни файлов
|
||||
if not content and not request.FILES:
|
||||
|
||||
@ -191,6 +191,11 @@ CSRF_TRUSTED_ORIGINS = _split_env_list(
|
||||
os.getenv("CSRF_TRUSTED_ORIGINS", "https://*.sytes.net")
|
||||
)
|
||||
|
||||
# Настройки CSRF для AJAX запросов
|
||||
CSRF_COOKIE_HTTPONLY = False # Позволяет JavaScript читать cookie
|
||||
CSRF_COOKIE_SAMESITE = 'Lax'
|
||||
CSRF_USE_SESSIONS = False
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# EMAIL
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
@ -360,6 +360,13 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
formData.append('chat_id', '{{ chat.id }}');
|
||||
|
||||
const csrftoken = getCookie('csrftoken');
|
||||
console.log('CSRF token:', csrftoken);
|
||||
|
||||
if (!csrftoken) {
|
||||
console.error('CSRF token not found in cookies!');
|
||||
alert('Ошибка: CSRF токен не найден. Обновите страницу.');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/v1/communications/upload-message/', {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user