From d9d05402e711e0f70eaa117542aad51d800991c9 Mon Sep 17 00:00:00 2001 From: Jason SECULA Date: Tue, 3 Jun 2025 10:51:07 +0200 Subject: [PATCH] Adding script to replace staging user in Airwatch with user assigned in GLPI --- scripts/StagingUserAssignation.py | 179 ++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 scripts/StagingUserAssignation.py diff --git a/scripts/StagingUserAssignation.py b/scripts/StagingUserAssignation.py new file mode 100644 index 0000000..c50abcb --- /dev/null +++ b/scripts/StagingUserAssignation.py @@ -0,0 +1,179 @@ +#!/usr/bin/python3 +import os +import base64 +import requests +import json + +#======== Paramètres du script ========# + +# Emplacement du verrou +lockFile = './magentaGLPIStaging.lock' + +debug=False + +# Informations du serveur Airwatch +#airwatchServer = 'https://pp-apimagenta.phm.education.gouv.fr' +airwatchServer = 'https://apimagenta.phm.education.gouv.fr' +airwatchAPIKey = '' +airwatchAPIUser = '' +airwatchAPIPassword = '' +stagingUser = 'staging-pr' + +# Informations du serveur GLPI +GLPIServer = 'http://127.0.0.1/glpi/' +GLPIAppToken = '' +GLPIUserToken = '' + +# ====================================== # + + +# Vérification de la présence du verrou avant de continuer +if(os.path.isfile(lockFile)): + if(debug): + print('Lock file is present, exiting...') + exit(0) +else: + open(lockFile, "w").close() + +# Adresse de recherche des appareils filtré sur l'utilisateur de staging +# avec limite de 500 appareils par page (limite max de l'API) +airwatchAPIDevicesSearchURI = f"/API/mdm/devices/search?user={stagingUser}&pagesize=500&page=" + +# User token formé par la concaténation du nom de l'utilisateur API et de son mot de passe converti en base 64 +airwatchAPIUserToken = base64.b64encode(f"{airwatchAPIUser}:{airwatchAPIPassword}".encode('ascii')).decode("ascii") + +airwatchHeaders = { + "Authorization": f"Basic {airwatchAPIUserToken}", + "aw-tenant-code": airwatchAPIKey, + "Accept": "application/json" +} + +# Page de départ pour la recherche +pageNumber = 0 + +# Initialisation de la variable devices qui va stocker l'ensemble des appareils trouvés +devices = [] + +uri = f"{airwatchServer}{airwatchAPIDevicesSearchURI}{pageNumber}" +if(debug): + print(f"Uri for device search on airwatch : {uri}") +result = requests.get(uri, headers=airwatchHeaders) + +if(debug): + print(f"Result of request : {result}") + +# On vérifie qu'on a bien un retour OK pour la requête API +if(result.status_code != 200): + # Suppression du verrou + os.remove(lockFile) + exit(0) + +result = result.json() + +# On fait une requête pour chaque page en fonction tant qu'on a pas atteint le nombre +# d'appareils trouvé dans la première requête +while(len(devices) != result["Total"]): + uri = f"{airwatchServer}{airwatchAPIDevicesSearchURI}{pageNumber}" + result = requests.get(uri, headers=airwatchHeaders).json() + devices += result["Devices"] + pageNumber += 1 + + +# Adresse d'initalisation de l'api GLPI +GLPIAPIInitUri = '/apirest.php/initSession/' + +GLPIHeaders = { + 'Content-Type': 'application/json', + "Authorization": f"user_token {GLPIUserToken}", + "App-Token": GLPIAppToken +} + +# Récupération d'un token de session +uri = f"{GLPIServer}{GLPIAPIInitUri}" +result = requests.get(uri, headers=GLPIHeaders) + +if(debug): + print(f"GLPI api access : {result}") + +if(result.status_code != 200): + # Suppression du verrou + os.remove(lockFile) + exit(1) + +GLPISessionToken = result.json()["session_token"] + +if(debug): + print(f"GLPI session Token: {GLPISessionToken}") + +# Changement des headers pour remplacer l'user token par le token de session +GLPIHeaders = { + 'Content-Type': 'application/json', + "Session-Token": GLPISessionToken, + "App-Token": GLPIAppToken +} + +# Adresse de recherche des appareils présents dans ordinateurs sur GLPI +GLPIAPISearchComputer = 'apirest.php/search/computer?' + +for device in devices: + if(device["EnrollmentStatus"] != 'Enrolled'): + continue + + if(device["Imei"] != ''): + if(debug): + print(f"Imei = {device['Imei']}") + # Recherche des appareils en fonction du numéro de série ou de l'imei + # l'imei pouvant être dans le champ numéro de série ou les champs imei custom + search_parameter = f'is_deleted=0&criteria[0][field]=5&withindexes=true&criteria[0][searchtype]=contains&criteria[0][value]=^{device["SerialNumber"]}$'\ + f'&criteria[1][link]=OR&criteria[1][field]=5&criteria[1][searchtype]=contains&criteria[1][value]=^{device["Imei"]}$'\ + f'&criteria[2][link]=OR&criteria[2][field]=76667&criteria[2][searchtype]=contains&criteria[2][value]=^{device["Imei"]}$'\ + f'&criteria[3][link]=OR&criteria[3][field]=76670&criteria[3][searchtype]=contains&criteria[3][value]=^{device["Imei"]}$' + else: + # Recherche des appareils en fonction du numéro de série seulement + search_parameter = f'is_deleted=0&criteria[0][field]=5&withindexes=true&criteria[0][searchtype]=contains&criteria[0][value]=^{device["SerialNumber"]}$' + + if(debug): + print(f"Serial Number = {device['SerialNumber']}") + + searchUri = f"{GLPIServer}{GLPIAPISearchComputer}{search_parameter}" + if(debug): + print(f"searchURI = {searchUri}") + search = requests.get(searchUri, headers=GLPIHeaders) + + + # On ne gère pas pour l'instant d'autres code que le code 200 + # voir en fonction des codes erreurs retournés par le serveur + if(search.status_code != 200): + break + + search = search.json() + + if(search["totalcount"] == 1): + # Récupération de l'utilisateur de l'appareil dans la fiche GLPI de l'appareil + for device_id, data in search["data"].items(): + device_user = search["data"][device_id]["70"] + if(debug): + print(f"user on device in GLPI : {device_user}") + # Vérification que l'appareil est associé à un utilisateur dans GLPI + if(device_user != None): + # Récupération de l'utilisateur sur Magenta + uri = f"{airwatchServer}/API/system/users/search?username={device_user}" + if(debug): + print(f"Airwatch user search uri : {uri}") + user = requests.get(uri, headers=airwatchHeaders) + + # On ne gère pas pour l'instant d'autres code que le code 200 + # voir en fonction des codes erreurs retournés par le serveur + if(user.status_code != 200): + break + + user = user.json() + # Changement de l'utilisateur assigné sur l'appareil dans Magenta + patchUri = f'{airwatchServer}/API/mdm/devices/{device["Id"]["Value"]}/enrollmentuser/{user["Users"][0]["Id"]["Value"]}' + if(debug): + print(f"patchUri = {patchUri}") + requests.patch(patchUri, headers=airwatchHeaders) + +# Suppression du verrou +os.remove(lockFile) +exit(0)