using System; using System.Configuration; using System.IO; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading.Tasks; using System.Xml; using System.Xml.Linq; using BeWoDatabaseTerminator.Data; using BeWoDatabaseTerminator.Security; using BeWoDatabaseTerminator.Utils; using Newtonsoft.Json; using MySqlHelper = BeWoDatabaseTerminator.MySql.MySqlHelper; namespace BeWoDatabaseTerminator { internal class Program { private const string APIKEY = "CwjlSCbNqctEsofpGY64Z4aO6pShNYAdGtjMqHsjO64FuK23qoRDUqIjUC0P"; private static string _ConnectionStringServer; private static string _ConnectionStringPassword; private static string _ConnectionStringUserID; private static string _ConnectionStringPort; private static string _MultitenancyPath; private static string _BackupConfigFolderPath; private static string _CreateScriptsFolderPath; private static string _ServerName; private static string _InsertScriptName; private static string _CreateScriptName; private static string _ChangesScriptName; private static string _LogFilePath; private static void PinCertificate() { ServicePointManager.ServerCertificateValidationCallback = PinPublicKey; } private static String PUB_KEY_X3 = "9CD30CF05AE52E47B7725D3783B3686330EAD735261925E1BDBE35F170922FB7B84B4105ABA99E350858ECB12AC468870BA3E375E4E6F3A76271BA7981601FD7919A9FF3D0786771C8690E9591CFFEE699E9603C48CC7ECA4D7712249D471B5AEBB9EC1E37001C9CAC7BA705EACE4AEBBD41E53698B9CBFD6D3C9668DF232A42900C867467C87FA59AB8526114133F65E98287CBDBFA0E56F68689F3853F9786AFB0DC1AEF6B0D95167DC42BA065B299043675806BAC4AF31B9049782FA2964F2A20252904C674C0D031CD8F31389516BAA833B843F1B11FC3307FA27931133D2D36F8E3FCF2336AB93931C5AFC48D0D1D641633AAFA8429B6D40BC0D87DC3930203010001"; private static String PUB_KEY_R3 = "BB021528CCF6A094D30F12EC8D5592C3F882F199A67A4288A75D26AAB52BB9C54CB1AF8E6BF975C8A3D70F4794145535578C9EA8A23919F5823C42A94E6EF53BC32EDB8DC0B05CF35938E7EDCF69F05A0B1BBEC094242587FA3771B313E71CACE19BEFDBE43B45524596A9C153CE34C852EEB5AEED8FDE6070E2A554ABB66D0E97A540346B2BD3BC66EB66347CFA6B8B8F572999F830175DBA726FFB81C5ADD286583D17C7E709BBF12BF786DCC1DA715DD446E3CCAD25C188BC60677566B3F118F7A25CE653FF3A88B647A5FF1318EA9809773F9D53F9CF01E5F5A6701714AF63A4FF99B3939DDC53A706FE48851DA169AE2575BB13CC5203F5ED51A18BDB150203010001"; private static String PUB_KEY_E1 = "245c2da22afd1c4ba65d97732731acb2a06962ef65e8a6b0f0ac4b9fff1c0b700fd3982f4dfc0f009b37f074055732972e05ef2a4325a3fb6e342713f64f7e69d302995eeb244792c1249be6b1218fc12481fc68cc1f69ba58f51922f774c616"; private static String PUB_KEY_E5 = "0d0b3a8a6b618eb6efdc5f58e7c6424554ab63f66661480a2e5975b481023750b73f1679dc98eca1289772201c2ccfd57c52204e54785b84146bc090ae85ecc051413c5a877f064dd4fe60d1fa6c2de17d951088a208540f991a4ce6ea0aacd8"; private static String PUB_KEY_E6 = "d9f19e4687f8217160a826eba3fab9eada1db912a7d426d95114b1617c7596bf220b391fd5bed10a46aa2d3c4a09842ebe409555e91940376675ed324e770449f8707bc318e7cef77110feac74d800d4ed6d1c731633109c3ab2ea6c62f4bdb8"; private static String PUB_KEY_E7 = "0441e8049308587fbe37300cc0a041eafe56da84933ec900dbab6712cff94f5309e8a82fab29e59f1546f45b624e0fd4834199b79f4072451c2c5c4a32a6c2dbc6056a65ffdadaf075b4403b146895b6a8e26a71e274655153de16d41e27c133fd"; private static String PUB_KEY_E8 = "04d165f25edc4bb40c029cd2b2faeee96cab3aae38a1f4d4393233c542d4cc330c34c7212090705ce8622f1c71b342d779be460dc1db47a113a0c7df8126633bd48d1df63d823332f6f42be7f5963ab41367187b6b3e8d48d9eadeedae6d3e874c"; private static String PUB_KEY_R10 = "CF57E5E6C45412EDB447FEC92758764650288C1D3E88DF059DD5B51829BDDDB55ABFFAF6CEA3BEAF00214B625A5A3C012FC55803F689FF8E1143EBC1B5E01407968F6F1FD7E7BA8139097565B7C2AF185B372628E7A3F4072B6D1AFFAB58BC95AE40FFE9CB57C4B55B7F780D1861BC17E754C6BB4991CD6E18D18085EEA66536BC74EABC504CEAFC21F338169394BAB0D36B3806CD16127ACA5275C8AD76B2C29C5D98455C6F617BC62DEE3C13528601D957E6381CDF8DB51F92919AE74A1CCC45A87255F0B0E6A307ECFDA71B669E3F488B71847158C93AFAEF5EF25B442B3C74E78FB247C1076ACD9AB70D96F712812651540AEC61F6F7F5E2F28AC8950D8D0203010001"; private static String PUB_KEY_R11 = "BA87BC5C1B0039CBCA0ACDD46710F9013CA54EA561CB26CA52FB1501B7B928F5281EED27B324183967090C08ECE03AB03B770EBDF3E53954410C4EAE41D69974DE51DBEF7BFF58BDA8B713F6DE31D5F272C9726A0B8374959C4600641499F3B1D922D9CDA892AA1C267A3FFEEF58057B089581DB710F8EFBE33109BB09BE504D5F8F91763D5A9D9E83F2E9C466B3E106664348188065A037189A9B843297B1B2BDC4F815009D2788FBE26317966C9B27674BC4DB285E69C279F0495CE02450E1C4BCA105AC7B406D00B4C2413FA758B82FC55C9BA5BB099EF1FEEBB08539FDA80AEF45C478EB652AC2CF5F3CDEE35C4D1BF70B272BAA0B4277534F796A1D87D90203010001"; private static String PUB_KEY_R12 = "00da982874adbe94fe3be01ee2e54b75ab2c127feda703327e3697ece8318fa5138d0b992e1ecd01513d4ce5286e095531aaa5225d72f42d07c24d403cdf0123b97837f51a653234e686719d04ef84085bbd021a99eba601009a73906d8fa207a0d097d3da456181353d14f9c4c05f6adc0b961ab09fe32aeabd2ad698c79b71ab3b740f3cdbb260be5a4b4e18e9db2a735c8961659efeed3ca6cb4e6fe49ef90046b3ff194d2a63b38e66c6188570c750656f3b74e548830f08585d2d239d5ea3fee8db00a1d2f4e3194df2ee7af6279ee5cd9c2da2f27f9c17adef133739d1b4c82c41d686c0e9ec21f8591b7fb93a7c9f5c019d6204c228bd0aad3cca10"; private static String PUB_KEY_R13 = "00a567708dd0568164151761cdb906d4ad19908c2650379816639254dbd9cc840593ecd3ec081ba0605143487d2bc748969eb42dda9dc8273b57a19fabf0d60ed40e30ca6f9bb1d1d6a49d323e584e356f4558687117fc3ed85d82a02fb2516cb01a5db859ce3565c88ba1af1037ffe39c5dc2491734ff8c2b8b8df0bc712c930c1d05c4bac7cdaac95e7cd1c901f79c03f6fc0a5df4da7be6db764270ebf44d22da00776fd6c95f17fdda752ea5570cf6ea5cb6e073a568cfa174e275827e109fc1f5a2eb01e938b10a44ccd3c289f54935820a34b31ce988c2474e820e0a36f0474f8af1290475dacde19a5cff5e9d9895ba9a43d04aa21705010430d332b38f"; private static bool PinPublicKey(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslpolicyerrors) { try { if (certificate == null || chain == null) return false; bool chainContainsPk = false; foreach (var element in chain.ChainElements) { String pk = element.Certificate.GetPublicKeyString().ToLower(); if (pk.Contains(PUB_KEY_X3.ToLower()) || pk.Contains(PUB_KEY_R3.ToLower()) || pk.Contains(PUB_KEY_E1.ToLower()) || pk.Contains(PUB_KEY_E5.ToLower()) || pk.Contains(PUB_KEY_E6.ToLower()) || pk.Contains(PUB_KEY_E7.ToLower()) || pk.Contains(PUB_KEY_E8.ToLower()) || pk.Contains(PUB_KEY_R10.ToLower()) || pk.Contains(PUB_KEY_R11.ToLower()) || pk.Contains(PUB_KEY_R12.ToLower()) || pk.Contains(PUB_KEY_R13.ToLower())) { chainContainsPk = true; } } bool subjectAccepted = certificate.Subject.Trim().ToLower().EndsWith(".bewoplaner.de") || certificate.Subject.Trim().ToLower().EndsWith(".ownchat.de"); return chainContainsPk && subjectAccepted; } catch (Exception e) { return false; } } private static async Task Main(string[] args) { ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; PinCertificate(); _ServerName = ConfigurationManager.AppSettings["ServerName"]; _MultitenancyPath = ConfigurationManager.AppSettings["MultitenancyPath"]; _BackupConfigFolderPath = ConfigurationManager.AppSettings["BackupConfigFolderPath"]; _CreateScriptsFolderPath = ConfigurationManager.AppSettings["CreateScriptsFolderPath"]; _ConnectionStringServer = ConfigurationManager.AppSettings["ConnectionStringServer"]; _ConnectionStringPassword = ConfigurationManager.AppSettings["ConnectionStringPassword"]; _ConnectionStringUserID = ConfigurationManager.AppSettings["ConnectionStringUserId"]; _ConnectionStringPort = ConfigurationManager.AppSettings["ConnectionStringPort"]; _CreateScriptName = ConfigurationManager.AppSettings["CreateScriptName"]; _ChangesScriptName = ConfigurationManager.AppSettings["ChangesScriptName"]; _InsertScriptName = ConfigurationManager.AppSettings["InsertScriptName"]; _LogFilePath = ConfigurationManager.AppSettings["LogFilePath"]; if (!Directory.Exists(_LogFilePath)) { Directory.CreateDirectory(_LogFilePath); } try { FileUtils.DeleteOldLogs(_LogFilePath); } catch(Exception exception) { FileUtils.WriteLog(exception?.ToString(), _LogFilePath); } string response = null; try { FileUtils.WriteLog($"Lade ContractStatuses für {_ServerName} herunter.", _LogFilePath); response = await GetDatabaseStatuses(_ServerName); } catch(Exception exception) { FileUtils.WriteLog(exception.ToString(), _LogFilePath); LogUtils.LogError(exception); } FileUtils.WriteLog("Verarbeite Serverantwort.", _LogFilePath); await ExecuteDatabaseChanges(response); } /// /// Führt die Änderungen an den Datenbanken durch bzw. das Anlegen. /// /// Die Antwort des Servers mit den Stati als Json-String. /// Der Rückgabetyp bei asynchronen Methoden ist Task, wenn er sonst void wäre. private static async Task ExecuteDatabaseChanges(string serverResponse) { var contractStatusCollection = serverResponse is null ? new ContractStatusCollection() : JsonConvert.DeserializeObject(serverResponse); if(!(contractStatusCollection is null)) { var statusCount = contractStatusCollection.ContractStatuses.Count; FileUtils.WriteLog($"Es wurde{(statusCount > 1 ? "n" : string.Empty)} {(statusCount > 1 ? statusCount.ToString() : statusCount == 0 ? "kein" : "ein")} ContractStat{(statusCount > 1 ? "i" : "us")} gefunden.", _LogFilePath); foreach (var contractStatusKeyValuePair in contractStatusCollection.ContractStatuses) { var contractStatus = contractStatusKeyValuePair.Value; //if (contractStatus.Tenant == "5564670353") //{ //} //else //{ // continue; //} if (contractStatus.Activate == 1) { FileUtils.WriteLog($"Aktiviere/Erstelle Datenbank `{contractStatus.Tenant}`.", _LogFilePath); await ActivateDatabase(contractStatus.Tenant, contractStatus); } if(contractStatus.Deactivate == 1) { FileUtils.WriteLog($"Deaktiviere Datenbank `{contractStatus.Tenant}`.", _LogFilePath); ToggleConfigActivation(contractStatus, false); ToggleBackupConfigActivation(contractStatus, false); } if(contractStatus.Delete == 1) { FileUtils.WriteLog($"Lösche Datenbank `{contractStatus.Tenant}`.", _LogFilePath); DeleteDatabase(contractStatus); } } } } /// /// Extrahiert die MySQL-Verbindung aus der Config-File. /// /// Pfad zur Config-File. /// Gibt die MySQL-Verbindung zurück. private static string ExtractConnectionString(string configPath) { var connectionString = string.Empty; try { if(!File.Exists(configPath)) { return null; } using(var reader = XmlReader.Create(configPath)) { while(reader.Read()) { if(reader.NodeType == XmlNodeType.Element) { if(reader.GetAttribute("name") == "connection.connection_string") { if(XNode.ReadFrom(reader) is XElement xElement) { connectionString = xElement.Value.Trim(); } } } } } } catch(Exception exception) { FileUtils.WriteLog(exception.ToString(), _LogFilePath); LogUtils.LogError(exception); } // Server=127.0.0.1;Password=BeWoPl@ner!;User ID=BeWoUser;Initial Catalog=chattest;Port=2206 return connectionString; } /// /// Extrahiert Server, Password, User ID und Port aus dem ConnectionString der Config-Datei. /// /// private static void ExtractConnectionStringParts(string connectionString) { var splitConnectionString = connectionString.Split(';'); foreach(var part in splitConnectionString) { var x = part.Split('='); if(x.Length == 2) { switch(x[0]) { case "Server": _ConnectionStringServer = x[1]; break; case "Password": _ConnectionStringPassword = x[1]; break; case "User ID": _ConnectionStringUserID = x[1]; break; case "Port": _ConnectionStringPort = x[1]; break; } } } } /// /// Datenbank wird angelegt oder reaktiviert. /// /// Kundennummer der zu anlegenden oder reaktivierenden Datenbank. /// ContractStatus der anzulegenden oder reaktivierenden Datenbank. /// Der Rückgabetyp bei asynchronen Methoden ist Task, wenn er sonst void wäre. private static async Task ActivateDatabase(string tenant, ContractStatus contractStatus) { var connectionString = $"Server={_ConnectionStringServer};Password={_ConnectionStringPassword};User ID={_ConnectionStringUserID};Port={_ConnectionStringPort}"; //connectionString += ";Charset=utf8mb4"; var isExisting = new MySqlHelper(connectionString).CheckForDatabase(tenant); var configFilePath = Path.Combine(_MultitenancyPath, $"{tenant}.config"); // Config-Datei existiert bereits if (File.Exists(configFilePath)) { FileUtils.WriteLog($"Die Config-Datei '{configFilePath}' existiert. Nix muss gemacht werden", _LogFilePath); //Nichts machen //FileUtils.WriteLog($"Die Config-Datei '{configFilePath}' existiert.", _LogFilePath); //connectionString = isExisting ? ExtractConnectionString(configFilePath) : connectionString; //if(!isExisting) //{ // RunCreateScripts(tenant, connectionString); //} } // Config-Datei ist deaktiviert else if (File.Exists(Path.Combine(_MultitenancyPath, $"{tenant}.config.deactivated"))) { FileUtils.WriteLog($"Die Config-Datei '{tenant}.config.deactivated' existiert.", _LogFilePath); //connectionString = isExisting ? ExtractConnectionString(configFilePath) : connectionString; ToggleConfigActivation(contractStatus, true); ToggleBackupConfigActivation(contractStatus, true); //if(!isExisting) //{ // RunCreateScripts(tenant, connectionString); //} } // Config-Datei existiert nicht else { FileUtils.WriteLog($"Die Config-Datei '{configFilePath}' existiert nicht.", _LogFilePath); if (!isExisting) { RunCreateScripts(tenant, connectionString); await SendInitialPasswordToTool(contractStatus); } } } /// /// Löscht die angegebene Datenbank. /// /// Kundennummer, die gleichzeitig auch der Name der Datenbank ist. private static void DeleteDatabase(ContractStatus contractStatus) { var configFile = Path.Combine(_MultitenancyPath, $"{contractStatus.Tenant}.config"); var deactivatedFile = Path.Combine(_MultitenancyPath, $"{contractStatus.Tenant}.config.deactivated"); if (!File.Exists(deactivatedFile) && File.Exists(configFile)) { ToggleConfigActivation(contractStatus, false); ToggleBackupConfigActivation(contractStatus, false); } if (File.Exists(deactivatedFile)) { var deleteFile = Path.Combine(_MultitenancyPath, $"{contractStatus.Tenant}.config.deleted"); if (!File.Exists(deleteFile)) { File.Move(deactivatedFile, deleteFile); } var connectionString = ExtractConnectionString(deleteFile); var mySqlHelper = new MySqlHelper(connectionString); mySqlHelper.DeleteDatabase(contractStatus.Tenant); //File.Delete(deactivatedFile); FileUtils.WriteLog($"Datenbank `{contractStatus.Tenant}` und {contractStatus.Tenant}.config.deactivated wurden gelöscht.", _LogFilePath); SendDBStatusToTool(contractStatus, false, true); } else { LogUtils.LogMessage($"Die Config-Datei (*.config.deactivated) für Datenbank `{contractStatus.Tenant}` existiert nicht.", ConsoleColor.Red, ConsoleColor.Black); FileUtils.WriteLog($"{contractStatus.Tenant}.config nicht gefunden. Datenbank `{contractStatus.Tenant}`, falls vorhanden, nicht gelöscht.", _LogFilePath); } } /// /// Entfernt oder fügt ".deactivated" an die Config-Datei. /// /// Kundennummer der zu de- bwz. reaktivierenden Datenbank. /// Ob de- oder reaktiviert werden soll. private static void ToggleConfigActivation(ContractStatus contractStatus, bool isToBeActivated) { var fileName1 = isToBeActivated ? $"{contractStatus.Tenant}.config.deactivated" : $"{contractStatus.Tenant}.config"; var fileName2 = isToBeActivated ? $"{contractStatus.Tenant}.config" : $"{contractStatus.Tenant}.config.deactivated"; var path1 = Path.Combine(_MultitenancyPath, fileName1); var path2 = Path.Combine(_MultitenancyPath, fileName2); if(File.Exists(path1) && !File.Exists(path2)) { File.Move(path1, path2); if(File.Exists(path1)) { File.Delete(path1); if (!isToBeActivated) { SendDBStatusToTool(contractStatus, true, false); } } FileUtils.WriteLog($"{contractStatus.Tenant}.config {(isToBeActivated == false ? "de" : string.Empty)}aktiviert.", _LogFilePath); } else { FileUtils.WriteLog($"Fehler beim {(isToBeActivated == false ? "Dea" : "A")}ktivieren: {fileName1} existiert nicht oder {fileName2} existiert.", _LogFilePath); } } private static void ToggleBackupConfigActivation(ContractStatus contractStatus, bool isToBeActivated) { if (!String.IsNullOrEmpty(_BackupConfigFolderPath)) { var fileName1 = isToBeActivated ? $"{contractStatus.Tenant}.db2mail.deactivated" : $"{contractStatus.Tenant}.db2mail"; var fileName2 = isToBeActivated ? $"{contractStatus.Tenant}.db2mail" : $"{contractStatus.Tenant}.db2mail.deactivated"; var path1 = Path.Combine(_BackupConfigFolderPath, fileName1); var path2 = Path.Combine(_BackupConfigFolderPath, fileName2); if (File.Exists(path1) && !File.Exists(path2)) { File.Move(path1, path2); if (File.Exists(path1)) { File.Delete(path1); } FileUtils.WriteLog($"{contractStatus.Tenant}.db2mail {(isToBeActivated == false ? "de" : string.Empty)}aktiviert.", _LogFilePath); } else { FileUtils.WriteLog($"Fehler beim {(isToBeActivated == false ? "Dea" : "A")}ktivieren: {fileName1} existiert nicht oder {fileName2} existiert.", _LogFilePath); } } } /// /// Erzeugt eine neue Datenbank, passt sie dem neuesten Stand an und füllt sie mit Basisdaten. /// /// Kundennummer der neuen Datenbank. /// MySQL-Verbindung aus der Config-Datei. private static void RunCreateScripts(string tenant, string connectionString) { #if DEBUG if (!Directory.Exists(_CreateScriptsFolderPath)) { Directory.CreateDirectory(_CreateScriptsFolderPath); } if (!Directory.Exists(_MultitenancyPath)) { Directory.CreateDirectory(_MultitenancyPath); } #endif if (Directory.Exists(_CreateScriptsFolderPath) && Directory.Exists(_MultitenancyPath) && Directory.Exists(_BackupConfigFolderPath)) { FileUtils.GenerateNewConfigFile(Path.Combine(_MultitenancyPath, $"{tenant}.config"), connectionString, tenant); FileUtils.GenerateNewDBAdminFile(Path.Combine(_BackupConfigFolderPath, $"{tenant}.db2mail"), tenant, _ConnectionStringPort, _ConnectionStringUserID, _ConnectionStringPassword); var createScriptPath = Path.Combine(_CreateScriptsFolderPath, _CreateScriptName); var changesScriptPath = Path.Combine(_CreateScriptsFolderPath, _ChangesScriptName); var insertScriptPath = Path.Combine(_CreateScriptsFolderPath, _InsertScriptName); if (File.Exists(createScriptPath) && File.Exists(changesScriptPath) && File.Exists(insertScriptPath)) { var mySqlHelper = new MySqlHelper(connectionString); var isExisting = mySqlHelper.CheckForDatabase(tenant); if(!isExisting) { try { mySqlHelper.RunScript(createScriptPath, true, tenant); mySqlHelper.RunScript(changesScriptPath, false, tenant); mySqlHelper.RunScript(insertScriptPath, false, tenant); FileUtils.WriteLog($"Skripte zur Erstellung von Datenbank `{tenant}` ausgeführt und Datenbank angelegt.", _LogFilePath); } catch(Exception exception) { FileUtils.WriteLog(exception?.ToString(), _LogFilePath); LogUtils.LogError(exception); } } } } else { if(!Directory.Exists(_CreateScriptsFolderPath)) { FileUtils.WriteLog($"Das Verzeichnis CreateScriptsFolderPath '{_CreateScriptsFolderPath}' existiert nicht.", _LogFilePath); } if(!Directory.Exists(_LogFilePath)) { FileUtils.WriteLog($"Das Verzeichnis LogFilePath '{_LogFilePath}' existiert nicht.", _LogFilePath); } } } /// /// Erzeugt und schickt das Initialpasswort für eine neue Datenbank an das Tool mit Hilfe des apiKeys. /// /// ContractStatus für den eine neue Datenbank angelegt werden soll. /// Der für das Tool nötige API-Key. /// Der Rückgabetyp bei asynchronen Methoden ist Task, wenn er sonst void wäre. private static async Task SendInitialPasswordToTool(ContractStatus contractStatus) { var mySqlHelper1 = new MySqlHelper($"Server={_ConnectionStringServer};Password={_ConnectionStringPassword};User ID={_ConnectionStringUserID};Port={_ConnectionStringPort}"); var databaseExists = false; try { databaseExists = mySqlHelper1.CheckForDatabase(contractStatus.Tenant); } catch(Exception exception) { FileUtils.WriteLog(exception?.ToString(), _LogFilePath); } if(!(contractStatus is null) && databaseExists) { var password = PasswordHelper.GenerateInitialPassword(new Random()); var uri = new Uri($"https://support.bewoplaner.de/api/save_initialpw.php?APIKEY1={APIKEY}&LicenseTypeID={contractStatus.LicenseTypeId}&CustomerID={contractStatus.Tenant}&InitialPW={password}"); var request = (HttpWebRequest) WebRequest.Create(uri); var isSendInitialPasswordToApiSuccessful = false; FileUtils.WriteLog($"Sende Initialpasswort für Datenbank `{contractStatus.Tenant}` an API.", _LogFilePath); try { using(var response = (HttpWebResponse) await request.GetResponseAsync()) { if(response.GetResponseStream() is Stream reponseStream) { using(var reader = new StreamReader(reponseStream, Encoding.UTF8)) { var text = await reader.ReadToEndAsync(); var initialPasswordResponse = JsonConvert.DeserializeObject(text); isSendInitialPasswordToApiSuccessful = initialPasswordResponse?.IsSuccess ?? false; } } } if(isSendInitialPasswordToApiSuccessful) { var configFilePath = Path.Combine(_MultitenancyPath, $"{contractStatus.Tenant}.config"); if(File.Exists(configFilePath)) { var connectionString = ExtractConnectionString(configFilePath); var mySqlHelper = new MySqlHelper(connectionString); var personOid = mySqlHelper.InsertPerson(); if(!(personOid is null)) { var employeeOid = mySqlHelper.InsertEmployee(personOid.Value); if(!(employeeOid is null)) { var applicationUserOid = mySqlHelper.InsertApplicationUser(employeeOid.Value, password); if(!(applicationUserOid is null)) { mySqlHelper.LinkInitialUserToAdminRights(applicationUserOid.Value); FileUtils.WriteLog("Benutzer in der Datenbank angelegt.", _LogFilePath); } } } } else { FileUtils.WriteLog($"{configFilePath} existiert nicht.", _LogFilePath); } } else { FileUtils.WriteLog($"Das Setzen des Initialpassworts für Datenbank `{contractStatus.Tenant}` ist fehlgeschlagen!", _LogFilePath); } } catch(Exception exception) { FileUtils.WriteLog(exception?.ToString(), _LogFilePath); } } else { var logMessage = $"SendInitialPasswordToTool ContractStatus ist null"; FileUtils.WriteLog(logMessage, _LogFilePath); } } private static async Task SendDBStatusToTool(ContractStatus contractStatus, bool deactivated, bool deleted) { if (contractStatus != null) { String t = ""; if (deactivated) { t = "1"; } if (deleted) { t = "2"; } var uri = new Uri($"https://support.bewoplaner.de/api/dbstate.php?APIKEY1={APIKEY}&LicenseTypeID={contractStatus.LicenseTypeId}&CustomerID={contractStatus.Tenant}&Type={t}"); var request = (HttpWebRequest)WebRequest.Create(uri); FileUtils.WriteLog($"Sende Status für Datenbank `{contractStatus.Tenant}` an API.", _LogFilePath); try { using (var response = (HttpWebResponse)await request.GetResponseAsync()) { if (response.GetResponseStream() is Stream reponseStream) { using (var reader = new StreamReader(reponseStream, Encoding.UTF8)) { var text = await reader.ReadToEndAsync(); } } } } catch (Exception exception) { FileUtils.WriteLog(exception?.ToString(), _LogFilePath); } } else { var logMessage = $"SendDBStatusToTool ContractStatus ist null"; FileUtils.WriteLog(logMessage, _LogFilePath); } } /// /// Lädt die Stati für die Datenbanken, die geändert werden sollen. /// /// Name des Servers, z.B. "app6.bewoplaner.de" /// Uri für zum Testen. Wird nur im Debug-Modus benutzt /// private static async Task GetDatabaseStatuses(string serverName, string debugUri = null) { var uri = new Uri($"https://support.bewoplaner.de/api/getcontractstate.php?ContractsState={serverName}"); var request = (HttpWebRequest) WebRequest.Create(uri); using(var response = (HttpWebResponse) await request.GetResponseAsync()) { using(var stream = response.GetResponseStream()) { if(!(stream is null)) { using(var streamReader = new StreamReader(stream)) { var json = await streamReader.ReadToEndAsync(); return json; } } return null; } } } } }