From c4cd85bb9d4a895e32e46bf172a8f295ea1d9ca9 Mon Sep 17 00:00:00 2001
From: Samuel Gaist <samuel.gaist@idiap.ch>
Date: Tue, 17 Jul 2018 17:51:07 +0200
Subject: [PATCH] [utils][commands] Add django command to get users active on
 the site

This commands allows to retrieve the list of users who have a
session opened on the site. Note that this does not mean that they
are currently using the web site, just that they have logged in.

This can be useful when needing to do an unplanned reboot of the
platform for security reasons to warn potentially affected users.
---
 .../management/commands/list_active_users.py  | 78 +++++++++++++++++++
 1 file changed, 78 insertions(+)
 create mode 100644 beat/web/utils/management/commands/list_active_users.py

diff --git a/beat/web/utils/management/commands/list_active_users.py b/beat/web/utils/management/commands/list_active_users.py
new file mode 100644
index 000000000..df3ffd28e
--- /dev/null
+++ b/beat/web/utils/management/commands/list_active_users.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python
+# vim: set fileencoding=utf-8 :
+# encoding: utf-8
+
+###############################################################################
+#                                                                             #
+# Copyright (c) 2018 Idiap Research Institute, http://www.idiap.ch/           #
+# Contact: beat.support@idiap.ch                                              #
+#                                                                             #
+# This file is part of the beat.web module of the BEAT platform.              #
+#                                                                             #
+# Commercial License Usage                                                    #
+# Licensees holding valid commercial BEAT licenses may use this file in       #
+# accordance with the terms contained in a written agreement between you      #
+# and Idiap. For further information contact tto@idiap.ch                     #
+#                                                                             #
+# Alternatively, this file may be used under the terms of the GNU Affero      #
+# Public License version 3 as published by the Free Software and appearing    #
+# in the file LICENSE.AGPL included in the packaging of this file.            #
+# The BEAT platform is distributed in the hope that it will be useful, but    #
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY  #
+# or FITNESS FOR A PARTICULAR PURPOSE.                                        #
+#                                                                             #
+# You should have received a copy of the GNU Affero Public License along      #
+# with the BEAT platform. If not, see http://www.gnu.org/licenses/.           #
+#                                                                             #
+###############################################################################
+
+
+from django.core.management.base import BaseCommand, CommandError
+from django.contrib.auth.models import User
+from django.contrib.sessions.models import Session
+from django.utils import timezone
+
+
+def get_current_users():
+    """
+    Get the list of users active on the site.
+
+    Works better if the configuration of the site has:
+
+        SESSION_EXPIRE_AT_BROWSER_CLOSE = True
+
+    Inspired from:
+    https://www.codingforentrepreneurs.com/blog/django-tutorial-get-list-of-current-users/
+    """
+
+    active_sessions = Session.objects.filter(expire_date__gte=timezone.now())
+    user_id_list = []
+    for session in active_sessions:
+        data = session.get_decoded()
+        user_id_list.append(data.get('_auth_user_id', None))
+    # Query all logged in users based on id list
+    return User.objects.filter(id__in=user_id_list)
+
+
+class Command(BaseCommand):
+
+    help = 'Get active users'
+
+    def add_arguments(self, parser):
+        parser.add_argument('--email', '-e', action='store_true',
+                        dest='show_email', default=False, help='Set this flag'\
+                        'to also print email addresse')
+        parser.add_argument('--only-email', '-o', action='store_true',
+                        dest='show_only_email', default=False, help='Set this'\
+                        'flag to only print email addresse')
+
+    def handle(self, *args, **options):
+        current_users = get_current_users()
+        for user in current_users:
+            if options['show_only_email']:
+                print(user.email)
+            else:
+                user_data = "{} {}".format(user.first_name, user.last_name)
+                if options['show_email']:
+                    user_data += " {}".format(user.email)
+                print(user_data)
\ No newline at end of file
-- 
GitLab