diff --git a/apps/audits/api.py b/apps/audits/api.py index 82774f512..d60eeb523 100644 --- a/apps/audits/api.py +++ b/apps/audits/api.py @@ -32,7 +32,7 @@ from rbac.permissions import RBACPermission from terminal.models import default_storage from users.models import User from .backends import TYPE_ENGINE_MAPPING -from .const import ActivityChoices +from .const import ActivityChoices, ActionChoices from .filters import UserSessionFilterSet, OperateLogFilterSet from .models import ( FTPLog, UserLoginLog, OperateLog, PasswordChangeLog, @@ -45,7 +45,7 @@ from .serializers import ( FileSerializer, UserSessionSerializer, JobsAuditSerializer, ServiceAccessLogSerializer ) -from .utils import construct_userlogin_usernames +from .utils import construct_userlogin_usernames, record_operate_log_and_activity_log logger = get_logger(__name__) @@ -126,6 +126,11 @@ class FTPLogViewSet(OrgModelViewSet): response['Content-Type'] = 'application/octet-stream' filename = escape_uri_path(ftp_log.filename) response["Content-Disposition"] = "attachment; filename*=UTF-8''{}".format(filename) + + record_operate_log_and_activity_log( + [ftp_log.id], ActionChoices.download, '', self.model, + resource_display=f'{ftp_log.asset}: {ftp_log.filename}', + ) return response @action(methods=[POST], detail=True, permission_classes=[IsServiceAccount, ], serializer_class=FileSerializer) diff --git a/apps/audits/models.py b/apps/audits/models.py index 10b1479c1..1072c7b6e 100644 --- a/apps/audits/models.py +++ b/apps/audits/models.py @@ -73,6 +73,9 @@ class FTPLog(OrgModelMixin): models.Index(fields=['date_start', 'org_id'], name='idx_date_start_org'), ] + def __str__(self): + return "{0.id} of {0.user} to {0.asset}".format(self) + @property def filepath(self): return os.path.join(self.upload_to, self.date_start.strftime('%Y-%m-%d'), str(self.id)) diff --git a/apps/audits/utils.py b/apps/audits/utils.py index 4d743da60..1f3149321 100644 --- a/apps/audits/utils.py +++ b/apps/audits/utils.py @@ -1,5 +1,6 @@ import copy from datetime import datetime +from itertools import chain from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation from django.core.exceptions import ObjectDoesNotExist @@ -7,7 +8,6 @@ from django.db import models from django.db.models import F, Value, CharField from django.db.models.functions import Concat from django.utils import translation -from itertools import chain from common.db.fields import RelatedManager from common.utils import validate_ip, get_ip_city, get_logger @@ -16,7 +16,6 @@ from .const import DEFAULT_CITY, ActivityChoices as LogChoice from .handler import create_or_update_operate_log from .models import ActivityLog - logger = get_logger(__name__) @@ -151,7 +150,7 @@ def record_operate_log_and_activity_log(ids, action, detail, model, **kwargs): org_id = current_org.id with translation.override('en'): - resource_type = model._meta.verbose_name + resource_type = kwargs.pop('resource_type', None) or model._meta.verbose_name create_or_update_operate_log(action, resource_type, force=True, **kwargs) base_data = {'type': LogChoice.operate_log, 'detail': detail, 'org_id': org_id} activities = [ActivityLog(resource_id=r_id, **base_data) for r_id in ids] diff --git a/apps/terminal/api/session/session.py b/apps/terminal/api/session/session.py index 317a7b824..581566216 100644 --- a/apps/terminal/api/session/session.py +++ b/apps/terminal/api/session/session.py @@ -154,8 +154,8 @@ class SessionViewSet(OrgBulkModelViewSet): REPLAY_OP, self.request.user, _('Download'), str(session) ) record_operate_log_and_activity_log( - [session.asset_id], ActionChoices.download, detail, - model=Session, resource_display=str(session) + [session.asset_id], ActionChoices.download, detail, Session, + resource_display=f'{session.asset}', resource_type=_('Session replay') ) return response @@ -284,8 +284,8 @@ class SessionReplayViewSet(AsyncApiMixin, viewsets.ViewSet): REPLAY_OP, self.request.user, _('View'), str(session) ) record_operate_log_and_activity_log( - [session.asset_id], ActionChoices.download, detail, - model=Session, resource_display=str(session) + [session.asset_id], ActionChoices.download, detail, Session, + resource_display=f'{session.asset}', resource_type=_('Session replay') ) def retrieve(self, request, *args, **kwargs):