src: add user session detection implementation

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
Verify if psutil.users() has any value.

Linux
Verify all the psutil.users() asociated to a terminal.
master
Alejandro Sirgo Rica 2024-11-13 19:41:20 +01:00
parent a1bd0c36f3
commit a36c4daa23
6 changed files with 73 additions and 3 deletions

View File

@ -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,21 @@ 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:
has_logged_user = True
break
self.session = has_logged_user
if self.session != old_status:
return self.session
return None

View File

@ -837,3 +837,6 @@ class OgLiveOperations:
logging.info('Sending response to refresh request')
return json_body
def check_interactive_session_change(self):
return False

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -8,6 +8,7 @@
import os
import ctypes
import psutil
import subprocess
from subprocess import CalledProcessError
import multiprocessing as mp
@ -64,6 +65,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)
@ -122,4 +124,20 @@ 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
has_logged_user = False
for user in psutil.users():
has_logged_user = True
break
self.session = has_logged_user
if self.session != old_status:
return self.session
return None