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
|
2021-08-10 23:17:56 +03:00
|
|
|
from urllib.parse import parse_qsl
|
2022-04-11 00:23:55 -05:00
|
|
|
import tornado.websocket
|
2022-01-26 01:45:30 +00:00
|
|
|
|
2023-08-09 23:47:53 +02:00
|
|
|
from app.classes.shared.main_controller import Controller
|
2022-04-11 00:23:55 -05:00
|
|
|
from app.classes.shared.helpers import Helpers
|
2023-09-05 23:00:52 +02:00
|
|
|
from app.classes.shared.websocket_manager import WebSocketManager
|
2020-12-17 15:39:29 +02:00
|
|
|
|
2022-03-08 04:40:44 +00:00
|
|
|
logger = logging.getLogger(__name__)
|
2022-01-15 02:23:50 +02:00
|
|
|
|
2022-03-23 02:50:12 +00:00
|
|
|
|
2023-09-05 23:08:40 +02:00
|
|
|
class WebSocketHandler(tornado.websocket.WebSocketHandler):
|
2022-01-15 02:23:50 +02:00
|
|
|
page = None
|
|
|
|
page_query_params = None
|
2023-08-09 23:47:53 +02:00
|
|
|
controller: Controller = None
|
2022-01-15 02:23:50 +02:00
|
|
|
tasks_manager = None
|
|
|
|
translator = None
|
|
|
|
io_loop = None
|
2021-03-01 02:54:20 +02:00
|
|
|
|
2022-04-11 11:08:36 +01:00
|
|
|
def initialize(
|
2023-08-31 21:35:30 -04:00
|
|
|
self,
|
|
|
|
helper=None,
|
|
|
|
controller=None,
|
|
|
|
tasks_manager=None,
|
|
|
|
translator=None,
|
|
|
|
file_helper=None,
|
2022-04-11 11:08:36 +01:00
|
|
|
):
|
2022-04-11 00:23:55 -05:00
|
|
|
self.helper = helper
|
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
|
2023-08-31 21:35:30 -04:00
|
|
|
self.file_helper = file_helper
|
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):
|
2022-03-23 02:50:12 +00:00
|
|
|
remote_ip = (
|
|
|
|
self.request.headers.get("X-Real-IP")
|
|
|
|
or self.request.headers.get("X-Forwarded-For")
|
|
|
|
or self.request.remote_ip
|
|
|
|
)
|
2021-03-01 02:54:20 +02:00
|
|
|
return remote_ip
|
|
|
|
|
2022-01-26 01:45:30 +00:00
|
|
|
# pylint: disable=arguments-differ
|
2020-12-17 15:39:29 +02:00
|
|
|
def open(self):
|
2022-03-23 02:50:12 +00:00
|
|
|
logger.debug("Checking WebSocket authentication")
|
2021-03-01 02:54:20 +02:00
|
|
|
if self.check_auth():
|
|
|
|
self.handle()
|
|
|
|
else:
|
2023-08-09 23:47:53 +02:00
|
|
|
WebSocketManager().broadcast_to_admins(
|
2022-03-23 02:50:12 +00:00
|
|
|
self, "notification", "Not authenticated for WebSocket connection"
|
|
|
|
)
|
2023-08-09 23:47:53 +02:00
|
|
|
self.close(1011, "Forbidden WS Access")
|
2022-03-23 02:50:12 +00: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(),
|
|
|
|
)
|
2023-08-09 23:47:53 +02:00
|
|
|
WebSocketManager().broadcast(
|
2022-03-23 02:50:12 +00:00
|
|
|
"notification",
|
|
|
|
"Someone tried to connect via WebSocket without proper authentication",
|
|
|
|
)
|
|
|
|
logger.warning(
|
|
|
|
"Someone tried to connect via WebSocket without proper authentication"
|
|
|
|
)
|
2021-03-01 02:54:20 +02:00
|
|
|
|
|
|
|
def handle(self):
|
2022-03-23 02:50:12 +00:00
|
|
|
self.page = self.get_query_argument("page")
|
|
|
|
self.page_query_params = dict(
|
|
|
|
parse_qsl(
|
2022-04-11 00:23:55 -05:00
|
|
|
Helpers.remove_prefix(self.get_query_argument("page_query_params"), "?")
|
2022-03-23 02:50:12 +00:00
|
|
|
)
|
|
|
|
)
|
2023-08-09 23:47:53 +02:00
|
|
|
WebSocketManager().add_client(self)
|
2022-03-23 02:50:12 +00:00
|
|
|
logger.debug("Opened WebSocket connection")
|
2023-09-05 23:08:40 +02:00
|
|
|
|
|
|
|
# pylint: disable=arguments-renamed
|
|
|
|
def on_message(self, raw_message):
|
|
|
|
logger.debug(f"Got message from WebSocket connection {raw_message}")
|
|
|
|
message = json.loads(raw_message)
|
|
|
|
logger.debug(f"Event Type: {message['event']}, Data: {message['data']}")
|
|
|
|
|
|
|
|
def on_close(self):
|
|
|
|
WebSocketManager().remove_client(self)
|
|
|
|
logger.debug("Closed WebSocket connection")
|
|
|
|
|
|
|
|
async def write_message_int(self, message):
|
|
|
|
self.write_message(message)
|
|
|
|
|
|
|
|
def write_message_async(self, message):
|
|
|
|
asyncio.run_coroutine_threadsafe(
|
|
|
|
self.write_message_int(message), self.io_loop.asyncio_loop
|
|
|
|
)
|
|
|
|
|
|
|
|
def send_message(self, event_type: str, data):
|
|
|
|
message = str(json.dumps({"event": event_type, "data": data}))
|
|
|
|
self.write_message_async(message)
|
|
|
|
|
|
|
|
def get_user_id(self):
|
|
|
|
_, _, user = self.controller.authentication.check(self.get_cookie("token"))
|
|
|
|
return user["user_id"]
|
|
|
|
|
|
|
|
def check_auth(self):
|
|
|
|
return self.controller.authentication.check_bool(self.get_cookie("token"))
|