2022-10-11 16:48:36 +02:00
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
{
2024-01-24 13:29:51 +01:00
private const string APIKEY = "CwjlSCbNqctEsofpGY64Z4aO6pShNYAdGtjMqHsjO64FuK23qoRDUqIjUC0P" ;
2022-10-11 16:48:36 +02:00
private static string _ConnectionStringServer ;
private static string _ConnectionStringPassword ;
private static string _ConnectionStringUserID ;
private static string _ConnectionStringPort ;
private static string _MultitenancyPath ;
2024-02-01 01:06:46 +01:00
private static string _BackupConfigFolderPath ;
2022-10-11 16:48:36 +02:00
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 ;
}
2024-09-01 20:47:02 +02:00
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" ;
2022-10-11 16:48:36 +02:00
private static bool PinPublicKey ( object sender , X509Certificate certificate , X509Chain chain , SslPolicyErrors sslpolicyerrors )
{
try
{
2024-09-01 20:47:02 +02:00
if ( certificate = = null | | chain = = null )
2022-10-11 16:48:36 +02:00
return false ;
2024-09-01 20:47:02 +02:00
bool chainContainsPk = false ;
2022-10-11 16:48:36 +02:00
2024-09-01 20:47:02 +02:00
foreach ( var element in chain . ChainElements )
2022-10-11 16:48:36 +02:00
{
2024-09-01 20:47:02 +02:00
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 ( ) ) )
2022-10-11 16:48:36 +02:00
{
2024-09-01 20:47:02 +02:00
chainContainsPk = true ;
2022-10-11 16:48:36 +02:00
}
}
2024-09-01 20:47:02 +02:00
bool subjectAccepted = certificate . Subject . Trim ( ) . ToLower ( ) . EndsWith ( ".bewoplaner.de" ) | |
certificate . Subject . Trim ( ) . ToLower ( ) . EndsWith ( ".ownchat.de" ) ;
return chainContainsPk & & subjectAccepted ;
2022-10-11 16:48:36 +02:00
}
2024-09-01 20:47:02 +02:00
catch ( Exception e )
2022-10-11 16:48:36 +02:00
{
return false ;
}
2024-09-01 20:47:02 +02:00
2022-10-11 16:48:36 +02:00
}
2024-09-01 20:47:02 +02:00
2022-10-11 16:48:36 +02:00
private static async Task Main ( string [ ] args )
{
ServicePointManager . SecurityProtocol = SecurityProtocolType . Tls12 ;
PinCertificate ( ) ;
_ServerName = ConfigurationManager . AppSettings [ "ServerName" ] ;
_MultitenancyPath = ConfigurationManager . AppSettings [ "MultitenancyPath" ] ;
2024-02-01 01:06:46 +01:00
_BackupConfigFolderPath = ConfigurationManager . AppSettings [ "BackupConfigFolderPath" ] ;
2022-10-11 16:48:36 +02:00
_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" ] ;
2024-01-16 18:42:02 +01:00
if ( ! Directory . Exists ( _LogFilePath ) )
{
Directory . CreateDirectory ( _LogFilePath ) ;
}
2022-10-11 16:48:36 +02:00
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 ) ;
2024-08-07 16:26:43 +02:00
foreach ( var contractStatusKeyValuePair in contractStatusCollection . ContractStatuses )
2022-10-11 16:48:36 +02:00
{
var contractStatus = contractStatusKeyValuePair . Value ;
2024-02-21 16:53:55 +01:00
//if (contractStatus.Tenant == "5564670353")
//{
2024-01-16 18:42:02 +01:00
2024-02-21 16:53:55 +01:00
//}
//else
//{
// continue;
//}
2024-01-16 18:42:02 +01:00
if ( contractStatus . Activate = = 1 )
2022-10-11 16:48:36 +02:00
{
FileUtils . WriteLog ( $"Aktiviere/Erstelle Datenbank `{contractStatus.Tenant}`." , _LogFilePath ) ;
await ActivateDatabase ( contractStatus . Tenant , contractStatus ) ;
}
if ( contractStatus . Deactivate = = 1 )
{
FileUtils . WriteLog ( $"Deaktiviere Datenbank `{contractStatus.Tenant}`." , _LogFilePath ) ;
2024-08-07 16:26:43 +02:00
ToggleConfigActivation ( contractStatus , false ) ;
ToggleBackupConfigActivation ( contractStatus , false ) ;
2024-02-01 01:06:46 +01:00
2022-10-11 16:48:36 +02:00
}
if ( contractStatus . Delete = = 1 )
{
2024-08-07 16:26:43 +02:00
FileUtils . WriteLog ( $"Lösche Datenbank `{contractStatus.Tenant}`." , _LogFilePath ) ;
DeleteDatabase ( contractStatus ) ;
2022-10-11 16:48:36 +02:00
}
}
}
}
/// <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
2024-01-16 18:42:02 +01:00
if ( File . Exists ( configFilePath ) )
2022-10-11 16:48:36 +02:00
{
2024-01-16 18:42:02 +01:00
FileUtils . WriteLog ( $"Die Config-Datei '{configFilePath}' existiert. Nix muss gemacht werden" , _LogFilePath ) ;
//Nichts machen
2022-10-11 16:48:36 +02:00
2024-01-16 18:42:02 +01:00
//FileUtils.WriteLog($"Die Config-Datei '{configFilePath}' existiert.", _LogFilePath);
//connectionString = isExisting ? ExtractConnectionString(configFilePath) : connectionString;
//if(!isExisting)
//{
// RunCreateScripts(tenant, connectionString);
//}
2022-10-11 16:48:36 +02:00
}
// Config-Datei ist deaktiviert
2024-02-21 16:53:55 +01:00
else if ( File . Exists ( Path . Combine ( _MultitenancyPath , $"{tenant}.config.deactivated" ) ) )
2022-10-11 16:48:36 +02:00
{
FileUtils . WriteLog ( $"Die Config-Datei '{tenant}.config.deactivated' existiert." , _LogFilePath ) ;
2024-01-16 18:42:02 +01:00
//connectionString = isExisting ? ExtractConnectionString(configFilePath) : connectionString;
2022-10-11 16:48:36 +02:00
2024-01-24 13:29:51 +01:00
ToggleConfigActivation ( contractStatus , true ) ;
2024-02-01 01:06:46 +01:00
ToggleBackupConfigActivation ( contractStatus , true ) ;
2024-01-16 18:42:02 +01:00
//if(!isExisting)
//{
// RunCreateScripts(tenant, connectionString);
//}
2022-10-11 16:48:36 +02:00
}
// Config-Datei existiert nicht
else
{
FileUtils . WriteLog ( $"Die Config-Datei '{configFilePath}' existiert nicht." , _LogFilePath ) ;
2024-02-21 16:53:55 +01:00
if ( ! isExisting )
{
RunCreateScripts ( tenant , connectionString ) ;
await SendInitialPasswordToTool ( contractStatus ) ;
}
2022-10-11 16:48:36 +02:00
}
}
/// <summary>
/// Löscht die angegebene Datenbank.
/// </summary>
/// <param name="tenant">Kundennummer, die gleichzeitig auch der Name der Datenbank ist.</param>
2024-01-24 13:29:51 +01:00
private static void DeleteDatabase ( ContractStatus contractStatus )
2022-10-11 16:48:36 +02:00
{
2024-08-07 16:26:43 +02:00
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 ) )
2022-10-11 16:48:36 +02:00
{
2024-08-07 16:26:43 +02:00
var deleteFile = Path . Combine ( _MultitenancyPath , $"{contractStatus.Tenant}.config.deleted" ) ;
if ( ! File . Exists ( deleteFile ) )
{
File . Move ( deactivatedFile , deleteFile ) ;
}
var connectionString = ExtractConnectionString ( deleteFile ) ;
2022-10-11 16:48:36 +02:00
var mySqlHelper = new MySqlHelper ( connectionString ) ;
2024-01-24 13:29:51 +01:00
mySqlHelper . DeleteDatabase ( contractStatus . Tenant ) ;
2022-10-11 16:48:36 +02:00
2024-08-07 16:26:43 +02:00
//File.Delete(deactivatedFile);
2022-10-11 16:48:36 +02:00
2024-01-24 13:29:51 +01:00
FileUtils . WriteLog ( $"Datenbank `{contractStatus.Tenant}` und {contractStatus.Tenant}.config.deactivated wurden gelöscht." , _LogFilePath ) ;
SendDBStatusToTool ( contractStatus , false , true ) ;
2022-10-11 16:48:36 +02:00
}
else
{
2024-08-07 16:26:43 +02:00
LogUtils . LogMessage ( $"Die Config-Datei (*.config.deactivated) für Datenbank `{contractStatus.Tenant}` existiert nicht." , ConsoleColor . Red , ConsoleColor . Black ) ;
2024-01-24 13:29:51 +01:00
FileUtils . WriteLog ( $"{contractStatus.Tenant}.config nicht gefunden. Datenbank `{contractStatus.Tenant}`, falls vorhanden, nicht gelöscht." , _LogFilePath ) ;
2022-10-11 16:48:36 +02:00
}
}
/// <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>
2024-01-24 13:29:51 +01:00
private static void ToggleConfigActivation ( ContractStatus contractStatus , bool isToBeActivated )
2022-10-11 16:48:36 +02:00
{
2024-01-24 13:29:51 +01:00
var fileName1 = isToBeActivated ? $"{contractStatus.Tenant}.config.deactivated" : $"{contractStatus.Tenant}.config" ;
var fileName2 = isToBeActivated ? $"{contractStatus.Tenant}.config" : $"{contractStatus.Tenant}.config.deactivated" ;
2022-10-11 16:48:36 +02:00
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 ) ;
2024-01-24 13:29:51 +01:00
if ( ! isToBeActivated )
{
SendDBStatusToTool ( contractStatus , true , false ) ;
}
2022-10-11 16:48:36 +02:00
}
2024-01-24 13:29:51 +01:00
FileUtils . WriteLog ( $"{contractStatus.Tenant}.config {(isToBeActivated == false ? " de " : string.Empty)}aktiviert." , _LogFilePath ) ;
2022-10-11 16:48:36 +02:00
}
else
{
FileUtils . WriteLog ( $"Fehler beim {(isToBeActivated == false ? " Dea " : " A ")}ktivieren: {fileName1} existiert nicht oder {fileName2} existiert." , _LogFilePath ) ;
}
}
2024-02-01 01:06:46 +01:00
private static void ToggleBackupConfigActivation ( ContractStatus contractStatus , bool isToBeActivated )
{
2024-08-07 16:26:43 +02:00
if ( ! String . IsNullOrEmpty ( _BackupConfigFolderPath ) )
{
var fileName1 = isToBeActivated ? $"{contractStatus.Tenant}.db2mail.deactivated" : $"{contractStatus.Tenant}.db2mail" ;
var fileName2 = isToBeActivated ? $"{contractStatus.Tenant}.db2mail" : $"{contractStatus.Tenant}.db2mail.deactivated" ;
2024-02-01 01:06:46 +01:00
2024-08-07 16:26:43 +02:00
var path1 = Path . Combine ( _BackupConfigFolderPath , fileName1 ) ;
var path2 = Path . Combine ( _BackupConfigFolderPath , fileName2 ) ;
2024-02-01 01:06:46 +01:00
2024-08-07 16:26:43 +02:00
if ( File . Exists ( path1 ) & & ! File . Exists ( path2 ) )
2024-02-01 01:06:46 +01:00
{
2024-08-07 16:26:43 +02:00
File . Move ( path1 , path2 ) ;
if ( File . Exists ( path1 ) )
{
File . Delete ( path1 ) ;
2024-02-01 01:06:46 +01:00
2024-08-07 16:26:43 +02:00
}
2024-02-01 01:06:46 +01:00
2024-08-07 16:26:43 +02:00
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 ) ;
}
2024-02-01 01:06:46 +01:00
}
}
2022-10-11 16:48:36 +02:00
/// <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 )
{
2024-01-16 18:42:02 +01:00
#if DEBUG
if ( ! Directory . Exists ( _CreateScriptsFolderPath ) )
{
Directory . CreateDirectory ( _CreateScriptsFolderPath ) ;
}
if ( ! Directory . Exists ( _MultitenancyPath ) )
{
Directory . CreateDirectory ( _MultitenancyPath ) ;
}
#endif
2024-02-01 01:06:46 +01:00
if ( Directory . Exists ( _CreateScriptsFolderPath ) & & Directory . Exists ( _MultitenancyPath ) & & Directory . Exists ( _BackupConfigFolderPath ) )
2022-10-11 16:48:36 +02:00
{
2024-02-01 01:06:46 +01:00
FileUtils . GenerateNewConfigFile ( Path . Combine ( _MultitenancyPath , $"{tenant}.config" ) , connectionString , tenant ) ;
2024-02-21 16:53:55 +01:00
FileUtils . GenerateNewDBAdminFile ( Path . Combine ( _BackupConfigFolderPath , $"{tenant}.db2mail" ) , tenant , _ConnectionStringPort , _ConnectionStringUserID , _ConnectionStringPassword ) ;
2024-02-01 01:06:46 +01:00
2022-10-11 16:48:36 +02:00
var createScriptPath = Path . Combine ( _CreateScriptsFolderPath , _CreateScriptName ) ;
var changesScriptPath = Path . Combine ( _CreateScriptsFolderPath , _ChangesScriptName ) ;
var insertScriptPath = Path . Combine ( _CreateScriptsFolderPath , _InsertScriptName ) ;
2024-01-16 18:42:02 +01:00
if ( File . Exists ( createScriptPath ) & & File . Exists ( changesScriptPath ) & & File . Exists ( insertScriptPath ) )
2022-10-11 16:48:36 +02:00
{
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>
2024-01-24 13:29:51 +01:00
private static async Task SendInitialPasswordToTool ( ContractStatus contractStatus )
2022-10-11 16:48:36 +02:00
{
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 ) ;
}
2024-01-24 13:29:51 +01:00
if ( ! ( contractStatus is null ) & & databaseExists )
2022-10-11 16:48:36 +02:00
{
var password = PasswordHelper . GenerateInitialPassword ( new Random ( ) ) ;
2024-01-16 18:42:02 +01:00
2022-10-11 16:48:36 +02:00
2024-01-24 13:29:51 +01:00
var uri = new Uri ( $"https://support.bewoplaner.de/api/save_initialpw.php?APIKEY1={APIKEY}&LicenseTypeID={contractStatus.LicenseTypeId}&CustomerID={contractStatus.Tenant}&InitialPW={password}" ) ;
2022-10-11 16:48:36 +02:00
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
{
2024-01-24 13:29:51 +01:00
var logMessage = $"SendInitialPasswordToTool ContractStatus ist null" ;
2022-10-11 16:48:36 +02:00
2024-01-24 13:29:51 +01:00
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 )
2022-10-11 16:48:36 +02:00
{
2024-01-24 13:29:51 +01:00
t = "2" ;
2022-10-11 16:48:36 +02:00
}
2024-01-24 13:29:51 +01:00
var uri = new Uri ( $"https://support.bewoplaner.de/api/dbstate.php?APIKEY1={APIKEY}&LicenseTypeID={contractStatus.LicenseTypeId}&CustomerID={contractStatus.Tenant}&Type={t}" ) ;
2024-08-07 16:26:43 +02:00
2024-01-24 13:29:51 +01:00
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 ( ) ;
}
}
}
2022-10-11 16:48:36 +02:00
2024-01-24 13:29:51 +01:00
}
catch ( Exception exception )
2022-10-11 16:48:36 +02:00
{
2024-01-24 13:29:51 +01:00
FileUtils . WriteLog ( exception ? . ToString ( ) , _LogFilePath ) ;
2022-10-11 16:48:36 +02:00
}
2024-01-24 13:29:51 +01:00
}
else
{
var logMessage = $"SendDBStatusToTool ContractStatus ist null" ;
2022-10-11 16:48:36 +02:00
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 ;
}
}
}
}
}