672 lines
31 KiB
C#
672 lines
31 KiB
C#
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 const String PUB_KEY_X3 = "9CD30CF05AE52E47B7725D3783B3686330EAD735261925E1BDBE35F170922FB7B84B4105ABA99E350858ECB12AC468870BA3E375E4E6F3A76271BA7981601FD7919A9FF3D0786771C8690E9591CFFEE699E9603C48CC7ECA4D7712249D471B5AEBB9EC1E37001C9CAC7BA705EACE4AEBBD41E53698B9CBFD6D3C9668DF232A42900C867467C87FA59AB8526114133F65E98287CBDBFA0E56F68689F3853F9786AFB0DC1AEF6B0D95167DC42BA065B299043675806BAC4AF31B9049782FA2964F2A20252904C674C0D031CD8F31389516BAA833B843F1B11FC3307FA27931133D2D36F8E3FCF2336AB93931C5AFC48D0D1D641633AAFA8429B6D40BC0D87DC3930203010001";
|
|
|
|
private const String PUB_KEY_R3 = "BB021528CCF6A094D30F12EC8D5592C3F882F199A67A4288A75D26AAB52BB9C54CB1AF8E6BF975C8A3D70F4794145535578C9EA8A23919F5823C42A94E6EF53BC32EDB8DC0B05CF35938E7EDCF69F05A0B1BBEC094242587FA3771B313E71CACE19BEFDBE43B45524596A9C153CE34C852EEB5AEED8FDE6070E2A554ABB66D0E97A540346B2BD3BC66EB66347CFA6B8B8F572999F830175DBA726FFB81C5ADD286583D17C7E709BBF12BF786DCC1DA715DD446E3CCAD25C188BC60677566B3F118F7A25CE653FF3A88B647A5FF1318EA9809773F9D53F9CF01E5F5A6701714AF63A4FF99B3939DDC53A706FE48851DA169AE2575BB13CC5203F5ED51A18BDB150203010001";
|
|
|
|
private const String PUB_KEY_E1 = "245c2da22afd1c4ba65d97732731acb2a06962ef65e8a6b0f0ac4b9fff1c0b700fd3982f4dfc0f009b37f074055732972e05ef2a4325a3fb6e342713f64f7e69d302995eeb244792c1249be6b1218fc12481fc68cc1f69ba58f51922f774c616";
|
|
|
|
private const String PUB_KEY_E5 = "0d0b3a8a6b618eb6efdc5f58e7c6424554ab63f66661480a2e5975b481023750b73f1679dc98eca1289772201c2ccfd57c52204e54785b84146bc090ae85ecc051413c5a877f064dd4fe60d1fa6c2de17d951088a208540f991a4ce6ea0aacd8";
|
|
|
|
private const String PUB_KEY_E6 = "d9f19e4687f8217160a826eba3fab9eada1db912a7d426d95114b1617c7596bf220b391fd5bed10a46aa2d3c4a09842ebe409555e91940376675ed324e770449f8707bc318e7cef77110feac74d800d4ed6d1c731633109c3ab2ea6c62f4bdb8";
|
|
|
|
private const String PUB_KEY_R10 = "CF57E5E6C45412EDB447FEC92758764650288C1D3E88DF059DD5B51829BDDDB55ABFFAF6CEA3BEAF00214B625A5A3C012FC55803F689FF8E1143EBC1B5E01407968F6F1FD7E7BA8139097565B7C2AF185B372628E7A3F4072B6D1AFFAB58BC95AE40FFE9CB57C4B55B7F780D1861BC17E754C6BB4991CD6E18D18085EEA66536BC74EABC504CEAFC21F338169394BAB0D36B3806CD16127ACA5275C8AD76B2C29C5D98455C6F617BC62DEE3C13528601D957E6381CDF8DB51F92919AE74A1CCC45A87255F0B0E6A307ECFDA71B669E3F488B71847158C93AFAEF5EF25B442B3C74E78FB247C1076ACD9AB70D96F712812651540AEC61F6F7F5E2F28AC8950D8D0203010001";
|
|
|
|
private const String PUB_KEY_R11 = "BA87BC5C1B0039CBCA0ACDD46710F9013CA54EA561CB26CA52FB1501B7B928F5281EED27B324183967090C08ECE03AB03B770EBDF3E53954410C4EAE41D69974DE51DBEF7BFF58BDA8B713F6DE31D5F272C9726A0B8374959C4600641499F3B1D922D9CDA892AA1C267A3FFEEF58057B089581DB710F8EFBE33109BB09BE504D5F8F91763D5A9D9E83F2E9C466B3E106664348188065A037189A9B843297B1B2BDC4F815009D2788FBE26317966C9B27674BC4DB285E69C279F0495CE02450E1C4BCA105AC7B406D00B4C2413FA758B82FC55C9BA5BB099EF1FEEBB08539FDA80AEF45C478EB652AC2CF5F3CDEE35C4D1BF70B272BAA0B4277534F796A1D87D90203010001";
|
|
|
|
|
|
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_R10.ToLower()) ||
|
|
pk.Contains(PUB_KEY_R11.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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Führt die Änderungen an den Datenbanken durch bzw. das Anlegen.
|
|
/// </summary>
|
|
/// <param name="serverResponse">Die Antwort des Servers mit den Stati als Json-String.</param>
|
|
/// <returns>Der Rückgabetyp bei asynchronen Methoden ist Task, wenn er sonst void wäre.</returns>
|
|
private static async Task ExecuteDatabaseChanges(string serverResponse)
|
|
{
|
|
var contractStatusCollection = serverResponse is null ? new ContractStatusCollection() : JsonConvert.DeserializeObject<ContractStatusCollection>(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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extrahiert die MySQL-Verbindung aus der Config-File.
|
|
/// </summary>
|
|
/// <param name="configPath">Pfad zur Config-File.</param>
|
|
/// <returns>Gibt die MySQL-Verbindung zurück.</returns>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extrahiert Server, Password, User ID und Port aus dem ConnectionString der Config-Datei.
|
|
/// </summary>
|
|
/// <param name="connectionString"></param>
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Datenbank wird angelegt oder reaktiviert.
|
|
/// </summary>
|
|
/// <param name="tenant">Kundennummer der zu anlegenden oder reaktivierenden Datenbank.</param>
|
|
/// <param name="contractStatus">ContractStatus der anzulegenden oder reaktivierenden Datenbank.</param>
|
|
/// <returns>Der Rückgabetyp bei asynchronen Methoden ist Task, wenn er sonst void wäre.</returns>
|
|
private static async Task ActivateDatabase(string tenant, ContractStatus contractStatus)
|
|
{
|
|
var connectionString = $"Server={_ConnectionStringServer};Password={_ConnectionStringPassword};User ID={_ConnectionStringUserID};Port={_ConnectionStringPort}";
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Löscht die angegebene Datenbank.
|
|
/// </summary>
|
|
/// <param name="tenant">Kundennummer, die gleichzeitig auch der Name der Datenbank ist.</param>
|
|
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);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Entfernt oder fügt ".deactivated" an die Config-Datei.
|
|
/// </summary>
|
|
/// <param name="tenant">Kundennummer der zu de- bwz. reaktivierenden Datenbank.</param>
|
|
/// <param name="isToBeActivated">Ob de- oder reaktiviert werden soll.</param>
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Erzeugt eine neue Datenbank, passt sie dem neuesten Stand an und füllt sie mit Basisdaten.
|
|
/// </summary>
|
|
/// <param name="tenant">Kundennummer der neuen Datenbank.</param>
|
|
/// <param name="connectionString">MySQL-Verbindung aus der Config-Datei.</param>
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Erzeugt und schickt das Initialpasswort für eine neue Datenbank an das Tool mit Hilfe des apiKeys.
|
|
/// </summary>
|
|
/// <param name="contractStatus">ContractStatus für den eine neue Datenbank angelegt werden soll.</param>
|
|
/// <param name="apiKey">Der für das Tool nötige API-Key.</param>
|
|
/// <returns>Der Rückgabetyp bei asynchronen Methoden ist Task, wenn er sonst void wäre.</returns>
|
|
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<InitialPasswordResponse>(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);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Lädt die Stati für die Datenbanken, die geändert werden sollen.
|
|
/// </summary>
|
|
/// <param name="serverName">Name des Servers, z.B. "app6.bewoplaner.de"</param>
|
|
/// <param name="debugUri">Uri für zum Testen. Wird nur im Debug-Modus benutzt</param>
|
|
/// <returns></returns>
|
|
private static async Task<string> 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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|