From 181973f23549c06edaca20d7c7ef809f7a192c96 Mon Sep 17 00:00:00 2001 From: Bai Date: Fri, 8 May 2020 15:41:56 +0800 Subject: [PATCH] =?UTF-8?q?[Update]=20=E4=BC=98=E5=8C=96=E4=BB=AA=E8=A1=A8?= =?UTF-8?q?=E7=9B=98=E9=A1=B5=E9=9D=A2=E5=8A=A0=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jumpserver/api.py | 295 ++++++++++++++++++++++++++ apps/jumpserver/urls.py | 3 +- apps/jumpserver/views/index.py | 236 +-------------------- apps/templates/index.html | 376 +++++++++++++++++++++++---------- 4 files changed, 557 insertions(+), 353 deletions(-) create mode 100644 apps/jumpserver/api.py diff --git a/apps/jumpserver/api.py b/apps/jumpserver/api.py new file mode 100644 index 000000000..e272c9ff3 --- /dev/null +++ b/apps/jumpserver/api.py @@ -0,0 +1,295 @@ +from django.core.cache import cache +from django.utils import timezone +from django.utils.timesince import timesince +from django.db.models import Count, Max +from django.http.response import JsonResponse +from rest_framework.views import APIView +from collections import Counter + +from users.models import User +from assets.models import Asset +from terminal.models import Session +from orgs.utils import current_org +from common.permissions import IsOrgAdmin +from common.utils import lazyproperty + +__all__ = ['IndexApi'] + + +class MonthLoginMetricMixin: + + @lazyproperty + def session_month(self): + month_ago = timezone.now() - timezone.timedelta(days=30) + session_month = Session.objects.filter(date_start__gt=month_ago) + return session_month + + @lazyproperty + def session_month_dates(self): + dates = self.session_month.dates('date_start', 'day') + return dates + + def get_month_metrics_date(self): + month_metrics_date = [d.strftime('%m-%d') for d in self.session_month_dates] or ['0'] + return month_metrics_date + + @staticmethod + def get_cache_key(date, tp): + date_str = date.strftime("%Y%m%d") + key = "SESSION_MONTH_{}_{}".format(tp, date_str) + return key + + def __get_data_from_cache(self, date, tp): + if date == timezone.now().date(): + return None + cache_key = self.get_cache_key(date, tp) + count = cache.get(cache_key) + return count + + def __set_data_to_cache(self, date, tp, count): + cache_key = self.get_cache_key(date, tp) + cache.set(cache_key, count, 3600*24*7) + + @staticmethod + def get_date_start_2_end(d): + time_min = timezone.datetime.min.time() + time_max = timezone.datetime.max.time() + tz = timezone.get_current_timezone() + ds = timezone.datetime.combine(d, time_min).replace(tzinfo=tz) + de = timezone.datetime.combine(d, time_max).replace(tzinfo=tz) + return ds, de + + def get_date_login_count(self, date): + tp = "LOGIN" + count = self.__get_data_from_cache(date, tp) + if count is not None: + return count + ds, de = self.get_date_start_2_end(date) + count = Session.objects.filter(date_start__range=(ds, de)).count() + self.__set_data_to_cache(date, tp, count) + return count + + def get_month_metrics_total_count_login(self): + data = [] + for d in self.session_month_dates: + count = self.get_date_login_count(d) + data.append(count) + if len(data) == 0: + data = [0] + return data + + def get_date_user_count(self, date): + tp = "USER" + count = self.__get_data_from_cache(date, tp) + if count is not None: + return count + ds, de = self.get_date_start_2_end(date) + count = len(set(Session.objects.filter(date_start__range=(ds, de)).values_list('user', flat=True))) + self.__set_data_to_cache(date, tp, count) + return count + + def get_month_metrics_total_count_active_users(self): + data = [] + for d in self.session_month_dates: + count = self.get_date_user_count(d) + data.append(count) + return data + + def get_date_asset_count(self, date): + tp = "ASSET" + count = self.__get_data_from_cache(date, tp) + if count is not None: + return count + ds, de = self.get_date_start_2_end(date) + count = len(set(Session.objects.filter(date_start__range=(ds, de)).values_list('asset', flat=True))) + self.__set_data_to_cache(date, tp, count) + return count + + def get_month_metrics_total_count_active_assets(self): + data = [] + for d in self.session_month_dates: + count = self.get_date_asset_count(d) + data.append(count) + return data + + @lazyproperty + def month_total_count_active_users(self): + count = len(set(self.session_month.values_list('user', flat=True))) + return count + + @lazyproperty + def month_total_count_inactive_users(self): + total = current_org.get_org_members().count() + active = self.month_total_count_active_users + count = total - active + if count < 0: + count = 0 + return count + + @lazyproperty + def month_total_count_disabled_users(self): + return current_org.get_org_members().filter(is_active=False).count() + + @lazyproperty + def month_total_count_active_assets(self): + return len(set(self.session_month.values_list('asset', flat=True))) + + @lazyproperty + def month_total_count_inactive_assets(self): + total = Asset.objects.all().count() + active = self.month_total_count_active_assets + count = total - active + if count < 0: + count = 0 + return count + + @lazyproperty + def month_total_count_disabled_assets(self): + return Asset.objects.filter(is_active=False).count() + + +class WeekSessionMetricMixin: + session_week = None + + @lazyproperty + def session_week(self): + week_ago = timezone.now() - timezone.timedelta(weeks=1) + session_week = Session.objects.filter(date_start__gt=week_ago) + return session_week + + def get_week_login_times_top5_users(self): + users = self.session_week.values_list('user', flat=True) + users = [ + {'user': user, 'total': total} + for user, total in Counter(users).most_common(5) + ] + return users + + def get_week_total_count_login_users(self): + return len(set(self.session_week.values_list('user', flat=True))) + + def get_week_total_count_login_times(self): + return self.session_week.count() + + def get_week_login_times_top10_assets(self): + assets = self.session_week.values("asset")\ + .annotate(total=Count("asset"))\ + .annotate(last=Max("date_start")).order_by("-total")[:10] + for asset in assets: + asset['last'] = str(asset['last']) + return list(assets) + + def get_week_login_times_top10_users(self): + users = self.session_week.values("user") \ + .annotate(total=Count("user")) \ + .annotate(last=Max("date_start")).order_by("-total")[:10] + for user in users: + user['last'] = str(user['last']) + return list(users) + + def get_week_login_record_top10_sessions(self): + sessions = self.session_week.order_by('-date_start')[:10] + for session in sessions: + session.avatar_url = User.get_avatar_url("") + sessions = [ + { + 'user': session.user, + 'asset': session.asset, + 'is_finished': session.is_finished, + 'date_start': str(session.date_start), + 'timesince': timesince(session.date_start) + } + for session in sessions + ] + return sessions + + +class TotalCountMixin: + @staticmethod + def get_total_count_users(): + return current_org.get_org_members().count() + + @staticmethod + def get_total_count_assets(): + return Asset.objects.all().count() + + @staticmethod + def get_total_count_online_users(): + count = len(set(Session.objects.filter(is_finished=False).values_list('user', flat=True))) + return count + + @staticmethod + def get_total_count_online_assets(): + return Session.objects.filter(is_finished=False).count() + + +class IndexApi(TotalCountMixin, WeekSessionMetricMixin, MonthLoginMetricMixin, APIView): + permission_classes = (IsOrgAdmin,) + http_method_names = ['get'] + + def get(self, request, *args, **kwargs): + data = {} + + query_params = self.request.query_params + + _all = query_params.get('all') + + if _all or query_params.get('total_count'): + data.update({ + 'total_count_assets': self.get_total_count_assets(), + 'total_count_users': self.get_total_count_users(), + 'total_count_online_users': self.get_total_count_online_users(), + 'total_count_online_assets': self.get_total_count_online_assets(), + }) + + if _all or query_params.get('month_metrics'): + data.update({ + 'month_metrics_date': self.get_month_metrics_date(), + 'month_metrics_total_count_login': self.get_month_metrics_total_count_login(), + 'month_metrics_total_count_active_users': self.get_month_metrics_total_count_active_users(), + 'month_metrics_total_count_active_assets': self.get_month_metrics_total_count_active_assets(), + }) + + if _all or query_params.get('month_total_count_users'): + data.update({ + 'month_total_count_active_users': self.month_total_count_active_users, + 'month_total_count_inactive_users': self.month_total_count_inactive_users, + 'month_total_count_disabled_users': self.month_total_count_disabled_users, + }) + + if _all or query_params.get('month_total_count_assets'): + data.update({ + 'month_total_count_active_assets': self.month_total_count_active_assets, + 'month_total_count_inactive_assets': self.month_total_count_inactive_assets, + 'month_total_count_disabled_assets': self.month_total_count_disabled_assets, + }) + + if _all or query_params.get('week_total_count'): + data.update({ + 'week_total_count_login_users': self.get_week_total_count_login_users(), + 'week_total_count_login_times': self.get_week_total_count_login_times(), + }) + + if _all or query_params.get('week_login_times_top5_users'): + data.update({ + 'week_login_times_top5_users': self.get_week_login_times_top5_users(), + }) + + if _all or query_params.get('week_login_times_top10_assets'): + data.update({ + 'week_login_times_top10_assets': self.get_week_login_times_top10_assets(), + }) + + if _all or query_params.get('week_login_times_top10_users'): + data.update({ + 'week_login_times_top10_users': self.get_week_login_times_top10_users(), + }) + + if _all or query_params.get('week_login_record_top10_sessions'): + data.update({ + 'week_login_record_top10_sessions': self.get_week_login_record_top10_sessions() + }) + + return JsonResponse(data, status=200) + + diff --git a/apps/jumpserver/urls.py b/apps/jumpserver/urls.py index c4653969b..ade854397 100644 --- a/apps/jumpserver/urls.py +++ b/apps/jumpserver/urls.py @@ -7,9 +7,10 @@ from django.conf.urls.static import static from django.conf.urls.i18n import i18n_patterns from django.views.i18n import JavaScriptCatalog -from . import views +from . import views, api api_v1 = [ + path('index/', api.IndexApi.as_view()), path('users/', include('users.urls.api_urls', namespace='api-users')), path('assets/', include('assets.urls.api_urls', namespace='api-assets')), path('perms/', include('perms.urls.api_urls', namespace='api-perms')), diff --git a/apps/jumpserver/views/index.py b/apps/jumpserver/views/index.py index 1bcb2a57e..ffcb10493 100644 --- a/apps/jumpserver/views/index.py +++ b/apps/jumpserver/views/index.py @@ -1,224 +1,12 @@ -from django.core.cache import cache from django.views.generic import TemplateView -from django.utils import timezone from django.utils.translation import ugettext_lazy as _ -from django.db.models import Count, Max from django.shortcuts import redirect - -from users.models import User -from assets.models import Asset -from terminal.models import Session -from orgs.utils import current_org from common.permissions import PermissionsMixin, IsValidUser -from common.utils import timeit, lazyproperty __all__ = ['IndexView'] -class MonthLoginMetricMixin: - @lazyproperty - def session_month(self): - month_ago = timezone.now() - timezone.timedelta(days=30) - session_month = Session.objects.filter(date_start__gt=month_ago) - return session_month - - @lazyproperty - def session_month_dates(self): - dates = self.session_month.dates('date_start', 'day') - return dates - - def get_month_day_metrics(self): - month_str = [ - d.strftime('%m-%d') for d in self.session_month_dates - ] or ['0'] - return month_str - - @staticmethod - def get_cache_key(date, tp): - date_str = date.strftime("%Y%m%d") - key = "SESSION_MONTH_{}_{}".format(tp, date_str) - return key - - def __get_data_from_cache(self, date, tp): - if date == timezone.now().date(): - return None - cache_key = self.get_cache_key(date, tp) - count = cache.get(cache_key) - return count - - def __set_data_to_cache(self, date, tp, count): - cache_key = self.get_cache_key(date, tp) - cache.set(cache_key, count, 3600*24*7) - - @lazyproperty - def user_disabled_total(self): - return current_org.get_org_members().filter(is_active=False).count() - - @lazyproperty - def asset_disabled_total(self): - return Asset.objects.filter(is_active=False).count() - - @staticmethod - def get_date_start_2_end(d): - time_min = timezone.datetime.min.time() - time_max = timezone.datetime.max.time() - tz = timezone.get_current_timezone() - ds = timezone.datetime.combine(d, time_min).replace(tzinfo=tz) - de = timezone.datetime.combine(d, time_max).replace(tzinfo=tz) - return ds, de - - def get_date_login_count(self, date): - tp = "LOGIN" - count = self.__get_data_from_cache(date, tp) - if count is not None: - return count - ds, de = self.get_date_start_2_end(date) - count = Session.objects.filter(date_start__range=(ds, de)).count() - self.__set_data_to_cache(date, tp, count) - return count - - def get_month_login_metrics(self): - data = [] - for d in self.session_month_dates: - count = self.get_date_login_count(d) - data.append(count) - if len(data) == 0: - data = [0] - return data - - def get_date_user_count(self, date): - tp = "USER" - count = self.__get_data_from_cache(date, tp) - if count is not None: - return count - ds, de = self.get_date_start_2_end(date) - count = Session.objects.filter(date_start__range=(ds, de))\ - .values('user').distinct().count() - self.__set_data_to_cache(date, tp, count) - return count - - def get_month_active_user_metrics(self): - data = [] - for d in self.session_month_dates: - count = self.get_date_user_count(d) - data.append(count) - return data - - def get_date_asset_count(self, date): - tp = "ASSET" - count = self.__get_data_from_cache(date, tp) - if count is not None: - return count - ds, de = self.get_date_start_2_end(date) - count = Session.objects.filter(date_start__range=(ds, de)) \ - .values('asset').distinct().count() - self.__set_data_to_cache(date, tp, count) - return count - - def get_month_active_asset_metrics(self): - data = [] - for d in self.session_month_dates: - count = self.get_date_asset_count(d) - data.append(count) - return data - - @lazyproperty - def month_active_user_total(self): - count = self.session_month.values('user').distinct().count() - return count - - @lazyproperty - def month_inactive_user_total(self): - total = current_org.get_org_members().count() - active = self.month_active_user_total - count = total - active - if count < 0: - count = 0 - return count - - @lazyproperty - def month_active_asset_total(self): - return self.session_month.values('asset').distinct().count() - - @lazyproperty - def month_inactive_asset_total(self): - total = Asset.objects.all().count() - active = self.month_active_asset_total - count = total - active - if count < 0: - count = 0 - return count - - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - context.update({ - 'month_str': self.get_month_day_metrics(), - 'month_total_visit_count': self.get_month_login_metrics(), - 'month_user': self.get_month_active_user_metrics(), - 'mouth_asset': self.get_month_active_asset_metrics(), - 'month_user_active': self.month_active_user_total, - 'month_user_inactive': self.month_inactive_user_total, - 'month_user_disabled': self.user_disabled_total, - 'month_asset_active': self.month_active_asset_total, - 'month_asset_inactive': self.month_inactive_asset_total, - 'month_asset_disabled': self.asset_disabled_total, - }) - return context - - -class WeekSessionMetricMixin: - session_week = None - - @lazyproperty - def session_week(self): - week_ago = timezone.now() - timezone.timedelta(weeks=1) - session_week = Session.objects.filter(date_start__gt=week_ago) - return session_week - - def get_top5_user_a_week(self): - users = self.session_week.values('user') \ - .annotate(total=Count('user')) \ - .order_by('-total')[:5] - return users - - def get_week_login_user_count(self): - return self.session_week.values('user').distinct().count() - - def get_week_login_asset_count(self): - return self.session_week.count() - - def get_week_top10_assets(self): - assets = self.session_week.values("asset")\ - .annotate(total=Count("asset"))\ - .annotate(last=Max("date_start")).order_by("-total")[:10] - return assets - - def get_week_top10_users(self): - users = self.session_week.values("user") \ - .annotate(total=Count("user")) \ - .annotate(last=Max("date_start")).order_by("-total")[:10] - return users - - def get_last10_sessions(self): - sessions = self.session_week.order_by('-date_start')[:10] - for session in sessions: - session.avatar_url = User.get_avatar_url("") - return sessions - - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - context.update({ - 'user_visit_count_weekly': self.get_week_login_user_count(), - 'asset_visit_count_weekly': self.get_week_login_asset_count(), - 'user_visit_count_top_five': self.get_top5_user_a_week(), - 'last_login_ten': self.get_last10_sessions(), - 'week_asset_hot_ten': self.get_week_top10_assets(), - 'week_user_hot_ten': self.get_week_top10_users(), - }) - return context - - -class IndexView(PermissionsMixin, MonthLoginMetricMixin, WeekSessionMetricMixin, TemplateView): +class IndexView(PermissionsMixin, TemplateView): template_name = 'index.html' permission_classes = [IsValidUser] @@ -229,31 +17,9 @@ class IndexView(PermissionsMixin, MonthLoginMetricMixin, WeekSessionMetricMixin, return redirect('assets:user-asset-list') return super(IndexView, self).dispatch(request, *args, **kwargs) - @staticmethod - def get_user_count(): - return current_org.get_org_members().count() - - @staticmethod - def get_asset_count(): - return Asset.objects.all().count() - - @staticmethod - def get_online_user_count(): - count = Session.objects.filter(is_finished=False)\ - .values_list('user', flat=True).distinct().count() - return count - - @staticmethod - def get_online_session_count(): - return Session.objects.filter(is_finished=False).count() - def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context.update({ - 'assets_count': self.get_asset_count(), - 'users_count': self.get_user_count(), - 'online_user_count': self.get_online_user_count(), - 'online_asset_count': self.get_online_session_count(), 'app': _("Dashboard"), }) return context diff --git a/apps/templates/index.html b/apps/templates/index.html index b667f473d..36f57137c 100644 --- a/apps/templates/index.html +++ b/apps/templates/index.html @@ -11,7 +11,7 @@
{% trans 'Total users' %}
-

{{ users_count }}

+

All users
@@ -19,12 +19,12 @@
- Hosts -
{% trans 'Total hosts' %}
+ Assets +
{% trans 'Total assets' %}
-

{{ assets_count }}

- All hosts +

+ All assets
@@ -36,7 +36,7 @@
{% trans 'Online users' %}
-

{{ online_user_count }}

+

Online users
@@ -50,7 +50,7 @@
-

{{ online_asset_count }}

+

Online sessions
@@ -58,19 +58,11 @@
- {% trans 'In the past week, a total of ' %}{{ user_visit_count_weekly }}{% trans ' users have logged in ' %}{{ asset_visit_count_weekly }}{% trans ' times asset.' %} -
    - {% for data in user_visit_count_top_five %} -
  • - - {{ data.total }}{% trans ' times/week' %} - - {{ forloop.counter }} {{ data.user }} -
  • - {% endfor %} + {% trans 'In the past week, a total of ' %}{% trans ' users have logged in ' %}{% trans ' times asset.' %} +
-
+

@@ -81,13 +73,13 @@

-
+
{% trans 'User' %}
-
-
{% trans 'Host' %}
+
+
{% trans 'Asset' %}
@@ -120,27 +112,7 @@

{% trans 'Top 10 assets in a week'%}

{% trans 'Login frequency and last login record.' %}
-
- {% if week_asset_hot_ten %} - {% for data in week_asset_hot_ten %} -
-
-
- - {{ data.asset }} -
- {{ data.total }}{% trans ' times' %} -
-
-

{% trans 'The time last logged in' %}

-

{% trans 'At' %} {{ data.last|date:"Y-m-d H:i:s" }}

-
-
-
- {% endfor %} - {% else %} -

{% trans '(No)' %}

- {% endif %} +
@@ -158,27 +130,7 @@

-
- {% if last_login_ten %} - {% for login in last_login_ten %} -
- - image - -
- {% ifequal login.is_finished 0 %} - {{ login.date_start|timesince }} {% trans 'Before' %} - {% else %} - {{ login.date_start|timesince }} {% trans 'Before' %} - {% endifequal %} - {{ login.user }} {% trans 'Login in ' %}{{ login.asset }}
- {{ login.date_start }} -
-
- {% endfor %} - {% else %} -

{% trans '(No)' %}

- {% endif %} +
@@ -206,27 +158,7 @@

{% trans 'Top 10 users in a week' %}

{% trans 'User login frequency and last login record.' %}
-
- {% if week_user_hot_ten %} - {% for data in week_user_hot_ten %} -
-
-
- - {{ data.user }} -
- {{ data.total }}{% trans ' times' %} -
-
-

{% trans 'The time last logged in' %}

-

{% trans 'At' %} {{ data.last|date:"Y-m-d H:i:s" }}

-
-
-
- {% endfor %} - {% else %} -

{% trans '(No)' %}

- {% endif %} +
@@ -238,27 +170,15 @@ {% block custom_foot_js %} {% endblock %}