2020-12-17 15:39:29 +02:00
import json
2021-04-03 12:36:01 -05:00
import logging
2021-08-11 23:29:31 +03:00
import asyncio
2020-12-17 15:39:29 +02:00
2021-08-10 23:17:56 +03:00
from urllib . parse import parse_qsl
2021-09-09 00:01:10 +02:00
from app . classes . models . users import Users
2021-08-10 23:17:56 +03:00
from app . classes . shared . helpers import helper
2021-02-26 17:39:35 +02:00
from app . classes . web . websocket_helper import websocket_helper
2020-12-17 15:39:29 +02:00
2021-04-03 12:36:01 -05:00
logger = logging . getLogger ( __name__ )
2021-08-11 23:29:31 +03:00
try :
import tornado . websocket
except ModuleNotFoundError as e :
logger . critical ( " Import Error: Unable to load {} module " . format ( e , e . name ) )
console . critical ( " Import Error: Unable to load {} module " . format ( e , e . name ) )
sys . exit ( 1 )
2020-12-17 15:39:29 +02:00
2021-03-01 02:54:20 +02:00
class SocketHandler ( tornado . websocket . WebSocketHandler ) :
2021-03-26 15:57:50 +02:00
def initialize ( self , controller = None , tasks_manager = None , translator = None ) :
2021-03-21 23:02:18 -05:00
self . controller = controller
self . tasks_manager = tasks_manager
2021-03-26 15:57:50 +02:00
self . translator = translator
2021-08-11 23:29:31 +03:00
self . io_loop = tornado . ioloop . IOLoop . current ( )
2021-03-21 23:02:18 -05:00
2021-03-01 02:54:20 +02:00
def get_remote_ip ( self ) :
remote_ip = self . request . headers . get ( " X-Real-IP " ) or \
self . request . headers . get ( " X-Forwarded-For " ) or \
self . request . remote_ip
return remote_ip
def check_auth ( self ) :
user_data_cookie_raw = self . get_secure_cookie ( ' user_data ' )
if user_data_cookie_raw and user_data_cookie_raw . decode ( ' utf-8 ' ) :
user_data_cookie = user_data_cookie_raw . decode ( ' utf-8 ' )
user_id = json . loads ( user_data_cookie ) [ ' user_id ' ]
query = Users . select ( ) . where ( Users . user_id == user_id )
if query . exists ( ) :
return True
return False
2020-12-17 15:39:29 +02:00
def open ( self ) :
2021-08-10 23:17:56 +03:00
logger . debug ( ' Checking WebSocket authentication ' )
2021-03-01 02:54:20 +02:00
if self . check_auth ( ) :
self . handle ( )
else :
websocket_helper . send_message ( self , ' notification ' , ' Not authenticated for WebSocket connection ' )
self . close ( )
2021-09-09 00:01:10 +02:00
self . controller . management . add_to_audit_log_raw ( ' unknown ' , 0 , 0 , ' Someone tried to connect via WebSocket without proper authentication ' , self . get_remote_ip ( ) )
2021-03-01 02:54:20 +02:00
websocket_helper . broadcast ( ' notification ' , ' Someone tried to connect via WebSocket without proper authentication ' )
2021-08-10 23:17:56 +03:00
logger . warning ( ' Someone tried to connect via WebSocket without proper authentication ' )
2021-03-01 02:54:20 +02:00
def handle ( self ) :
2021-08-10 23:17:56 +03:00
self . page = self . get_query_argument ( ' page ' )
self . page_query_params = dict ( parse_qsl ( helper . remove_prefix (
self . get_query_argument ( ' page_query_params ' ) ,
' ? '
) ) )
websocket_helper . add_client ( self )
2021-04-03 12:36:01 -05:00
logger . debug ( ' Opened WebSocket connection ' )
2021-03-01 02:54:20 +02:00
# websocket_helper.broadcast('notification', 'New client connected')
2020-12-17 15:39:29 +02:00
2021-01-18 21:34:29 +02:00
def on_message ( self , rawMessage ) :
2020-12-17 15:39:29 +02:00
2021-04-03 12:36:01 -05:00
logger . debug ( ' Got message from WebSocket connection {} ' . format ( rawMessage ) )
2021-01-18 21:34:29 +02:00
message = json . loads ( rawMessage )
2021-04-03 12:36:01 -05:00
logger . debug ( ' Event Type: {} , Data: {} ' . format ( message [ ' event ' ] , message [ ' data ' ] ) )
2020-12-17 15:39:29 +02:00
def on_close ( self ) :
2021-08-10 23:17:56 +03:00
websocket_helper . remove_client ( self )
2021-04-03 12:36:01 -05:00
logger . debug ( ' Closed WebSocket connection ' )
2021-03-01 02:54:20 +02:00
# websocket_helper.broadcast('notification', 'Client disconnected')
2020-12-17 15:39:29 +02:00
2021-08-11 23:29:31 +03:00
async def write_message_int ( self , message ) :
self . write_message ( message )
def write_message_helper ( self , message ) :
asyncio . run_coroutine_threadsafe ( self . write_message_int ( message ) , self . io_loop . asyncio_loop )