server/backend/mlmAccess.py
Dorian Zedler c8d5b4a7f3
- Delete obsolete users
- Alter pairing credentials to allow panel pairing
- Start working on panel workflow
2021-08-23 13:59:38 +02:00

125 lines
No EOL
4.2 KiB
Python
Executable file

#!/usr/bin/python3
import paho.mqtt.client as mqtt
from dbHelper import MaDbHelper
from pairingHandler import MaPairingHandler
import logging, coloredlogs, os, sys, random, string
coloredlogs.install(level='INFO', fmt='%(asctime)s - [%(levelname)s] %(message)s')
class MlmAccess:
def __init__(self):
logging.info("=== MlmAccess ===")
self._config = self._readConfig()
self._initDb()
self._initMqtt()
self._pairingHanlder = MaPairingHandler(self._mqtt, self._db)
self._mqtt.loop_forever()
def _initDb(self):
logging.info("Initializing Database")
self._db = MaDbHelper(self._config)
initUsers = [
("backend", self._config["MQTT_BACKEND_PASSWORD"], ["mlmAccess/#"], ["mlmAccess/#"]),
("pair", self._config["PAIR_SECRET"], ["mlmAccess/pair/request/#"], ["mlmAccess/pair/response/#"])
]
for username, password, publishAclPatterns, subscribeAclPatterns in initUsers:
if not self._db.addUser(username, password, publishAclPatterns, subscribeAclPatterns):
self._db.updateUser(username, password, publishAclPatterns, subscribeAclPatterns)
obsoleteSystemUsers = ["pair-actor"]
for username in obsoleteSystemUsers:
self._db.deleteUser(username)
def _initMqtt(self):
logging.info("Initializing MQTT")
self._mqtt = client = mqtt.Client(client_id="backend")
self._mqtt.username_pw_set("backend", self._config["MQTT_BACKEND_PASSWORD"])
self._mqtt.on_connect = self._mqttOnConnect
self._mqtt.on_message = self._mqttOnMessage
self._mqtt.connect(self._config["MQTT_HOST"], self._config["MQTT_PORT"], 60)
def _mqttOnConnect(self, client, userdata, flags, rc):
if rc != 0:
logging.error(f"Error connecting to MQTT broker: {rc}")
return
logging.info("Successfully connected to MQTT broker")
logging.info("Subscribing to actor subjects:")
for user in self._db.getAllUsers():
if user.startswith("actor-"):
actorSubject = f"mlmAccess/actor/{user.replace('actor-', '')}/status"
elif user.startswith("panel-"):
actorSubject = "mlmAccess/panel"
else:
continue
logging.info(f"* {actorSubject}")
client.subscribe(actorSubject)
# call hooks of child objects
self._pairingHanlder._mqttOnConnect(client, userdata, flags, rc)
def _mqttOnMessage(self, client, userdata, message):
topic = message.topic
topic = topic.replace("mlmAccess/", "")
messageContent = str(message.payload.decode("utf-8"))
logging.info(f"Message on topic {topic}: {messageContent}")
if topic.startswith("pair"):
self._pairingHanlder.handlePairingRequest(topic, messageContent)
def _readConfig(self):
configKeyPrefix = "MLMACCESS_"
requiredConfigKeys = [
'MYSQL_USER',
'MYSQL_PASSWORD',
'MYSQL_DATABASE',
'PAIR_SECRET'
]
allowedConfigKeys = [
'MYSQL_HOST',
'MYSQL_PORT',
'MQTT_HOST',
'MQTT_PORT',
]
backendPassword = ''.join(random.choices(string.ascii_uppercase + string.ascii_lowercase + string.digits, k=20))
config = {
"MYSQL_HOST": "mysql",
"MYSQL_PORT": 4306,
"MQTT_HOST": "mqtt",
"MQTT_PORT": 1883,
"MQTT_BACKEND_PASSWORD": backendPassword
}
for configKey in requiredConfigKeys:
if configKeyPrefix + configKey not in os.environ:
logging.error(f"Required environment value {configKeyPrefix + configKey} is not set")
sys.exit(1)
config[configKey] = os.environ[configKeyPrefix + configKey]
for configKey in allowedConfigKeys:
if configKeyPrefix + configKey in os.environ:
config[configKey] = os.environ[configKeyPrefix + configKey]
logging.info("CONFIG:")
for key, value in config.items():
logging.info(" * {:25}: {}".format(key, value))
return config
if __name__ == "__main__":
MlmAccess()