summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlejandro Sirgo Rica <asirgo@soleta.eu>2024-11-13 19:41:20 +0100
committerAlejandro Sirgo Rica <asirgo@soleta.eu>2024-11-21 17:19:27 +0100
commit0bc485e2c4ccdc5e117bbb9f12d85e926ba7deac (patch)
tree276f51d2c303f520a398aac8ddcbdfe560d6ddb7 /src
parentbd921dcbd69526c22cd5f2acf60f6ab528e50c04 (diff)
src: add user session detection implementationwinlinux
Detect user login and logout for Linux and Windows. Report an active interactive session through the /refresh response so a new ogserver instance can update the session status. Poll the session change in 5 second intervals in a thread. Use the same event socket previously used by the old session detection mechanism to notify a session change. Use the method check_interactive_session_change in each ogOperations.py to report the session status. Return values: None: no session changes are found True: login False: logout Windows check_interactive_session_change uses the WMI API to obtain session information. Obtain the list of sessions associated to interactive sessions and then filter the sessions with a valid user. Linux Check if any user has the DISPLAY or WAYLAND_DISPLAY environment variable defined as that means there is an interactive session in execution.
Diffstat (limited to 'src')
-rw-r--r--src/linux/ogOperations.py30
-rw-r--r--src/live/ogOperations.py3
-rw-r--r--src/ogClient.py24
-rw-r--r--src/ogRest.py3
-rw-r--r--src/virtual/ogOperations.py3
-rw-r--r--src/windows/ogOperations.py32
6 files changed, 92 insertions, 3 deletions
diff --git a/src/linux/ogOperations.py b/src/linux/ogOperations.py
index 4728201..10efaa4 100644
--- a/src/linux/ogOperations.py
+++ b/src/linux/ogOperations.py
@@ -7,6 +7,7 @@
# (at your option) any later version.
import os
+import psutil
import subprocess
from subprocess import CalledProcessError
from src.log import OgError
@@ -15,6 +16,9 @@ from src.ogRest import ThreadState
class OgLinuxOperations:
+ def __init__(self):
+ self.session = False
+
def _restartBrowser(self, url):
raise OgError('Function not implemented')
@@ -66,4 +70,28 @@ class OgLinuxOperations:
raise OgError('Function not implemented')
def refresh(self, ogRest):
- return {"status": "LINUX"}
+ if self.session:
+ session_value = 'LINUXS'
+ else:
+ session_value = 'LINUX'
+ return {"status": session_value}
+
+ def check_interactive_session_change(self):
+ old_status = self.session
+ has_logged_user = False
+ for user in psutil.users():
+ if user.terminal:
+ try:
+ process = psutil.Process(user.pid)
+ env = process.environ()
+ if "DISPLAY" in env or "WAYLAND_DISPLAY" in env:
+ has_logged_user = True
+ break
+
+ except (psutil.NoSuchProcess, psutil.AccessDenied):
+ continue
+ self.session = has_logged_user
+
+ if self.session != old_status:
+ return self.session
+ return None
diff --git a/src/live/ogOperations.py b/src/live/ogOperations.py
index 2666606..ef18e33 100644
--- a/src/live/ogOperations.py
+++ b/src/live/ogOperations.py
@@ -837,3 +837,6 @@ class OgLiveOperations:
logging.info('Sending response to refresh request')
return json_body
+
+ def check_interactive_session_change(self):
+ return False
diff --git a/src/ogClient.py b/src/ogClient.py
index 51aa33b..2635a3f 100644
--- a/src/ogClient.py
+++ b/src/ogClient.py
@@ -6,6 +6,7 @@
# Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
+import threading
import errno
import select
import socket
@@ -26,6 +27,8 @@ class State(Enum):
class ogClient:
OG_PATH = '/opt/opengnsys/'
+ SESSION_POLL_INTERVAL = 5
+ EVENT_SOCKET_PORT = 55885
def __init__(self, config):
self.CONFIG = config
@@ -36,7 +39,7 @@ class ogClient:
if self.mode in {'linux', 'windows'}:
self.event_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.event_sock.setblocking(0)
- self.event_sock.bind(('127.0.0.1', 55885))
+ self.event_sock.bind(('127.0.0.1', ogClient.EVENT_SOCKET_PORT))
else:
self.event_sock = None
@@ -49,6 +52,25 @@ class ogClient:
self.ogrest = ogRest(self.CONFIG)
self.seq = None
+ self.session_check_thread = threading.Thread(target=self._session_check_loop, daemon=True)
+ self.session_check_thread.start()
+
+ def _session_check_loop(self):
+ while True:
+ session_status = self.ogrest.check_interactive_session_change()
+ if session_status is True:
+ message = "session start user"
+ elif session_status is False:
+ message = "session stop user"
+ else:
+ message = None
+
+ if message:
+ self.event_sock.sendto(message.encode('utf-8'),
+ ('127.0.0.1', ogClient.EVENT_SOCKET_PORT))
+
+ time.sleep(ogClient.SESSION_POLL_INTERVAL)
+
def get_socket(self):
return self.sock
diff --git a/src/ogRest.py b/src/ogRest.py
index 7511c76..5731350 100644
--- a/src/ogRest.py
+++ b/src/ogRest.py
@@ -443,3 +443,6 @@ class ogRest():
def process_refresh(self, client):
threading.Thread(target=ogThread.refresh, args=(client, self,)).start()
+
+ def check_interactive_session_change(self):
+ return self.operations.check_interactive_session_change()
diff --git a/src/virtual/ogOperations.py b/src/virtual/ogOperations.py
index c51f59d..86ae0ed 100644
--- a/src/virtual/ogOperations.py
+++ b/src/virtual/ogOperations.py
@@ -629,3 +629,6 @@ class OgVirtualOperations:
for k, v in device_names.items():
f.write(f'{k}={v}\n')
f.truncate()
+
+ def check_interactive_session_change(self):
+ return None
diff --git a/src/windows/ogOperations.py b/src/windows/ogOperations.py
index 8c98da7..6396811 100644
--- a/src/windows/ogOperations.py
+++ b/src/windows/ogOperations.py
@@ -8,11 +8,13 @@
import os
import ctypes
+import pythoncom
import subprocess
from subprocess import CalledProcessError
import multiprocessing as mp
from multiprocessing import Process, freeze_support
from src.log import OgError
+import wmi
from PIL import Image, ImageDraw
from pystray import Icon, Menu, MenuItem
@@ -64,6 +66,7 @@ def create_systray():
class OgWindowsOperations:
def __init__(self):
+ self.session = False
freeze_support()
mp.set_start_method('spawn')
self.systray_p = Process(target=create_systray, daemon=True)
@@ -125,4 +128,31 @@ class OgWindowsOperations:
raise OgError('Function not implemented')
def refresh(self, ogRest):
- return {"status": "WIN"}
+ if self.session:
+ session_value = 'WINS'
+ else:
+ session_value = 'WIN'
+ return {"status": session_value}
+
+ def check_interactive_session_change(self):
+ old_status = self.session
+ pythoncom.CoInitialize()
+ has_logged_user = False
+ try:
+ c = wmi.WMI()
+ sessions = c.Win32_LogonSession(LogonType=2)
+
+ for session in sessions:
+ if has_logged_user:
+ break
+ for user in session.associators("Win32_LoggedOnUser"):
+ if user and user.AccountType == 1:
+ has_logged_user = True
+ break
+ finally:
+ pythoncom.CoUninitialize()
+ self.session = has_logged_user
+
+ if self.session != old_status:
+ return self.session
+ return None