You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
3.9 KiB
118 lines
3.9 KiB
from .events import SystemEvent
|
|
|
|
try:
|
|
from autobahn.websocket import WebSocketServerProtocol
|
|
except ImportError:
|
|
WebSocketServerProtocol = object
|
|
|
|
def WebSocketClientHandlerFactory(config, clients, event_store, server_status):
|
|
"""Factory method for webhook request handler class"""
|
|
|
|
class WebSocketClientHandler(WebSocketServerProtocol, object):
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self._config = config
|
|
self.clients = clients
|
|
self._event_store = event_store
|
|
self._server_status = server_status
|
|
import logging
|
|
self.logger = logging.getLogger()
|
|
super(WebSocketClientHandler, self).__init__(*args, **kwargs)
|
|
|
|
def onConnect(self, request):
|
|
self.logger.info("Client connecting: {0}".format(request.peer))
|
|
|
|
# Web UI needs to be enabled
|
|
if not self.validate_web_ui_enabled():
|
|
return
|
|
|
|
# Client needs to be whitelisted
|
|
if not self.validate_web_ui_whitelist():
|
|
return
|
|
|
|
def onOpen(self):
|
|
self.logger.info("WebSocket connection open.")
|
|
|
|
def onMessage(self, payload, isBinary):
|
|
import json
|
|
|
|
if isBinary:
|
|
return
|
|
|
|
try:
|
|
data = json.loads(payload)
|
|
|
|
# Handle authentication requests
|
|
if 'type' in data and data['type'] == 'authenticate':
|
|
|
|
# Verify auth key
|
|
if 'auth-key' in data and data['auth-key'] == self._server_status['auth-key']:
|
|
self.clients.append(self)
|
|
|
|
# Let the client know that they are authenticated
|
|
self.sendMessage(json.dumps({
|
|
"type": "authenticated"
|
|
}))
|
|
return
|
|
|
|
else:
|
|
self.logger.error("Recieved bad auth key.")
|
|
|
|
self.sendMessage(json.dumps({
|
|
"type": "bad-auth-key"
|
|
}))
|
|
return
|
|
|
|
except Exception as e:
|
|
|
|
self.logger.error("Unable to interpret incoming message: %s" % e)
|
|
|
|
if self not in self.clients:
|
|
self.logger.error("Recieved message form unauthenticated client, closing connection.")
|
|
self.sendClose()
|
|
return
|
|
|
|
#self.logger.info("WebSocket connection open.")
|
|
#if isBinary:
|
|
# self.logger.info("Binary message received: {0} bytes".format(len(payload)))
|
|
#else:
|
|
# self.logger.info("Text message received: {0}".format(payload.decode('utf8')))
|
|
|
|
#for client in self.clients:
|
|
# client.sendMessage(payload, isBinary)
|
|
|
|
# echo back message verbatim
|
|
#self.sendMessage(payload, isBinary)
|
|
|
|
def onClose(self, wasClean, code, reason):
|
|
self.logger.info("WebSocket connection closed: {0}".format(reason))
|
|
|
|
if self in self.clients:
|
|
self.clients.remove(self)
|
|
|
|
def validate_web_ui_enabled(self):
|
|
"""Verify that the Web UI is enabled"""
|
|
|
|
if self._config['web-ui-enabled']:
|
|
return True
|
|
|
|
self.sendClose()
|
|
return False
|
|
|
|
def validate_web_ui_whitelist(self):
|
|
"""Verify that the client address is whitelisted"""
|
|
|
|
# Allow all if whitelist is empty
|
|
if len(self._config['web-ui-whitelist']) == 0:
|
|
return True
|
|
|
|
# Verify that client IP is whitelisted
|
|
if self.peer.host in self._config['web-ui-whitelist']:
|
|
return True
|
|
|
|
self.sendClose()
|
|
logger.info("Unautorized connection attempt from %s" % self.peer.host)
|
|
return False
|
|
|
|
return WebSocketClientHandler
|