• BaiJiangJie's avatar
    Dev (#2838) · 9ca4a8c9
    BaiJiangJie authored
    * Dev ansible windows 2 (#2783)
    
    * [Update] 改密支持windows
    
    * [Update] 修改asset表结构
    
    * [Feature] Windows支持批量改密、测试可连接性等功能
    
    * [Update] 处理创建资产时labels的问题
    
    * [Update] 优化测试管理系统、系统用户可连接性任务执行逻辑
    
    * [Update] 优化ansible任务逻辑;添加自动推送rdp系统用户功能
    
    * [Update] 添加翻译
    
    * [Update] 优化ansible任务逻辑(测试系统用户可连接性, 通过协议过滤资产)
    
    * [Update] 更新翻译
    
    * [Update] 更新翻译
    
    * [Update] 推送windows系统用户,默认添加到Users、Remote Desktop Users组中
    
    * [Update] 优化小细节
    
    * [Update] 更新翻译,删除多余代码
    
    * [Update] 更新翻译信息
    
    * [Bugfix] 修复windows推送系统用户小bug (#2794)
    
    * [Update] 邮件设置添加配置项:发送账号 (#2796)
    
    * [Bugfix] 和资产相关的Serializer添加protocols字段; (#2800)
    
    * [Bugfix] 和资产相关的Serializer添加protocols字段;
    
    * [Bugfix] RemoteApp Form 修改过滤RDP协议资产
    
    * [Bugfix] 修改小问题
    
    * [Update] 用户授权相关API,如果需要切换到root org (#2803)
    
    * [Update] 用户授权相关API,如果需要切换到root org
    
    * [Update] 优化小问题
    
    * [Update] 增加审计员权限控制 (#2792)
    
    * [Update] 审计员
    
    * [Update] 增加审计员的权限控制
    
    * [Update] 增加审计员Api全校的控制
    
    * [Update] 优化auditor的api权限控制
    
    * [Update] 优化审计员权限控制
    
    * [Update]优化管理员权限的View
    
    * [Update] 优化超级管理权限的View
    
    * [Update] 添加审计员切换组织查询会话管理数据
    
    * [Update] 前端禁用审计员在线会话终断按钮
    
    * [Update]优化细节问题
    
    * [Update] Auth Info (#2806)
    
    * [Update] 修改支持auth info导出
    
    * [Update] 统一认证查看
    
    * [Update] 修改auth book manager
    
    * [Update] 修改auth info
    
    * [Update] 完成修改auth info
    
    * [Update] 优化api
    
    * [Update] 修改assets 的related
    
    * [Update] serializer mixin继承 (#2810)
    
    * [Update] serializer mixin继承
    
    * [Update] 修改system user更新serialzier
    
    * [Update] 修改success message
    
    * [Update] 添加一键禁用LDAP认证脚本 (#2813)
    
    * [Update] 修改资产创建格式
    
    * [Update] 兼容之前的protocols格式
    
    * [Update] Merge master_bugfix to dev_bugfix (#2817)
    
    * [Update] 邮件设置添加配置项:发送账号 (#2795)
    
    * [Bugfix] 修复普通用户被授权的RemoteApp列表加载为空的bug
    
    * [Bugfix] 修复普通用户加载被授权的RemoteApp为空的bug
    
    * [Update] 修改邮件测试的接受者为发送者
    
    * [Update] 修改小问题
    
    * [Update] 修改资产授权序列类返回资产protocols的协议格式/, 同时添加protocol和port字段
    
    * [Update] 修改文案 (#2823)
    
    * [Update] 修改文案
    
    * [Update] 修改文案2
    
    * [Bugfix] 修复资产没有管理用户时获取connectivity字段失败的bug
    
    * [Update] 优化测试可连接性时结果获取 (#2825)
    
    * [Update] 修改资产使用patch方法更新时页面不提示messages信息
    
    * [Update] 添加迁移文件,修改设置资产可连接性时管理用户为None的bug
    
    * [Update] 修改org.middleware自动切换组织的bug (#2829)
    
    * [Update] 修改org.middleware自动切换组织的bug
    
    * [Update] 将切换组织逻辑移动到PermsUtil中
    
    * [Update] 修改首页组织名称显示来源
    9ca4a8c9
views.py 10.2 KB
import csv
import json
import uuid
import codecs


from django.conf import settings
from django.urls import reverse
from django.utils import timezone
from django.core.cache import cache
from django.http import HttpResponse, JsonResponse
from django.utils.decorators import method_decorator
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from django.views.generic import ListView
from django.utils.translation import ugettext as _
from django.db.models import Q

from audits.utils import get_excel_response, write_content_to_excel
from common.mixins import DatetimeSearchMixin
from common.permissions import PermissionsMixin, IsOrgAdmin, IsAuditor, IsValidUser

from orgs.utils import current_org
from ops.views import CommandExecutionListView as UserCommandExecutionListView
from .models import FTPLog, OperateLog, PasswordChangeLog, UserLoginLog


def get_resource_type_list():
    from users.models import User, UserGroup
    from assets.models import (
        Asset, Node, AdminUser, SystemUser, Domain, Gateway, CommandFilter,
        CommandFilterRule,
    )
    from orgs.models import Organization
    from perms.models import AssetPermission

    models = [
        User, UserGroup, Asset, Node, AdminUser, SystemUser, Domain,
        Gateway, Organization, AssetPermission, CommandFilter, CommandFilterRule
    ]
    return [model._meta.verbose_name for model in models]


class FTPLogListView(PermissionsMixin, DatetimeSearchMixin, ListView):
    model = FTPLog
    template_name = 'audits/ftp_log_list.html'
    paginate_by = settings.DISPLAY_PER_PAGE
    user = asset = system_user = filename = ''
    date_from = date_to = None
    permission_classes = [IsOrgAdmin | IsAuditor]

    def get_queryset(self):
        self.queryset = super().get_queryset()
        self.user = self.request.GET.get('user')
        self.asset = self.request.GET.get('asset')
        self.system_user = self.request.GET.get('system_user')
        self.filename = self.request.GET.get('filename', '')

        filter_kwargs = dict()
        filter_kwargs['date_start__gt'] = self.date_from
        filter_kwargs['date_start__lt'] = self.date_to
        if self.user:
            filter_kwargs['user'] = self.user
        if self.asset:
            filter_kwargs['asset'] = self.asset
        if self.system_user:
            filter_kwargs['system_user'] = self.system_user
        if self.filename:
            filter_kwargs['filename__contains'] = self.filename
        if filter_kwargs:
            self.queryset = self.queryset.filter(**filter_kwargs).order_by('-date_start')
        return self.queryset

    def get_context_data(self, **kwargs):
        context = {
            'user_list': FTPLog.objects.values_list('user', flat=True).distinct(),
            'asset_list': FTPLog.objects.values_list('asset', flat=True).distinct(),
            'system_user_list': FTPLog.objects.values_list('system_user', flat=True).distinct(),
            'date_from': self.date_from,
            'date_to': self.date_to,
            'user': self.user,
            'asset': self.asset,
            'system_user': self.system_user,
            'filename': self.filename,
            "app": _("Audits"),
            "action": _("FTP log"),
        }
        kwargs.update(context)
        return super().get_context_data(**kwargs)


class OperateLogListView(PermissionsMixin, DatetimeSearchMixin, ListView):
    model = OperateLog
    template_name = 'audits/operate_log_list.html'
    paginate_by = settings.DISPLAY_PER_PAGE
    user = action = resource_type = ''
    date_from = date_to = None
    actions_dict = dict(OperateLog.ACTION_CHOICES)
    permission_classes = [IsOrgAdmin | IsAuditor]

    def get_queryset(self):
        self.queryset = super().get_queryset()
        self.user = self.request.GET.get('user')
        self.action = self.request.GET.get('action')
        self.resource_type = self.request.GET.get('resource_type')

        filter_kwargs = dict()
        filter_kwargs['datetime__gt'] = self.date_from
        filter_kwargs['datetime__lt'] = self.date_to
        if self.user:
            filter_kwargs['user'] = self.user
        if self.action:
            filter_kwargs['action'] = self.action
        if self.resource_type:
            filter_kwargs['resource_type'] = self.resource_type
        if filter_kwargs:
            self.queryset = self.queryset.filter(**filter_kwargs).order_by('-datetime')
        return self.queryset

    def get_context_data(self, **kwargs):
        context = {
            'user_list': current_org.get_org_users(),
            'actions': self.actions_dict,
            'resource_type_list': get_resource_type_list(),
            'date_from': self.date_from,
            'date_to': self.date_to,
            'user': self.user,
            'resource_type': self.resource_type,
            "app": _("Audits"),
            "action": _("Operate log"),
        }
        kwargs.update(context)
        return super().get_context_data(**kwargs)


class PasswordChangeLogList(PermissionsMixin, DatetimeSearchMixin, ListView):
    model = PasswordChangeLog
    template_name = 'audits/password_change_log_list.html'
    paginate_by = settings.DISPLAY_PER_PAGE
    user = ''
    date_from = date_to = None
    permission_classes = [IsOrgAdmin | IsAuditor]

    def get_queryset(self):
        users = current_org.get_org_users()
        self.queryset = super().get_queryset().filter(
            user__in=[user.__str__() for user in users]
        )
        self.user = self.request.GET.get('user')

        filter_kwargs = dict()
        filter_kwargs['datetime__gt'] = self.date_from
        filter_kwargs['datetime__lt'] = self.date_to
        if self.user:
            filter_kwargs['user'] = self.user
        if filter_kwargs:
            self.queryset = self.queryset.filter(**filter_kwargs).order_by('-datetime')
        return self.queryset

    def get_context_data(self, **kwargs):
        context = {
            'user_list': current_org.get_org_users(),
            'date_from': self.date_from,
            'date_to': self.date_to,
            'user': self.user,
            "app": _("Audits"),
            "action": _("Password change log"),
        }
        kwargs.update(context)
        return super().get_context_data(**kwargs)


class LoginLogListView(PermissionsMixin, DatetimeSearchMixin, ListView):
    template_name = 'audits/login_log_list.html'
    model = UserLoginLog
    paginate_by = settings.DISPLAY_PER_PAGE
    user = keyword = ""
    date_to = date_from = None
    permission_classes = [IsOrgAdmin | IsAuditor]

    @staticmethod
    def get_org_users():
        users = current_org.get_org_users().values_list('username', flat=True)
        return users

    def get_queryset(self):
        if current_org.is_default():
            queryset = super().get_queryset()
        else:
            users = self.get_org_users()
            queryset = super().get_queryset().filter(username__in=users)

        self.user = self.request.GET.get('user', '')
        self.keyword = self.request.GET.get("keyword", '')

        queryset = queryset.filter(
            datetime__gt=self.date_from, datetime__lt=self.date_to
        )
        if self.user:
            queryset = queryset.filter(username=self.user)
        if self.keyword:
            queryset = queryset.filter(
                Q(ip__contains=self.keyword) |
                Q(city__contains=self.keyword) |
                Q(username__contains=self.keyword)
            )
        return queryset

    def get_context_data(self, **kwargs):
        context = {
            'app': _('Audits'),
            'action': _('Login log'),
            'date_from': self.date_from,
            'date_to': self.date_to,
            'user': self.user,
            'keyword': self.keyword,
            'user_list': self.get_org_users(),
        }
        kwargs.update(context)
        return super().get_context_data(**kwargs)


class CommandExecutionListView(UserCommandExecutionListView):
    user_id = None

    def get_queryset(self):
        queryset = self._get_queryset()
        self.user_id = self.request.GET.get('user')
        org_users = self.get_user_list()
        if self.user_id:
            queryset = queryset.filter(user=self.user_id)
        else:
            queryset = queryset.filter(user__in=org_users)
        return queryset

    def get_user_list(self):
        users = current_org.get_org_users()
        return users

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context.update({
            'app': _('Audits'),
            'action': _('Command execution log'),
            'date_from': self.date_from,
            'date_to': self.date_to,
            'user_list': self.get_user_list(),
            'keyword': self.keyword,
            'user_id': self.user_id,
        })
        return context


@method_decorator(csrf_exempt, name='dispatch')
class LoginLogExportView(PermissionsMixin, View):
    permission_classes = [IsValidUser]

    def get(self, request):
        fields = [
            field for field in UserLoginLog._meta.fields
        ]
        filename = 'login-logs-{}.csv'.format(
            timezone.localtime(timezone.now()).strftime('%Y-%m-%d_%H-%M-%S')
        )
        excel_response = get_excel_response(filename)
        header = [field.verbose_name for field in fields]
        login_logs = cache.get(request.GET.get('spm', ''), [])

        response = write_content_to_excel(excel_response, login_logs=login_logs,
                                          header=header, fields=fields)
        return response

    def post(self, request):
        try:
            date_form = json.loads(request.body).get('date_form', [])
            date_to = json.loads(request.body).get('date_to', [])
            user = json.loads(request.body).get('user', [])
            keyword = json.loads(request.body).get('keyword', [])

            login_logs = UserLoginLog.get_login_logs(
                date_form=date_form, date_to=date_to, user=user, keyword=keyword)
        except ValueError:
            return HttpResponse('Json object not valid', status=400)
        spm = uuid.uuid4().hex
        cache.set(spm, login_logs, 300)
        url = reverse('audits:login-log-export') + '?spm=%s' % spm
        return JsonResponse({'redirect': url})