From 3f9f42b5932f4f0dd6033f966263cf00357dde41 Mon Sep 17 00:00:00 2001 From: Rene Evertz Date: Thu, 6 Jun 2024 15:42:04 +0200 Subject: [PATCH] =?UTF-8?q?Logik=20=C3=BCbertragen=20-=20weitere=20Ausarbe?= =?UTF-8?q?itung?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BeWoLauncher/Logic/Behavior/LaunchBehavior.cs | 6 +- .../Logic/Controller/DownloadController.cs | 2 +- BeWoLauncher/Logic/Utils/LauncherPaths.cs | 2 +- Service/Service.csproj | 4 + .../DownloadBeWoServiceImp.cs | 127 ++--------- Service/ServiceUtils/Paths/ServerFilePaths.cs | 38 +++- .../ServiceUtils/Update/UpdateConfigReader.cs | 37 +++- .../ServiceUtils/Update/UpdateFileLimiter.cs | 23 ++ .../Update/UpdateFileResponseBuilder.cs | 45 +--- .../Update/UpdatePlanResponseBuilder.cs | 87 +++----- .../Update/UpdateRequestValidator.cs | 201 ++++++++++++++++++ .../Update/UpdateServerSession.cs | 19 ++ .../Update/UpdateServerSessionManager.cs | 145 +++++++++++++ .../DataContract/UpdateFileRequest.cs | 7 +- .../DataContract/UpdatePlanResponse.cs | 6 + 15 files changed, 523 insertions(+), 226 deletions(-) create mode 100644 Service/ServiceUtils/Update/UpdateFileLimiter.cs create mode 100644 Service/ServiceUtils/Update/UpdateRequestValidator.cs create mode 100644 Service/ServiceUtils/Update/UpdateServerSession.cs create mode 100644 Service/ServiceUtils/Update/UpdateServerSessionManager.cs diff --git a/BeWoLauncher/Logic/Behavior/LaunchBehavior.cs b/BeWoLauncher/Logic/Behavior/LaunchBehavior.cs index 8700ae914..1297a5074 100644 --- a/BeWoLauncher/Logic/Behavior/LaunchBehavior.cs +++ b/BeWoLauncher/Logic/Behavior/LaunchBehavior.cs @@ -89,7 +89,7 @@ namespace BeWoLauncher.Logic.Behavior { GenericTextLogger.Post(error); - ViewBehavior.ShowError(error); + ShowError(error); } } @@ -108,7 +108,7 @@ namespace BeWoLauncher.Logic.Behavior { GenericTextLogger.Post(error); - ViewBehavior.ShowError(error); + ShowError(error); } } @@ -124,7 +124,7 @@ namespace BeWoLauncher.Logic.Behavior { GenericTextLogger.Post(error); - ViewBehavior.ShowError(error); + ShowError(error); } } diff --git a/BeWoLauncher/Logic/Controller/DownloadController.cs b/BeWoLauncher/Logic/Controller/DownloadController.cs index a4cca168b..7024b29f8 100644 --- a/BeWoLauncher/Logic/Controller/DownloadController.cs +++ b/BeWoLauncher/Logic/Controller/DownloadController.cs @@ -121,6 +121,7 @@ namespace BeWoLauncher.Logic.Controller try { Manager.GetDeletePlan(); + return null; } catch (Exception e) @@ -140,7 +141,6 @@ namespace BeWoLauncher.Logic.Controller } - return false; } diff --git a/BeWoLauncher/Logic/Utils/LauncherPaths.cs b/BeWoLauncher/Logic/Utils/LauncherPaths.cs index d951f3631..c33c35692 100644 --- a/BeWoLauncher/Logic/Utils/LauncherPaths.cs +++ b/BeWoLauncher/Logic/Utils/LauncherPaths.cs @@ -83,7 +83,7 @@ namespace BeWoLauncher.Logic.Utils } public static string GetLoggerPath() { - return Path.Combine(new string[] { LauncherAppdataConfig.Location, "log" }); + return Path.Combine(new string[] { LauncherAppdataConfig.Location, "log", "update" }); } public static string GetDownloadPath() { diff --git a/Service/Service.csproj b/Service/Service.csproj index f18d88560..fcd5864df 100644 --- a/Service/Service.csproj +++ b/Service/Service.csproj @@ -510,8 +510,12 @@ + + + + diff --git a/Service/ServiceImplementations/DownloadBeWoServiceImp.cs b/Service/ServiceImplementations/DownloadBeWoServiceImp.cs index 523554d42..f7feca60a 100644 --- a/Service/ServiceImplementations/DownloadBeWoServiceImp.cs +++ b/Service/ServiceImplementations/DownloadBeWoServiceImp.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using System.Net; using System.ServiceModel; +using System.Threading; using System.Xml; using BeWo.Data; using BeWo.Service.ServiceContracts; @@ -22,8 +23,6 @@ namespace BeWo.Service.ServiceImplementations [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)] public class DownloadBeWoServiceImp : IDownloadBeWoService { - private string GETSERVER_URL = "https://support.bewoplaner.de/api/getserver.php?k={0}&t=0"; - public string Tenant => MultitenancyOperationContextExt.Current.Tenant; public UpdatePlanResponse GetUpdatePlan(UpdatePlanRequest request) @@ -38,14 +37,10 @@ namespace BeWo.Service.ServiceImplementations { GenericTextLogger.Post("Validiere Plan Request."); - ValidatePlanRequest(request); - - GenericTextLogger.Post("Plan Request erfolreich validiert. Verifiziere Login."); - - VerifyLogin(request.Login); - - GenericTextLogger.Post("Login verifiziert. Baue Antwort."); + UpdateRequestValidator.ValidatePlanRequest(request); + GenericTextLogger.Post("Plan Request erfolreich validiert. Baue Antwort."); + UpdatePlanResponseBuilder.BuildResponse(request, Tenant, response); response.Successful = true; @@ -77,69 +72,13 @@ namespace BeWo.Service.ServiceImplementations response.Error = e.ToString(); } + if(response.Error is object) + { + Thread.Sleep(3000); + } + return response; } - - private void ValidatePlanRequest(UpdatePlanRequest request) - { - if (!TryValidatePlanRequest(request)) - throw new UpdateException("Kann Request nicht bestätigen"); - } - private bool TryValidatePlanRequest(UpdatePlanRequest request) - { - if (request.PlanerRootFolderExists) - { - // ... - } - else - { - // Root Folder ex. nicht - if (request.DownloadFolderExists) - return false; - - if (!request.DownloadFolderIsEmpty) - return false; - - if (request.ApplyFolderExists) - return false; - - if (!request.ApplyFolderIsEmpty) - return false; - } - - return true; - } - - private void VerifyLogin(LoginDC login) => VerifyLogin(login.Username, login.Password, Tenant, login.Pin, login.ClientID); - private void VerifyLogin(string username, string password, string tenant, string pin, string clientid) - { - string server_address = string.Empty; - - try - { - SessionInformation.Login.Username = username; - SessionInformation.Login.Password = password; - SessionInformation.Login.Tenant = tenant; - - server_address = GetServerFromTenant(); - -#if DEBUG - server_address = "http://localhost:3777/Host"; -#endif - - ServiceFacade.UpdateServerAddresses(server_address); - - var result = ServiceFacade.DoLauncherServiceSync(x => x.IsUserValid(username, password, pin, clientid, true)); - - if (result != BS.SharedLauncher.Enums.UserValidationResult.UserValid) - throw new HideClientUpdateException("Kann Anmeldung nicht bestätigen!"); - } - catch (Exception e) - { - throw new HideClientUpdateException("Kann Anmeldung nicht bestätigen! ", e); - } - } - public UpdateFileResponse GetUpdateFile(UpdateFileRequest request) { GenericTextLogger.Init(ServerFilePaths.GetLogFolderPath(Tenant)); @@ -152,17 +91,13 @@ namespace BeWo.Service.ServiceImplementations { GenericTextLogger.Post("Validiere File Request."); - // ValidatePlanRequest(request); + UpdateRequestValidator.ValidateFileRequest(request); GenericTextLogger.Post("Plan Request erfolreich validiert."); GenericTextLogger.PostArrow($"File: {request.UpdateFile.RelativePath}"); - GenericTextLogger.Post("Verifiziere Login."); - - VerifyLogin(request.Login); - - GenericTextLogger.Post("Login verifiziert. Baue Antwort."); + GenericTextLogger.Post("Baue Antwort."); UpdateFileResponseBuilder.BuildResponse(request, Tenant, response); @@ -195,43 +130,13 @@ namespace BeWo.Service.ServiceImplementations response.Error = e.ToString(); } + if(response.Error is object) + { + Thread.Sleep(3000); + } + return response; } - private bool isUpdateFileRequestValid(UpdateFileRequest request) - { - // Check for Login - // Check for Correct Version - // Check for File Permissions - - return true; - } - private string GetServerFromTenant(string tenant = null) - { - if (tenant is null) - tenant = SessionInformation.Login.Tenant; - - if (tenant == "demo") - return null; - - try - { - - String url = String.Format(GETSERVER_URL, tenant); - using (WebClient client = new WebClient()) - { - //MessageBox.Show(hostAddress); - byte[] response = client.UploadValues(url, "POST", new NameValueCollection()); - - String server = System.Text.Encoding.ASCII.GetString(response); - - return $"https://{server}/service"; - } - } - catch (Exception ex) - { - throw new HideClientUpdateException("Login konnte nicht verifiziert werden.", ex); - } - } public bool TestConnection() { diff --git a/Service/ServiceUtils/Paths/ServerFilePaths.cs b/Service/ServiceUtils/Paths/ServerFilePaths.cs index 1607c89ea..b5aa17055 100644 --- a/Service/ServiceUtils/Paths/ServerFilePaths.cs +++ b/Service/ServiceUtils/Paths/ServerFilePaths.cs @@ -1,4 +1,6 @@ -using System; +using BS.SharedLauncher.Enums; +using BS.SharedLauncher.Exceptions; +using System; using System.Collections.Generic; using System.Configuration; using System.IO; @@ -58,10 +60,38 @@ namespace BeWo.Service.ServiceUtils.Paths private static string GetVersionFolderPath(string version) => Path.Combine(VersionsFilePath, version); - public static string GetSpecialTenantFolderPath(string tenant) => Path.Combine(SpecialTenantFilesPath, tenant); + private static string GetSpecialTenantFolderPath(string tenant) => Path.Combine(SpecialTenantFilesPath, tenant); + private static string GetVersionTenantFolderPath(string version, string tenant) => Path.Combine(GetVersionFolderPath(version), tenant); + private static string GetVersionDefaultFolderPath(string version) => GetVersionTenantFolderPath(version, "default"); - public static string GetVersionTenantFolderPath(string version, string tenant) => Path.Combine(GetVersionFolderPath(version), tenant); - public static string GetVersionDefaultFolderPath(string version) => GetVersionTenantFolderPath(version, "default"); + public static string GetSourceFolderPath(UpdateFileSource source, string version, string tenant) + { + switch (source) + { + case UpdateFileSource.Invalid: + throw new UpdateException("Invalid UpdateFileSource"); + + case UpdateFileSource.VersionDefault: + return GetVersionDefaultFolderPath(version); + + case UpdateFileSource.VersionTenant: + return GetVersionTenantFolderPath(version, tenant); + + case UpdateFileSource.VersionUser: + break; + + case UpdateFileSource.OverrideTenant: + return GetSpecialTenantFolderPath(tenant); + + case UpdateFileSource.OverrideUser: + break; + default: + break; + } + + // User bekommt eigene Daten Feature + throw new UpdateException("UpdateFileSourceType Unknown: " + source.ToString()); + } public static string GetLogFolderPath(string tenant) => Path.Combine(LogPath, tenant); } diff --git a/Service/ServiceUtils/Update/UpdateConfigReader.cs b/Service/ServiceUtils/Update/UpdateConfigReader.cs index 22d178066..0ca3546d9 100644 --- a/Service/ServiceUtils/Update/UpdateConfigReader.cs +++ b/Service/ServiceUtils/Update/UpdateConfigReader.cs @@ -1,4 +1,5 @@ -using BS.SharedLauncher.Enums; +using BeWo.Service.ServiceUtils.Paths; +using BS.SharedLauncher.Enums; using System; using System.Collections.Generic; using System.Linq; @@ -8,12 +9,34 @@ using System.Xml; namespace BeWo.Service.ServiceUtils.Update { - public class UpdateConfigReader + public static class UpdateConfigReader { - private XmlDocument Document{ get; set; } + public static Tuple GetDefaultTenantVersion(string tenant) + { + var reader = new UpdateConfigReaderClient(ServerFilePaths.UpdateConfigPath, tenant); + + return new Tuple(reader.GetDefaultVersion(), reader.GetSpecificVersion()); + } + + public static string GetValidVersion(string tenant) + { + var tuple = GetDefaultTenantVersion(tenant); + + return GetValidVersion(tuple.Item1, tuple.Item2); + } + + public static string GetValidVersion(string default_version, string tenant_version) + { + return tenant_version ?? default_version; + } + } + + internal class UpdateConfigReaderClient + { + private XmlDocument Document { get; set; } private string Tenant { get; set; } - public UpdateConfigReader(string configFilePath, string tenant) + internal UpdateConfigReaderClient(string configFilePath, string tenant) { Document = new XmlDocument(); Document.Load(configFilePath); @@ -22,16 +45,16 @@ namespace BeWo.Service.ServiceUtils.Update } //public PlanerUpdateSource Source => GotSpecialVersion ? PlanerUpdateSource.SpecialVersion : PlanerUpdateSource.NewestVersion; - + public string GetSpecificVersion() { try { - return Document.SelectSingleNode($"/config/versions/tenant[@id='{Tenant}']/version")?.InnerXml; + return Document.SelectSingleNode($"/config/versions/tenant[@id='{Tenant}']/version").InnerXml; } catch (Exception) { - return null; + return null; } } diff --git a/Service/ServiceUtils/Update/UpdateFileLimiter.cs b/Service/ServiceUtils/Update/UpdateFileLimiter.cs new file mode 100644 index 000000000..09911c687 --- /dev/null +++ b/Service/ServiceUtils/Update/UpdateFileLimiter.cs @@ -0,0 +1,23 @@ +using BS.SharedLauncher.DataContract; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BeWo.Service.ServiceUtils.Update +{ + public class UpdateFileLimiter + { + public UpdateFileDC UpdateFile { get; set; } + public int RequestsLeft { get; set; } + + public bool CanRequestMore + { + get + { + return RequestsLeft > 0; + } + } + } +} diff --git a/Service/ServiceUtils/Update/UpdateFileResponseBuilder.cs b/Service/ServiceUtils/Update/UpdateFileResponseBuilder.cs index 9ad7890f6..5ab75215e 100644 --- a/Service/ServiceUtils/Update/UpdateFileResponseBuilder.cs +++ b/Service/ServiceUtils/Update/UpdateFileResponseBuilder.cs @@ -18,59 +18,20 @@ namespace BeWo.Service.ServiceUtils.Update private static string _Version; private static string _Tenant; - private static UpdateFileRequest _Request; private static UpdateFileResponse _Response; public static void BuildResponse(UpdateFileRequest request, string tenant, UpdateFileResponse response) { _Response = response; _Tenant = tenant; - _Request = request; _Version = request.Version; - calculate(); + calculate(request.UpdateFile.AbsolutePath); } - private static void calculate() + private static void calculate(string path) { - var relative_path = _Request.UpdateFile.RelativePath; - var path = Path.Combine(getSourceFolderPath(), relative_path); - - var file_data = File.ReadAllBytes(path); - - if (file_data.Length > 512 * 1024 * 1024 - 1) - throw new HideClientUpdateException($"Die angefragte File \"{relative_path}\" überschreitet die maximale Größe von 512 MB."); - - _Response.FileData = file_data; - } - - private static string getSourceFolderPath() - { - switch (_Request.UpdateFile.Source) - { - case BS.SharedLauncher.Enums.UpdateFileSource.Invalid: - throw new UpdateException("Invalid UpdateFileSource"); - - case BS.SharedLauncher.Enums.UpdateFileSource.VersionDefault: - return ServerFilePaths.GetVersionDefaultFolderPath(_Version); - - case BS.SharedLauncher.Enums.UpdateFileSource.VersionTenant: - return ServerFilePaths.GetVersionTenantFolderPath(_Version, _Tenant); - - case BS.SharedLauncher.Enums.UpdateFileSource.VersionUser: - break; - - case BS.SharedLauncher.Enums.UpdateFileSource.OverrideTenant: - return ServerFilePaths.GetSpecialTenantFolderPath(_Tenant); - - case BS.SharedLauncher.Enums.UpdateFileSource.OverrideUser: - break; - default: - break; - } - - // User bekommt eigene Daten Feature - throw new HideClientUpdateException("#479839129"); + _Response.FileData = File.ReadAllBytes(path); } } } diff --git a/Service/ServiceUtils/Update/UpdatePlanResponseBuilder.cs b/Service/ServiceUtils/Update/UpdatePlanResponseBuilder.cs index e906b7c25..052a4caa2 100644 --- a/Service/ServiceUtils/Update/UpdatePlanResponseBuilder.cs +++ b/Service/ServiceUtils/Update/UpdatePlanResponseBuilder.cs @@ -27,69 +27,35 @@ namespace BeWo.Service.ServiceUtils.Update { _Response = response; + var (default_version, tenant_version) = UpdateConfigReader.GetDefaultTenantVersion(tenant); + _Version = UpdateConfigReader.GetValidVersion(default_version, tenant_version); + _Tenant = tenant; _Request = request; - ReadUpdateConfig(out string default_version, out string special_version); - _Response.CurrentPackage = new UpdatePlanDC { DefaultVersion = default_version, - TenantVersion = special_version + TenantVersion = tenant_version }; - _Version = _Response.CurrentPackage.Version; + // Lädt komplettes Paket ohne Hash + CalcFullPackage(); - try - { - // Lädt komplettes Paket ohne Hash - CalcFullPackage(); + // Lade Hash Werte + _Response.CurrentPackage.LoadHash(); - // Lade Hash Werte - _Response.CurrentPackage.LoadHash(); + CalcFilesToRequest(); - CalcFilesToRequest(); + if (!_Request.ApplyFolderIsEmpty) + CalcFilesToDeleteInApply(); - if (!_Request.ApplyFolderIsEmpty) - CalcFilesToDeleteInApply(); + if (!_Request.DownloadFolderIsEmpty) + CalcFilesToApplyInDownload(); - if (!_Request.DownloadFolderIsEmpty) - CalcFilesToApplyInDownload(); + CalcDownloadSize(); - CalcDownloadSize(); - } - catch(Exception e) - { - throw new HideClientUpdateException("Erstellprozess gescheitert", e); - } - } - - private static void ReadUpdateConfig(out string default_version, out string special_version) - { - string path = GetUpdateConfigPath(); - - try - { - var reader = new UpdateConfigReader(path, _Tenant); - - default_version = reader.GetDefaultVersion(); - special_version = reader.GetSpecificVersion(); - } - catch(Exception e) - { - throw new HideClientUpdateException($"Konnte UpdateConfig File für \"{_Tenant}\" nicht lesen.", e); - } - } - private static string GetUpdateConfigPath() - { - try - { - return ServerFilePaths.UpdateConfigPath; - } - catch (Exception e) - { - throw new HideClientUpdateException($"Konnte UpdateConfig Path für \"{_Tenant}\" nicht lesen.", e); - } + _Response.HasToDo = _Response.HasToDo(); } private static void CalcFullPackage() @@ -122,6 +88,7 @@ namespace BeWo.Service.ServiceUtils.Update _Response.FilesToRequest.Add(file); } } + private static void CalcFilesToDeleteInApply() { foreach (var file in _Request.ApplyPackage.Files) @@ -129,13 +96,14 @@ namespace BeWo.Service.ServiceUtils.Update // Datei wird gebraucht if (_Response.CurrentPackage.ContainsPlanerFile(file)) continue; - + if (_Response.FilesToDeleteInApply is null) _Response.FilesToDeleteInApply = new List(); _Response.FilesToDeleteInApply.Add(file); } } + private static void CalcFilesToApplyInDownload() { foreach (var file in _Request.DownloadedFiles) @@ -150,6 +118,7 @@ namespace BeWo.Service.ServiceUtils.Update _Response.FilesToApply.Add(file); } } + private static void CalcDownloadSize() { if (_Response.FilesToRequest is null || !_Response.FilesToRequest.Any()) @@ -166,13 +135,20 @@ namespace BeWo.Service.ServiceUtils.Update _Response.DownloadSize = count; } - private static List getVersionDefaultFiles(string version) => getPlanerFiles(ServerFilePaths.GetVersionDefaultFolderPath(version), UpdateFileSource.VersionDefault, false); - private static List getVersionTenantFiles(string version, string tenant) => getPlanerFiles(ServerFilePaths.GetVersionTenantFolderPath(version, tenant), UpdateFileSource.VersionTenant, true); - private static List getSpecialTenantFiles(string tenant) => getPlanerFiles(ServerFilePaths.GetSpecialTenantFolderPath(tenant), UpdateFileSource.OverrideTenant, true); + private static List getVersionDefaultFiles(string version) + => getPlanerFiles(ServerFilePaths.GetSourceFolderPath(UpdateFileSource.VersionDefault, version, null), + UpdateFileSource.VersionDefault, false); + private static List getVersionTenantFiles(string version, string tenant) + => getPlanerFiles(ServerFilePaths.GetSourceFolderPath(UpdateFileSource.VersionTenant, version, tenant), + UpdateFileSource.VersionTenant, true); + private static List getSpecialTenantFiles(string tenant) + => getPlanerFiles(ServerFilePaths.GetSourceFolderPath(UpdateFileSource.OverrideTenant, null, tenant), + UpdateFileSource.OverrideTenant, true); private static List getPlanerFiles(string path, UpdateFileSource source, bool ignoreOnError) { - if (!Directory.Exists(path)) { + if (!Directory.Exists(path)) + { if (ignoreOnError) return new List(); else @@ -190,6 +166,9 @@ namespace BeWo.Service.ServiceUtils.Update if (update.GetExtensionType() == ".xml") return true; + if (update.GetExtensionType() == ".pdb") + return true; + return false; } } diff --git a/Service/ServiceUtils/Update/UpdateRequestValidator.cs b/Service/ServiceUtils/Update/UpdateRequestValidator.cs new file mode 100644 index 000000000..6dac884f5 --- /dev/null +++ b/Service/ServiceUtils/Update/UpdateRequestValidator.cs @@ -0,0 +1,201 @@ +using BeWo.Data; +using BeWo.Service.ServiceProxy; +using BS.SharedLauncher.DataContract; +using BS.SharedLauncher.Enums; +using BS.SharedLauncher.Exceptions; +using BS.SharedLauncher.Information; +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; + +namespace BeWo.Service.ServiceUtils.Update +{ + public static class UpdateRequestValidator + { + private static string GETSERVER_URL = "https://support.bewoplaner.de/api/getserver.php?k={0}&t=0"; + + public static string Tenant => MultitenancyOperationContextExt.Current.Tenant; + + public static void ValidatePlanRequest(UpdatePlanRequest request) + { + ValidateLogin(request); + + if (!TryValidatePlanRequestProperties(request)) + throw new HideClientUpdateException("Kann Request nicht bestätigen"); + } + + public static void ValidateFileRequest(UpdateFileRequest request) + { + if (!TryValidateFileRequestProperties(request)) + throw new HideClientUpdateException("Kann Request nicht bestätigen"); + + if (!TryValidateVersion(request, Tenant)) + throw new HideClientUpdateException("Kann Request nicht bestätigen"); + + if (!TryValidateSource(request)) + throw new HideClientUpdateException("Kann Request nicht bestätigen"); + + ValidateSession(request, Tenant); + } + + private static bool TryValidatePlanRequestProperties(UpdatePlanRequest request) + { + if (request.PlanerRootFolderExists) + { + // ... + } + else + { + // Root Folder ex. nicht + if (request.DownloadFolderExists) + return false; + + if (!request.DownloadFolderIsEmpty) + return false; + + if (request.ApplyFolderExists) + return false; + + if (!request.ApplyFolderIsEmpty) + return false; + } + + return true; + } + + private static void ValidateLogin(UpdatePlanRequest request) => ValidateLogin(request.Login); + private static void ValidateLogin(LoginDC login) => ValidateLogin(login.Username, login.Password, Tenant, login.Pin, login.ClientID); + private static void ValidateLogin(string username, string password, string tenant, string pin, string clientid) + { + string server_address = string.Empty; + + try + { + SessionInformation.Login.Username = username; + SessionInformation.Login.Password = password; + SessionInformation.Login.Tenant = tenant; + + server_address = GetServerFromTenant(); + +#if DEBUG + server_address = "http://localhost:3777/Host"; +#endif + + ServiceFacade.UpdateServerAddresses(server_address); + + var result = ServiceFacade.DoLauncherServiceSync(x => x.IsUserValid(username, password, pin, clientid, true)); + + if (result != UserValidationResult.UserValid) + throw new HideClientUpdateException("Kann Anmeldung nicht bestätigen! Result: " + result.ToString()); + } + catch (Exception e) + { + throw new HideClientUpdateException("Kann Anmeldung nicht bestätigen! ", e); + } + } + + private static bool TryValidateFileRequestProperties(UpdateFileRequest request) + { + if (string.IsNullOrWhiteSpace(request.UpdateSessionId)) + return false; + + if (string.IsNullOrWhiteSpace(request.Version)) + return false; + + if (request.UpdateFile is null) + return false; + + if (string.IsNullOrWhiteSpace(request.UpdateFile.RelativePath)) + return false; + + return true; + } + private static bool TryValidateVersion(UpdateFileRequest request, string tenant) + { + var version_config = UpdateConfigReader.GetValidVersion(tenant); + + return request.Version == version_config; + } + private static bool TryValidateSource(UpdateFileRequest request) + { + switch (request.UpdateFile.Source) + { + case UpdateFileSource.Invalid: + return false; + case UpdateFileSource.VersionDefault: + break; + case UpdateFileSource.VersionTenant: + break; + case UpdateFileSource.VersionUser: + return false; + case UpdateFileSource.OverrideTenant: + break; + case UpdateFileSource.OverrideUser: + return false; + default: + return false; + } + + return true; + } + + private static void ValidateSession(UpdateFileRequest request, string tenant) + { + var error = TryValidateSession(request, tenant); + + if (!string.IsNullOrWhiteSpace(error)) + throw new HideClientUpdateException(error); + } + private static string TryValidateSession(UpdateFileRequest request, string tenant) + { + var session = UpdateServerSessionManager.CurrentSession(request.UpdateSessionId); + + if (session is null) + return $"Session \"{request.UpdateSessionId}\" nicht verfügbar"; + + if (session.Tenant != tenant) + return $"Tenant konnte nicht bestätigt werden. {session.Tenant} != {tenant}"; + + if (!session.FileLimiterDict.ContainsKey( + request.UpdateFile.RelativePath)) + return $"Angefragte Datei nicht verfügbar. Anfrage an \"{request.UpdateFile.RelativePath}\""; + + if (session.IsTimeouted) + return $"Session \"{request.UpdateSessionId}\" nicht mehr verfügbar - Timeout"; + + return null; + } + + private static string GetServerFromTenant(string tenant = null) + { + if (tenant is null) + tenant = SessionInformation.Login.Tenant; + + if (tenant == "demo") + return null; + + try + { + + String url = String.Format(GETSERVER_URL, tenant); + using (WebClient client = new WebClient()) + { + //MessageBox.Show(hostAddress); + byte[] response = client.UploadValues(url, "POST", new NameValueCollection()); + + String server = System.Text.Encoding.ASCII.GetString(response); + + return $"https://{server}/service"; + } + } + catch (Exception ex) + { + throw new HideClientUpdateException("Login konnte nicht verifiziert werden.", ex); + } + } + } +} diff --git a/Service/ServiceUtils/Update/UpdateServerSession.cs b/Service/ServiceUtils/Update/UpdateServerSession.cs new file mode 100644 index 000000000..63206b72f --- /dev/null +++ b/Service/ServiceUtils/Update/UpdateServerSession.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BeWo.Service.ServiceUtils.Update +{ + public class UpdateServerSession + { + public string Id { get; set; } + public string Tenant { get; set; } + public DateTime Created { get; set; } + public DateTime Timeout { get; set; } + public Dictionary FileLimiterDict { get; set; } + + public bool IsTimeouted => Timeout < DateTime.Now; + } +} diff --git a/Service/ServiceUtils/Update/UpdateServerSessionManager.cs b/Service/ServiceUtils/Update/UpdateServerSessionManager.cs new file mode 100644 index 000000000..a8e6c121e --- /dev/null +++ b/Service/ServiceUtils/Update/UpdateServerSessionManager.cs @@ -0,0 +1,145 @@ +using BS.SharedLauncher.DataContract; +using BS.SharedLauncher.Exceptions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.ServiceModel; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace BeWo.Service.ServiceUtils.Update +{ + public static class UpdateServerSessionManager + { + private static string _Lock => string.Empty; + private static readonly Dictionary _UpdateServerSessions = new Dictionary(); + + public static UpdateServerSession CurrentSession(string session_id) + { + try + { + Monitor.Enter(_Lock); + + return _UpdateServerSessions.TryGetValue(session_id, out var session) ? session : null; + } + catch (Exception e) + { + throw new FaultException(e.StackTrace + e.InnerException != null ? e.InnerException.Message : string.Empty); + } + finally + { + Monitor.Exit(_Lock); + } + } + + public static string GenerateUniqueSessionId() + { + var session_id = Guid.NewGuid().ToString(); + + if (_UpdateServerSessions.ContainsKey(session_id)) + return GenerateUniqueSessionId(); + + return session_id; + } + + public static void CreateSession(UpdatePlanResponse res, string tenant) + { + try + { + Monitor.Enter(_Lock); + + var session_id = GenerateUniqueSessionId(); + + if (_UpdateServerSessions.ContainsKey(session_id)) + throw new UpdateException("session id generation error"); + + var session = new UpdateServerSession() + { + Id = session_id, + Tenant = tenant, + Created = DateTime.Now, + Timeout = DateTime.Now.AddMinutes(10), + FileLimiterDict = res.FilesToRequest.ToDictionary(file => file.RelativePath, file => new UpdateFileLimiter() + { + RequestsLeft = 5, + UpdateFile = file + }) + }; + + _UpdateServerSessions.Add(session_id, session); + + res.Session_Id = session_id; + } + finally + { + Monitor.Exit(_Lock); + } + } + + public static void CloseSession(string session_id) + { + try + { + Monitor.Enter(_Lock); + + _UpdateServerSessions.Remove(session_id); + + CheckForTimeoutSessions(); + } + finally + { + Monitor.Exit(_Lock); + } + } + + public static void CheckForTimeoutSessions() + { + try + { + Monitor.Enter(_Lock); + + foreach (var key_pair in _UpdateServerSessions) + { + var session_id = key_pair.Key; + var session = key_pair.Value; + + if (session.IsTimeouted) + _UpdateServerSessions.Remove(session_id); + } + } + finally + { + Monitor.Exit(_Lock); + } + } + + public static void LoadAbsolutePath(UpdateFileRequest request) + { + try + { + Monitor.Enter(_Lock); + + var file_id = request.UpdateFile.RelativePath; + + var session_id = request.UpdateSessionId; + var session = _UpdateServerSessions[session_id]; + var limiter = session.FileLimiterDict[file_id]; + + request.UpdateFile.AbsolutePath = limiter.UpdateFile.AbsolutePath; + + limiter.RequestsLeft--; + + if (!limiter.CanRequestMore) + session.FileLimiterDict.Remove(file_id); + + if (!session.FileLimiterDict.Any()) + CloseSession(session_id); + } + finally + { + Monitor.Exit(_Lock); + } + } + } +} diff --git a/SharedLauncher/DataContract/UpdateFileRequest.cs b/SharedLauncher/DataContract/UpdateFileRequest.cs index 307842296..799d70ab8 100644 --- a/SharedLauncher/DataContract/UpdateFileRequest.cs +++ b/SharedLauncher/DataContract/UpdateFileRequest.cs @@ -18,18 +18,19 @@ namespace BS.SharedLauncher.DataContract } - public UpdateFileRequest(string version) : base() + public UpdateFileRequest(string version, string session_id) : base() { Version = version; + UpdateSessionId = session_id; } [DataMember] public string Version { get; set; } [DataMember] - public UpdateFileDC UpdateFile { get; set; } + public string UpdateSessionId { get; set; } [DataMember] - public LoginDC Login { get; set; } + public UpdateFileDC UpdateFile { get; set; } } } diff --git a/SharedLauncher/DataContract/UpdatePlanResponse.cs b/SharedLauncher/DataContract/UpdatePlanResponse.cs index 8db3b5bd0..08a27f865 100644 --- a/SharedLauncher/DataContract/UpdatePlanResponse.cs +++ b/SharedLauncher/DataContract/UpdatePlanResponse.cs @@ -21,9 +21,15 @@ namespace BS.SharedLauncher.DataContract } + [DataMember] + public string Session_Id { get; set; } + [DataMember] public UpdatePlanDC CurrentPackage { get; set; } + [DataMember] + public bool HasToDo { get; set; } + [DataMember] public List FilesToRequest { get; set; }