99 lines
4.2 KiB
Python
99 lines
4.2 KiB
Python
import logging
|
|
import os
|
|
|
|
from django.conf import settings
|
|
from django.db.models import Q
|
|
from django.http import JsonResponse, HttpResponseForbidden, HttpResponseNotFound
|
|
from rest_framework.decorators import action
|
|
from rest_framework.generics import get_object_or_404, GenericAPIView
|
|
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin, DestroyModelMixin
|
|
from rest_framework.viewsets import GenericViewSet
|
|
|
|
from core.mixins import ApiPermissionCheckMixin
|
|
from core.utils import store_file_response
|
|
from devices.services.endpoint.endpoint_antivirus import EndpointAntivirusService
|
|
from perms.models import Perm
|
|
from storage.exception import StorageException
|
|
from storage.models import DataStorage
|
|
from storage.serializers import AntivirusStorageSerializer, StorageSerializer, StorageListSerializer
|
|
|
|
_log = logging.getLogger()
|
|
|
|
|
|
class StorageViewSet(ApiPermissionCheckMixin,
|
|
ListModelMixin,
|
|
RetrieveModelMixin,
|
|
DestroyModelMixin,
|
|
GenericViewSet):
|
|
console_permissions = [Perm.can_view_storage]
|
|
ordering_fields = ['id', 'format', 'size', 'description', 'created', 'filename']
|
|
|
|
def get_serializer_class(self):
|
|
if self.action == 'list':
|
|
return StorageListSerializer
|
|
return StorageSerializer
|
|
|
|
def get_queryset(self):
|
|
queryset = DataStorage.objects
|
|
user = self.request.user
|
|
storage_filter = Q(user=user)
|
|
|
|
if not user.is_superuser:
|
|
if user.has_perm(Perm.perm_req(Perm.can_download_rotation_files)):
|
|
storage_filter |= Q(type=DataStorage.Type.DB_DUMP)
|
|
queryset = queryset.filter(storage_filter).distinct()
|
|
return queryset.all()
|
|
|
|
class Meta:
|
|
model = DataStorage
|
|
|
|
@action(detail=True, name='download', methods=['GET'])
|
|
def download(self, request, *args, **kwargs):
|
|
cur = get_object_or_404(DataStorage, pk=kwargs['pk'])
|
|
if cur.type == DataStorage.Type.DB_DUMP and not request.user.has_perm(
|
|
Perm.perm_req(Perm.can_download_rotation_files)):
|
|
_log.error(
|
|
f'User [{request.user}] try to get storage with id [{cur.id}] without permissions [can_download_rotation_files] ')
|
|
return HttpResponseForbidden()
|
|
|
|
# Check that user owns this file
|
|
if not request.user.is_superuser and cur.type != DataStorage.Type.DB_DUMP:
|
|
if request.user != cur.user:
|
|
_log.error(f'User [{request.user}] try to get storage with id [{id}] that belongs to [{cur.user}]')
|
|
return HttpResponseForbidden()
|
|
|
|
# Check that file exists
|
|
file_path = os.path.join(settings.MEDIA_ROOT, cur.file.name)
|
|
if not os.path.exists(file_path):
|
|
_log.error(f'User [{request.user}] try to download file [{cur.pk}:{cur.file.name}] but file doesnt exist')
|
|
return HttpResponseNotFound()
|
|
|
|
_log.info(f'User [{request.user}] start download file [{cur.pk}:{cur.file.name}]')
|
|
cur.save()
|
|
return store_file_response(file_path)
|
|
|
|
|
|
class AntivirusStorageView(ApiPermissionCheckMixin,
|
|
GenericAPIView):
|
|
serializer_class = AntivirusStorageSerializer
|
|
console_permissions = [Perm.can_view_storage]
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
if 'file' not in request.FILES:
|
|
raise StorageException({'status': 'error', 'detail': 'Upload file is required'})
|
|
# Calculating file size for storage instance info
|
|
file = request.FILES['file']
|
|
file.seek(0, os.SEEK_END)
|
|
file_length = file.tell()
|
|
# Setting up necessary service field values for storage field
|
|
request.data['user'] = request.user.pk
|
|
request.data['size'] = file_length
|
|
serializer = self.get_serializer(data=request.data)
|
|
if serializer.is_valid():
|
|
DataStorage.objects.filter(format=DataStorage.Type.CLAMAV).delete()
|
|
serializer.save()
|
|
_log.info('Update ClamAV signature database in storage')
|
|
EndpointAntivirusService.all_update(True)
|
|
return JsonResponse({'status': 'ok'})
|
|
else:
|
|
raise StorageException({'status': 'err', 'message': serializer.errors})
|