jumpserver/apps/reports/api/accouts/account.py

98 lines
3.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# -*- coding: utf-8 -*-
#
from collections import defaultdict
from django.db.models import Count, Q, F, Value
from django.db.models.functions import Concat
from django.http import JsonResponse
from rest_framework.views import APIView
from accounts.models import Account, AccountTemplate
from assets.const import Connectivity
from common.permissions import IsValidLicense
from common.utils import lazyproperty
from rbac.permissions import RBACPermission
from reports.api.assets.base import group_stats
from reports.mixins import DateRangeMixin
__all__ = ['AccountStatisticApi']
class AccountStatisticApi(DateRangeMixin, APIView):
http_method_names = ['get']
# TODO: Define the required RBAC permissions for this API
rbac_perms = {
'GET': 'accounts.view_account',
}
permission_classes = [RBACPermission, IsValidLicense]
@lazyproperty
def base_qs(self):
return Account.objects.all()
@lazyproperty
def template_qs(self):
return AccountTemplate.objects.all()
def get_change_secret_account_metrics(self):
filtered_queryset = self.filter_by_date_range(self.base_qs, 'date_change_secret')
data = defaultdict(set)
for t, _id in filtered_queryset.values_list('date_change_secret', 'id'):
date_str = str(t.date())
data[date_str].add(_id)
metrics = [len(data.get(str(d), set())) for d in self.date_range_list]
return metrics
def get(self, request, *args, **kwargs):
qs = self.base_qs
stats = qs.aggregate(
total=Count(1),
active=Count(1, filter=Q(is_active=True)),
connected=Count(1, filter=Q(connectivity=Connectivity.OK)),
su_from=Count(1, filter=Q(su_from__isnull=False)),
date_change_secret=Count(1, filter=Q(secret_reset=True)),
)
stats['template_total'] = self.template_qs.count()
source_pie_data = [
{'name': str(source), 'value': total}
for source, total in
qs.values('source').annotate(
total=Count(1)
).values_list('source', 'total')
]
by_connectivity = group_stats(
qs, 'label', 'connectivity', Connectivity.as_dict(),
)
top_assets = qs.values('asset__name') \
.annotate(account_count=Count('id')) \
.order_by('-account_count')[:10]
top_version_accounts = qs.annotate(
display_key=Concat(
F('asset__name'),
Value(''),
F('username'),
Value('')
)
).values('display_key', 'version').order_by('-version')[:10]
payload = {
'account_stats': stats,
'top_assets': list(top_assets),
'top_version_accounts': list(top_version_accounts),
'source_pie': source_pie_data,
'by_connectivity': by_connectivity,
'change_secret_account_metrics': {
'dates_metrics_date': self.dates_metrics_date,
'dates_metrics_total': self.get_change_secret_account_metrics(),
}
}
return JsonResponse(payload, status=200)