mirror of https://github.com/jumpserver/jumpserver
98 lines
3.2 KiB
Python
98 lines
3.2 KiB
Python
# -*- 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)
|