from paho.mqtt import client as mqtt_client from keycloak import KeycloakAdmin import json import mysql.connector import os broker = 'mosquitto' port = 1883 client_id = f'FabMan' KEYCLOAK_URL = "http://keycloak:8080/auth/" KEYCLOAK_USERNAME = os.environ['KEYCLOAK_USER_NAME'] KEYCLOAK_PASSWORD = os.environ['KEYCLOAK_USER_PW'] REALM = os.environ['KEYCLOAK_REALM'] FabDB = mysql.connector.connect( host="FabDB", user=os.environ['FABDB_DB_USER_NAME'], password=os.environ['FABDB_DB_USER_PW'], database=os.environ['FABDB_DB_NAME'] ) def connect_mqtt(): def on_connect(client, userdata, flags, rc): if rc == 0: print("Connected to MQTT Broker!") else: print("Failed to connect, return code %d\n", rc) client = mqtt_client.Client(client_id) client.username_pw_set("admin", "user") client.on_connect = on_connect client.connect(broker, port) return client def publish(client,topic,msg): result = client.publish(topic, msg) # result: [0, 1] status = result[0] if status == 0: #print(f"Send `{msg}` to topic `{topic}`") pass else: print(f"Failed to send message to topic {topic}") def changePlug(client,PlugID,state): publish(client,f"/FabLogging/{PlugID}/POWER",state) cmd = ["OFF", "On"][state] publish(client,f"/aktoren/{PlugID}/cmnd/POWER",cmd) def changeDisplay(client,MachineID,status,text): publish(client,f"/cmnd/reader/{MachineID}",'{"Cmd": "message", "MssgID": %s , "ClrTxt":"" , "AddnTxt":"%s"}' % ((status), (text))) def checkPermission(UserPermsJSON,PermissionPath): permission = False error = 0 MachinePermArray = PermissionPath.split(".") for UserPerm in UserPermsJSON: #print(f"check {UserPerm}") UserPermArray = UserPerm.split(".") x = 0 for UserPermPart in UserPermArray: if(error == 0): #print(f"Compare {UserPermPart} and {MachinePermArray[x]}") if not (MachinePermArray[x] == UserPermPart): if(UserPermPart == "*"): #print("* regelt") permission = True else: error = 1 #print(f"MISmatch between {MachinePermArray[x]} and {UserPermPart}") else: pass #print(f"Match between {MachinePermArray[x]} and {UserPermPart}") x = x + 1 if(error == 1): pass #print("Error") else: #print("Hurra") permission = True error = 0 return permission def msg_handler(msg,client): print("") print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic") topic = msg.topic MQTT_KEY = json.loads(msg.payload.decode())["UID"] keycloak_admin = KeycloakAdmin( server_url=KEYCLOAK_URL, username=KEYCLOAK_USERNAME, password=KEYCLOAK_PASSWORD, realm_name=REALM, verify=True) users = keycloak_admin.get_users({}) knownUser = False ReaderID = msg.topic.split("/")[-1] for user in users: try: FabCardID = user['attributes']['FabCard'][0] UserPermissions = user['attributes']['FabPermissions'][0] if (FabCardID == MQTT_KEY): knownUser = True print(f"FabCard matches with user {user['username']}") mycursor = FabDB.cursor() mycursor.execute(f'SELECT PlugName,PermissionPath,Status,LastUser FROM ReaderPlug WHERE ReaderID="{ReaderID}";') myValues = mycursor.fetchall()[0] PlugID = myValues[0] PermissionPath = myValues[1] MachineStatus = myValues[2] LastUser = myValues[3] #print(PermissionPath) UserPermsJSON = json.loads(UserPermissions) permission = checkPermission(UserPermsJSON, PermissionPath) print('System "use" access %s' % ['denied','granted'][permission]) if(permission): error = False status = MachineStatus ActualUser = user['username'] if(status): status = False if(LastUser == ActualUser): error = False else: try: if (keycloak_admin.get_user_groups(user_id=user['id'])[0]['name'] == 'Mentoren'): print('Overrided becouse of "Mentor" Group') else: print(f'Bereits benutzt von {LastUser}') error = True except IndexError: print("No groups available") error = True if(error): changeDisplay(client, ReaderID, 9, LastUser) else: status = True error = False if(error == False): #KSstatus ^= True switch = ["off", "on"][status] print(f"Turn Plug {switch}") #print(status) changePlug(client, PlugID, status) publish(client,f"/FabLogging/{PlugID}/USER",ActualUser) try: firstCombo = user['firstName']+" " DisplayUser = firstCombo+user['lastName'] if(len(firstCombo) >= 7): DisplayUser = user['firstName'][:7] except KeyError: DisplayUser = user['username'] if(len(DisplayUser) > 7): DisplayUser = DisplayUser[0:7] + "." + DisplayUser[7+1: ] DisplayUser = DisplayUser[:8] changeDisplay(client, ReaderID, [20, 20][status], ["Bitte anmelden", f"Login\n{DisplayUser}"][status]) mycursor.execute(f'UPDATE ReaderPlug SET Status={status}, LastUser="{ActualUser}" WHERE ReaderID="{ReaderID}";') FabDB.commit() else: changeDisplay(client, ReaderID, 7, "") except KeyError: # Key is not present pass if not (knownUser): changeDisplay(client, ReaderID, 16, MQTT_KEY) def subscribe(client: mqtt_client, topic): def on_message(client, userdata, msg): msg_handler(msg,client) client.subscribe(topic) client.on_message = on_message def run(): client = connect_mqtt() subscribe(client,"/rfid_reader/#") client.loop_forever() if __name__ == '__main__': run()