diff --git a/.hgignore b/.hgignore index 7a83c128..7c015892 100644 --- a/.hgignore +++ b/.hgignore @@ -30,3 +30,4 @@ WebsitePanel/Sources/UpgradeLog.XML WebsitePanel/Sources/UpgradeLog.htm WebsitePanel/Sources/_UpgradeReport_Files/UpgradeReport_Information.png WebsitePanel/Sources/_UpgradeReport_Files/UpgradeReport_Success.png +WebsitePanel/Sources/packages diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/RemoteDesktopServicesProxy.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/RemoteDesktopServicesProxy.cs index c69238e5..0b6ae7ab 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/RemoteDesktopServicesProxy.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/RemoteDesktopServicesProxy.cs @@ -543,8 +543,9 @@ namespace WebsitePanel.EnterpriseServer { /// [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/GetFreeRdsServersPaged", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] - public RdsServersPaged GetFreeRdsServersPaged(string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows) { + public RdsServersPaged GetFreeRdsServersPaged(int packageId, string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows) { object[] results = this.Invoke("GetFreeRdsServersPaged", new object[] { + packageId, filterColumn, filterValue, sortColumn, @@ -554,8 +555,9 @@ namespace WebsitePanel.EnterpriseServer { } /// - public System.IAsyncResult BeginGetFreeRdsServersPaged(string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows, System.AsyncCallback callback, object asyncState) { + public System.IAsyncResult BeginGetFreeRdsServersPaged(int packageId, string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows, System.AsyncCallback callback, object asyncState) { return this.BeginInvoke("GetFreeRdsServersPaged", new object[] { + packageId, filterColumn, filterValue, sortColumn, @@ -570,16 +572,17 @@ namespace WebsitePanel.EnterpriseServer { } /// - public void GetFreeRdsServersPagedAsync(string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows) { - this.GetFreeRdsServersPagedAsync(filterColumn, filterValue, sortColumn, startRow, maximumRows, null); + public void GetFreeRdsServersPagedAsync(int packageId, string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows) { + this.GetFreeRdsServersPagedAsync(packageId, filterColumn, filterValue, sortColumn, startRow, maximumRows, null); } /// - public void GetFreeRdsServersPagedAsync(string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows, object userState) { + public void GetFreeRdsServersPagedAsync(int packageId, string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows, object userState) { if ((this.GetFreeRdsServersPagedOperationCompleted == null)) { this.GetFreeRdsServersPagedOperationCompleted = new System.Threading.SendOrPostCallback(this.OnGetFreeRdsServersPagedOperationCompleted); } this.InvokeAsync("GetFreeRdsServersPaged", new object[] { + packageId, filterColumn, filterValue, sortColumn, diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/RemoteDesktopServices/RemoteDesktopServicesController.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/RemoteDesktopServices/RemoteDesktopServicesController.cs index 6d90839d..2cb67c2b 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/RemoteDesktopServices/RemoteDesktopServicesController.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/RemoteDesktopServices/RemoteDesktopServicesController.cs @@ -93,9 +93,9 @@ namespace WebsitePanel.EnterpriseServer return GetRdsServersPagedInternal(filterColumn, filterValue, sortColumn, startRow, maximumRows); } - public static RdsServersPaged GetFreeRdsServersPaged(string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows) + public static RdsServersPaged GetFreeRdsServersPaged(int packageId, string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows) { - return GetFreeRdsServersPagedInternal(filterColumn, filterValue, sortColumn, startRow, maximumRows); + return GetFreeRdsServersPagedInternal(packageId, filterColumn, filterValue, sortColumn, startRow, maximumRows); } public static RdsServersPaged GetOrganizationRdsServersPaged(int itemId, int? collectionId, string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows) @@ -477,17 +477,26 @@ namespace WebsitePanel.EnterpriseServer return result; } - private static RdsServersPaged GetFreeRdsServersPagedInternal(string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows) + private static RdsServersPaged GetFreeRdsServersPagedInternal(int itemId, string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows) { - DataSet ds = DataProvider.GetRDSServersPaged(null, null, filterColumn, filterValue, sortColumn, startRow, maximumRows); - RdsServersPaged result = new RdsServersPaged(); + Organization org = OrganizationController.GetOrganization(itemId); + + if (org == null) + { + return result; + } + + var rds = GetRemoteDesktopServices(GetRemoteDesktopServiceID(org.PackageId)); + var existingServers = rds.GetServersExistingInCollections(); + + DataSet ds = DataProvider.GetRDSServersPaged(null, null, filterColumn, filterValue, sortColumn, startRow, maximumRows); result.RecordsCount = (int)ds.Tables[0].Rows[0][0]; List tmpServers = new List(); ObjectUtils.FillCollectionFromDataView(tmpServers, ds.Tables[1].DefaultView); - + tmpServers = tmpServers.Where(x => !existingServers.Select(y => y.ToUpper()).Contains(x.FqdName.ToUpper())).ToList(); result.Servers = tmpServers.ToArray(); return result; diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/SchedulerTasks/DomainExpirationTask.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/SchedulerTasks/DomainExpirationTask.cs index b6c9c613..be4f50a3 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/SchedulerTasks/DomainExpirationTask.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/SchedulerTasks/DomainExpirationTask.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2015, Outercurve Foundation. +// Copyright (c) 2015, Outercurve Foundation. // All rights reserved. // // Redistribution and use in source and binary forms, with or without modification, @@ -57,7 +57,7 @@ namespace WebsitePanel.EnterpriseServer { BackgroundTask topTask = TaskManager.TopTask; var domainUsers = new Dictionary(); - var checkedDomains = new List(); + var checkedDomains = new List(); var expiredDomains = new List(); var nonExistenDomains = new List(); var allDomains = new List(); @@ -101,12 +101,12 @@ namespace WebsitePanel.EnterpriseServer foreach (var domain in domains) { - if (checkedDomains.Contains(domain.DomainId)) + if (checkedDomains.Any(x=> x.DomainId == domain.DomainId)) { continue; } - checkedDomains.Add(domain.DomainId); + checkedDomains.Add(domain); ServerController.UpdateDomainWhoisData(domain); @@ -124,12 +124,11 @@ namespace WebsitePanel.EnterpriseServer } } - var subDomains = allDomains.Where(x => x.ExpirationDate == null || CheckDomainExpiration(x.ExpirationDate, daysBeforeNotify)).GroupBy(p => p.DomainId).Select(g => g.First()).ToList(); - allTopLevelDomains = allTopLevelDomains.GroupBy(p => p.DomainId).Select(g => g.First()).ToList(); + var subDomains = allDomains.Where(x => !checkedDomains.Any(z => z.DomainId == x.DomainId && z.ExpirationDate != null)).GroupBy(p => p.DomainId).Select(g => g.First()).ToList(); foreach (var subDomain in subDomains) { - var mainDomain = allTopLevelDomains.Where(x => subDomain.DomainId != x.DomainId && subDomain.DomainName.ToLowerInvariant().Contains(x.DomainName.ToLowerInvariant())).OrderByDescending(s => s.DomainName.Length).FirstOrDefault(); ; + var mainDomain = checkedDomains.Where(x => subDomain.DomainId != x.DomainId && subDomain.DomainName.ToLowerInvariant().Contains(x.DomainName.ToLowerInvariant())).OrderByDescending(s => s.DomainName.Length).FirstOrDefault(); ; if (mainDomain != null) { diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Servers/ServerController.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Servers/ServerController.cs index d0d17ade..c9aec104 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Servers/ServerController.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Servers/ServerController.cs @@ -2709,6 +2709,7 @@ namespace WebsitePanel.EnterpriseServer domain.CreationDate = ParseDate(creationDateString); domain.ExpirationDate = ParseDate(expirationDateString); domain.RegistrarName = ParseWhoisDomainInfo(whoisResult.Raw, _registrarNamePatterns); + domain.LastUpdateDate = DateTime.Now; DataProvider.UpdateWhoisDomainInfo(domain.DomainId, domain.CreationDate, domain.ExpirationDate, DateTime.Now, domain.RegistrarName); } @@ -2727,6 +2728,7 @@ namespace WebsitePanel.EnterpriseServer domain.CreationDate = creationDate; domain.ExpirationDate = expirationDate; domain.RegistrarName = registrarName; + domain.LastUpdateDate = DateTime.Now; return domain; } diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esRemoteDesktopServices.asmx.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esRemoteDesktopServices.asmx.cs index e1791e23..43df9f33 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esRemoteDesktopServices.asmx.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esRemoteDesktopServices.asmx.cs @@ -99,10 +99,10 @@ namespace WebsitePanel.EnterpriseServer } [WebMethod] - public RdsServersPaged GetFreeRdsServersPaged(string filterColumn, string filterValue, + public RdsServersPaged GetFreeRdsServersPaged(int packageId, string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows) { - return RemoteDesktopServicesController.GetFreeRdsServersPaged(filterColumn, filterValue, + return RemoteDesktopServicesController.GetFreeRdsServersPaged(packageId, filterColumn, filterValue, sortColumn, startRow, maximumRows); } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Base/RemoteDesktopServices/IRemoteDesktopServices.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Base/RemoteDesktopServices/IRemoteDesktopServices.cs index f13c3802..455db52d 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Base/RemoteDesktopServices/IRemoteDesktopServices.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Base/RemoteDesktopServices/IRemoteDesktopServices.cs @@ -64,5 +64,6 @@ namespace WebsitePanel.Providers.RemoteDesktopServices string[] GetApplicationUsers(string collectionName, string applicationName); bool SetApplicationUsers(string collectionName, RemoteApplication remoteApp, string[] users); bool CheckRDSServerAvaliable(string hostname); + List GetServersExistingInCollections(); } } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Mail.IceWarp/IceWarp.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Mail.IceWarp/IceWarp.cs index a7ad0c97..f0538c23 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Mail.IceWarp/IceWarp.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Mail.IceWarp/IceWarp.cs @@ -477,7 +477,7 @@ namespace WebsitePanel.Providers.Mail Log.WriteStart(String.Format("Calculating mail account '{0}' size", item.Name)); // calculate disk space var accountObject = GetAccountObject(item.Name); - var size = Convert.ToInt64((object)accountObject.GetProperty("U_MailboxSize")); + var size = Convert.ToInt64((object)accountObject.GetProperty("U_MailboxSize")) * 1024; var diskspace = new ServiceProviderItemDiskSpace {ItemId = item.Id, DiskSpace = size}; itemsDiskspace.Add(diskspace); @@ -564,8 +564,8 @@ namespace WebsitePanel.Providers.Mail Year = date.Year, Month = date.Month, Day = date.Day, - BytesSent = line[mailSentField], - BytesReceived = line[mailReceivedField] + BytesSent = Convert.ToInt64(fields[mailSentField])*1024, + BytesReceived = Convert.ToInt64(fields[mailReceivedField])*1024 }; days.Add(dailyStats); continue; @@ -1035,7 +1035,7 @@ namespace WebsitePanel.Providers.Mail { var forwardTo = GetForwardToAddressFromAccountObject(accountObject); var aliases = GetAliasListFromAccountObject(accountObject) as IEnumerable; - aliasList.AddRange(aliases.Where(a => a != forwardTo).Select(alias => new MailAlias {Name = alias + "@" + domainName, ForwardTo = forwardTo + "@" + domainName})); + aliasList.AddRange(aliases.Where(a => a + "@" + domainName != forwardTo).Select(alias => new MailAlias {Name = alias + "@" + domainName, ForwardTo = forwardTo})); } accountObject.FindDone(); diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs b/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs index e829d1d6..dd604a9e 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs @@ -220,7 +220,15 @@ namespace WebsitePanel.Providers.RemoteDesktopServices try { - runSpace = OpenRunspace(); + runSpace = OpenRunspace(); + + var existingServers = GetServersExistingInCollections(runSpace); + existingServers = existingServers.Select(x => x.ToUpper()).Intersect(collection.Servers.Select(x => x.FqdName.ToUpper())).ToList(); + + if (existingServers.Any()) + { + throw new Exception(string.Format("Server{0} {1} already added to another collection", existingServers.Count == 1 ? "" : "s", string.Join(" ,", existingServers.ToArray()))); + } foreach (var server in collection.Servers) { @@ -302,6 +310,24 @@ namespace WebsitePanel.Providers.RemoteDesktopServices return result; } + public List GetServersExistingInCollections() + { + Runspace runSpace = null; + List existingServers = new List(); + + try + { + runSpace = OpenRunspace(); + existingServers = GetServersExistingInCollections(runSpace); + } + finally + { + CloseRunspace(runSpace); + } + + return existingServers; + } + public RdsCollection GetCollection(string collectionName) { RdsCollection collection =null; @@ -1380,6 +1406,23 @@ namespace WebsitePanel.Providers.RemoteDesktopServices return ExecuteShellCommand(runSpace, invokeCommand, false); } + internal Collection ExecuteRemoteShellCommand(Runspace runSpace, string hostName, List scripts, params string[] moduleImports) + { + Command invokeCommand = new Command("Invoke-Command"); + invokeCommand.Parameters.Add("ComputerName", hostName); + + RunspaceInvoke invoke = new RunspaceInvoke(); + string commandString = moduleImports.Any() ? string.Format("import-module {0};", string.Join(",", moduleImports)) : string.Empty; + + commandString = string.Format("{0};{1}", commandString, string.Join(";", scripts.ToArray())); + + ScriptBlock sb = invoke.Invoke(string.Format("{{{0}}}", commandString))[0].BaseObject as ScriptBlock; + + invokeCommand.Parameters.Add("ScriptBlock", sb); + + return ExecuteShellCommand(runSpace, invokeCommand, false); + } + internal Collection ExecuteShellCommand(Runspace runSpace, Command cmd) { return ExecuteShellCommand(runSpace, cmd, true); @@ -1396,6 +1439,38 @@ namespace WebsitePanel.Providers.RemoteDesktopServices return ExecuteShellCommand(runSpace, cmd, true, out errors); } + internal Collection ExecuteShellCommand(Runspace runspace, List scripts, out object[] errors) + { + Log.WriteStart("ExecuteShellCommand"); + var errorList = new List(); + Collection results; + + using (Pipeline pipeLine = runspace.CreatePipeline()) + { + foreach (string script in scripts) + { + pipeLine.Commands.AddScript(script); + } + + results = pipeLine.Invoke(); + + if (pipeLine.Error != null && pipeLine.Error.Count > 0) + { + foreach (object item in pipeLine.Error.ReadToEnd()) + { + errorList.Add(item); + string errorMessage = string.Format("Invoke error: {0}", item); + Log.WriteWarning(errorMessage); + } + } + } + + errors = errorList.ToArray(); + Log.WriteEnd("ExecuteShellCommand"); + + return results; + } + internal Collection ExecuteShellCommand(Runspace runSpace, Command cmd, bool useDomainController, out object[] errors) { @@ -1517,6 +1592,29 @@ namespace WebsitePanel.Providers.RemoteDesktopServices return result; } + internal List GetServersExistingInCollections(Runspace runSpace) + { + var existingHosts = new List(); + var scripts = new List(); + scripts.Add(string.Format("$sessions = Get-RDSessionCollection -ConnectionBroker {0}", ConnectionBroker)); + scripts.Add(string.Format("foreach($session in $sessions){{Get-RDSessionHost $session.CollectionName -ConnectionBroker {0}|Select SessionHost}}", ConnectionBroker)); + object[] errors; + + var sessionHosts = ExecuteShellCommand(runSpace, scripts, out errors); + + foreach(var host in sessionHosts) + { + var sessionHost = GetPSObjectProperty(host, "SessionHost"); + + if (sessionHost != null) + { + existingHosts.Add(sessionHost.ToString()); + } + } + + return existingHosts; + } + #endregion } } diff --git a/WebsitePanel/Sources/WebsitePanel.Server.Client/RemoteDesktopServicesProxy.cs b/WebsitePanel/Sources/WebsitePanel.Server.Client/RemoteDesktopServicesProxy.cs index 6f4043e5..dd085a7e 100644 --- a/WebsitePanel/Sources/WebsitePanel.Server.Client/RemoteDesktopServicesProxy.cs +++ b/WebsitePanel/Sources/WebsitePanel.Server.Client/RemoteDesktopServicesProxy.cs @@ -99,6 +99,8 @@ namespace WebsitePanel.Providers.RemoteDesktopServices { private System.Threading.SendOrPostCallback CheckRDSServerAvaliableOperationCompleted; + private System.Threading.SendOrPostCallback GetServersExistingInCollectionsOperationCompleted; + /// public RemoteDesktopServices() { this.Url = "http://localhost:9003/RemoteDesktopServices.asmx"; @@ -167,6 +169,9 @@ namespace WebsitePanel.Providers.RemoteDesktopServices { /// public event CheckRDSServerAvaliableCompletedEventHandler CheckRDSServerAvaliableCompleted; + /// + public event GetServersExistingInCollectionsCompletedEventHandler GetServersExistingInCollectionsCompleted; + /// [System.Web.Services.Protocols.SoapHeaderAttribute("ServiceProviderSettingsSoapHeaderValue")] [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/server/CreateCollection", RequestNamespace="http://smbsaas/websitepanel/server/", ResponseNamespace="http://smbsaas/websitepanel/server/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] @@ -1096,6 +1101,45 @@ namespace WebsitePanel.Providers.RemoteDesktopServices { } } + /// + [System.Web.Services.Protocols.SoapHeaderAttribute("ServiceProviderSettingsSoapHeaderValue")] + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/server/GetServersExistingInCollections", RequestNamespace="http://smbsaas/websitepanel/server/", ResponseNamespace="http://smbsaas/websitepanel/server/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] + public string[] GetServersExistingInCollections() { + object[] results = this.Invoke("GetServersExistingInCollections", new object[0]); + return ((string[])(results[0])); + } + + /// + public System.IAsyncResult BeginGetServersExistingInCollections(System.AsyncCallback callback, object asyncState) { + return this.BeginInvoke("GetServersExistingInCollections", new object[0], callback, asyncState); + } + + /// + public string[] EndGetServersExistingInCollections(System.IAsyncResult asyncResult) { + object[] results = this.EndInvoke(asyncResult); + return ((string[])(results[0])); + } + + /// + public void GetServersExistingInCollectionsAsync() { + this.GetServersExistingInCollectionsAsync(null); + } + + /// + public void GetServersExistingInCollectionsAsync(object userState) { + if ((this.GetServersExistingInCollectionsOperationCompleted == null)) { + this.GetServersExistingInCollectionsOperationCompleted = new System.Threading.SendOrPostCallback(this.OnGetServersExistingInCollectionsOperationCompleted); + } + this.InvokeAsync("GetServersExistingInCollections", new object[0], this.GetServersExistingInCollectionsOperationCompleted, userState); + } + + private void OnGetServersExistingInCollectionsOperationCompleted(object arg) { + if ((this.GetServersExistingInCollectionsCompleted != null)) { + System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); + this.GetServersExistingInCollectionsCompleted(this, new GetServersExistingInCollectionsCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); + } + } + /// public new void CancelAsync(object userState) { base.CancelAsync(userState); @@ -1537,4 +1581,30 @@ namespace WebsitePanel.Providers.RemoteDesktopServices { } } } + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] + public delegate void GetServersExistingInCollectionsCompletedEventHandler(object sender, GetServersExistingInCollectionsCompletedEventArgs e); + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + public partial class GetServersExistingInCollectionsCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs { + + private object[] results; + + internal GetServersExistingInCollectionsCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : + base(exception, cancelled, userState) { + this.results = results; + } + + /// + public string[] Result { + get { + this.RaiseExceptionIfNecessary(); + return ((string[])(this.results[0])); + } + } + } } diff --git a/WebsitePanel/Sources/WebsitePanel.Server/RemoteDesktopServices.asmx.cs b/WebsitePanel/Sources/WebsitePanel.Server/RemoteDesktopServices.asmx.cs index 2d153e60..e004f3f6 100644 --- a/WebsitePanel/Sources/WebsitePanel.Server/RemoteDesktopServices.asmx.cs +++ b/WebsitePanel/Sources/WebsitePanel.Server/RemoteDesktopServices.asmx.cs @@ -410,5 +410,22 @@ namespace WebsitePanel.Server throw; } } + + [WebMethod, SoapHeader("settings")] + public List GetServersExistingInCollections() + { + try + { + Log.WriteStart("'{0}' GetServersExistingInCollections", ProviderSettings.ProviderName); + var result = RDSProvider.GetServersExistingInCollections(); + Log.WriteEnd("'{0}' GetServersExistingInCollections", ProviderSettings.ProviderName); + return result; + } + catch (Exception ex) + { + Log.WriteError(String.Format("'{0}' GetServersExistingInCollections", ProviderSettings.ProviderName), ex); + throw; + } + } } } diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/Entities/AbstractConfigCollection.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/AbstractConfigCollection.cs similarity index 87% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/Entities/AbstractConfigCollection.cs rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/AbstractConfigCollection.cs index 3dca9866..fb49467c 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/Entities/AbstractConfigCollection.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/AbstractConfigCollection.cs @@ -1,7 +1,7 @@ using System.Configuration; using WebsitePanel.WebDavPortal.WebConfigSections; -namespace WebsitePanel.WebDavPortal.Config.Entities +namespace WebsitePanel.WebDav.Core.Config.Entities { public abstract class AbstractConfigCollection { diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/Entities/ElementsRendering.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/ElementsRendering.cs similarity index 57% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/Entities/ElementsRendering.cs rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/ElementsRendering.cs index 04a1105d..f6f33649 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/Entities/ElementsRendering.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/ElementsRendering.cs @@ -1,14 +1,19 @@ -namespace WebsitePanel.WebDavPortal.Config.Entities +using System.Collections.Generic; +using System.Linq; + +namespace WebsitePanel.WebDav.Core.Config.Entities { public class ElementsRendering : AbstractConfigCollection { public int DefaultCount { get; private set; } public int AddElementsCount { get; private set; } + public List ElementsToIgnore { get; private set; } public ElementsRendering() { DefaultCount = ConfigSection.ElementsRendering.DefaultCount; AddElementsCount = ConfigSection.ElementsRendering.AddElementsCount; + ElementsToIgnore = ConfigSection.ElementsRendering.ElementsToIgnore.Split(',').ToList(); } } } \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/Entities/FileIconsDictionary.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/FileIconsDictionary.cs similarity index 90% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/Entities/FileIconsDictionary.cs rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/FileIconsDictionary.cs index 45568227..6bd7b26c 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/Entities/FileIconsDictionary.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/FileIconsDictionary.cs @@ -1,9 +1,9 @@ using System.Collections; using System.Collections.Generic; using System.Linq; -using WebsitePanel.WebDavPortal.WebConfigSections; +using WebsitePanel.WebDav.Core.Config.WebConfigSections; -namespace WebsitePanel.WebDavPortal.Config.Entities +namespace WebsitePanel.WebDav.Core.Config.Entities { public class FileIconsDictionary : AbstractConfigCollection, IReadOnlyDictionary { diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/Entities/HttpErrorsCollection.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/HttpErrorsCollection.cs similarity index 52% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/Entities/HttpErrorsCollection.cs rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/HttpErrorsCollection.cs index 2aab1acb..e2c6b920 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/Entities/HttpErrorsCollection.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/HttpErrorsCollection.cs @@ -1,7 +1,6 @@ using System.Globalization; -using Resources.Resource; -namespace WebsitePanel.WebDavPortal.Config.Entities +namespace WebsitePanel.WebDav.Core.Config.Entities { public class HttpErrorsCollection { @@ -9,14 +8,14 @@ namespace WebsitePanel.WebDavPortal.Config.Entities { get { - var message = errors.ResourceManager.GetString("_" + statusCode.ToString(CultureInfo.InvariantCulture)); + var message = Resources.HttpErrors.ResourceManager.GetString("_" + statusCode.ToString(CultureInfo.InvariantCulture)); return message ?? Default; } } public string Default { - get { return errors.Default; } + get { return Resources.HttpErrors.Default; } } } } \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/Entities/OfficeOnlineCollection.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/OfficeOnlineCollection.cs similarity index 92% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/Entities/OfficeOnlineCollection.cs rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/OfficeOnlineCollection.cs index c247020f..a28114b5 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/Entities/OfficeOnlineCollection.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/OfficeOnlineCollection.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Linq; using WebsitePanel.WebDavPortal.WebConfigSections; -namespace WebsitePanel.WebDavPortal.Config.Entities +namespace WebsitePanel.WebDav.Core.Config.Entities { public class OfficeOnlineCollection : AbstractConfigCollection, IReadOnlyCollection { diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/Entities/SessionKeysCollection.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/SessionKeysCollection.cs similarity index 88% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/Entities/SessionKeysCollection.cs rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/SessionKeysCollection.cs index c733473d..057be2cf 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/Entities/SessionKeysCollection.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/SessionKeysCollection.cs @@ -1,9 +1,8 @@ using System.Collections.Generic; -using System.Configuration; using System.Linq; using WebsitePanel.WebDavPortal.WebConfigSections; -namespace WebsitePanel.WebDavPortal.Config.Entities +namespace WebsitePanel.WebDav.Core.Config.Entities { public class SessionKeysCollection : AbstractConfigCollection { @@ -14,12 +13,12 @@ namespace WebsitePanel.WebDavPortal.Config.Entities _sessionKeys = ConfigSection.SessionKeys.Cast(); } - public string AccountInfo + public string AuthTicket { get { SessionKeysElement sessionKey = - _sessionKeys.FirstOrDefault(x => x.Key == SessionKeysElement.AccountInfoKey); + _sessionKeys.FirstOrDefault(x => x.Key == SessionKeysElement.AuthTicketKey); return sessionKey != null ? sessionKey.Value : null; } } diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/Entities/WebsitePanelConstantUserParameters.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/WebsitePanelConstantUserParameters.cs similarity index 85% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/Entities/WebsitePanelConstantUserParameters.cs rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/WebsitePanelConstantUserParameters.cs index 41336fcb..fdc6c99f 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/Entities/WebsitePanelConstantUserParameters.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/WebsitePanelConstantUserParameters.cs @@ -1,4 +1,4 @@ -namespace WebsitePanel.WebDavPortal.Config.Entities +namespace WebsitePanel.WebDav.Core.Config.Entities { public class WebsitePanelConstantUserParameters : AbstractConfigCollection { diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/IWebDavAppConfig.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/IWebDavAppConfig.cs similarity index 81% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/IWebDavAppConfig.cs rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/IWebDavAppConfig.cs index efed85e9..9bb3b4d8 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/IWebDavAppConfig.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/IWebDavAppConfig.cs @@ -1,6 +1,6 @@ -using WebsitePanel.WebDavPortal.Config.Entities; +using WebsitePanel.WebDav.Core.Config.Entities; -namespace WebsitePanel.WebDavPortal.Config +namespace WebsitePanel.WebDav.Core.Config { public interface IWebDavAppConfig { diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/ApplicationNameElement.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/ApplicationNameElement.cs similarity index 83% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/ApplicationNameElement.cs rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/ApplicationNameElement.cs index 7ab267ea..149c4432 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/ApplicationNameElement.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/ApplicationNameElement.cs @@ -1,6 +1,6 @@ using System.Configuration; -namespace WebsitePanel.WebDavPortal.WebConfigSections +namespace WebsitePanel.WebDav.Core.Config.WebConfigSections { public class ApplicationNameElement : ConfigurationElement { diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/AuthTimeoutCookieNameElement.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/AuthTimeoutCookieNameElement.cs new file mode 100644 index 00000000..7585199a --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/AuthTimeoutCookieNameElement.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WebsitePanel.WebDav.Core.Config.WebConfigSections +{ + public class AuthTimeoutCookieNameElement : ConfigurationElement + { + private const string ValueKey = "value"; + + [ConfigurationProperty(ValueKey, IsKey = true, IsRequired = true)] + public string Value + { + get { return (string)this[ValueKey]; } + set { this[ValueKey] = value; } + } + } +} diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/ElementsRenderingElement.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/ElementsRenderingElement.cs similarity index 63% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/ElementsRenderingElement.cs rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/ElementsRenderingElement.cs index 996d4a30..f25b2034 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/ElementsRenderingElement.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/ElementsRenderingElement.cs @@ -1,11 +1,12 @@ using System.Configuration; -namespace WebsitePanel.WebDavPortal.WebConfigSections +namespace WebsitePanel.WebDav.Core.Config.WebConfigSections { public class ElementsRenderingElement : ConfigurationElement { private const string DefaultCountKey = "defaultCount"; private const string AddElementsCountKey = "addElementsCount"; + private const string ElementsToIgnoreKey = "elementsToIgnoreKey"; [ConfigurationProperty(DefaultCountKey, IsKey = true, IsRequired = true, DefaultValue = 30)] public int DefaultCount @@ -20,5 +21,12 @@ namespace WebsitePanel.WebDavPortal.WebConfigSections get { return (int)this[AddElementsCountKey]; } set { this[AddElementsCountKey] = value; } } + + [ConfigurationProperty(ElementsToIgnoreKey, IsKey = true, IsRequired = true, DefaultValue = "")] + public string ElementsToIgnore + { + get { return (string)this[ElementsToIgnoreKey]; } + set { this[ElementsToIgnoreKey] = value; } + } } } \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/FileIconsElement.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/FileIconsElement.cs similarity index 88% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/FileIconsElement.cs rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/FileIconsElement.cs index bd31e4e1..a55039c4 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/FileIconsElement.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/FileIconsElement.cs @@ -1,6 +1,6 @@ using System.Configuration; -namespace WebsitePanel.WebDavPortal.WebConfigSections +namespace WebsitePanel.WebDav.Core.Config.WebConfigSections { public class FileIconsElement : ConfigurationElement { diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/FileIconsElementCollection.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/FileIconsElementCollection.cs similarity index 90% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/FileIconsElementCollection.cs rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/FileIconsElementCollection.cs index 90868515..fb3d5340 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/FileIconsElementCollection.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/FileIconsElementCollection.cs @@ -1,6 +1,6 @@ using System.Configuration; -namespace WebsitePanel.WebDavPortal.WebConfigSections +namespace WebsitePanel.WebDav.Core.Config.WebConfigSections { [ConfigurationCollection(typeof (FileIconsElement))] public class FileIconsElementCollection : ConfigurationElementCollection diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/OfficeOnlineElement.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/OfficeOnlineElement.cs similarity index 100% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/OfficeOnlineElement.cs rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/OfficeOnlineElement.cs diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/OfficeOnlineElementCollection.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/OfficeOnlineElementCollection.cs similarity index 100% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/OfficeOnlineElementCollection.cs rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/OfficeOnlineElementCollection.cs diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/SessionKeysElement.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/SessionKeysElement.cs similarity index 91% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/SessionKeysElement.cs rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/SessionKeysElement.cs index d082c528..cfe2e0b9 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/SessionKeysElement.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/SessionKeysElement.cs @@ -8,6 +8,7 @@ namespace WebsitePanel.WebDavPortal.WebConfigSections private const string ValueKey = "value"; public const string AccountInfoKey = "AccountInfoSessionKey"; + public const string AuthTicketKey = "AuthTicketKey"; public const string WebDavManagerKey = "WebDavManagerSessionKey"; public const string ResourseRenderCountKey = "ResourseRenderCountSessionKey"; public const string ItemIdSessionKey = "ItemId"; diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/SessionKeysElementCollection.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/SessionKeysElementCollection.cs similarity index 78% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/SessionKeysElementCollection.cs rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/SessionKeysElementCollection.cs index 31abb74e..b1c67591 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/SessionKeysElementCollection.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/SessionKeysElementCollection.cs @@ -1,6 +1,7 @@ using System.Configuration; +using WebsitePanel.WebDavPortal.WebConfigSections; -namespace WebsitePanel.WebDavPortal.WebConfigSections +namespace WebsitePanel.WebDav.Core.Config.WebConfigSections { [ConfigurationCollection(typeof (SessionKeysElement))] public class SessionKeysElementCollection : ConfigurationElementCollection diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/UserDomainElement.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/UserDomainElement.cs similarity index 83% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/UserDomainElement.cs rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/UserDomainElement.cs index c8ce5ab9..68145beb 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/UserDomainElement.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/UserDomainElement.cs @@ -1,6 +1,6 @@ using System.Configuration; -namespace WebsitePanel.WebDavPortal.WebConfigSections +namespace WebsitePanel.WebDav.Core.Config.WebConfigSections { public class UserDomainElement : ConfigurationElement { diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/WebDavExplorerConfigurationSettingsSection.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/WebDavExplorerConfigurationSettingsSection.cs similarity index 84% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/WebDavExplorerConfigurationSettingsSection.cs rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/WebDavExplorerConfigurationSettingsSection.cs index e84491ab..af4e472e 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/WebDavExplorerConfigurationSettingsSection.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/WebDavExplorerConfigurationSettingsSection.cs @@ -1,10 +1,12 @@ using System.Configuration; +using WebsitePanel.WebDav.Core.Config.WebConfigSections; namespace WebsitePanel.WebDavPortal.WebConfigSections { public class WebDavExplorerConfigurationSettingsSection : ConfigurationSection { private const string UserDomainKey = "userDomain"; + private const string AuthTimeoutCookieNameKey = "authTimeoutCookieName"; private const string AppName = "applicationName"; private const string WebsitePanelConstantUserKey = "websitePanelConstantUser"; private const string ElementsRenderingKey = "elementsRendering"; @@ -16,6 +18,13 @@ namespace WebsitePanel.WebDavPortal.WebConfigSections public const string SectionName = "webDavExplorerConfigurationSettings"; + [ConfigurationProperty(AuthTimeoutCookieNameKey, IsRequired = true)] + public AuthTimeoutCookieNameElement AuthTimeoutCookieName + { + get { return (AuthTimeoutCookieNameElement)this[AuthTimeoutCookieNameKey]; } + set { this[AuthTimeoutCookieNameKey] = value; } + } + [ConfigurationProperty(UserDomainKey, IsRequired = true)] public UserDomainElement UserDomain { diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/WebsitePanelConstantUserElement.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/WebsitePanelConstantUserElement.cs similarity index 89% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/WebsitePanelConstantUserElement.cs rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/WebsitePanelConstantUserElement.cs index dfbb388e..abe87357 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebConfigSections/WebsitePanelConstantUserElement.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/WebsitePanelConstantUserElement.cs @@ -1,6 +1,6 @@ using System.Configuration; -namespace WebsitePanel.WebDavPortal.WebConfigSections +namespace WebsitePanel.WebDav.Core.Config.WebConfigSections { public class WebsitePanelConstantUserElement : ConfigurationElement { diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/WebDavAppConfigManager.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebDavAppConfigManager.cs similarity index 86% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/WebDavAppConfigManager.cs rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebDavAppConfigManager.cs index 31e9d2b9..cd28a090 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Config/WebDavAppConfigManager.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebDavAppConfigManager.cs @@ -1,8 +1,8 @@ using System.Configuration; -using WebsitePanel.WebDavPortal.Config.Entities; +using WebsitePanel.WebDav.Core.Config.Entities; using WebsitePanel.WebDavPortal.WebConfigSections; -namespace WebsitePanel.WebDavPortal.Config +namespace WebsitePanel.WebDav.Core.Config { public class WebDavAppConfigManager : IWebDavAppConfig { @@ -35,6 +35,11 @@ namespace WebsitePanel.WebDavPortal.Config get { return _configSection.ApplicationName.Value; } } + public string AuthTimeoutCookieName + { + get { return _configSection.AuthTimeoutCookieName.Value; } + } + public ElementsRendering ElementsRendering { get; private set; } public WebsitePanelConstantUserParameters WebsitePanelConstantUserParameters { get; private set; } public SessionKeysCollection SessionKeys { get; private set; } diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IHierarchyItem.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IHierarchyItem.cs index acebf9ac..94f7348f 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IHierarchyItem.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IHierarchyItem.cs @@ -59,7 +59,10 @@ namespace WebsitePanel.WebDav.Core { get { - string displayName = _href.AbsoluteUri.Replace(_baseUri.AbsoluteUri, ""); + var href = HttpUtility.UrlDecode(_href.AbsoluteUri); + var baseUri = HttpUtility.UrlDecode(_baseUri.AbsoluteUri); + + string displayName = href.Replace(baseUri, ""); displayName = Regex.Replace(displayName, "\\/$", ""); Match displayNameMatch = Regex.Match(displayName, "([\\/]+)$"); if (displayNameMatch.Success) diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Interfaces/Security/IAuthenticationService.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Interfaces/Security/IAuthenticationService.cs new file mode 100644 index 00000000..6bd042a4 --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Interfaces/Security/IAuthenticationService.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WebsitePanel.WebDav.Core.Security.Authentication.Principals; + +namespace WebsitePanel.WebDav.Core.Interfaces.Security +{ + public interface IAuthenticationService + { + WspPrincipal LogIn(string login, string password); + void CreateAuthenticationTicket(WspPrincipal principal); + void LogOut(); + } +} diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_GlobalResources/Resource.errors.designer.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Resources/HttpErrors.Designer.cs similarity index 82% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_GlobalResources/Resource.errors.designer.cs rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Resources/HttpErrors.Designer.cs index f673f97d..33bd76c7 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_GlobalResources/Resource.errors.designer.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Resources/HttpErrors.Designer.cs @@ -1,14 +1,14 @@ -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.18449 +// Runtime Version:4.0.30319.33440 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace Resources.Resource { +namespace WebsitePanel.WebDav.Core.Resources { using System; @@ -18,18 +18,18 @@ namespace Resources.Resource { // This class was auto-generated by the StronglyTypedResourceBuilder // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option or rebuild the Visual Studio project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Web.Application.StronglyTypedResourceProxyBuilder", "12.0.0.0")] + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class errors { + internal class HttpErrors { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal errors() { + internal HttpErrors() { } /// @@ -39,7 +39,7 @@ namespace Resources.Resource { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Resources.Resource.errors", global::System.Reflection.Assembly.Load("App_GlobalResources")); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WebsitePanel.WebDav.Core.Resources.HttpErrors", typeof(HttpErrors).Assembly); resourceMan = temp; } return resourceMan; @@ -60,15 +60,6 @@ namespace Resources.Resource { } } - /// - /// Looks up a localized string similar to Fatal error. - /// - internal static string Default { - get { - return ResourceManager.GetString("Default", resourceCulture); - } - } - /// /// Looks up a localized string similar to The requested content was not found. /// @@ -86,5 +77,14 @@ namespace Resources.Resource { return ResourceManager.GetString("_500", resourceCulture); } } + + /// + /// Looks up a localized string similar to Fatal error. + /// + internal static string Default { + get { + return ResourceManager.GetString("Default", resourceCulture); + } + } } } diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_GlobalResources/Resource.errors.resx b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Resources/HttpErrors.resx similarity index 100% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_GlobalResources/Resource.errors.resx rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Resources/HttpErrors.resx diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Authentication/FormsAuthenticationService.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Authentication/FormsAuthenticationService.cs new file mode 100644 index 00000000..b33ae4ac --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Authentication/FormsAuthenticationService.cs @@ -0,0 +1,75 @@ +using System; +using System.DirectoryServices.AccountManagement; +using System.Web; +using System.Web.Script.Serialization; +using System.Web.Security; +using WebsitePanel.WebDav.Core.Config; +using WebsitePanel.WebDav.Core.Interfaces.Security; +using WebsitePanel.WebDav.Core.Security.Authentication.Principals; +using WebsitePanel.WebDav.Core.Security.Cryptography; +using WebsitePanel.WebDav.Core.Wsp.Framework; + +namespace WebsitePanel.WebDav.Core.Security.Authentication +{ + public class FormsAuthenticationService : IAuthenticationService + { + private readonly ICryptography _cryptography; + private readonly PrincipalContext _principalContext; + + public FormsAuthenticationService(ICryptography cryptography) + { + _cryptography = cryptography; + _principalContext = new PrincipalContext(ContextType.Domain, WebDavAppConfigManager.Instance.UserDomain); + } + + public WspPrincipal LogIn(string login, string password) + { + if (_principalContext.ValidateCredentials(login, password) == false) + { + return null; + } + + var principal = new WspPrincipal(login); + + var exchangeAccount = WSP.Services.ExchangeServer.GetAccountByAccountNameWithoutItemId(login); + var organization = WSP.Services.Organizations.GetOrganization(exchangeAccount.ItemId); + + principal.AccountId = exchangeAccount.AccountId; + principal.ItemId = exchangeAccount.ItemId; + principal.OrganizationId = organization.OrganizationId; + principal.DisplayName = exchangeAccount.DisplayName; + principal.EncryptedPassword = _cryptography.Encrypt(password); + + CreateAuthenticationTicket(principal); + + HttpContext.Current.User = principal; + + return principal; + } + + public void CreateAuthenticationTicket(WspPrincipal principal) + { + var serializer = new JavaScriptSerializer(); + string userData = serializer.Serialize(principal); + + var authTicket = new FormsAuthenticationTicket(1, principal.Identity.Name, DateTime.Now, DateTime.Now.Add(FormsAuthentication.Timeout), + FormsAuthentication.SlidingExpiration, userData); + + var encTicket = FormsAuthentication.Encrypt(authTicket); + + var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket); + + if (FormsAuthentication.SlidingExpiration) + { + cookie.Expires = authTicket.Expiration; + } + + HttpContext.Current.Response.Cookies.Add(cookie); + } + + public void LogOut() + { + FormsAuthentication.SignOut(); + } + } +} diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Authentication/Principals/WspPrincipal.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Authentication/Principals/WspPrincipal.cs new file mode 100644 index 00000000..15401a14 --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Authentication/Principals/WspPrincipal.cs @@ -0,0 +1,47 @@ +using System.Security.Principal; +using System.Web.Script.Serialization; +using System.Web.Security; +using System.Xml.Serialization; + +namespace WebsitePanel.WebDav.Core.Security.Authentication.Principals +{ + public class WspPrincipal : IPrincipal + { + public int AccountId { get; set; } + public string OrganizationId { get; set; } + public int ItemId { get; set; } + + public string Login { get; set; } + public string EncryptedPassword { get; set; } + + public string DisplayName { get; set; } + + public string UserName + { + get + { + return !string.IsNullOrEmpty(Login) ? Login.Split('@')[0] : string.Empty; + } + } + + [XmlIgnore, ScriptIgnore] + public IIdentity Identity { get; private set; } + + public WspPrincipal(string username) + { + Identity = new GenericIdentity(username); + Login = username; + } + + public WspPrincipal() + { + } + + public bool IsInRole(string role) + { + return Identity.IsAuthenticated + && !string.IsNullOrWhiteSpace(role) + && Roles.IsUserInRole(Identity.Name, role); + } + } +} diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Cryptography/CryptoUtils.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Cryptography/CryptoUtils.cs similarity index 94% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/Cryptography/CryptoUtils.cs rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Cryptography/CryptoUtils.cs index 5251babd..893ebfc1 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Cryptography/CryptoUtils.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Cryptography/CryptoUtils.cs @@ -1,14 +1,11 @@ -using Microsoft.Win32; -using System; -using System.Collections.Generic; +using System; using System.Configuration; using System.IO; -using System.Linq; using System.Security.Cryptography; using System.Text; -using System.Web; +using Microsoft.Win32; -namespace WebsitePanel.WebDavPortal.Cryptography +namespace WebsitePanel.WebDav.Core.Security.Cryptography { public class CryptoUtils : ICryptography { diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Cryptography/ICryptography.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Cryptography/ICryptography.cs similarity index 67% rename from WebsitePanel/Sources/WebsitePanel.WebDavPortal/Cryptography/ICryptography.cs rename to WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Cryptography/ICryptography.cs index 09eb03a4..b3c8e6a1 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Cryptography/ICryptography.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Cryptography/ICryptography.cs @@ -1,4 +1,4 @@ -namespace WebsitePanel.WebDavPortal.Cryptography +namespace WebsitePanel.WebDav.Core.Security.Cryptography { public interface ICryptography { diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/WebsitePanel.WebDav.Core.csproj b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/WebsitePanel.WebDav.Core.csproj index 03eaee5a..cdd7e02b 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/WebsitePanel.WebDav.Core.csproj +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/WebsitePanel.WebDav.Core.csproj @@ -11,6 +11,8 @@ WebsitePanel.WebDav.Core v4.5 512 + ..\ + true true @@ -30,18 +32,82 @@ 4 + + True + ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll + + + False + ..\..\..\..\Scheduler Domains\WebsitePanel\Bin\Microsoft.Web.Services3.dll + True + + + C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Web.dll + + + False + ..\packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.Helpers.dll + + + False + ..\packages\Microsoft.AspNet.Mvc.5.2.2\lib\net45\System.Web.Mvc.dll + + + False + ..\packages\Microsoft.AspNet.Razor.3.2.2\lib\net45\System.Web.Razor.dll + + + + False + ..\packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.WebPages.dll + + + False + ..\packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.WebPages.Deployment.dll + + + False + ..\packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.WebPages.Razor.dll + + + ..\WebsitePanel.WebPortal\Bin\WebsitePanel.EnterpriseServer.Client.dll + + + ..\WebsitePanel.WebPortal\Bin\WebsitePanel.Providers.Base.dll + + + + + + + + + + + + + + + + + + + + + + @@ -49,6 +115,7 @@ + @@ -56,9 +123,45 @@ + + True + True + HttpErrors.resx + + + + + + + + + + + + + + + + + {C99EFB18-FFE7-45BB-8CA8-29336F3E8C68} + WebsitePanel.WebPortal + + + + + ResXFileCodeGenerator + HttpErrors.Designer.cs + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + -
+
+
+ + + + + + + + + + + + + + - - - - + + + + - - + + - - + + + - - - - + + + + - - - - - - - - + + + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - + - + + @@ -84,7 +90,7 @@ - + @@ -93,7 +99,7 @@ - + @@ -102,32 +108,32 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebsitePanel.WebDavPortal.csproj b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebsitePanel.WebDavPortal.csproj index 5b2ea9ec..bd1bf241 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebsitePanel.WebDavPortal.csproj +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebsitePanel.WebDavPortal.csproj @@ -48,6 +48,9 @@ False ..\packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll + + ..\packages\log4net.2.0.0\lib\net40-full\log4net.dll + ..\..\Lib\Microsoft.Web.Services3.dll @@ -134,33 +137,18 @@ - - True - True - Resource.errors.resx - - - - - - - - - - - - - - - + + + + @@ -179,17 +167,8 @@ - - - - - - - - - - - + + @@ -241,6 +220,7 @@ Designer + @@ -249,6 +229,7 @@ + @@ -285,21 +266,11 @@ - - - GlobalResourceProxyGenerator - Resource.errors.designer.cs - - {BA147805-9EF1-45F2-BF32-A5825D4E950D} WebsitePanel.WebDav.Core - - {12232731-5C45-4ED6-98F8-D47ABE728280} - WebsitePanel.Portal.Modules - 10.0 diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/packages.config b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/packages.config index 5c38485f..f297089d 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/packages.config +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/packages.config @@ -3,7 +3,9 @@ + + diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/App_GlobalResources/WebsitePanel_SharedResources.ascx.resx b/WebsitePanel/Sources/WebsitePanel.WebPortal/App_GlobalResources/WebsitePanel_SharedResources.ascx.resx index f3dc6d89..27771dda 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/App_GlobalResources/WebsitePanel_SharedResources.ascx.resx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/App_GlobalResources/WebsitePanel_SharedResources.ascx.resx @@ -5626,4 +5626,7 @@ You cannot use a IDN domain name for organizations + + Collection not created + \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/Code/Helpers/RDSHelper.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/Code/Helpers/RDSHelper.cs index 75e0cfab..0e13992a 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/Code/Helpers/RDSHelper.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/Code/Helpers/RDSHelper.cs @@ -71,9 +71,9 @@ namespace WebsitePanel.Portal return rdsServers.Servers; } - public RdsServer[] GetFreeRDSServers() + public RdsServer[] GetFreeRDSServers(int packageId) { - return ES.Services.RDS.GetFreeRdsServersPaged("", "", "", 0, 1000).Servers; + return ES.Services.RDS.GetFreeRdsServersPaged(packageId, "", "", "", 0, 1000).Servers; } #endregion diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/AddRDSServer.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/AddRDSServer.ascx.cs index f60e76f3..aac45078 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/AddRDSServer.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/AddRDSServer.ascx.cs @@ -50,7 +50,7 @@ namespace WebsitePanel.Portal.RDS private void BindRDSServers() { - ddlServers.DataSource = new RDSHelper().GetFreeRDSServers(); + ddlServers.DataSource = new RDSHelper().GetFreeRDSServers(PanelRequest.ItemID); ddlServers.DataTextField = "Name"; ddlServers.DataValueField = "Id"; ddlServers.DataBind(); diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSCreateCollection.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSCreateCollection.ascx.cs index ae93b5b4..7d23c02a 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSCreateCollection.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSCreateCollection.ascx.cs @@ -50,7 +50,9 @@ namespace WebsitePanel.Portal.RDS protected void btnSave_Click(object sender, EventArgs e) { if (!Page.IsValid) + { return; + } try { @@ -59,14 +61,15 @@ namespace WebsitePanel.Portal.RDS messageBox.ShowErrorMessage("RDS_CREATE_COLLECTION_RDSSERVER_REQUAIRED"); return; } + RdsCollection collection = new RdsCollection{ Name = txtCollectionName.Text, Servers = servers.GetServers(), Description = "" }; - ES.Services.RDS.AddRdsCollection(PanelRequest.ItemID, collection); - - Response.Redirect(EditUrl("ItemID", PanelRequest.ItemID.ToString(), "rds_collections", - "SpaceID=" + PanelSecurity.PackageId)); + Response.Redirect(EditUrl("ItemID", PanelRequest.ItemID.ToString(), "rds_collections", "SpaceID=" + PanelSecurity.PackageId)); + } + catch (Exception ex) + { + messageBox.ShowErrorMessage("RDSCOLLECTION_NOT_CREATED", ex); } - catch { } } } }