From 6bf818f1d8680ef958af3df9ab1281ca039b9929 Mon Sep 17 00:00:00 2001 From: vfedosevich Date: Mon, 2 Mar 2015 02:11:38 -0800 Subject: [PATCH 01/46] web portal es tab view added --- WebsitePanel/Database/update_db.sql | 144 ++++++++ .../EnterpriseStorageProxy.cs | 320 ++++++++++++++++++ .../Data/DataProvider.cs | 63 ++++ .../EnterpriseStorageController.cs | 154 +++++++++ .../esEnterpriseStorage.asmx.cs | 30 ++ .../Config/Entities/SessionKeysCollection.cs | 10 + .../WebConfigSections/SessionKeysElement.cs | 1 + .../Owa/WopiServer.cs | 4 +- .../Authorization/Enums/WebDavPermissions.cs | 4 +- .../WebDavAuthorizationService.cs | 48 +++ .../Controllers/FileSystemController.cs | 2 +- .../WebsitePanel.WebDavPortal/Web.config | 1 + .../ESModule_ControlsHierarchy.config | 1 + .../App_Data/WebsitePanel_Modules.config | 3 + ...riseStorageFolderGeneralSettings.ascx.resx | 3 + ...eFolderSettingsFolderPermissions.ascx.resx | 135 ++++++++ ...eStorageFolderSettingsOwaEditing.ascx.resx | 135 ++++++++ ...nterpriseStorageFolderGeneralSettings.ascx | 107 +++--- ...rpriseStorageFolderGeneralSettings.ascx.cs | 7 +- ...rageFolderGeneralSettings.ascx.designer.cs | 82 ++--- ...torageFolderSettingsFolderPermissions.ascx | 55 +++ ...ageFolderSettingsFolderPermissions.ascx.cs | 86 +++++ ...SettingsFolderPermissions.ascx.designer.cs | 132 ++++++++ ...rpriseStorageFolderSettingsOwaEditing.ascx | 54 +++ ...iseStorageFolderSettingsOwaEditing.ascx.cs | 80 +++++ ...eFolderSettingsOwaEditing.ascx.designer.cs | 132 ++++++++ .../EnterpriseStorageEditFolderTabs.ascx.resx | 129 +++++++ .../EnterpriseStorageOwaUsersList.ascx.resx | 156 +++++++++ .../EnterpriseStorageEditFolderTabs.ascx | 31 ++ .../EnterpriseStorageEditFolderTabs.ascx.cs | 52 +++ ...riseStorageEditFolderTabs.ascx.designer.cs | 24 ++ .../EnterpriseStorageOwaUsersList.ascx | 114 +++++++ .../EnterpriseStorageOwaUsersList.ascx.cs | 214 ++++++++++++ ...rpriseStorageOwaUsersList.ascx.designer.cs | 159 +++++++++ .../WebsitePanel.Portal.Modules.csproj | 36 ++ 35 files changed, 2592 insertions(+), 116 deletions(-) create mode 100644 WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/EnterpriseStorageFolderSettingsFolderPermissions.ascx.resx create mode 100644 WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/EnterpriseStorageFolderSettingsOwaEditing.ascx.resx create mode 100644 WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsFolderPermissions.ascx create mode 100644 WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsFolderPermissions.ascx.cs create mode 100644 WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsFolderPermissions.ascx.designer.cs create mode 100644 WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsOwaEditing.ascx create mode 100644 WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsOwaEditing.ascx.cs create mode 100644 WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsOwaEditing.ascx.designer.cs create mode 100644 WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/App_LocalResources/EnterpriseStorageEditFolderTabs.ascx.resx create mode 100644 WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/App_LocalResources/EnterpriseStorageOwaUsersList.ascx.resx create mode 100644 WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageEditFolderTabs.ascx create mode 100644 WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageEditFolderTabs.ascx.cs create mode 100644 WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageEditFolderTabs.ascx.designer.cs create mode 100644 WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageOwaUsersList.ascx create mode 100644 WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageOwaUsersList.ascx.cs create mode 100644 WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageOwaUsersList.ascx.designer.cs diff --git a/WebsitePanel/Database/update_db.sql b/WebsitePanel/Database/update_db.sql index 54df0493..270e1dcc 100644 --- a/WebsitePanel/Database/update_db.sql +++ b/WebsitePanel/Database/update_db.sql @@ -8729,3 +8729,147 @@ AND SI.ItemName = @ItemName AND ((@GroupName IS NULL) OR (@GroupName IS NOT NULL AND RG.GroupName = @GroupName)) RETURN GO + + +--ES OWA Editing +IF NOT EXISTS (SELECT * FROM SYS.TABLES WHERE name = 'EnterpriseFoldersOwaPermissions') +CREATE TABLE EnterpriseFoldersOwaPermissions +( + ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY, + ItemID INT NOT NULL, + FolderID INT NOT NULL, + AccountID INT NOT NULL +) +GO + +IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS WHERE CONSTRAINT_NAME ='FK_EnterpriseFoldersOwaPermissions_AccountId') +ALTER TABLE [dbo].[EnterpriseFoldersOwaPermissions] +DROP CONSTRAINT [FK_EnterpriseFoldersOwaPermissions_AccountId] +GO + +ALTER TABLE [dbo].[EnterpriseFoldersOwaPermissions] WITH CHECK ADD CONSTRAINT [FK_EnterpriseFoldersOwaPermissions_AccountId] FOREIGN KEY([AccountID]) +REFERENCES [dbo].[ExchangeAccounts] ([AccountID]) +ON DELETE CASCADE +GO + +IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS WHERE CONSTRAINT_NAME ='FK_EnterpriseFoldersOwaPermissions_FolderId') +ALTER TABLE [dbo].[EnterpriseFoldersOwaPermissions] +DROP CONSTRAINT [FK_EnterpriseFoldersOwaPermissions_FolderId] +GO + +ALTER TABLE [dbo].[EnterpriseFoldersOwaPermissions] WITH CHECK ADD CONSTRAINT [FK_EnterpriseFoldersOwaPermissions_FolderId] FOREIGN KEY([FolderID]) +REFERENCES [dbo].[EnterpriseFolders] ([EnterpriseFolderID]) +ON DELETE CASCADE +GO + + + +IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE type = 'P' AND name = 'DeleteAllEnterpriseFolderOwaUsers') +DROP PROCEDURE DeleteAllEnterpriseFolderOwaUsers +GO +CREATE PROCEDURE [dbo].[DeleteAllEnterpriseFolderOwaUsers] +( + @ItemID int, + @FolderID int +) +AS +DELETE FROM EnterpriseFoldersOwaPermissions +WHERE ItemId = @ItemID AND FolderID = @FolderID +GO + + + + + +IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE type = 'P' AND name = 'AddEnterpriseFolderOwaUser') +DROP PROCEDURE AddEnterpriseFolderOwaUser +GO +CREATE PROCEDURE [dbo].[AddEnterpriseFolderOwaUser] +( + @ESOwsaUserId INT OUTPUT, + @ItemID INT, + @FolderID INT, + @AccountID INT +) +AS +INSERT INTO EnterpriseFoldersOwaPermissions +( + ItemID , + FolderID, + AccountID +) +VALUES +( + @ItemID, + @FolderID, + @AccountID +) + +SET @ESOwsaUserId = SCOPE_IDENTITY() + +RETURN +GO + + + +IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE type = 'P' AND name = 'GetEnterpriseFolderOwaUsers') +DROP PROCEDURE GetEnterpriseFolderOwaUsers +GO +CREATE PROCEDURE [dbo].[GetEnterpriseFolderOwaUsers] +( + @ItemID INT, + @FolderID INT +) +AS +SELECT + EA.AccountID, + EA.ItemID, + EA.AccountType, + EA.AccountName, + EA.DisplayName, + EA.PrimaryEmailAddress, + EA.MailEnabledPublicFolder, + EA.MailboxPlanId, + EA.SubscriberNumber, + EA.UserPrincipalName + FROM EnterpriseFoldersOwaPermissions AS EFOP + LEFT JOIN ExchangeAccounts AS EA ON EA.AccountID = EFOP.AccountID + WHERE EFOP.ItemID = @ItemID AND EFOP.FolderID = @FolderID +GO + + + +IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE type = 'P' AND name = 'GetEnterpriseFolderId') +DROP PROCEDURE GetEnterpriseFolderId +GO +CREATE PROCEDURE [dbo].[GetEnterpriseFolderId] +( + @ItemID INT, + @FolderName varchar(max) +) +AS +SELECT TOP 1 + EnterpriseFolderID + FROM EnterpriseFolders + WHERE ItemId = @ItemID AND FolderName = @FolderName +GO + + + + + +IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE type = 'P' AND name = 'GetUserEnterpriseFolderWithOwaEditPermission') +DROP PROCEDURE GetUserEnterpriseFolderWithOwaEditPermission +GO +CREATE PROCEDURE [dbo].[GetUserEnterpriseFolderWithOwaEditPermission] +( + @ItemID INT, + @AccountID INT +) +AS +SELECT + EF.FolderName + FROM EnterpriseFoldersOwaPermissions AS EFOP + LEFT JOIN [dbo].[EnterpriseFolders] AS EF ON EF.EnterpriseFolderID = EFOP.FolderID + WHERE EFOP.ItemID = @ItemID AND EFOP.AccountID = @AccountID +GO \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/EnterpriseStorageProxy.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/EnterpriseStorageProxy.cs index 87682b0f..ef29192f 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/EnterpriseStorageProxy.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/EnterpriseStorageProxy.cs @@ -81,6 +81,16 @@ namespace WebsitePanel.EnterpriseServer { private System.Threading.SendOrPostCallback SetEnterpriseFolderSettingsOperationCompleted; + private System.Threading.SendOrPostCallback SetEnterpriseFolderGeneralSettingsOperationCompleted; + + private System.Threading.SendOrPostCallback SetEnterpriseFolderPermissionSettingsOperationCompleted; + + private System.Threading.SendOrPostCallback GetFolderOwaAccountsOperationCompleted; + + private System.Threading.SendOrPostCallback SetFolderOwaAccountsOperationCompleted; + + private System.Threading.SendOrPostCallback GetUserEnterpriseFolderWithOwaEditPermissionOperationCompleted; + private System.Threading.SendOrPostCallback GetStatisticsOperationCompleted; private System.Threading.SendOrPostCallback GetStatisticsByOrganizationOperationCompleted; @@ -169,6 +179,21 @@ namespace WebsitePanel.EnterpriseServer { /// public event SetEnterpriseFolderSettingsCompletedEventHandler SetEnterpriseFolderSettingsCompleted; + /// + public event SetEnterpriseFolderGeneralSettingsCompletedEventHandler SetEnterpriseFolderGeneralSettingsCompleted; + + /// + public event SetEnterpriseFolderPermissionSettingsCompletedEventHandler SetEnterpriseFolderPermissionSettingsCompleted; + + /// + public event GetFolderOwaAccountsCompletedEventHandler GetFolderOwaAccountsCompleted; + + /// + public event SetFolderOwaAccountsCompletedEventHandler SetFolderOwaAccountsCompleted; + + /// + public event GetUserEnterpriseFolderWithOwaEditPermissionCompletedEventHandler GetUserEnterpriseFolderWithOwaEditPermissionCompleted; + /// public event GetStatisticsCompletedEventHandler GetStatisticsCompleted; @@ -1223,6 +1248,237 @@ namespace WebsitePanel.EnterpriseServer { } } + /// + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/SetEnterpriseFolderGeneralSettings", 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 void SetEnterpriseFolderGeneralSettings(int itemId, SystemFile folder, bool directoyBrowsingEnabled, int quota, QuotaType quotaType) { + this.Invoke("SetEnterpriseFolderGeneralSettings", new object[] { + itemId, + folder, + directoyBrowsingEnabled, + quota, + quotaType}); + } + + /// + public System.IAsyncResult BeginSetEnterpriseFolderGeneralSettings(int itemId, SystemFile folder, bool directoyBrowsingEnabled, int quota, QuotaType quotaType, System.AsyncCallback callback, object asyncState) { + return this.BeginInvoke("SetEnterpriseFolderGeneralSettings", new object[] { + itemId, + folder, + directoyBrowsingEnabled, + quota, + quotaType}, callback, asyncState); + } + + /// + public void EndSetEnterpriseFolderGeneralSettings(System.IAsyncResult asyncResult) { + this.EndInvoke(asyncResult); + } + + /// + public void SetEnterpriseFolderGeneralSettingsAsync(int itemId, SystemFile folder, bool directoyBrowsingEnabled, int quota, QuotaType quotaType) { + this.SetEnterpriseFolderGeneralSettingsAsync(itemId, folder, directoyBrowsingEnabled, quota, quotaType, null); + } + + /// + public void SetEnterpriseFolderGeneralSettingsAsync(int itemId, SystemFile folder, bool directoyBrowsingEnabled, int quota, QuotaType quotaType, object userState) { + if ((this.SetEnterpriseFolderGeneralSettingsOperationCompleted == null)) { + this.SetEnterpriseFolderGeneralSettingsOperationCompleted = new System.Threading.SendOrPostCallback(this.OnSetEnterpriseFolderGeneralSettingsOperationCompleted); + } + this.InvokeAsync("SetEnterpriseFolderGeneralSettings", new object[] { + itemId, + folder, + directoyBrowsingEnabled, + quota, + quotaType}, this.SetEnterpriseFolderGeneralSettingsOperationCompleted, userState); + } + + private void OnSetEnterpriseFolderGeneralSettingsOperationCompleted(object arg) { + if ((this.SetEnterpriseFolderGeneralSettingsCompleted != null)) { + System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); + this.SetEnterpriseFolderGeneralSettingsCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); + } + } + + /// + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/SetEnterpriseFolderPermissionSetting" + + "s", 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 void SetEnterpriseFolderPermissionSettings(int itemId, SystemFile folder, ESPermission[] permissions) { + this.Invoke("SetEnterpriseFolderPermissionSettings", new object[] { + itemId, + folder, + permissions}); + } + + /// + public System.IAsyncResult BeginSetEnterpriseFolderPermissionSettings(int itemId, SystemFile folder, ESPermission[] permissions, System.AsyncCallback callback, object asyncState) { + return this.BeginInvoke("SetEnterpriseFolderPermissionSettings", new object[] { + itemId, + folder, + permissions}, callback, asyncState); + } + + /// + public void EndSetEnterpriseFolderPermissionSettings(System.IAsyncResult asyncResult) { + this.EndInvoke(asyncResult); + } + + /// + public void SetEnterpriseFolderPermissionSettingsAsync(int itemId, SystemFile folder, ESPermission[] permissions) { + this.SetEnterpriseFolderPermissionSettingsAsync(itemId, folder, permissions, null); + } + + /// + public void SetEnterpriseFolderPermissionSettingsAsync(int itemId, SystemFile folder, ESPermission[] permissions, object userState) { + if ((this.SetEnterpriseFolderPermissionSettingsOperationCompleted == null)) { + this.SetEnterpriseFolderPermissionSettingsOperationCompleted = new System.Threading.SendOrPostCallback(this.OnSetEnterpriseFolderPermissionSettingsOperationCompleted); + } + this.InvokeAsync("SetEnterpriseFolderPermissionSettings", new object[] { + itemId, + folder, + permissions}, this.SetEnterpriseFolderPermissionSettingsOperationCompleted, userState); + } + + private void OnSetEnterpriseFolderPermissionSettingsOperationCompleted(object arg) { + if ((this.SetEnterpriseFolderPermissionSettingsCompleted != null)) { + System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); + this.SetEnterpriseFolderPermissionSettingsCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); + } + } + + /// + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/GetFolderOwaAccounts", 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 OrganizationUser[] GetFolderOwaAccounts(int itemId, SystemFile folder) { + object[] results = this.Invoke("GetFolderOwaAccounts", new object[] { + itemId, + folder}); + return ((OrganizationUser[])(results[0])); + } + + /// + public System.IAsyncResult BeginGetFolderOwaAccounts(int itemId, SystemFile folder, System.AsyncCallback callback, object asyncState) { + return this.BeginInvoke("GetFolderOwaAccounts", new object[] { + itemId, + folder}, callback, asyncState); + } + + /// + public OrganizationUser[] EndGetFolderOwaAccounts(System.IAsyncResult asyncResult) { + object[] results = this.EndInvoke(asyncResult); + return ((OrganizationUser[])(results[0])); + } + + /// + public void GetFolderOwaAccountsAsync(int itemId, SystemFile folder) { + this.GetFolderOwaAccountsAsync(itemId, folder, null); + } + + /// + public void GetFolderOwaAccountsAsync(int itemId, SystemFile folder, object userState) { + if ((this.GetFolderOwaAccountsOperationCompleted == null)) { + this.GetFolderOwaAccountsOperationCompleted = new System.Threading.SendOrPostCallback(this.OnGetFolderOwaAccountsOperationCompleted); + } + this.InvokeAsync("GetFolderOwaAccounts", new object[] { + itemId, + folder}, this.GetFolderOwaAccountsOperationCompleted, userState); + } + + private void OnGetFolderOwaAccountsOperationCompleted(object arg) { + if ((this.GetFolderOwaAccountsCompleted != null)) { + System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); + this.GetFolderOwaAccountsCompleted(this, new GetFolderOwaAccountsCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); + } + } + + /// + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/SetFolderOwaAccounts", 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 void SetFolderOwaAccounts(int itemId, SystemFile folder, OrganizationUser[] users) { + this.Invoke("SetFolderOwaAccounts", new object[] { + itemId, + folder, + users}); + } + + /// + public System.IAsyncResult BeginSetFolderOwaAccounts(int itemId, SystemFile folder, OrganizationUser[] users, System.AsyncCallback callback, object asyncState) { + return this.BeginInvoke("SetFolderOwaAccounts", new object[] { + itemId, + folder, + users}, callback, asyncState); + } + + /// + public void EndSetFolderOwaAccounts(System.IAsyncResult asyncResult) { + this.EndInvoke(asyncResult); + } + + /// + public void SetFolderOwaAccountsAsync(int itemId, SystemFile folder, OrganizationUser[] users) { + this.SetFolderOwaAccountsAsync(itemId, folder, users, null); + } + + /// + public void SetFolderOwaAccountsAsync(int itemId, SystemFile folder, OrganizationUser[] users, object userState) { + if ((this.SetFolderOwaAccountsOperationCompleted == null)) { + this.SetFolderOwaAccountsOperationCompleted = new System.Threading.SendOrPostCallback(this.OnSetFolderOwaAccountsOperationCompleted); + } + this.InvokeAsync("SetFolderOwaAccounts", new object[] { + itemId, + folder, + users}, this.SetFolderOwaAccountsOperationCompleted, userState); + } + + private void OnSetFolderOwaAccountsOperationCompleted(object arg) { + if ((this.SetFolderOwaAccountsCompleted != null)) { + System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); + this.SetFolderOwaAccountsCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); + } + } + + /// + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/GetUserEnterpriseFolderWithOwaEditPe" + + "rmission", 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 string[] GetUserEnterpriseFolderWithOwaEditPermission(int itemId, int[] accountIds) { + object[] results = this.Invoke("GetUserEnterpriseFolderWithOwaEditPermission", new object[] { + itemId, + accountIds}); + return ((string[])(results[0])); + } + + /// + public System.IAsyncResult BeginGetUserEnterpriseFolderWithOwaEditPermission(int itemId, int[] accountIds, System.AsyncCallback callback, object asyncState) { + return this.BeginInvoke("GetUserEnterpriseFolderWithOwaEditPermission", new object[] { + itemId, + accountIds}, callback, asyncState); + } + + /// + public string[] EndGetUserEnterpriseFolderWithOwaEditPermission(System.IAsyncResult asyncResult) { + object[] results = this.EndInvoke(asyncResult); + return ((string[])(results[0])); + } + + /// + public void GetUserEnterpriseFolderWithOwaEditPermissionAsync(int itemId, int[] accountIds) { + this.GetUserEnterpriseFolderWithOwaEditPermissionAsync(itemId, accountIds, null); + } + + /// + public void GetUserEnterpriseFolderWithOwaEditPermissionAsync(int itemId, int[] accountIds, object userState) { + if ((this.GetUserEnterpriseFolderWithOwaEditPermissionOperationCompleted == null)) { + this.GetUserEnterpriseFolderWithOwaEditPermissionOperationCompleted = new System.Threading.SendOrPostCallback(this.OnGetUserEnterpriseFolderWithOwaEditPermissionOperationCompleted); + } + this.InvokeAsync("GetUserEnterpriseFolderWithOwaEditPermission", new object[] { + itemId, + accountIds}, this.GetUserEnterpriseFolderWithOwaEditPermissionOperationCompleted, userState); + } + + private void OnGetUserEnterpriseFolderWithOwaEditPermissionOperationCompleted(object arg) { + if ((this.GetUserEnterpriseFolderWithOwaEditPermissionCompleted != null)) { + System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); + this.GetUserEnterpriseFolderWithOwaEditPermissionCompleted(this, new GetUserEnterpriseFolderWithOwaEditPermissionCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); + } + } + /// [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/GetStatistics", 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 OrganizationStatistics GetStatistics(int itemId) { @@ -2053,6 +2309,70 @@ namespace WebsitePanel.EnterpriseServer { [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] public delegate void SetEnterpriseFolderSettingsCompletedEventHandler(object sender, System.ComponentModel.AsyncCompletedEventArgs e); + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] + public delegate void SetEnterpriseFolderGeneralSettingsCompletedEventHandler(object sender, System.ComponentModel.AsyncCompletedEventArgs e); + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] + public delegate void SetEnterpriseFolderPermissionSettingsCompletedEventHandler(object sender, System.ComponentModel.AsyncCompletedEventArgs e); + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] + public delegate void GetFolderOwaAccountsCompletedEventHandler(object sender, GetFolderOwaAccountsCompletedEventArgs e); + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + public partial class GetFolderOwaAccountsCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs { + + private object[] results; + + internal GetFolderOwaAccountsCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : + base(exception, cancelled, userState) { + this.results = results; + } + + /// + public OrganizationUser[] Result { + get { + this.RaiseExceptionIfNecessary(); + return ((OrganizationUser[])(this.results[0])); + } + } + } + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] + public delegate void SetFolderOwaAccountsCompletedEventHandler(object sender, System.ComponentModel.AsyncCompletedEventArgs e); + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] + public delegate void GetUserEnterpriseFolderWithOwaEditPermissionCompletedEventHandler(object sender, GetUserEnterpriseFolderWithOwaEditPermissionCompletedEventArgs e); + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + public partial class GetUserEnterpriseFolderWithOwaEditPermissionCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs { + + private object[] results; + + internal GetUserEnterpriseFolderWithOwaEditPermissionCompletedEventArgs(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])); + } + } + } + /// [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] public delegate void GetStatisticsCompletedEventHandler(object sender, GetStatisticsCompletedEventArgs e); diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Data/DataProvider.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Data/DataProvider.cs index 1d903a9c..49501ef1 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Data/DataProvider.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Data/DataProvider.cs @@ -4543,6 +4543,69 @@ namespace WebsitePanel.EnterpriseServer ); } + public static void DeleteAllEnterpriseFolderOwaUsers(int itemId, int folderId) + { + SqlHelper.ExecuteNonQuery( + ConnectionString, + CommandType.StoredProcedure, + "DeleteAllEnterpriseFolderOwaUsers", + new SqlParameter("@ItemID", itemId), + new SqlParameter("@FolderID", folderId) + ); + } + + public static int AddEnterpriseFolderOwaUser(int itemId, int folderId, int accountId) + { + SqlParameter id = new SqlParameter("@ESOwsaUserId", SqlDbType.Int); + id.Direction = ParameterDirection.Output; + + SqlHelper.ExecuteNonQuery( + ConnectionString, + CommandType.StoredProcedure, + "AddEnterpriseFolderOwaUser", + id, + new SqlParameter("@ItemID", itemId), + new SqlParameter("@FolderID", folderId), + new SqlParameter("@AccountId", accountId) + ); + + // read identity + return Convert.ToInt32(id.Value); + } + + public static IDataReader GetEnterpriseFolderOwaUsers(int itemId, int folderId) + { + return SqlHelper.ExecuteReader( + ConnectionString, + CommandType.StoredProcedure, + "GetEnterpriseFolderOwaUsers", + new SqlParameter("@ItemID", itemId), + new SqlParameter("@FolderID", folderId) + ); + } + + public static IDataReader GetEnterpriseFolderId(int itemId, string folderName) + { + return SqlHelper.ExecuteReader( + ConnectionString, + CommandType.StoredProcedure, + "GetEnterpriseFolderId", + new SqlParameter("@ItemID", itemId), + new SqlParameter("@FolderName", folderName) + ); + } + + public static IDataReader GetUserEnterpriseFolderWithOwaEditPermission(int itemId, int accountId) + { + return SqlHelper.ExecuteReader( + ConnectionString, + CommandType.StoredProcedure, + "GetUserEnterpriseFolderWithOwaEditPermission", + new SqlParameter("@ItemID", itemId), + new SqlParameter("@AccountID", accountId) + ); + } + #endregion #region Support Service Levels diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/EnterpriseStorage/EnterpriseStorageController.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/EnterpriseStorage/EnterpriseStorageController.cs index d7fbc832..6402a7b0 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/EnterpriseStorage/EnterpriseStorageController.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/EnterpriseStorage/EnterpriseStorageController.cs @@ -152,6 +152,16 @@ namespace WebsitePanel.EnterpriseServer StartESBackgroundTaskInternal("SET_ENTERPRISE_FOLDER_SETTINGS", itemId, folder, permissions, directoyBrowsingEnabled, quota, quotaType); } + public static void SetESGeneralSettings(int itemId, SystemFile folder, bool directoyBrowsingEnabled, int quota, QuotaType quotaType) + { + SetESGeneralSettingsInternal("SET_ENTERPRISE_FOLDER_GENERAL_SETTINGS", itemId, folder, directoyBrowsingEnabled, quota, quotaType); + } + + public static void SetESFolderPermissionSettings(int itemId, SystemFile folder, ESPermission[] permissions) + { + SetESFolderPermissionSettingsInternal("SET_ENTERPRISE_FOLDER_GENERAL_SETTINGS", itemId, folder, permissions); + } + public static int AddWebDavAccessToken(WebDavAccessToken accessToken) { return DataProvider.AddWebDavAccessToken(accessToken); @@ -257,6 +267,69 @@ namespace WebsitePanel.EnterpriseServer return rootFolders; } + protected static void SetESGeneralSettingsInternal(string taskName, int itemId, SystemFile folder, bool directoyBrowsingEnabled, int quota, QuotaType quotaType) + { + // load organization + var org = OrganizationController.GetOrganization(itemId); + + try + { + TaskManager.StartTask("ENTERPRISE_STORAGE", taskName, org.PackageId); + + EnterpriseStorageController.SetFRSMQuotaOnFolder(itemId, folder.Name, quota, quotaType); + EnterpriseStorageController.SetDirectoryBrowseEnabled(itemId, folder.Url, directoyBrowsingEnabled); + } + catch (Exception ex) + { + // log error + TaskManager.WriteError(ex, "Error executing enterprise storage background task"); + } + finally + { + // complete task + try + { + TaskManager.CompleteTask(); + } + catch (Exception) + { + } + } + } + + protected static void SetESFolderPermissionSettingsInternal(string taskName, int itemId, SystemFile folder, ESPermission[] permissions) + { + // load organization + var org = OrganizationController.GetOrganization(itemId); + + new Thread(() => + { + try + { + TaskManager.StartTask("ENTERPRISE_STORAGE", taskName, org.PackageId); + + EnterpriseStorageController.SetFolderPermission(itemId, folder.Name, permissions); + } + catch (Exception ex) + { + // log error + TaskManager.WriteError(ex, "Error executing enterprise storage background task"); + } + finally + { + // complete task + try + { + TaskManager.CompleteTask(); + } + catch (Exception) + { + } + } + + }).Start(); + } + protected static void StartESBackgroundTaskInternal(string taskName, int itemId, SystemFile folder, ESPermission[] permissions, bool directoyBrowsingEnabled, int quota, QuotaType quotaType) { // load organization @@ -1265,6 +1338,87 @@ namespace WebsitePanel.EnterpriseServer return null; } + public static OrganizationUser[] GetFolderOwaAccounts(int itemId, string folderName) + { + try + { + var folderId = GetFolderId(itemId, folderName); + + var users = ObjectUtils.CreateListFromDataReader(DataProvider.GetEnterpriseFolderOwaUsers(itemId, folderId)); + + return users.ToArray(); + } + catch (Exception ex) + { + throw ex; + } + } + + public static void SetFolderOwaAccounts(int itemId, string folderName, OrganizationUser[] users) + { + try + { + var folderId = GetFolderId(itemId, folderName); + + DataProvider.DeleteAllEnterpriseFolderOwaUsers(itemId, folderId); + + foreach (var user in users) + { + DataProvider.AddEnterpriseFolderOwaUser(itemId, folderId, user.AccountId); + } + } + catch (Exception ex) + { + throw ex; + } + } + + protected static int GetFolderId(int itemId, string folderName) + { + try + { + GetFolder(itemId, folderName); + + var dataReader = DataProvider.GetEnterpriseFolderId(itemId, folderName); + + while (dataReader.Read()) + { + return (int)dataReader[0]; + } + + return -1; + } + catch (Exception ex) + { + throw ex; + } + } + + public static List GetUserEnterpriseFolderWithOwaEditPermission(int itemId, List accountIds) + { + try + { + var result = new List(); + + + foreach (var accountId in accountIds) + { + var reader = DataProvider.GetUserEnterpriseFolderWithOwaEditPermission(itemId, accountId); + + while (reader.Read()) + { + result.Add(Convert.ToString(reader["FolderName"])); + } + } + + return result.Distinct().ToList(); + } + catch (Exception ex) + { + throw ex; + } + } + #region WebDav portal public static string GetWebDavPortalUserSettingsByAccountId(int accountId) diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esEnterpriseStorage.asmx.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esEnterpriseStorage.asmx.cs index 6668b40b..f5ba338b 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esEnterpriseStorage.asmx.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esEnterpriseStorage.asmx.cs @@ -196,6 +196,36 @@ namespace WebsitePanel.EnterpriseServer EnterpriseStorageController.StartSetEnterpriseFolderSettingsBackgroundTask(itemId, folder, permissions, directoyBrowsingEnabled, quota, quotaType); } + [WebMethod] + public void SetEnterpriseFolderGeneralSettings(int itemId, SystemFile folder, bool directoyBrowsingEnabled, int quota, QuotaType quotaType) + { + EnterpriseStorageController.SetESGeneralSettings(itemId, folder, directoyBrowsingEnabled, quota, quotaType); + } + + [WebMethod] + public void SetEnterpriseFolderPermissionSettings(int itemId, SystemFile folder, ESPermission[] permissions) + { + EnterpriseStorageController.SetESFolderPermissionSettings(itemId, folder, permissions); + } + + [WebMethod] + public OrganizationUser[] GetFolderOwaAccounts(int itemId, SystemFile folder) + { + return EnterpriseStorageController.GetFolderOwaAccounts(itemId, folder.Name); + } + + [WebMethod] + public void SetFolderOwaAccounts(int itemId, SystemFile folder, OrganizationUser[] users) + { + EnterpriseStorageController.SetFolderOwaAccounts(itemId, folder.Name, users); + } + + [WebMethod] + public List GetUserEnterpriseFolderWithOwaEditPermission(int itemId, List accountIds) + { + return EnterpriseStorageController.GetUserEnterpriseFolderWithOwaEditPermission(itemId, accountIds); + } + #endregion #region Statistics diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/SessionKeysCollection.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/SessionKeysCollection.cs index f9337401..1a45b059 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/SessionKeysCollection.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/SessionKeysCollection.cs @@ -45,6 +45,16 @@ namespace WebsitePanel.WebDav.Core.Config.Entities } } + public string OwaEditFoldersSessionKey + { + get + { + SessionKeysElement sessionKey = + _sessionKeys.FirstOrDefault(x => x.Key == SessionKeysElement.OwaEditFoldersSessionKey); + return sessionKey != null ? sessionKey.Value : null; + } + } + public string WebDavRootFoldersPermissions { get diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/SessionKeysElement.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/SessionKeysElement.cs index ca2a44fd..76a0e7e8 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/SessionKeysElement.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/SessionKeysElement.cs @@ -14,6 +14,7 @@ namespace WebsitePanel.WebDav.Core.Config.WebConfigSections public const string WebDavRootFolderPermissionsKey = "WebDavRootFolderPermissionsKey"; public const string ResourseRenderCountKey = "ResourseRenderCountSessionKey"; public const string ItemIdSessionKey = "ItemId"; + public const string OwaEditFoldersSessionKey = "OwaEditFoldersSession"; [ConfigurationProperty(KeyKey, IsKey = true, IsRequired = true)] public string Key diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Owa/WopiServer.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Owa/WopiServer.cs index 547f930c..dada9bab 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Owa/WopiServer.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Owa/WopiServer.cs @@ -34,7 +34,9 @@ namespace WebsitePanel.WebDav.Core.Owa { var resource = _webDavManager.GetResource(path); - var readOnly = _webDavAuthorizationService.GetPermissions(WspContext.User, path).HasFlag(WebDavPermissions.Write) == false; + var permissions = _webDavAuthorizationService.GetPermissions(WspContext.User, path); + + var readOnly = permissions.HasFlag(WebDavPermissions.Write) == false || permissions.HasFlag(WebDavPermissions.OwaEdit) == false; var cFileInfo = new CheckFileInfo { diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Authorization/Enums/WebDavPermissions.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Authorization/Enums/WebDavPermissions.cs index b3c9a52e..dd25dc50 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Authorization/Enums/WebDavPermissions.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Authorization/Enums/WebDavPermissions.cs @@ -8,6 +8,8 @@ namespace WebsitePanel.WebDav.Core.Security.Authorization.Enums Empty = 0, None = 1, Read = 2, - Write = 4 + Write = 4, + OwaRead = 8, + OwaEdit = 16 } } \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Authorization/WebDavAuthorizationService.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Authorization/WebDavAuthorizationService.cs index f0c285f3..d3fe710c 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Authorization/WebDavAuthorizationService.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Security/Authorization/WebDavAuthorizationService.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Web; +using Cobalt; using WebsitePanel.EnterpriseServer.Base.HostedSolution; using WebsitePanel.Providers.HostedSolution; using WebsitePanel.WebDav.Core.Config; @@ -54,6 +55,17 @@ namespace WebsitePanel.WebDav.Core.Security.Authorization } } + var owaEditFolders = GetOwaFoldersWithEditPermission(principal); + + if (owaEditFolders.Contains(rootFolder)) + { + resultPermissions |= WebDavPermissions.OwaEdit; + } + else + { + resultPermissions |= WebDavPermissions.OwaRead; + } + return resultPermissions; } @@ -105,5 +117,41 @@ namespace WebsitePanel.WebDav.Core.Security.Authorization return groups ?? new ExchangeAccount[0]; } + + private IEnumerable GetOwaFoldersWithEditPermission(WspPrincipal principal) + { + var folders = HttpContext.Current.Session != null ? HttpContext.Current.Session[WebDavAppConfigManager.Instance.SessionKeys.OwaEditFoldersSessionKey] as IEnumerable : null; + + if (folders != null) + { + return folders; + } + + var accountsIds = new List(); + + accountsIds.Add(principal.AccountId); + + var groups = GetUserSecurityGroups(principal); + + accountsIds.AddRange(groups.Select(x=>x.AccountId)); + + try + { + folders = WspContext.Services.EnterpriseStorage.GetUserEnterpriseFolderWithOwaEditPermission(principal.ItemId, accountsIds.ToArray()); + } + catch (Exception) + { + //TODO remove try catch when es &portal will be updated + return new List(); + } + + + if (HttpContext.Current.Session != null) + { + HttpContext.Current.Session[WebDavAppConfigManager.Instance.SessionKeys.OwaEditFoldersSessionKey] = folders; + } + + return folders; + } } } \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/FileSystemController.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/FileSystemController.cs index c4c8591b..dbb50095 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/FileSystemController.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/FileSystemController.cs @@ -318,7 +318,7 @@ namespace WebsitePanel.WebDavPortal.Controllers { var permissions = _webDavAuthorizationService.GetPermissions(WspContext.User, pathPart); - if (permissions.HasFlag(WebDavPermissions.Write) == false || Request.Browser.IsMobileDevice) + if (permissions.HasFlag(WebDavPermissions.Write) == false || permissions.HasFlag(WebDavPermissions.OwaEdit) == false || Request.Browser.IsMobileDevice) { return new RedirectToRouteResult(FileSystemRouteNames.ViewOfficeOnline, null); } diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Web.config b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Web.config index 265b5f6e..3f07e5e5 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Web.config +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Web.config @@ -52,6 +52,7 @@ + diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/App_Data/ESModule_ControlsHierarchy.config b/WebsitePanel/Sources/WebsitePanel.WebPortal/App_Data/ESModule_ControlsHierarchy.config index f4e2aa27..ff127dbd 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/App_Data/ESModule_ControlsHierarchy.config +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/App_Data/ESModule_ControlsHierarchy.config @@ -135,6 +135,7 @@ + diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/App_Data/WebsitePanel_Modules.config b/WebsitePanel/Sources/WebsitePanel.WebPortal/App_Data/WebsitePanel_Modules.config index b78fd5a1..4f2a314a 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/App_Data/WebsitePanel_Modules.config +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/App_Data/WebsitePanel_Modules.config @@ -563,6 +563,9 @@ + + + diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/EnterpriseStorageFolderGeneralSettings.ascx.resx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/EnterpriseStorageFolderGeneralSettings.ascx.resx index 371dc3d8..38060605 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/EnterpriseStorageFolderGeneralSettings.ascx.resx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/EnterpriseStorageFolderGeneralSettings.ascx.resx @@ -168,4 +168,7 @@ Soft + + General Settings + \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/EnterpriseStorageFolderSettingsFolderPermissions.ascx.resx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/EnterpriseStorageFolderSettingsFolderPermissions.ascx.resx new file mode 100644 index 00000000..5052b0b5 --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/EnterpriseStorageFolderSettingsFolderPermissions.ascx.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ShowProgressDialog('Updating folder settings...'); + + + Save Changes + + + Folder Permissions + + + Permissions + + + Edit Folder + + \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/EnterpriseStorageFolderSettingsOwaEditing.ascx.resx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/EnterpriseStorageFolderSettingsOwaEditing.ascx.resx new file mode 100644 index 00000000..33677cf3 --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/EnterpriseStorageFolderSettingsOwaEditing.ascx.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ShowProgressDialog('Updating folder settings...'); + + + Save Changes + + + Office Web App Editing + + + Users + + + Edit Folder + + \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderGeneralSettings.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderGeneralSettings.ascx index 84cc95b7..37ced623 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderGeneralSettings.ascx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderGeneralSettings.ascx @@ -1,8 +1,11 @@ <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="EnterpriseStorageFolderGeneralSettings.ascx.cs" Inherits="WebsitePanel.Portal.ExchangeServer.EnterpriseStorageFolderGeneralSettings" %> + <%@ Register Src="../UserControls/SimpleMessageBox.ascx" TagName="SimpleMessageBox" TagPrefix="wsp" %> <%@ Register Src="UserControls/EnterpriseStoragePermissions.ascx" TagName="ESPermissions" TagPrefix="wsp"%> <%@ Register TagPrefix="wsp" TagName="CollapsiblePanel" Src="../UserControls/CollapsiblePanel.ascx" %> <%@ Register Src="../UserControls/EnableAsyncTasksSupport.ascx" TagName="EnableAsyncTasksSupport" TagPrefix="wsp" %> +<%@ Register TagPrefix="wsp" Namespace="WebsitePanel.Portal.ExchangeServer.UserControls" Assembly="WebsitePanel.Portal.Modules" %> +<%@ Register Src="UserControls/EnterpriseStorageEditFolderTabs.ascx" TagName="CollectionTabs" TagPrefix="wsp" %> @@ -16,62 +19,62 @@ - +
+ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + +
- - -
- - - -
- - -
-
-
 
- -
 
-
- - -
-
 
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + +
+ + +
+
+
 
+ +
 
+ - -
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderGeneralSettings.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderGeneralSettings.ascx.cs index 315780f2..ca4b3d1e 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderGeneralSettings.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderGeneralSettings.ascx.cs @@ -107,11 +107,7 @@ namespace WebsitePanel.Portal.ExchangeServer break; } - var esPermissions = ES.Services.EnterpriseStorage.GetEnterpriseFolderPermissions(PanelRequest.ItemID,folder.Name); - chkDirectoryBrowsing.Checked = ES.Services.EnterpriseStorage.GetDirectoryBrowseEnabled(PanelRequest.ItemID, folder.Url); - - permissions.SetPermissions(esPermissions); } catch (Exception ex) { @@ -159,10 +155,9 @@ namespace WebsitePanel.Portal.ExchangeServer } } - ES.Services.EnterpriseStorage.SetEnterpriseFolderSettings( + ES.Services.EnterpriseStorage.SetEnterpriseFolderGeneralSettings( PanelRequest.ItemID, folder, - permissions.GetPemissions(), chkDirectoryBrowsing.Checked, (int)(decimal.Parse(txtFolderSize.Text) * OneGb), rbtnQuotaSoft.Checked ? QuotaType.Soft : QuotaType.Hard); diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderGeneralSettings.ascx.designer.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderGeneralSettings.ascx.designer.cs index dc276b18..4488393f 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderGeneralSettings.ascx.designer.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderGeneralSettings.ascx.designer.cs @@ -1,31 +1,3 @@ -// Copyright (c) 2015, Outercurve Foundation. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// - Neither the name of the Outercurve Foundation nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - //------------------------------------------------------------------------------ // // This code was generated by a tool. @@ -76,6 +48,15 @@ namespace WebsitePanel.Portal.ExchangeServer { /// protected global::System.Web.UI.WebControls.Literal litFolderName; + /// + /// tabs control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::WebsitePanel.Portal.ExchangeServer.UserControls.EnterpriseStorageEditFolderTabs tabs; + /// /// messageBox control. /// @@ -85,6 +66,24 @@ namespace WebsitePanel.Portal.ExchangeServer { /// protected global::WebsitePanel.Portal.UserControls.SimpleMessageBox messageBox; + /// + /// colFolderGeneralSettings control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::WebsitePanel.Portal.CollapsiblePanel colFolderGeneralSettings; + + /// + /// panelFolderGeneralSettings control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Panel panelFolderGeneralSettings; + /// /// locFolderName control. /// @@ -211,33 +210,6 @@ namespace WebsitePanel.Portal.ExchangeServer { /// protected global::System.Web.UI.WebControls.CheckBox chkDirectoryBrowsing; - /// - /// PermissionsPanel control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.HtmlControls.HtmlGenericControl PermissionsPanel; - - /// - /// PermissionsSection control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Localize PermissionsSection; - - /// - /// permissions control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::WebsitePanel.Portal.ExchangeServer.UserControls.EnterpriseStoragePermissions permissions; - /// /// btnSave control. /// diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsFolderPermissions.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsFolderPermissions.ascx new file mode 100644 index 00000000..8bddadca --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsFolderPermissions.ascx @@ -0,0 +1,55 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="EnterpriseStorageFolderSettingsFolderPermissions.ascx.cs" Inherits="WebsitePanel.Portal.ExchangeServer.EnterpriseStorageFolderSettingsFolderPermissions" %> + + +<%@ Register Src="../UserControls/SimpleMessageBox.ascx" TagName="SimpleMessageBox" TagPrefix="wsp" %> +<%@ Register Src="UserControls/EnterpriseStoragePermissions.ascx" TagName="ESPermissions" TagPrefix="wsp"%> +<%@ Register TagPrefix="wsp" TagName="CollapsiblePanel" Src="../UserControls/CollapsiblePanel.ascx" %> +<%@ Register Src="../UserControls/EnableAsyncTasksSupport.ascx" TagName="EnableAsyncTasksSupport" TagPrefix="wsp" %> +<%@ Register TagPrefix="wsp" Namespace="WebsitePanel.Portal.ExchangeServer.UserControls" Assembly="WebsitePanel.Portal.Modules" %> +<%@ Register Src="UserControls/EnterpriseStorageEditFolderTabs.ascx" TagName="CollectionTabs" TagPrefix="wsp" %> + + + +
+
+
+
+
+
+
+ + + + +
+
+ + + + + + + + + + + + +
+
+ + +
+
 
+
+ +
+ + +
+
+
+
+
+
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsFolderPermissions.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsFolderPermissions.ascx.cs new file mode 100644 index 00000000..219a9f4c --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsFolderPermissions.ascx.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.UI; +using System.Web.UI.WebControls; +using WebsitePanel.Providers.HostedSolution; +using WebsitePanel.Providers.OS; + +namespace WebsitePanel.Portal.ExchangeServer +{ + public partial class EnterpriseStorageFolderSettingsFolderPermissions : WebsitePanelModuleBase + { + #region Constants + + private const int OneGb = 1024; + + #endregion + + protected void Page_Load(object sender, EventArgs e) + { + if (!IsPostBack) + { + if (!ES.Services.EnterpriseStorage.CheckUsersDomainExists(PanelRequest.ItemID)) + { + Response.Redirect(EditUrl("SpaceID", PanelSecurity.PackageId.ToString(), "enterprisestorage_folders", + "ItemID=" + PanelRequest.ItemID)); + } + + BindSettings(); + } + } + + private void BindSettings() + { + try + { + // get settings + Organization org = ES.Services.Organizations.GetOrganization(PanelRequest.ItemID); + + SystemFile folder = ES.Services.EnterpriseStorage.GetEnterpriseFolder( + PanelRequest.ItemID, PanelRequest.FolderID); + + litFolderName.Text = string.Format("{0}", folder.Name); + + // bind form + var esPermissions = ES.Services.EnterpriseStorage.GetEnterpriseFolderPermissions(PanelRequest.ItemID,folder.Name); + + permissions.SetPermissions(esPermissions); + } + catch (Exception ex) + { + messageBox.ShowErrorMessage("ENETERPRISE_STORAGE_GET_FOLDER_SETTINGS", ex); + } + } + + protected void btnSave_Click(object sender, EventArgs e) + { + if (!Page.IsValid) + return; + + try + { + SystemFile folder = new SystemFile { Name = PanelRequest.FolderID }; + + if (!ES.Services.EnterpriseStorage.CheckEnterpriseStorageInitialization(PanelSecurity.PackageId, PanelRequest.ItemID)) + { + ES.Services.EnterpriseStorage.CreateEnterpriseStorage(PanelSecurity.PackageId, PanelRequest.ItemID); + } + + ES.Services.EnterpriseStorage.SetEnterpriseFolderPermissionSettings( + PanelRequest.ItemID, + folder, + permissions.GetPemissions()); + + + Response.Redirect(EditUrl("SpaceID", PanelSecurity.PackageId.ToString(), "enterprisestorage_folders", + "ItemID=" + PanelRequest.ItemID)); + } + catch (Exception ex) + { + messageBox.ShowErrorMessage("ENTERPRISE_STORAGE_UPDATE_FOLDER_SETTINGS", ex); + } + } + } +} \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsFolderPermissions.ascx.designer.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsFolderPermissions.ascx.designer.cs new file mode 100644 index 00000000..503327d4 --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsFolderPermissions.ascx.designer.cs @@ -0,0 +1,132 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace WebsitePanel.Portal.ExchangeServer { + + + public partial class EnterpriseStorageFolderSettingsFolderPermissions { + + /// + /// asyncTasks control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::WebsitePanel.Portal.EnableAsyncTasksSupport asyncTasks; + + /// + /// Image1 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Image Image1; + + /// + /// locTitle control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Localize locTitle; + + /// + /// litFolderName control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Literal litFolderName; + + /// + /// tabs control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::WebsitePanel.Portal.ExchangeServer.UserControls.EnterpriseStorageEditFolderTabs tabs; + + /// + /// messageBox control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::WebsitePanel.Portal.UserControls.SimpleMessageBox messageBox; + + /// + /// colFolderPermissions control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::WebsitePanel.Portal.CollapsiblePanel colFolderPermissions; + + /// + /// panelFolderPermissions control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Panel panelFolderPermissions; + + /// + /// PermissionsPanel control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.HtmlControls.HtmlGenericControl PermissionsPanel; + + /// + /// PermissionsSection control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Localize PermissionsSection; + + /// + /// permissions control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::WebsitePanel.Portal.ExchangeServer.UserControls.EnterpriseStoragePermissions permissions; + + /// + /// btnSave control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button btnSave; + + /// + /// valSummary control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.ValidationSummary valSummary; + } +} diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsOwaEditing.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsOwaEditing.ascx new file mode 100644 index 00000000..5a88b08e --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsOwaEditing.ascx @@ -0,0 +1,54 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="EnterpriseStorageFolderSettingsOwaEditing.ascx.cs" Inherits="WebsitePanel.Portal.ExchangeServer.EnterpriseStorageFolderSettingsOwaEditing" %> + + +<%@ Register Src="../UserControls/SimpleMessageBox.ascx" TagName="SimpleMessageBox" TagPrefix="wsp" %> +<%@ Register Src="UserControls/EnterpriseStorageOwaUsersList.ascx" TagName="OwaUsers" TagPrefix="wsp"%> +<%@ Register TagPrefix="wsp" TagName="CollapsiblePanel" Src="../UserControls/CollapsiblePanel.ascx" %> +<%@ Register Src="../UserControls/EnableAsyncTasksSupport.ascx" TagName="EnableAsyncTasksSupport" TagPrefix="wsp" %> +<%@ Register Src="UserControls/EnterpriseStorageEditFolderTabs.ascx" TagName="CollectionTabs" TagPrefix="wsp" %> + + + +
+
+
+
+
+
+
+ + + + +
+
+ + + + + + + + + + + + +
+
+ + +
+
 
+
+ +
+ + +
+
+
+
+
+
\ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsOwaEditing.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsOwaEditing.ascx.cs new file mode 100644 index 00000000..108c1c24 --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsOwaEditing.ascx.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.UI; +using System.Web.UI.WebControls; +using WebsitePanel.Providers.HostedSolution; +using WebsitePanel.Providers.OS; + +namespace WebsitePanel.Portal.ExchangeServer +{ + public partial class EnterpriseStorageFolderSettingsOwaEditing : WebsitePanelModuleBase + { + protected void Page_Load(object sender, EventArgs e) + { + if (!IsPostBack) + { + if (!ES.Services.EnterpriseStorage.CheckUsersDomainExists(PanelRequest.ItemID)) + { + Response.Redirect(EditUrl("SpaceID", PanelSecurity.PackageId.ToString(), "enterprisestorage_folders", + "ItemID=" + PanelRequest.ItemID)); + } + + BindSettings(); + } + } + + private void BindSettings() + { + try + { + // get settings + Organization org = ES.Services.Organizations.GetOrganization(PanelRequest.ItemID); + + SystemFile folder = ES.Services.EnterpriseStorage.GetEnterpriseFolder( + PanelRequest.ItemID, PanelRequest.FolderID); + + litFolderName.Text = string.Format("{0}", folder.Name); + + // bind form + var esPermissions = ES.Services.EnterpriseStorage.GetFolderOwaAccounts(PanelRequest.ItemID, folder); + + owaUsers.SetUsers(esPermissions); + } + catch (Exception ex) + { + messageBox.ShowErrorMessage("ENETERPRISE_STORAGE_GET_FOLDER_SETTINGS", ex); + } + } + + protected void btnSave_Click(object sender, EventArgs e) + { + if (!Page.IsValid) + return; + + try + { + SystemFile folder = new SystemFile { Name = PanelRequest.FolderID }; + + if (!ES.Services.EnterpriseStorage.CheckEnterpriseStorageInitialization(PanelSecurity.PackageId, PanelRequest.ItemID)) + { + ES.Services.EnterpriseStorage.CreateEnterpriseStorage(PanelSecurity.PackageId, PanelRequest.ItemID); + } + + ES.Services.EnterpriseStorage.SetFolderOwaAccounts( + PanelRequest.ItemID, + folder, + owaUsers.GetUsers()); + + + Response.Redirect(EditUrl("SpaceID", PanelSecurity.PackageId.ToString(), "enterprisestorage_folders", + "ItemID=" + PanelRequest.ItemID)); + } + catch (Exception ex) + { + messageBox.ShowErrorMessage("ENTERPRISE_STORAGE_UPDATE_FOLDER_SETTINGS", ex); + } + } + } +} \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsOwaEditing.ascx.designer.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsOwaEditing.ascx.designer.cs new file mode 100644 index 00000000..b927b94e --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsOwaEditing.ascx.designer.cs @@ -0,0 +1,132 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace WebsitePanel.Portal.ExchangeServer { + + + public partial class EnterpriseStorageFolderSettingsOwaEditing { + + /// + /// asyncTasks control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::WebsitePanel.Portal.EnableAsyncTasksSupport asyncTasks; + + /// + /// Image1 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Image Image1; + + /// + /// locTitle control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Localize locTitle; + + /// + /// litFolderName control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Literal litFolderName; + + /// + /// tabs control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::WebsitePanel.Portal.ExchangeServer.UserControls.EnterpriseStorageEditFolderTabs tabs; + + /// + /// messageBox control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::WebsitePanel.Portal.UserControls.SimpleMessageBox messageBox; + + /// + /// colOwaEditing control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::WebsitePanel.Portal.CollapsiblePanel colOwaEditing; + + /// + /// panelFolderPermissions control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Panel panelFolderPermissions; + + /// + /// OwaUsersPanel control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.HtmlControls.HtmlGenericControl OwaUsersPanel; + + /// + /// locOwaEditingSection control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Localize locOwaEditingSection; + + /// + /// owaUsers control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::WebsitePanel.Portal.ExchangeServer.UserControls.EnterpriseStorageOwaUsersList owaUsers; + + /// + /// btnSave control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button btnSave; + + /// + /// valSummary control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.ValidationSummary valSummary; + } +} diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/App_LocalResources/EnterpriseStorageEditFolderTabs.ascx.resx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/App_LocalResources/EnterpriseStorageEditFolderTabs.ascx.resx new file mode 100644 index 00000000..da04d0f8 --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/App_LocalResources/EnterpriseStorageEditFolderTabs.ascx.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Folder Permissions + + + General Settings + + + Office Web App Editing + + \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/App_LocalResources/EnterpriseStorageOwaUsersList.ascx.resx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/App_LocalResources/EnterpriseStorageOwaUsersList.ascx.resx new file mode 100644 index 00000000..47a2f1e3 --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/App_LocalResources/EnterpriseStorageOwaUsersList.ascx.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Add... + + + Add Accounts + + + Cancel + + + Delete + + + Display Name + + + E-mail Address + + + Display Name + + + Email + + + No accounts found. + + + The list of users is empty. Click "Add..." button. + + + Users + + + Enabled Users + + \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageEditFolderTabs.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageEditFolderTabs.ascx new file mode 100644 index 00000000..1fdcdd00 --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageEditFolderTabs.ascx @@ -0,0 +1,31 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="EnterpriseStorageEditFolderTabs.ascx.cs" Inherits="WebsitePanel.Portal.ExchangeServer.UserControls.EnterpriseStorageEditFolderTabs" %> + + + + + +
+ + + + + <%# Eval("Name") %> + + + + + + <%# Eval("Name") %> + + + +
+
+ + \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageEditFolderTabs.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageEditFolderTabs.ascx.cs new file mode 100644 index 00000000..2065b00c --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageEditFolderTabs.ascx.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.UI; +using System.Web.UI.WebControls; +using WebsitePanel.Portal.Code.UserControls; + +namespace WebsitePanel.Portal.ExchangeServer.UserControls +{ + public partial class EnterpriseStorageEditFolderTabs : WebsitePanelControlBase + { + public string SelectedTab { get; set; } + + protected void Page_Load(object sender, EventArgs e) + { + BindTabs(); + } + + private void BindTabs() + { + List tabsList = new List(); + tabsList.Add(CreateTab("enterprisestorage_folder_settings", "Tab.GeneralSettings")); + tabsList.Add(CreateTab("enterprisestorage_folder_settings_folder_permissions", "Tab.FolderPermissions")); + tabsList.Add(CreateTab("enterprisestorage_folder_settings_owa_editing", "Tab.OwaEditPermissions")); + + int idx = 0; + + foreach (Tab tab in tabsList) + { + if (String.Compare(tab.Id, SelectedTab, true) == 0) + { + break; + } + + idx++; + } + + esTabs.SelectedIndex = idx; + esTabs.DataSource = tabsList; + esTabs.DataBind(); + } + + private Tab CreateTab(string id, string text) + { + return new Tab(id,GetLocalizedString(text), + HostModule.EditUrl("AccountID", PanelRequest.AccountID.ToString(), id, + "SpaceID=" + PanelSecurity.PackageId.ToString(), + "ItemID=" + PanelRequest.ItemID.ToString(), "FolderID=" + PanelRequest.FolderID)); + } + } +} \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageEditFolderTabs.ascx.designer.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageEditFolderTabs.ascx.designer.cs new file mode 100644 index 00000000..8d176214 --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageEditFolderTabs.ascx.designer.cs @@ -0,0 +1,24 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace WebsitePanel.Portal.ExchangeServer.UserControls { + + + public partial class EnterpriseStorageEditFolderTabs { + + /// + /// esTabs control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.DataList esTabs; + } +} diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageOwaUsersList.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageOwaUsersList.ascx new file mode 100644 index 00000000..a5b8246c --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageOwaUsersList.ascx @@ -0,0 +1,114 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="EnterpriseStorageOwaUsersList.ascx.cs" Inherits="WebsitePanel.Portal.ExchangeServer.UserControls.EnterpriseStorageOwaUsersList" %> + + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+ + diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageOwaUsersList.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageOwaUsersList.ascx.cs new file mode 100644 index 00000000..3d39c38c --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageOwaUsersList.ascx.cs @@ -0,0 +1,214 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.UI; +using System.Web.UI.WebControls; +using WebsitePanel.Providers.HostedSolution; + +namespace WebsitePanel.Portal.ExchangeServer.UserControls +{ + public partial class EnterpriseStorageOwaUsersList : WebsitePanelControlBase + { + public const string DirectionString = "DirectionString"; + + protected enum SelectedState + { + All, + Selected, + Unselected + } + + public void SetUsers(OrganizationUser[] users) + { + BindAccounts(users, false); + } + + public OrganizationUser[] GetUsers() + { + return GetGridViewUsers(EnterpriseStorageOwaUsersList.SelectedState.All).ToArray(); + } + + protected void Page_Load(object sender, EventArgs e) + { + // register javascript + if (!Page.ClientScript.IsClientScriptBlockRegistered("SelectAllCheckboxes")) + { + string script = @" function SelectAllCheckboxes(box) + { + var state = box.checked; + var elm = box.parentElement.parentElement.parentElement.parentElement.getElementsByTagName(""INPUT""); + for(i = 0; i < elm.length; i++) + if(elm[i].type == ""checkbox"" && elm[i].id != box.id && elm[i].checked != state && !elm[i].disabled) + elm[i].checked = state; + }"; + Page.ClientScript.RegisterClientScriptBlock(typeof(EnterpriseStorageOwaUsersList), "SelectAllCheckboxes", + script, true); + } + } + + protected void btnAdd_Click(object sender, EventArgs e) + { + // bind all accounts + BindPopupAccounts(); + + // show modal + AddAccountsModal.Show(); + } + + protected void btnDelete_Click(object sender, EventArgs e) + { + List selectedAccounts = GetGridViewUsers(EnterpriseStorageOwaUsersList.SelectedState.Unselected); + + BindAccounts(selectedAccounts.ToArray(), false); + } + + protected void btnAddSelected_Click(object sender, EventArgs e) + { + List selectedAccounts = GetGridViewAccounts(); + + BindAccounts(selectedAccounts.ToArray(), true); + + } + + public string GetAccountImage(int accountTypeId) + { + string imgName = string.Empty; + + ExchangeAccountType accountType = (ExchangeAccountType)accountTypeId; + switch (accountType) + { + case ExchangeAccountType.Room: + imgName = "room_16.gif"; + break; + case ExchangeAccountType.Equipment: + imgName = "equipment_16.gif"; + break; + default: + imgName = "admin_16.png"; + break; + } + + return GetThemedImage("Exchange/" + imgName); + } + + protected void BindPopupAccounts() + { + OrganizationUser[] accounts = ES.Services.Organizations.GetOrganizationUsersPaged(PanelRequest.ItemID, ddlSearchColumn.SelectedValue, txtSearchValue.Text + "%", null, 0, Int32.MaxValue).PageUsers; + + accounts = accounts.Where(x => !GetUsers().Select(p => p.AccountName).Contains(x.AccountName)).ToArray(); + + Array.Sort(accounts, CompareAccount); + + if (Direction == SortDirection.Ascending) + { + Array.Reverse(accounts); + Direction = SortDirection.Descending; + } + else + Direction = SortDirection.Ascending; + + gvPopupAccounts.DataSource = accounts; + gvPopupAccounts.DataBind(); + } + + protected void BindAccounts(OrganizationUser[] newUsers, bool preserveExisting) + { + // get binded addresses + List users = new List(); + if (preserveExisting) + users.AddRange(GetGridViewUsers(EnterpriseStorageOwaUsersList.SelectedState.All)); + + // add new accounts + if (newUsers != null) + { + foreach (OrganizationUser newUser in newUsers) + { + // check if exists + bool exists = false; + foreach (OrganizationUser user in users) + { + if (String.Compare(user.AccountName, newUser.AccountName, true) == 0) + { + exists = true; + break; + } + } + + if (exists) + continue; + + users.Add(newUser); + } + } + + gvUsers.DataSource = users; + gvUsers.DataBind(); + } + + protected List GetGridViewUsers(EnterpriseStorageOwaUsersList.SelectedState state) + { + List users = new List(); + for (int i = 0; i < gvUsers.Rows.Count; i++) + { + GridViewRow row = gvUsers.Rows[i]; + CheckBox chkSelect = (CheckBox)row.FindControl("chkSelect"); + if (chkSelect == null) + continue; + + OrganizationUser user = new OrganizationUser(); + user.AccountName = (string)gvUsers.DataKeys[i][0]; + user.DisplayName = ((Literal)row.FindControl("litAccount")).Text; + user.AccountId = Convert.ToInt32(((HiddenField)row.FindControl("hdnAccountId")).Value); + + if (state == EnterpriseStorageOwaUsersList.SelectedState.All || + (state == EnterpriseStorageOwaUsersList.SelectedState.Selected && chkSelect.Checked) || + (state == EnterpriseStorageOwaUsersList.SelectedState.Unselected && !chkSelect.Checked)) + users.Add(user); + } + + return users; + } + + protected List GetGridViewAccounts() + { + List accounts = new List(); + for (int i = 0; i < gvPopupAccounts.Rows.Count; i++) + { + GridViewRow row = gvPopupAccounts.Rows[i]; + CheckBox chkSelect = (CheckBox)row.FindControl("chkSelect"); + if (chkSelect == null) + continue; + + if (chkSelect.Checked) + { + accounts.Add(new OrganizationUser + { + AccountName = (string)gvPopupAccounts.DataKeys[i][0], + DisplayName = ((Literal)row.FindControl("litDisplayName")).Text, + AccountId = Convert.ToInt32(((HiddenField)row.FindControl("hdnAccountId")).Value) + }); + } + } + + return accounts; + + } + + protected void cmdSearch_Click(object sender, ImageClickEventArgs e) + { + BindPopupAccounts(); + } + + protected SortDirection Direction + { + get { return ViewState[DirectionString] == null ? SortDirection.Descending : (SortDirection)ViewState[DirectionString]; } + set { ViewState[DirectionString] = value; } + } + + protected static int CompareAccount(OrganizationUser user1, OrganizationUser user2) + { + return string.Compare(user1.DisplayName, user2.DisplayName); + } + } +} \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageOwaUsersList.ascx.designer.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageOwaUsersList.ascx.designer.cs new file mode 100644 index 00000000..d9681b0e --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageOwaUsersList.ascx.designer.cs @@ -0,0 +1,159 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace WebsitePanel.Portal.ExchangeServer.UserControls { + + + public partial class EnterpriseStorageOwaUsersList { + + /// + /// UsersUpdatePanel control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.UpdatePanel UsersUpdatePanel; + + /// + /// btnAdd control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button btnAdd; + + /// + /// btnDelete control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button btnDelete; + + /// + /// gvUsers control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.GridView gvUsers; + + /// + /// AddAccountsPanel control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Panel AddAccountsPanel; + + /// + /// headerAddAccounts control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Localize headerAddAccounts; + + /// + /// AddAccountsUpdatePanel control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.UpdatePanel AddAccountsUpdatePanel; + + /// + /// SearchPanel control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Panel SearchPanel; + + /// + /// ddlSearchColumn control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.DropDownList ddlSearchColumn; + + /// + /// txtSearchValue control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.TextBox txtSearchValue; + + /// + /// cmdSearch control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.ImageButton cmdSearch; + + /// + /// gvPopupAccounts control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.GridView gvPopupAccounts; + + /// + /// btnAddSelected control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button btnAddSelected; + + /// + /// btnCancelAdd control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button btnCancelAdd; + + /// + /// btnAddAccountsFake control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button btnAddAccountsFake; + + /// + /// AddAccountsModal control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::AjaxControlToolkit.ModalPopupExtender AddAccountsModal; + } +} diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/WebsitePanel.Portal.Modules.csproj b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/WebsitePanel.Portal.Modules.csproj index e5fa35b0..f989847b 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/WebsitePanel.Portal.Modules.csproj +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/WebsitePanel.Portal.Modules.csproj @@ -211,6 +211,20 @@ + + EnterpriseStorageFolderSettingsFolderPermissions.ascx + ASPXCodeBehind + + + EnterpriseStorageFolderSettingsFolderPermissions.ascx + + + EnterpriseStorageFolderSettingsOwaEditing.ascx + ASPXCodeBehind + + + EnterpriseStorageFolderSettingsOwaEditing.ascx + OrganizationDeletedUsers.ascx ASPXCodeBehind @@ -229,6 +243,20 @@ OrganizationDeletedUserGeneralSettings.ascx ASPXCodeBehind + + EnterpriseStorageEditFolderTabs.ascx + ASPXCodeBehind + + + EnterpriseStorageEditFolderTabs.ascx + + + EnterpriseStorageOwaUsersList.ascx + ASPXCodeBehind + + + EnterpriseStorageOwaUsersList.ascx + SmarterMail100_EditAccount.ascx ASPXCodeBehind @@ -4455,7 +4483,11 @@ + + + + @@ -4499,6 +4531,10 @@ Designer + + + + From 6dc1d0c259ff9180dede4db9800b086f0b2165ac Mon Sep 17 00:00:00 2001 From: vfedosevich Date: Mon, 2 Mar 2015 05:10:53 -0800 Subject: [PATCH 02/46] webdav portal root quote added --- .../Sources/WebsitePanel.WebDav.Core/IFolder.cs | 4 ++-- .../Sources/WebsitePanel.WebDav.Core/IResource.cs | 1 + .../Managers/WebDavManager.cs | 6 +++--- .../WebsitePanel.WebDavPortal/Content/Site.css | 10 ++++++++++ .../Controllers/FileSystemController.cs | 4 ++-- .../Profiles/Webdav/ResourceTableItemProfile.cs | 2 ++ .../Models/FileSystem/ResourceTableItemModel.cs | 3 +++ .../Scripts/appScripts/fileBrowsing.js | 15 ++++++++++++--- 8 files changed, 35 insertions(+), 10 deletions(-) diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IFolder.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IFolder.cs index f37b9f94..52b32743 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IFolder.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IFolder.cs @@ -295,11 +295,11 @@ namespace WebsitePanel.WebDav.Core { XmlResponseList = XmlDoc.GetElementsByTagName("d:response"); } - var children = new WebDavHierarchyItem[XmlResponseList.Count]; + var children = new WebDavResource[XmlResponseList.Count]; int counter = 0; foreach (XmlNode XmlCurrentResponse in XmlResponseList) { - var item = new WebDavHierarchyItem(); + var item = new WebDavResource(); item.SetCredentials(_credentials); foreach (XmlNode XmlCurrentNode in XmlCurrentResponse.ChildNodes) diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IResource.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IResource.cs index d1545431..34f4f81a 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IResource.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IResource.cs @@ -50,6 +50,7 @@ namespace WebsitePanel.WebDav.Core SendChunked = false; AllowWriteStreamBuffering = false; + IsRootItem = item.IsRootItem; SetCredentials(credentials); SetHierarchyItem(item); } diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Managers/WebDavManager.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Managers/WebDavManager.cs index 98ea32ec..4d1ab904 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Managers/WebDavManager.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Managers/WebDavManager.cs @@ -50,9 +50,9 @@ namespace WebsitePanel.WebDav.Core.Managers children = ConnectToWebDavServer().Select(x => new WebDavResource { Href = new Uri(x.Url), - ItemType = ItemType.Folder, - ContentLength = x.Size, - AllocatedSpace = x.FRSMQuotaMB, + ItemType = ItemType.Folder, + ContentLength = x.Size * 1024 * 1024, + AllocatedSpace = x.FRSMQuotaMB * 1024 * 1024, IsRootItem = true }).ToArray(); } diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css index f539d480..9137665c 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css @@ -295,6 +295,16 @@ tr.selected-file { display: block; } +.column-name { + position: relative; +} + +.column-name #quota { + position: absolute; + right: 0px; + top: 20%; +} + /* Theme Mods */ input,div{border-radius:0px!important;} diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/FileSystemController.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/FileSystemController.cs index dbb50095..46beea31 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/FileSystemController.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/FileSystemController.cs @@ -151,11 +151,11 @@ namespace WebsitePanel.WebDavPortal.Controllers if (string.IsNullOrEmpty(dtRequest.Search.Value) == false) { - folderItems = _webdavManager.SearchFiles(WspContext.User.ItemId, pathPart, dtRequest.Search.Value, WspContext.User.Login, true).Select(x => new WebDavResource(null, x)); + folderItems = _webdavManager.SearchFiles(WspContext.User.ItemId, pathPart, dtRequest.Search.Value, WspContext.User.Login, true).Cast(); } else { - folderItems = _webdavManager.OpenFolder(pathPart).Select(x=>new WebDavResource(null, x)); + folderItems = _webdavManager.OpenFolder(pathPart).Cast(); } var tableItems = Mapper.Map, IEnumerable>(folderItems).ToList(); diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Mapping/Profiles/Webdav/ResourceTableItemProfile.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Mapping/Profiles/Webdav/ResourceTableItemProfile.cs index a20e44b3..cc712682 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Mapping/Profiles/Webdav/ResourceTableItemProfile.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Mapping/Profiles/Webdav/ResourceTableItemProfile.cs @@ -45,7 +45,9 @@ namespace WebsitePanel.WebDavPortal.Mapping.Profiles.Webdav .ForMember(ti => ti.LastModified, x => x.MapFrom(hi => hi.LastModified)) .ForMember(ti => ti.LastModifiedFormated, x => x.MapFrom(hi => hi.LastModified == DateTime.MinValue ? "--" : (new WebDavResource(null, hi)).LastModified.ToString("dd/MM/yyyy hh:mm tt"))) + .ForMember(ti => ti.IsRoot, x => x.MapFrom(hi => hi.IsRootItem)) .ForMember(ti => ti.Size, x => x.MapFrom(hi => hi.ContentLength)) + .ForMember(ti => ti.Quota, x => x.MapFrom(hi => hi.AllocatedSpace)) .ForMember(ti => ti.IsFolder, x => x.MapFrom(hi => hi.ItemType == ItemType.Folder)); } } diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Models/FileSystem/ResourceTableItemModel.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Models/FileSystem/ResourceTableItemModel.cs index 24ac5e13..2d2121cf 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Models/FileSystem/ResourceTableItemModel.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Models/FileSystem/ResourceTableItemModel.cs @@ -12,11 +12,14 @@ namespace WebsitePanel.WebDavPortal.Models.FileSystem public bool IsTargetBlank { get; set; } public bool IsFolder { get; set; } public long Size { get; set; } + public bool IsRoot { get; set; } + public long Quota { get; set; } public string Type { get; set; } public DateTime LastModified { get; set; } public string LastModifiedFormated { get; set; } public string IconHref { get; set; } + public override dynamic this[int index] { get diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/fileBrowsing.js b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/fileBrowsing.js index 10478859..ec557926 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/fileBrowsing.js +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/fileBrowsing.js @@ -86,10 +86,11 @@ WspFileBrowser.prototype = { "columnDefs": [ { "render": function(data, type, row) { - return '' + - '' + + return '
' + + '' + row.DisplayName + - ''; + '' + (row.IsRoot ? '' + wsp.fileBrowser.bytesToSize(row.Size) + ' / ' + wsp.fileBrowser.bytesToSize(row.Quota) + '' : '') + +'
'; }, "targets": 0 }, @@ -186,6 +187,14 @@ WspFileBrowser.prototype = { } }); }; + }, + + bytesToSize: function(bytes) { + if (bytes == 0) return '0 Byte'; + var k = 1024; + var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + var i = Math.floor(Math.log(bytes) / Math.log(k)); + return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i]; } }; From b51b6ee201edf7c62a60d4f3b6b3501d4ce1039c Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Mon, 2 Mar 2015 10:29:07 -0500 Subject: [PATCH 03/46] Added tag build-2.1.0.599 for changeset fe670172cd10 From ef3d4d2e5089bac193d918d2450dd65161061a9c Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Mon, 2 Mar 2015 12:20:48 -0500 Subject: [PATCH 04/46] Added tag build-2.1.0.600 for changeset e2e05db39b2b From 716855ae0551656dc29f6644a7168c6d8522ef21 Mon Sep 17 00:00:00 2001 From: dev_amdtel Date: Mon, 2 Mar 2015 23:44:26 +0400 Subject: [PATCH 05/46] fix import existing resources for old dns providers (including SimpleDNS) --- .../DnsServers/DnsServerController.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/DnsServers/DnsServerController.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/DnsServers/DnsServerController.cs index d659f9aa..bab622ac 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/DnsServers/DnsServerController.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/DnsServers/DnsServerController.cs @@ -32,6 +32,7 @@ using System.Collections.Specialized; using System.Globalization; using System.Linq; using System.Xml; +using System.Text; using System.Xml.Serialization; using WebsitePanel.Providers; using WebsitePanel.Providers.DNS; @@ -385,7 +386,9 @@ namespace WebsitePanel.EnterpriseServer var idn = new IdnMapping(); if (itemType == typeof(DnsZone)) - items.AddRange(dns.GetZones().Select(z => idn.GetUnicode(z))); + items.AddRange(dns.GetZones().Select(z => + Encoding.UTF8.GetByteCount(z) == z.Length ? // IsASCII + idn.GetUnicode(z) : z )); return items; } From 170cdc035827041909ea8f883cb4751084820558 Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Mon, 2 Mar 2015 20:15:58 -0500 Subject: [PATCH 06/46] Remove Duplicate Handlers --- WebsitePanel/Sources/WebsitePanel.Server/Web.config | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/WebsitePanel/Sources/WebsitePanel.Server/Web.config b/WebsitePanel/Sources/WebsitePanel.Server/Web.config index d9d1bde5..0dcd0c7d 100644 --- a/WebsitePanel/Sources/WebsitePanel.Server/Web.config +++ b/WebsitePanel/Sources/WebsitePanel.Server/Web.config @@ -5,17 +5,6 @@
- - - -
-
-
-
- -
- - From d7af90326c21dc19eaa9d978f7c286f20b408d08 Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Mon, 2 Mar 2015 20:29:52 -0500 Subject: [PATCH 07/46] Added tag build-2.1.0.601 for changeset 8ccdc857fa3f From 6af59c8cc86a6dd4da0efa6a2a8d015ca639975b Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Mon, 2 Mar 2015 22:48:46 -0500 Subject: [PATCH 08/46] Added tag build-2.1.0.602 for changeset 28e4e60c0e5c From 839f6cda2b7198e05e6a193c0374e91574aeb444 Mon Sep 17 00:00:00 2001 From: vfedosevich Date: Mon, 2 Mar 2015 23:46:37 -0800 Subject: [PATCH 09/46] owa editing groups added --- .../EnterpriseStorageFolderSettingsOwaEditing.ascx.resx | 2 +- .../EnterpriseStorageFolderSettingsOwaEditing.ascx | 2 +- .../UserControls/EnterpriseStorageOwaUsersList.ascx.cs | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/EnterpriseStorageFolderSettingsOwaEditing.ascx.resx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/EnterpriseStorageFolderSettingsOwaEditing.ascx.resx index 33677cf3..012d8bf8 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/EnterpriseStorageFolderSettingsOwaEditing.ascx.resx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/EnterpriseStorageFolderSettingsOwaEditing.ascx.resx @@ -127,7 +127,7 @@ Office Web App Editing - Users + Users And Groups Edit Folder diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsOwaEditing.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsOwaEditing.ascx index 5a88b08e..07ed6c6c 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsOwaEditing.ascx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/EnterpriseStorageFolderSettingsOwaEditing.ascx @@ -34,7 +34,7 @@
- +
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageOwaUsersList.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageOwaUsersList.ascx.cs index 3d39c38c..bf79f327 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageOwaUsersList.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/UserControls/EnterpriseStorageOwaUsersList.ascx.cs @@ -94,7 +94,8 @@ namespace WebsitePanel.Portal.ExchangeServer.UserControls protected void BindPopupAccounts() { - OrganizationUser[] accounts = ES.Services.Organizations.GetOrganizationUsersPaged(PanelRequest.ItemID, ddlSearchColumn.SelectedValue, txtSearchValue.Text + "%", null, 0, Int32.MaxValue).PageUsers; + ExchangeAccount[] accounts = ES.Services.EnterpriseStorage.SearchESAccounts(PanelRequest.ItemID, + ddlSearchColumn.SelectedValue, txtSearchValue.Text + "%", ""); accounts = accounts.Where(x => !GetUsers().Select(p => p.AccountName).Contains(x.AccountName)).ToArray(); @@ -206,7 +207,7 @@ namespace WebsitePanel.Portal.ExchangeServer.UserControls set { ViewState[DirectionString] = value; } } - protected static int CompareAccount(OrganizationUser user1, OrganizationUser user2) + protected static int CompareAccount(ExchangeAccount user1, ExchangeAccount user2) { return string.Compare(user1.DisplayName, user2.DisplayName); } From 0ebe24141ee12bd94f0f62b8c8d826670a04a4ed Mon Sep 17 00:00:00 2001 From: vfedosevich Date: Tue, 3 Mar 2015 06:41:52 -0800 Subject: [PATCH 10/46] webdav portal search view added --- .../OS/SystemFile.cs | 1 + .../Windows2012.cs | 6 +- .../Extensions/UriExtensions.cs | 2 +- .../WebsitePanel.WebDav.Core/IItemContent.cs | 1 + .../WebsitePanel.WebDav.Core/IResource.cs | 2 + .../Interfaces/Managers/IWebDavManager.cs | 1 + .../Managers/WebDavManager.cs | 15 +-- .../App_Start/RouteConfig.cs | 12 ++ .../App_Start/Routes/FileSystemRouteNames.cs | 3 + .../Content/Site.css | 43 ++++++- .../Controllers/FileSystemController.cs | 31 ++++- .../Webdav/ResourceTableItemProfile.cs | 1 + .../FileSystem/ResourceTableItemModel.cs | 5 +- .../Resources/UI.Designer.cs | 36 ++++++ .../Resources/UI.resx | 12 ++ .../Scripts/appScripts/authentication.js | 11 +- .../Scripts/appScripts/fileBrowsing.js | 109 +++++++++++++++--- .../Views/FileSystem/ShowContent.cshtml | 6 - .../ShowContentSearchResultTable.cshtml | 28 +++++ .../FileSystem/_ShowContentBigIcons.cshtml | 15 --- .../Views/FileSystem/_ShowContentTable.cshtml | 5 - .../FileSystem/_ShowContentTopMenu.cshtml | 89 +++++++++----- .../Views/Shared/_Layout.cshtml | 9 +- .../WebsitePanel.WebDavPortal.csproj | 1 + 24 files changed, 345 insertions(+), 99 deletions(-) create mode 100644 WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/ShowContentSearchResultTable.cshtml diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Base/OS/SystemFile.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Base/OS/SystemFile.cs index 830bccab..83d68d90 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Base/OS/SystemFile.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Base/OS/SystemFile.cs @@ -145,6 +145,7 @@ namespace WebsitePanel.Providers.OS } public string RelativeUrl { get; set; } + public string Summary { get; set; } public string DriveLetter { diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.EnterpriseStorage.Windows2012/Windows2012.cs b/WebsitePanel/Sources/WebsitePanel.Providers.EnterpriseStorage.Windows2012/Windows2012.cs index e5ff425c..b2eed0b3 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.EnterpriseStorage.Windows2012/Windows2012.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.EnterpriseStorage.Windows2012/Windows2012.cs @@ -304,7 +304,7 @@ namespace WebsitePanel.Providers.EnterpriseStorage var rootFolder = Path.Combine(settings.LocationDrive + ":\\", settings.HomeFolder); rootFolder = Path.Combine(rootFolder, organizationId); - var wsSql = string.Format(@"SELECT System.FileName, System.DateModified, System.Size, System.Kind, System.ItemPathDisplay, System.ItemType FROM SYSTEMINDEX WHERE System.FileName LIKE '%{0}%' AND ({1})", + var wsSql = string.Format(@"SELECT System.FileName, System.DateModified, System.Size, System.Kind, System.ItemPathDisplay, System.ItemType, System.Search.AutoSummary FROM SYSTEMINDEX WHERE System.FileName LIKE '%{0}%' AND ({1})", searchText, string.Join(" OR ", searchPaths.Select(x => string.Format("{0} = '{1}'", recursive ? "SCOPE" : "DIRECTORY", Path.Combine(rootFolder, x))).ToArray())); conn.Open(); @@ -318,7 +318,7 @@ namespace WebsitePanel.Providers.EnterpriseStorage var file = new SystemFile {Name = reader[0] as string}; file.Changed = file.CreatedDate = reader[1] is DateTime ? (DateTime)reader[1] : new DateTime(); - file.Size = reader[2] is long ? (long) reader[2] : 0; + file.Size = reader[2] is Decimal ? Convert.ToInt64((Decimal) reader[2]) : 0; var kind = reader[3] is IEnumerable ? ((IEnumerable)reader[3]).Cast().ToList() : null; var itemType = reader[5] as string ?? string.Empty; @@ -342,6 +342,8 @@ namespace WebsitePanel.Providers.EnterpriseStorage } } + file.Summary = reader[6] as string; + result.Add(file); } } diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Extensions/UriExtensions.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Extensions/UriExtensions.cs index 3f6bd4c6..8ba4aeeb 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Extensions/UriExtensions.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Extensions/UriExtensions.cs @@ -3,7 +3,7 @@ using System.Linq; namespace WebsitePanel.WebDav.Core.Extensions { - static class UriExtensions + public static class UriExtensions { public static Uri Append(this Uri uri, params string[] paths) { diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IItemContent.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IItemContent.cs index 399aeba0..681efa2e 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IItemContent.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IItemContent.cs @@ -9,6 +9,7 @@ namespace WebsitePanel.WebDav.Core long ContentLength { get; } long AllocatedSpace { get; set; } string ContentType { get; } + string Summary { get; set; } void Download(string filename); byte[] Download(); diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IResource.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IResource.cs index 34f4f81a..1a099ebf 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IResource.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IResource.cs @@ -89,6 +89,8 @@ namespace WebsitePanel.WebDav.Core } } + public string Summary { get; set; } + /// /// Downloads content of the resource to a file specified by filename /// diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Interfaces/Managers/IWebDavManager.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Interfaces/Managers/IWebDavManager.cs index fd1fdc3a..bf634dd8 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Interfaces/Managers/IWebDavManager.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Interfaces/Managers/IWebDavManager.cs @@ -19,5 +19,6 @@ namespace WebsitePanel.WebDav.Core.Interfaces.Managers string GetFileUrl(string path); void DeleteResource(string path); void LockFile(string path); + string GetFileFolderPath(string path); } } \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Managers/WebDavManager.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Managers/WebDavManager.cs index 4d1ab904..d3f837a7 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Managers/WebDavManager.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Managers/WebDavManager.cs @@ -103,7 +103,7 @@ namespace WebsitePanel.WebDav.Core.Managers public bool IsFile(string path) { - string folder = GetFileFolder(path); + string folder = GetFileFolderPath(path); if (string.IsNullOrWhiteSpace(folder)) { @@ -124,7 +124,7 @@ namespace WebsitePanel.WebDav.Core.Managers { try { - string folder = GetFileFolder(path); + string folder = GetFileFolderPath(path); var resourceName = GetResourceName(path); @@ -212,7 +212,7 @@ namespace WebsitePanel.WebDav.Core.Managers path = RemoveLeadingFromPath(path, "edit"); path = RemoveLeadingFromPath(path, WspContext.User.OrganizationId); - string folderPath = GetFileFolder(path); + string folderPath = GetFileFolderPath(path); OpenFolder(folderPath); @@ -232,7 +232,7 @@ namespace WebsitePanel.WebDav.Core.Managers { try { - string folder = GetFileFolder(path); + string folder = GetFileFolderPath(path); var resourceName = GetResourceName(path); @@ -250,7 +250,7 @@ namespace WebsitePanel.WebDav.Core.Managers { try { - string folder = GetFileFolder(path); + string folder = GetFileFolderPath(path); var resourceName = GetResourceName(path); @@ -270,7 +270,7 @@ namespace WebsitePanel.WebDav.Core.Managers { try { - string folder = GetFileFolder(path); + string folder = GetFileFolderPath(path); var resourceName = GetResourceName(path); @@ -345,6 +345,7 @@ namespace WebsitePanel.WebDav.Core.Managers webDavitem.SetLastModified(file.Changed); webDavitem.ContentLength = file.Size; webDavitem.AllocatedSpace = file.FRSMQuotaMB; + webDavitem.Summary = file.Summary; convertResult.Add(webDavitem); } @@ -372,7 +373,7 @@ namespace WebsitePanel.WebDav.Core.Managers targetStream.Write(buffer, 0, n); } - private string GetFileFolder(string path) + public string GetFileFolderPath(string path) { path = path.TrimEnd('/'); diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/RouteConfig.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/RouteConfig.cs index 1a5981a4..a5dc75e8 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/RouteConfig.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/RouteConfig.cs @@ -46,6 +46,18 @@ namespace WebsitePanel.WebDavPortal #region Enterprise storage + routes.MapRoute( + name: FileSystemRouteNames.SearchFiles, + url: "storage/search/{org}/{*pathPart}", + defaults: new { controller = "FileSystem", action = "SearchFiles", pathPart = UrlParameter.Optional } + ); + + routes.MapRoute( + name: FileSystemRouteNames.SearchFilesContent, + url: "storage/ajax/search/{org}/{*pathPart}", + defaults: new { controller = "FileSystem", action = "SearchFilesContent", pathPart = UrlParameter.Optional } + ); + routes.MapRoute( name: FileSystemRouteNames.ChangeWebDavViewType, url: "storage/change-view-type/{viewType}", diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/Routes/FileSystemRouteNames.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/Routes/FileSystemRouteNames.cs index 23ac46e2..9a6832b2 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/Routes/FileSystemRouteNames.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/Routes/FileSystemRouteNames.cs @@ -21,5 +21,8 @@ namespace WebsitePanel.WebDavPortal.UI.Routes public const string DeleteFiles = "DeleteFilesRoute"; public const string DownloadFile = "DownloadFileRoute"; + + public const string SearchFiles = "SearchFilesRoute"; + public const string SearchFilesContent = "SearchFilesPostRoute"; } } \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css index 9137665c..988dabfa 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css @@ -60,6 +60,17 @@ tr.selected-file { .table-icon { height: 30px; + vertical-align: top; +} + +.column-name .file-info { + display: inline-block; + padding-left: 5px; + width: 90%; +} + +.table-icon.search { + height: 45px; } .noselect { @@ -77,6 +88,8 @@ tr.selected-file { #webdav-items-table .file-link { padding-left: 5px; + padding-top: 5px; + display: inline-block; vertical-align: middle !important; } @@ -86,6 +99,11 @@ tr.selected-file { height: 32px; } +#summary.summary { + font-size: 11px; + color: rgb(152, 152, 152); +} + .drag-and-drop-area input { /* IE 8 */ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; @@ -252,16 +270,29 @@ tr.selected-file { width: 200px; } -.search-block { - float: right; +.breadcrumb-wsp { + display: inline-block; + padding-top: 5px; } -.search-block input, .search-block label { +.search-block { + float: right; + margin-right: 10px !important; + width: 36%; +} + +.search-block input{ + display: inline-block; + font-weight: normal; +} + +.search-block label { display: inline-block; width: initial; font-weight: normal; } + .elements-container { padding-top: 10px; } @@ -371,4 +402,10 @@ div#breadcrumb_wrapper a:last-child { .header-portal-title { float: none; display: inline-block; +} + +@media (min-width: 768px) { + .navbar-right { + margin-right: 0; + } } \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/FileSystemController.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/FileSystemController.cs index 46beea31..9d4016e1 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/FileSystemController.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/FileSystemController.cs @@ -35,6 +35,7 @@ using WebsitePanel.WebDavPortal.Models.Common.Enums; using WebsitePanel.WebDavPortal.Models.FileSystem; using WebsitePanel.WebDavPortal.UI; using WebsitePanel.WebDavPortal.UI.Routes; +using WebsitePanel.WebDav.Core.Extensions; namespace WebsitePanel.WebDavPortal.Controllers @@ -143,7 +144,6 @@ namespace WebsitePanel.WebDavPortal.Controllers } } - [HttpGet] public ActionResult GetContentDetails(string org, string pathPart, [ModelBinder(typeof (JqueryDataTableModelBinder))] JqueryDataTableRequest dtRequest) { @@ -160,7 +160,7 @@ namespace WebsitePanel.WebDavPortal.Controllers var tableItems = Mapper.Map, IEnumerable>(folderItems).ToList(); - FillContentModel(tableItems); + FillContentModel(tableItems, org); var orders = dtRequest.Orders.ToList(); orders.Insert(0, new JqueryDataTableOrder{Column = 3, Ascending = false}); @@ -184,6 +184,24 @@ namespace WebsitePanel.WebDavPortal.Controllers return PartialView("_ResourseCollectionPartial", result); } + public ActionResult SearchFiles(string org, string pathPart, string searchValue) + { + if (string.IsNullOrEmpty(searchValue)) + { + return RedirectToRoute(FileSystemRouteNames.ShowContentPath); + } + + var model = new ModelForWebDav + { + UrlSuffix = pathPart, + Permissions = _webDavAuthorizationService.GetPermissions(WspContext.User, pathPart), + UserSettings = _userSettingsManager.GetUserSettings(WspContext.User.AccountId), + SearchValue = searchValue + }; + + return View("ShowContentSearchResultTable", model); + } + [HttpGet] public ActionResult DownloadFile(string org, string pathPart) { @@ -329,17 +347,17 @@ namespace WebsitePanel.WebDavPortal.Controllers } #endregion - private void FillContentModel(IEnumerable items) + private void FillContentModel(IEnumerable items, string organizationId) { foreach (var item in items) { var opener = _openerManager[Path.GetExtension(item.DisplayName)]; + var pathPart = item.Href.AbsolutePath.Replace("/" + WspContext.User.OrganizationId, "").TrimStart('/'); switch (opener) { case FileOpenerType.OfficeOnline: { - var pathPart = item.Href.AbsolutePath.Replace("/" + WspContext.User.OrganizationId, "").TrimStart('/'); item.Url = string.Concat(Url.RouteUrl(FileSystemRouteNames.EditOfficeOnline, new {org = WspContext.User.OrganizationId, pathPart = ""}), pathPart); break; } @@ -350,6 +368,11 @@ namespace WebsitePanel.WebDavPortal.Controllers } } + var folderPath = Server.UrlDecode(_webdavManager.GetFileFolderPath(pathPart)); + + item.FolderUrlAbsoluteString = Server.UrlDecode(Url.RouteUrl(FileSystemRouteNames.ShowContentPath, new {org = organizationId, pathPart = folderPath}, Request.Url.Scheme)); + item.FolderUrlLocalString = Url.RouteUrl(FileSystemRouteNames.ShowContentPath, new { org = organizationId, pathPart = folderPath }); + if (Request.Browser.IsMobileDevice) { item.IsTargetBlank = false; diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Mapping/Profiles/Webdav/ResourceTableItemProfile.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Mapping/Profiles/Webdav/ResourceTableItemProfile.cs index cc712682..17d1b07e 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Mapping/Profiles/Webdav/ResourceTableItemProfile.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Mapping/Profiles/Webdav/ResourceTableItemProfile.cs @@ -45,6 +45,7 @@ namespace WebsitePanel.WebDavPortal.Mapping.Profiles.Webdav .ForMember(ti => ti.LastModified, x => x.MapFrom(hi => hi.LastModified)) .ForMember(ti => ti.LastModifiedFormated, x => x.MapFrom(hi => hi.LastModified == DateTime.MinValue ? "--" : (new WebDavResource(null, hi)).LastModified.ToString("dd/MM/yyyy hh:mm tt"))) + .ForMember(ti => ti.Summary, x => x.MapFrom(hi => hi.Summary)) .ForMember(ti => ti.IsRoot, x => x.MapFrom(hi => hi.IsRootItem)) .ForMember(ti => ti.Size, x => x.MapFrom(hi => hi.ContentLength)) .ForMember(ti => ti.Quota, x => x.MapFrom(hi => hi.AllocatedSpace)) diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Models/FileSystem/ResourceTableItemModel.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Models/FileSystem/ResourceTableItemModel.cs index 2d2121cf..bc605c28 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Models/FileSystem/ResourceTableItemModel.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Models/FileSystem/ResourceTableItemModel.cs @@ -18,7 +18,10 @@ namespace WebsitePanel.WebDavPortal.Models.FileSystem public DateTime LastModified { get; set; } public string LastModifiedFormated { get; set; } public string IconHref { get; set; } - + public string FolderUrlAbsoluteString { get; set; } + public string FolderUrlLocalString { get; set; } + public string FolderName { get; set; } + public string Summary { get; set; } public override dynamic this[int index] { diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.Designer.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.Designer.cs index e3836593..0aa9d823 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.Designer.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.Designer.cs @@ -150,6 +150,15 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to File. + /// + public static string File { + get { + return ResourceManager.GetString("File", resourceCulture); + } + } + /// /// Looks up a localized string similar to File Upload. /// @@ -168,6 +177,15 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to Info. + /// + public static string Info { + get { + return ResourceManager.GetString("Info", resourceCulture); + } + } + /// /// Looks up a localized string similar to {0} items was removed.. /// @@ -258,6 +276,24 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to Search Documents. + /// + public static string SearchDocuments { + get { + return ResourceManager.GetString("SearchDocuments", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Search Results. + /// + public static string SearchResults { + get { + return ResourceManager.GetString("SearchResults", resourceCulture); + } + } + /// /// Looks up a localized string similar to Select files to upload. /// diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.resx b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.resx index 5cb4b1a3..7d3fbf56 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.resx +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.resx @@ -147,12 +147,18 @@ Error + + File + File Upload Gb + + Info + {0} items was removed. @@ -183,6 +189,12 @@ Search + + Search Documents + + + Search Results + Select files to upload diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/authentication.js b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/authentication.js index 3752ad1e..35a5b8ff 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/authentication.js +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/authentication.js @@ -1,18 +1,19 @@ -function CheckAuthenticationExpiration(authcookieName, logoutUrl) { - var c = $.cookie(authcookieName); - +function CheckAuthenticationExpiration(authTimeOutCookieName, authCookieName, logoutUrl) { + var c = $.cookie(authTimeOutCookieName); + if (c != null && c != "" && !isNaN(c)) { var now = new Date(); var ms = parseInt(c, 10); var expiration = new Date().setTime(ms); if (now > expiration) { + $.removeCookie(authTimeOutCookieName, { path: '/' }); window.location.replace(logoutUrl); } } } -function StartAuthExpirationCheckTimer(authcookieName, logoutUrl) { +function StartAuthExpirationCheckTimer(authTimeOutCookieName, authCookieName, logoutUrl) { setInterval(function() { - CheckAuthenticationExpiration(authcookieName, logoutUrl); + CheckAuthenticationExpiration(authTimeOutCookieName, authCookieName, logoutUrl); }, 20000); } \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/fileBrowsing.js b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/fileBrowsing.js index ec557926..f14edab4 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/fileBrowsing.js +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/fileBrowsing.js @@ -1,6 +1,12 @@ function WspFileBrowser() { - this.settings = { deletionBlockSelector: ".file-actions-menu .file-deletion", deletionUrl: "storage/files-group-action/delete" }; - this.table = null; + this.settings = { + deletionBlockSelector: ".file-actions-menu .file-deletion", + deletionUrl: "storage/files-group-action/delete", + textDateModified: "Date modified", + textSize: "Size" + }; + this.itemsTable = null; + this.searchTable = null; } WspFileBrowser.prototype = { @@ -34,7 +40,8 @@ WspFileBrowser.prototype = { }).get(); }, - deleteSelectedItems: function(e) { + deleteSelectedItems: function (e) { + $.ajax({ type: 'POST', url: wsp.fileBrowser.settings.deletionUrl, @@ -45,7 +52,7 @@ WspFileBrowser.prototype = { wsp.fileBrowser.clearDeletedItems(model.DeletedFiles); wsp.fileBrowser.refreshDeletionBlock(); - wsp.fileBrowser.refreshDataTable(); + wsp.fileBrowser.refreshDataTable(wsp.fileBrowser.itemsTable); wsp.dialogs.hideProcessDialog(); }, @@ -53,7 +60,7 @@ WspFileBrowser.prototype = { wsp.messages.addErrorMessage(errorThrown); wsp.fileBrowser.refreshDeletionBlock(); - wsp.fileBrowser.refreshDataTable(); + wsp.fileBrowser.refreshDataTable(wsp.fileBrowser.itemsTable); wsp.dialogs.hideProcessDialog(); } @@ -79,10 +86,11 @@ WspFileBrowser.prototype = { }, initDataTable: function (tableId, ajaxUrl) { - this.table = $(tableId).dataTable({ + this.itemsTable = $(tableId).dataTable({ "ajax": ajaxUrl, "processing": false, "serverSide": true, + "dom": 'rtlp', "columnDefs": [ { "render": function(data, type, row) { @@ -128,18 +136,87 @@ WspFileBrowser.prototype = { $(tableId).removeClass('dataTable'); - var oTable = this.table; - $(tableId+'_filter input').unbind(); - $(tableId+'_filter input').bind('keyup', function (e) { - if (e.keyCode == 13) { - oTable.fnFilter(this.value); - } - }); + //var oTable = this.table; + + //$(searchInputId).bind('keyup', function (e) { + // if (e.keyCode == 13) { + // oTable.fnFilter(this.value); + // } + //}); + + //$(searchInputId).keydown(function (event) { + // if (event.keyCode == 13) { + // event.preventDefault(); + // return false; + // } + + // return true; + //}); + }, - refreshDataTable: function () { - if (this.table != null) { - this.table.fnDraw(false); + initSearchDataTable: function (tableId, ajaxUrl, initSearch) { + + var settings = this.settings; + var classThis = this; + + this.searchTable = $(tableId).dataTable({ + "ajax": ajaxUrl, + "processing": false, + "serverSide": true, + "oSearch": { "sSearch": initSearch }, + "dom": 'rtlp', + "columnDefs": [ + { + "render": function (data, type, row) { + return '
' + + '' + + '
' + + '' + + row.DisplayName + + '' + + '
' + (row.Summary ? (row.Summary + '').substring(0, 500) + '...' : '') + '
' + + '' + + '
' + + '
'; + }, + "targets": 0 + }, + { + "render": function (data, type, row) { + return '
' +settings.textDateModified+': '+ row.LastModifiedFormated+ '
' + + '
' + settings.textSize + ': ' + classThis.bytesToSize(row.Size) + '
'; + }, + "orderable": false, + "width": "25%", + "targets": 1 + } + ], + "createdRow": function (row, data, index) { + $(row).addClass('element-container'); + }, + "fnPreDrawCallback": function () { + // gather info to compose a message + wsp.dialogs.showProcessDialog(); + return true; + }, + "fnDrawCallback": function () { + // in case your overlay needs to be put away automatically you can put it here + wsp.dialogs.hideProcessDialog(); + } + }); + + $(tableId).removeClass('dataTable'); + + }, + + refreshDataTable: function (table) { + if (table != null) { + table.fnDraw(false); } }, diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/ShowContent.cshtml b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/ShowContent.cshtml index b36be144..af490ffc 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/ShowContent.cshtml +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/ShowContent.cshtml @@ -53,9 +53,3 @@ else } } - -@section popups -{ - @Html.Partial("_ProcessDialog", null) - @Html.Partial("_ConfirmDialog") -} \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/ShowContentSearchResultTable.cshtml b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/ShowContentSearchResultTable.cshtml new file mode 100644 index 00000000..f75107fc --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/ShowContentSearchResultTable.cshtml @@ -0,0 +1,28 @@ +@using WebsitePanel.WebDavPortal.Resources +@using WebsitePanel.WebDavPortal.UI.Routes +@model WebsitePanel.WebDavPortal.Models.ModelForWebDav + + +@Html.Partial("_ShowContentTopMenu", Model) + +
+ + + + + + + +
@UI.File@UI.Details
+
+ +@section scripts +{ + +} + diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentBigIcons.cshtml b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentBigIcons.cshtml index e87f9c2d..8591768f 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentBigIcons.cshtml +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentBigIcons.cshtml @@ -3,21 +3,6 @@ @using WebsitePanel.WebDavPortal.UI.Routes @model WebsitePanel.WebDavPortal.Models.ModelForWebDav -
- - -
-
diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentTable.cshtml b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentTable.cshtml index 8aed098b..a729ca02 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentTable.cshtml +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentTable.cshtml @@ -15,8 +15,3 @@
-@section popups -{ - @Html.Partial("_ProcessDialog", null) - @Html.Partial("_ConfirmDialog") -} \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentTopMenu.cshtml b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentTopMenu.cshtml index 4a6089ff..0a31a28c 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentTopMenu.cshtml +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentTopMenu.cshtml @@ -10,42 +10,69 @@ @if (Model != null) { string header = WspContext.User.OrganizationId; - @header string[] elements = Model.UrlSuffix.Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries); - for (int i = 0; i < elements.Length; i++) - { - / - @elements[i] - } - } -
-
- @if (Model.Permissions.HasFlag(WebDavPermissions.Write)) - { -
+ @Html.Partial("_ProcessDialog", null) + @Html.Partial("_ConfirmDialog") + @RenderSection("popups", required: false)
@@ -62,9 +65,9 @@ @Scripts.Render("~/bundles/authScripts") } diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebsitePanel.WebDavPortal.csproj b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebsitePanel.WebDavPortal.csproj index 9327be8f..6ccbc782 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebsitePanel.WebDavPortal.csproj +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebsitePanel.WebDavPortal.csproj @@ -459,6 +459,7 @@ + From a4cb95e2db86a717e4b0da5f0afeebcc9941fe57 Mon Sep 17 00:00:00 2001 From: vfedosevich Date: Tue, 3 Mar 2015 07:01:01 -0800 Subject: [PATCH 11/46] webdav portal fix --- .../Views/FileSystem/_ShowContentTopMenu.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentTopMenu.cshtml b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentTopMenu.cshtml index 0a31a28c..496ac682 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentTopMenu.cshtml +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentTopMenu.cshtml @@ -10,7 +10,7 @@ @if (Model != null) { string header = WspContext.User.OrganizationId; - string[] elements = Model.UrlSuffix.Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries); + string[] elements = string.IsNullOrEmpty(Model.UrlSuffix)? new string[0]: Model.UrlSuffix.Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
- + + +
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditApplicationUsers.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditApplicationUsers.ascx.cs index 41bdec12..2a9be753 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditApplicationUsers.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditApplicationUsers.ascx.cs @@ -100,5 +100,10 @@ namespace WebsitePanel.Portal.RDS Response.Redirect(EditUrl("SpaceID", PanelSecurity.PackageId.ToString(), "rds_collection_edit_apps", "CollectionId=" + PanelRequest.CollectionID, "ItemID=" + PanelRequest.ItemID)); } } + + protected void btnExit_Click(object sender, EventArgs e) + { + Response.Redirect(EditUrl("SpaceID", PanelSecurity.PackageId.ToString(), "rds_collection_edit_apps", "CollectionId=" + PanelRequest.CollectionID, "ItemID=" + PanelRequest.ItemID)); + } } } diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditApplicationUsers.ascx.designer.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditApplicationUsers.ascx.designer.cs index fd65d541..62030191 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditApplicationUsers.ascx.designer.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditApplicationUsers.ascx.designer.cs @@ -139,12 +139,30 @@ namespace WebsitePanel.Portal.RDS { protected global::WebsitePanel.Portal.RDS.UserControls.RDSCollectionUsers users; /// - /// buttonPanel control. + /// btnSave control. /// /// /// Auto-generated field. /// To modify move field declaration from designer file to code-behind file. /// - protected global::WebsitePanel.Portal.ItemButtonPanel buttonPanel; + protected global::System.Web.UI.WebControls.Button btnSave; + + /// + /// btnSaveExit control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button btnSaveExit; + + /// + /// btnExit control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button btnExit; } } diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionUsers.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionUsers.ascx index 7f71695d..57a37195 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionUsers.ascx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionUsers.ascx @@ -1,6 +1,7 @@ <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="RDSEditCollectionUsers.ascx.cs" Inherits="WebsitePanel.Portal.RDS.RDSEditCollectionUsers" %> <%@ Register Src="../UserControls/SimpleMessageBox.ascx" TagName="SimpleMessageBox" TagPrefix="wsp" %> <%@ Register Src="../UserControls/EnableAsyncTasksSupport.ascx" TagName="EnableAsyncTasksSupport" TagPrefix="wsp" %> +<%@ Register Src="../UserControls/QuotaViewer.ascx" TagName="QuotaViewer" TagPrefix="wsp" %> <%@ Register Src="UserControls/RDSCollectionUsers.ascx" TagName="CollectionUsers" TagPrefix="wsp"%> <%@ Register Src="UserControls/RDSCollectionTabs.ascx" TagName="CollectionTabs" TagPrefix="wsp" %> <%@ Register TagPrefix="wsp" TagName="CollapsiblePanel" Src="../UserControls/CollapsiblePanel.ascx" %> @@ -34,6 +35,11 @@ +
+ +     + +
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionUsers.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionUsers.ascx.cs index beaeed58..767eab4f 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionUsers.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionUsers.ascx.cs @@ -39,9 +39,10 @@ namespace WebsitePanel.Portal.RDS { protected void Page_Load(object sender, EventArgs e) - { + { if (!IsPostBack) { + BindQuota(); var collectionUsers = ES.Services.RDS.GetRdsCollectionUsers(PanelRequest.CollectionID); var collection = ES.Services.RDS.GetRdsCollection(PanelRequest.CollectionID); @@ -50,6 +51,20 @@ namespace WebsitePanel.Portal.RDS } } + private void BindQuota() + { + PackageContext cntx = PackagesHelper.GetCachedPackageContext(PanelSecurity.PackageId); + OrganizationStatistics stats = ES.Services.Organizations.GetOrganizationStatisticsByOrganization(PanelRequest.ItemID); + OrganizationStatistics tenantStats = ES.Services.Organizations.GetOrganizationStatistics(PanelRequest.ItemID); + usersQuota.QuotaUsedValue = stats.CreatedRdsUsers; + usersQuota.QuotaValue = stats.AllocatedRdsUsers; + + if (stats.AllocatedUsers != -1) + { + usersQuota.QuotaAvailable = tenantStats.AllocatedRdsUsers - tenantStats.CreatedRdsUsers; + } + } + private bool SaveRdsUsers() { try @@ -73,6 +88,7 @@ namespace WebsitePanel.Portal.RDS } SaveRdsUsers(); + BindQuota(); } protected void btnSaveExit_Click(object sender, EventArgs e) diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionUsers.ascx.designer.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionUsers.ascx.designer.cs index b4cdce32..e584e549 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionUsers.ascx.designer.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionUsers.ascx.designer.cs @@ -93,6 +93,24 @@ namespace WebsitePanel.Portal.RDS { /// protected global::WebsitePanel.Portal.RDS.UserControls.RDSCollectionUsers users; + /// + /// locQuota control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Localize locQuota; + + /// + /// usersQuota control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::WebsitePanel.Portal.QuotaViewer usersQuota; + /// /// buttonPanel control. /// diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSUserSessions.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSUserSessions.ascx index 642ed06a..9afc8a5b 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSUserSessions.ascx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSUserSessions.ascx @@ -38,10 +38,11 @@ - + + diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSUserSessions.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSUserSessions.ascx.cs index 79e37ea8..9938e16e 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSUserSessions.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSUserSessions.ascx.cs @@ -5,6 +5,8 @@ using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; +using WebsitePanel.EnterpriseServer; +using WebsitePanel.Providers.HostedSolution; using WebsitePanel.Providers.RemoteDesktopServices; namespace WebsitePanel.Portal.RDS @@ -101,5 +103,15 @@ namespace WebsitePanel.Portal.RDS gvRDSUserSessions.DataSource = userSessions; gvRDSUserSessions.DataBind(); } + + public string GetAccountImage(bool vip) + { + if (vip) + { + return GetThemedImage("Exchange/vip_user_16.png"); + } + + return GetThemedImage("Exchange/accounting_mail_16.png"); + } } } \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/UserControls/RDSCollectionApps.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/UserControls/RDSCollectionApps.ascx.cs index 15bf0ecc..0474d715 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/UserControls/RDSCollectionApps.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/UserControls/RDSCollectionApps.ascx.cs @@ -210,7 +210,7 @@ namespace WebsitePanel.Portal.RDS.UserControls RemoteApplication app = new RemoteApplication(); app.Alias = (string)gvApps.DataKeys[i][0]; - app.DisplayName = ((HyperLink)row.FindControl("lnkDisplayName")).Text; + app.DisplayName = ((LinkButton)row.FindControl("lnkDisplayName")).Text; app.FilePath = ((HiddenField)row.FindControl("hfFilePath")).Value; app.RequiredCommandLine = ((HiddenField)row.FindControl("hfRequiredCommandLine")).Value; diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDSServers.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDSServers.ascx index 0aa32a4e..c38baf43 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDSServers.ascx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDSServers.ascx @@ -5,11 +5,18 @@ <%@ Register Src="UserControls/UserDetails.ascx" TagName="UserDetails" TagPrefix="uc2" %> <%@ Register Src="UserControls/CollapsiblePanel.ascx" TagName="CollapsiblePanel" TagPrefix="wsp" %> <%@ Register Src="UserControls/SimpleMessageBox.ascx" TagName="SimpleMessageBox" TagPrefix="wsp" %> +<%@ Register Src="UserControls/PopupHeader.ascx" TagName="PopupHeader" TagPrefix="wsp" %> +<%@ Register Src="UserControls/EnableAsyncTasksSupport.ascx" TagName="EnableAsyncTasksSupport" TagPrefix="wsp" %> - - + + + + + + +
@@ -43,11 +50,45 @@ - + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + + + +
-

@Math.Round(Convert.ToDecimal(resource.ContentLength) / 1024, 2) / @Math.Round(Convert.ToDecimal(resource.AllocatedSpace) / 1024, 2) @UI.GigabyteShort

+

@ViewDataHelper.BytesToSize(resource.ContentLength) / @ViewDataHelper.BytesToSize(resource.AllocatedSpace)

}
diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebsitePanel.WebDavPortal.csproj b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebsitePanel.WebDavPortal.csproj index 6ccbc782..a2c21f6c 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebsitePanel.WebDavPortal.csproj +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebsitePanel.WebDavPortal.csproj @@ -183,6 +183,7 @@ Global.asax + From 2ce49650d4ab2a348762cf3d8db52588ebaed4f3 Mon Sep 17 00:00:00 2001 From: vfedosevich Date: Mon, 9 Mar 2015 03:55:14 -0700 Subject: [PATCH 26/46] webdav portal fixes --- WebsitePanel/Sources/WebsitePanel.WebDav.Core/IResource.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IResource.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IResource.cs index 2f706746..8a46fff6 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IResource.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/IResource.cs @@ -260,7 +260,7 @@ namespace WebsitePanel.WebDav.Core { get { - string displayName = _href.AbsoluteUri.Trim('/').Replace(_baseUri.AbsoluteUri.Trim('/'), ""); + string displayName = _href.ToString().Trim('/').Replace(_baseUri.ToString().Trim('/'), ""); displayName = Regex.Replace(displayName, "\\/$", ""); Match displayNameMatch = Regex.Match(displayName, "([\\/]+)$"); if (displayNameMatch.Success) From d24cad7ac7f271d702f47e56bd088fa04163f9fb Mon Sep 17 00:00:00 2001 From: vfedosevich Date: Mon, 9 Mar 2015 06:53:35 -0700 Subject: [PATCH 27/46] RDS Fixes --- .../Windows2012.cs | 116 +++++++++++++++++- .../App_LocalResources/RDS_Settings.ascx.resx | 3 + .../ProviderControls/RDS_Settings.ascx | 9 ++ .../ProviderControls/RDS_Settings.ascx.cs | 2 + .../RDS_Settings.ascx.designer.cs | 27 ++++ .../UserControls/RDSCollectionApps.ascx.cs | 2 +- 6 files changed, 154 insertions(+), 5 deletions(-) diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs b/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs index 930584d2..39cac14c 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs @@ -70,7 +70,8 @@ namespace WebsitePanel.Providers.RemoteDesktopServices private const string AddNpsString = "netsh nps add np name=\"\"{0}\"\" policysource=\"1\" processingorder=\"{1}\" conditionid=\"0x3d\" conditiondata=\"^5$\" conditionid=\"0x1fb5\" conditiondata=\"{2}\" conditionid=\"0x1e\" conditiondata=\"UserAuthType:(PW|CA)\" profileid=\"0x1005\" profiledata=\"TRUE\" profileid=\"0x100f\" profiledata=\"TRUE\" profileid=\"0x1009\" profiledata=\"0x7\" profileid=\"0x1fe6\" profiledata=\"0x40000000\""; private const string WspAdministratorsGroupDescription = "WSP Org Administrators"; private const string RdsServersOU = "RDSServers"; - private const string RDSHelpDeskComputerGroup = "Websitepanel-RDSHelpDesk-Computer"; + private const string RdsServersRootOU = "RDSRootServers"; + private const string RDSHelpDeskComputerGroup = "Websitepanel-RDSHelpDesk-Computer"; private const string RDSHelpDeskGroup = "WSP-HelpDeskAdministrators"; private const string RDSHelpDeskGroupDescription = "WSP Help Desk Administrators"; private const string LocalAdministratorsGroupName = "Administrators"; @@ -95,6 +96,14 @@ namespace WebsitePanel.Providers.RemoteDesktopServices } } + private string ComputersRootOU + { + get + { + return ProviderSettings["ComputersRootOU"]; + } + } + private string CentralNpsHost { get @@ -313,6 +322,9 @@ namespace WebsitePanel.Providers.RemoteDesktopServices CheckOrCreateHelpDeskComputerGroup(); string helpDeskGroupSamAccountName = CheckOrCreateAdGroup(GetHelpDeskGroupPath(RDSHelpDeskGroup), GetRootOUPath(), RDSHelpDeskGroup, RDSHelpDeskGroupDescription); + string groupName = GetLocalAdminsGroupName(collection.Name); + string groupPath = GetGroupPath(organizationId, collection.Name, groupName); + string localAdminsGroupSamAccountName = CheckOrCreateAdGroup(groupPath, GetOrganizationPath(organizationId), groupName, WspAdministratorsGroupDescription); if (!ActiveDirectoryUtils.AdObjectExists(GetUsersGroupPath(organizationId, collection.Name))) { @@ -344,7 +356,8 @@ namespace WebsitePanel.Providers.RemoteDesktopServices //add session servers to group foreach (var rdsServer in collection.Servers) { - AddAdGroupToLocalAdmins(runSpace, rdsServer.FqdName, helpDeskGroupSamAccountName); + AddAdGroupToLocalAdmins(runSpace, rdsServer.FqdName, helpDeskGroupSamAccountName); + AddAdGroupToLocalAdmins(runSpace, rdsServer.FqdName, localAdminsGroupSamAccountName); AddComputerToCollectionAdComputerGroup(organizationId, collection.Name, rdsServer); } } @@ -570,8 +583,12 @@ namespace WebsitePanel.Providers.RemoteDesktopServices ExecuteShellCommand(runSpace, cmd, false); CheckOrCreateHelpDeskComputerGroup(); - string helpDeskGroupSamAccountName = CheckOrCreateAdGroup(GetHelpDeskGroupPath(RDSHelpDeskGroup), GetRootOUPath(), RDSHelpDeskGroup, RDSHelpDeskGroupDescription); + string helpDeskGroupSamAccountName = CheckOrCreateAdGroup(GetHelpDeskGroupPath(RDSHelpDeskGroup), GetRootOUPath(), RDSHelpDeskGroup, RDSHelpDeskGroupDescription); + string groupName = GetLocalAdminsGroupName(collectionName); + string groupPath = GetGroupPath(organizationId, collectionName, groupName); + string localAdminsGroupSamAccountName = CheckOrCreateAdGroup(groupPath, GetOrganizationPath(organizationId), groupName, WspAdministratorsGroupDescription); + AddAdGroupToLocalAdmins(runSpace, server.FqdName, LocalAdministratorsGroupName); AddAdGroupToLocalAdmins(runSpace, server.FqdName, helpDeskGroupSamAccountName); AddComputerToCollectionAdComputerGroup(organizationId, collectionName, server); } @@ -1363,6 +1380,14 @@ namespace WebsitePanel.Providers.RemoteDesktopServices return installationResult; } + private void CheckOrCreateComputersRoot(string computersRootPath) + { + if (ActiveDirectoryUtils.AdObjectExists(computersRootPath) && !ActiveDirectoryUtils.AdObjectExists(GetRdsServersGroupPath())) + { + ActiveDirectoryUtils.CreateGroup(computersRootPath, RdsServersRootOU); + } + } + public void MoveRdsServerToTenantOU(string hostName, string organizationId) { var tenantComputerGroupPath = GetTenantComputerGroupPath(organizationId); @@ -1373,7 +1398,14 @@ namespace WebsitePanel.Providers.RemoteDesktopServices } hostName = hostName.ToLower().Replace(string.Format(".{0}", ServerSettings.ADRootDomain.ToLower()), ""); - var computerPath = GetComputerPath(hostName, true); + var computerPath = GetComputerPath(hostName, true); + var rootComputerPath = GetRdsServerPath(hostName); + var tenantComputerPath = GetTenantComputerPath(hostName, organizationId); + + if (!string.IsNullOrEmpty(ComputersRootOU)) + { + CheckOrCreateComputersRoot(GetComputersRootPath()); + } if(!ActiveDirectoryUtils.AdObjectExists(computerPath)) { @@ -1385,6 +1417,14 @@ namespace WebsitePanel.Providers.RemoteDesktopServices var computerObject = ActiveDirectoryUtils.GetADObject(computerPath); var samName = (string)ActiveDirectoryUtils.GetADObjectProperty(computerObject, "sAMAccountName"); + if (!string.IsNullOrEmpty(ComputersRootOU)) + { + if (ActiveDirectoryUtils.IsComputerInGroup(samName, RdsServersRootOU)) + { + ActiveDirectoryUtils.RemoveObjectFromGroup(computerPath, GetRdsServersGroupPath()); + } + } + if (!ActiveDirectoryUtils.IsComputerInGroup(samName, RdsServersOU)) { DirectoryEntry group = new DirectoryEntry(tenantComputerGroupPath); @@ -1400,6 +1440,12 @@ namespace WebsitePanel.Providers.RemoteDesktopServices var tenantComputerGroupPath = GetTenantComputerGroupPath(organizationId); hostName = hostName.ToLower().Replace(string.Format(".{0}", ServerSettings.ADRootDomain.ToLower()), ""); var tenantComputerPath = GetTenantComputerPath(hostName, organizationId); + var rootComputerPath = GetRdsServerPath(hostName); + + if (!string.IsNullOrEmpty(ComputersRootOU)) + { + CheckOrCreateComputersRoot(GetComputersRootPath()); + } var computerPath = GetComputerPath(hostName, true); @@ -1417,6 +1463,14 @@ namespace WebsitePanel.Providers.RemoteDesktopServices { ActiveDirectoryUtils.RemoveObjectFromGroup(computerPath, tenantComputerGroupPath); } + + if (ActiveDirectoryUtils.AdObjectExists(GetComputersRootPath()) && !string.IsNullOrEmpty(ComputersRootOU) && !ActiveDirectoryUtils.IsComputerInGroup(samName, RdsServersRootOU)) + { + DirectoryEntry group = new DirectoryEntry(GetRdsServersGroupPath()); + group.Invoke("Add", computerObject.Path); + + group.CommitChanges(); + } } } @@ -1543,6 +1597,10 @@ namespace WebsitePanel.Providers.RemoteDesktopServices { remoteApp.Users = users; } + else + { + remoteApp.Users = null; + } return remoteApp; } @@ -1734,6 +1792,56 @@ namespace WebsitePanel.Providers.RemoteDesktopServices return sb.ToString(); } + private string GetComputersRootPath() + { + StringBuilder sb = new StringBuilder(); + + AppendProtocol(sb); + AppendDomainController(sb); + AppendOUPath(sb, ComputersRootOU); + AppendDomainPath(sb, RootDomain); + + return sb.ToString(); + } + + private string GetRdsServersGroupPath() + { + StringBuilder sb = new StringBuilder(); + + AppendProtocol(sb); + AppendDomainController(sb); + AppendCNPath(sb, RdsServersRootOU); + AppendOUPath(sb, ComputersRootOU); + AppendDomainPath(sb, RootDomain); + + return sb.ToString(); + } + + private string GetRdsServerPath(string name) + { + StringBuilder sb = new StringBuilder(); + + AppendProtocol(sb); + AppendDomainController(sb); + AppendCNPath(sb, name); + AppendCNPath(sb, RdsServersRootOU); + AppendOUPath(sb, ComputersRootOU); + AppendDomainPath(sb, RootDomain); + + return sb.ToString(); + } + + private string GetRootPath() + { + StringBuilder sb = new StringBuilder(); + + AppendProtocol(sb); + AppendDomainController(sb); + AppendDomainPath(sb, RootDomain); + + return sb.ToString(); + } + internal string GetTenantComputerGroupPath(string organizationId) { StringBuilder sb = new StringBuilder(); diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/App_LocalResources/RDS_Settings.ascx.resx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/App_LocalResources/RDS_Settings.ascx.resx index d8e514f9..dd9c465d 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/App_LocalResources/RDS_Settings.ascx.resx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/App_LocalResources/RDS_Settings.ascx.resx @@ -144,4 +144,7 @@ SAN Name: + + Computers Root OU: + \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/RDS_Settings.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/RDS_Settings.ascx index 62f67170..415fd085 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/RDS_Settings.ascx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/RDS_Settings.ascx @@ -76,6 +76,15 @@ + + + + + + + + + diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/RDS_Settings.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/RDS_Settings.ascx.cs index 19c684e7..8806b61d 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/RDS_Settings.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/RDS_Settings.ascx.cs @@ -83,6 +83,7 @@ namespace WebsitePanel.Portal.ProviderControls UpdateLyncServersGrid(); txtRootOU.Text = settings["RootOU"]; + txtComputersRootOu.Text = settings["ComputersRootOU"]; txtPrimaryDomainController.Text = settings["PrimaryDomainController"]; if (!string.IsNullOrEmpty(settings["UseCentralNPS"]) && bool.TrueString == settings["UseCentralNPS"]) @@ -103,6 +104,7 @@ namespace WebsitePanel.Portal.ProviderControls { settings["ConnectionBroker"] = txtConnectionBroker.Text; settings["RootOU"] = txtRootOU.Text; + settings["ComputersRootOU"] = txtComputersRootOu.Text; settings["PrimaryDomainController"] = txtPrimaryDomainController.Text; settings["UseCentralNPS"] = chkUseCentralNPS.Checked.ToString(); settings["CentralNPS"] = chkUseCentralNPS.Checked ? txtCentralNPS.Text : string.Empty; diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/RDS_Settings.ascx.designer.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/RDS_Settings.ascx.designer.cs index 0a5bf54b..81ceb1a6 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/RDS_Settings.ascx.designer.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/RDS_Settings.ascx.designer.cs @@ -138,6 +138,33 @@ namespace WebsitePanel.Portal.ProviderControls { /// protected global::System.Web.UI.WebControls.RequiredFieldValidator RequiredFieldValidator4; + /// + /// lblComputersRootOU control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Label lblComputersRootOU; + + /// + /// txtComputersRootOu control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.TextBox txtComputersRootOu; + + /// + /// RequiredFieldValidator1 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.RequiredFieldValidator RequiredFieldValidator1; + /// /// lblPrimaryDomainController control. /// diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/UserControls/RDSCollectionApps.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/UserControls/RDSCollectionApps.ascx.cs index c293ea26..47e39a3d 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/UserControls/RDSCollectionApps.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/UserControls/RDSCollectionApps.ascx.cs @@ -215,7 +215,7 @@ namespace WebsitePanel.Portal.RDS.UserControls app.RequiredCommandLine = ((HiddenField)row.FindControl("hfRequiredCommandLine")).Value; var users = ((HiddenField)row.FindControl("hfUsers")).Value; - if (users != null) + if (!string.IsNullOrEmpty(users)) { app.Users = new string[]{"New"}; } From 9c991c861183861f21a3fec333d46aaa4fedf3b2 Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Mon, 9 Mar 2015 10:22:42 -0400 Subject: [PATCH 28/46] Added tag build-2.1.0.608 for changeset 4ba072d0a9b2 From 4efc1b045697c4f6e5386fafd5054160636a82be Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Mon, 9 Mar 2015 11:23:41 -0400 Subject: [PATCH 29/46] Added tag build-2.1.0.609 for changeset 4b919035dcca From a7672a30123e510b9f0a60572bcff1958a759d83 Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Mon, 9 Mar 2015 12:05:24 -0400 Subject: [PATCH 30/46] Added tag build-2.1.0.610 for changeset 3056ccfd4d17 From fd8ca11f383d14f38bdfcb3911a8a1a059bce7d2 Mon Sep 17 00:00:00 2001 From: vfedosevich Date: Tue, 10 Mar 2015 06:31:40 -0700 Subject: [PATCH 31/46] Help desk groups descriptions added --- .../Windows2012.cs | 24 +++++-------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs b/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs index 39cac14c..56a70d39 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs @@ -67,8 +67,10 @@ namespace WebsitePanel.Providers.RemoteDesktopServices private const string Admins = "Admins"; private const string RdsGroupFormat = "rds-{0}-{1}"; private const string RdsModuleName = "RemoteDesktopServices"; - private const string AddNpsString = "netsh nps add np name=\"\"{0}\"\" policysource=\"1\" processingorder=\"{1}\" conditionid=\"0x3d\" conditiondata=\"^5$\" conditionid=\"0x1fb5\" conditiondata=\"{2}\" conditionid=\"0x1e\" conditiondata=\"UserAuthType:(PW|CA)\" profileid=\"0x1005\" profiledata=\"TRUE\" profileid=\"0x100f\" profiledata=\"TRUE\" profileid=\"0x1009\" profiledata=\"0x7\" profileid=\"0x1fe6\" profiledata=\"0x40000000\""; - private const string WspAdministratorsGroupDescription = "WSP Org Administrators"; + private const string AddNpsString = "netsh nps add np name=\"\"{0}\"\" policysource=\"1\" processingorder=\"{1}\" conditionid=\"0x3d\" conditiondata=\"^5$\" conditionid=\"0x1fb5\" conditiondata=\"{2}\" conditionid=\"0x1e\" conditiondata=\"UserAuthType:(PW|CA)\" profileid=\"0x1005\" profiledata=\"TRUE\" profileid=\"0x100f\" profiledata=\"TRUE\" profileid=\"0x1009\" profiledata=\"0x7\" profileid=\"0x1fe6\" profiledata=\"0x40000000\""; + private const string WspAdministratorsGroupDescription = "WSP RDS Collection Adminstrators"; + private const string RdsCollectionUsersGroupDescription = "WSP RDS Collection Users"; + private const string RdsCollectionComputersGroupDescription = "WSP RDS Collection Computers"; private const string RdsServersOU = "RDSServers"; private const string RdsServersRootOU = "RDSRootServers"; private const string RDSHelpDeskComputerGroup = "Websitepanel-RDSHelpDesk-Computer"; @@ -310,27 +312,13 @@ namespace WebsitePanel.Providers.RemoteDesktopServices EditRdsCollectionSettingsInternal(collection, runSpace); var orgPath = GetOrganizationPath(organizationId); - - if (!ActiveDirectoryUtils.AdObjectExists(GetComputerGroupPath(organizationId, collection.Name))) - { - //Create computer group - ActiveDirectoryUtils.CreateGroup(orgPath, GetComputersGroupName(collection.Name)); - - //todo Connection broker server must be added by default ??? - //ActiveDirectoryUtils.AddObjectToGroup(GetComputerPath(ConnectionBroker), GetComputerGroupPath(organizationId, collection.Name)); - } - + CheckOrCreateAdGroup(GetComputerGroupPath(organizationId, collection.Name), orgPath, GetComputersGroupName(collection.Name), RdsCollectionComputersGroupDescription); CheckOrCreateHelpDeskComputerGroup(); string helpDeskGroupSamAccountName = CheckOrCreateAdGroup(GetHelpDeskGroupPath(RDSHelpDeskGroup), GetRootOUPath(), RDSHelpDeskGroup, RDSHelpDeskGroupDescription); string groupName = GetLocalAdminsGroupName(collection.Name); string groupPath = GetGroupPath(organizationId, collection.Name, groupName); string localAdminsGroupSamAccountName = CheckOrCreateAdGroup(groupPath, GetOrganizationPath(organizationId), groupName, WspAdministratorsGroupDescription); - - if (!ActiveDirectoryUtils.AdObjectExists(GetUsersGroupPath(organizationId, collection.Name))) - { - //Create user group - ActiveDirectoryUtils.CreateGroup(orgPath, GetUsersGroupName(collection.Name)); - } + CheckOrCreateAdGroup(GetUsersGroupPath(organizationId, collection.Name), orgPath, GetUsersGroupName(collection.Name), RdsCollectionUsersGroupDescription); var capPolicyName = GetPolicyName(organizationId, collection.Name, RdsPolicyTypes.RdCap); var rapPolicyName = GetPolicyName(organizationId, collection.Name, RdsPolicyTypes.RdRap); From 743563baa20b8db0ea4e8a214b2a248254f6cfd5 Mon Sep 17 00:00:00 2001 From: vfedosevich Date: Wed, 11 Mar 2015 01:09:08 -0700 Subject: [PATCH 32/46] RDS fixes --- .../Windows2012.cs | 148 ++++++------------ .../RDS/RDSEditCollectionUsers.ascx.cs | 6 + .../UserControls/RDSCollectionUsers.ascx.cs | 21 ++- 3 files changed, 71 insertions(+), 104 deletions(-) diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs b/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs index 56a70d39..41c6e520 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs @@ -71,8 +71,8 @@ namespace WebsitePanel.Providers.RemoteDesktopServices private const string WspAdministratorsGroupDescription = "WSP RDS Collection Adminstrators"; private const string RdsCollectionUsersGroupDescription = "WSP RDS Collection Users"; private const string RdsCollectionComputersGroupDescription = "WSP RDS Collection Computers"; - private const string RdsServersOU = "RDSServers"; - private const string RdsServersRootOU = "RDSRootServers"; + private const string RdsServersOU = "RDSServersOU"; + private const string RdsServersRootOU = "RDSRootServersOU"; private const string RDSHelpDeskComputerGroup = "Websitepanel-RDSHelpDesk-Computer"; private const string RDSHelpDeskGroup = "WSP-HelpDeskAdministrators"; private const string RDSHelpDeskGroupDescription = "WSP Help Desk Administrators"; @@ -339,11 +339,12 @@ namespace WebsitePanel.Providers.RemoteDesktopServices } //add user group to collection - AddUserGroupsToCollection(runSpace, collection.Name, new List { GetUsersGroupName(collection.Name) }); + AddUserGroupsToCollection(runSpace, collection.Name, new List { GetUsersGroupName(collection.Name) }); //add session servers to group foreach (var rdsServer in collection.Servers) - { + { + MoveRdsServerToTenantOU(rdsServer.Name, organizationId); AddAdGroupToLocalAdmins(runSpace, rdsServer.FqdName, helpDeskGroupSamAccountName); AddAdGroupToLocalAdmins(runSpace, rdsServer.FqdName, localAdminsGroupSamAccountName); AddComputerToCollectionAdComputerGroup(organizationId, collection.Name, rdsServer); @@ -1281,28 +1282,22 @@ namespace WebsitePanel.Providers.RemoteDesktopServices } private void AddComputerToCollectionAdComputerGroup(string organizationId, string collectionName, RdsServer server) - { - var computerPath = GetComputerPath(server.Name, false); - var computerGroupName = GetComputersGroupName( collectionName); + { + var computerGroupName = GetComputersGroupName( collectionName); + var computerObject = GetComputerObject(server.Name); - if (!ActiveDirectoryUtils.AdObjectExists(computerPath)) - { - computerPath = GetComputerPath(server.Name, true); - } - - if (ActiveDirectoryUtils.AdObjectExists(computerPath)) - { - var computerObject = ActiveDirectoryUtils.GetADObject(computerPath); + if (computerObject != null) + { var samName = (string)ActiveDirectoryUtils.GetADObjectProperty(computerObject, "sAMAccountName"); if (!ActiveDirectoryUtils.IsComputerInGroup(samName, computerGroupName)) { - ActiveDirectoryUtils.AddObjectToGroup(computerPath, GetComputerGroupPath(organizationId, collectionName)); + ActiveDirectoryUtils.AddObjectToGroup(computerObject.Path, GetComputerGroupPath(organizationId, collectionName)); } if (!ActiveDirectoryUtils.IsComputerInGroup(samName, RDSHelpDeskComputerGroup)) { - ActiveDirectoryUtils.AddObjectToGroup(computerPath, GetHelpDeskGroupPath(RDSHelpDeskComputerGroup)); + ActiveDirectoryUtils.AddObjectToGroup(computerObject.Path, GetHelpDeskGroupPath(RDSHelpDeskComputerGroup)); } } @@ -1310,30 +1305,24 @@ namespace WebsitePanel.Providers.RemoteDesktopServices } private void RemoveComputerFromCollectionAdComputerGroup(string organizationId, string collectionName, RdsServer server) - { - var computerPath = GetComputerPath(server.Name, false); + { var computerGroupName = GetComputersGroupName(collectionName); + var computerObject = GetComputerObject(server.Name); - if (!ActiveDirectoryUtils.AdObjectExists(computerPath)) - { - computerPath = GetComputerPath(server.Name, true); - } - - if (ActiveDirectoryUtils.AdObjectExists(computerPath)) - { - var computerObject = ActiveDirectoryUtils.GetADObject(computerPath); + if (computerObject != null) + { var samName = (string)ActiveDirectoryUtils.GetADObjectProperty(computerObject, "sAMAccountName"); if (ActiveDirectoryUtils.IsComputerInGroup(samName, computerGroupName)) { - ActiveDirectoryUtils.RemoveObjectFromGroup(computerPath, GetComputerGroupPath(organizationId, collectionName)); + ActiveDirectoryUtils.RemoveObjectFromGroup(computerObject.Path, GetComputerGroupPath(organizationId, collectionName)); } if (ActiveDirectoryUtils.AdObjectExists(GetHelpDeskGroupPath(RDSHelpDeskComputerGroup))) { if (ActiveDirectoryUtils.IsComputerInGroup(samName, RDSHelpDeskComputerGroup)) { - ActiveDirectoryUtils.RemoveObjectFromGroup(computerPath, GetHelpDeskGroupPath(RDSHelpDeskComputerGroup)); + ActiveDirectoryUtils.RemoveObjectFromGroup(computerObject.Path, GetHelpDeskGroupPath(RDSHelpDeskComputerGroup)); } } } @@ -1372,7 +1361,8 @@ namespace WebsitePanel.Providers.RemoteDesktopServices { if (ActiveDirectoryUtils.AdObjectExists(computersRootPath) && !ActiveDirectoryUtils.AdObjectExists(GetRdsServersGroupPath())) { - ActiveDirectoryUtils.CreateGroup(computersRootPath, RdsServersRootOU); + //ActiveDirectoryUtils.CreateGroup(computersRootPath, RdsServersRootOU); + ActiveDirectoryUtils.CreateOrganizationalUnit(RdsServersRootOU, computersRootPath); } } @@ -1382,82 +1372,57 @@ namespace WebsitePanel.Providers.RemoteDesktopServices if (!ActiveDirectoryUtils.AdObjectExists(tenantComputerGroupPath)) { - ActiveDirectoryUtils.CreateGroup(GetOrganizationPath(organizationId), RdsServersOU); + ActiveDirectoryUtils.CreateOrganizationalUnit(RdsServersOU, GetOrganizationPath(organizationId)); } - hostName = hostName.ToLower().Replace(string.Format(".{0}", ServerSettings.ADRootDomain.ToLower()), ""); - var computerPath = GetComputerPath(hostName, true); + hostName = hostName.ToLower().Replace(string.Format(".{0}", ServerSettings.ADRootDomain.ToLower()), ""); var rootComputerPath = GetRdsServerPath(hostName); var tenantComputerPath = GetTenantComputerPath(hostName, organizationId); if (!string.IsNullOrEmpty(ComputersRootOU)) { CheckOrCreateComputersRoot(GetComputersRootPath()); - } + } + + var computerObject = GetComputerObject(hostName); - if(!ActiveDirectoryUtils.AdObjectExists(computerPath)) + if (computerObject != null) { - computerPath = GetComputerPath(hostName, false); - } - - if (ActiveDirectoryUtils.AdObjectExists(computerPath)) - { - var computerObject = ActiveDirectoryUtils.GetADObject(computerPath); var samName = (string)ActiveDirectoryUtils.GetADObjectProperty(computerObject, "sAMAccountName"); - if (!string.IsNullOrEmpty(ComputersRootOU)) - { - if (ActiveDirectoryUtils.IsComputerInGroup(samName, RdsServersRootOU)) - { - ActiveDirectoryUtils.RemoveObjectFromGroup(computerPath, GetRdsServersGroupPath()); - } - } - if (!ActiveDirectoryUtils.IsComputerInGroup(samName, RdsServersOU)) - { + { DirectoryEntry group = new DirectoryEntry(tenantComputerGroupPath); - group.Invoke("Add", computerObject.Path); - - group.CommitChanges(); + computerObject.MoveTo(group); } - } + } } public void RemoveRdsServerFromTenantOU(string hostName, string organizationId) { var tenantComputerGroupPath = GetTenantComputerGroupPath(organizationId); - hostName = hostName.ToLower().Replace(string.Format(".{0}", ServerSettings.ADRootDomain.ToLower()), ""); - var tenantComputerPath = GetTenantComputerPath(hostName, organizationId); - var rootComputerPath = GetRdsServerPath(hostName); + hostName = hostName.ToLower().Replace(string.Format(".{0}", ServerSettings.ADRootDomain.ToLower()), ""); if (!string.IsNullOrEmpty(ComputersRootOU)) { CheckOrCreateComputersRoot(GetComputersRootPath()); - } + } - var computerPath = GetComputerPath(hostName, true); - - if (!ActiveDirectoryUtils.AdObjectExists(computerPath)) + if (!ActiveDirectoryUtils.AdObjectExists(tenantComputerGroupPath)) { - computerPath = GetComputerPath(hostName, false); + ActiveDirectoryUtils.CreateOrganizationalUnit(RdsServersOU, GetOrganizationPath(organizationId)); } - - if (ActiveDirectoryUtils.AdObjectExists(computerPath)) + + var computerObject = GetComputerObject(hostName); + + if (computerObject != null) { - var computerObject = ActiveDirectoryUtils.GetADObject(computerPath); var samName = (string)ActiveDirectoryUtils.GetADObjectProperty(computerObject, "sAMAccountName"); - - if (ActiveDirectoryUtils.IsComputerInGroup(samName, RdsServersOU)) - { - ActiveDirectoryUtils.RemoveObjectFromGroup(computerPath, tenantComputerGroupPath); - } - + if (ActiveDirectoryUtils.AdObjectExists(GetComputersRootPath()) && !string.IsNullOrEmpty(ComputersRootOU) && !ActiveDirectoryUtils.IsComputerInGroup(samName, RdsServersRootOU)) { DirectoryEntry group = new DirectoryEntry(GetRdsServersGroupPath()); - group.Invoke("Add", computerObject.Path); - - group.CommitChanges(); + computerObject.MoveTo(group); } } } @@ -1744,26 +1709,17 @@ namespace WebsitePanel.Providers.RemoteDesktopServices return sb.ToString(); } - private string GetComputerPath(string objName, bool domainController) + private DirectoryEntry GetComputerObject(string computerName) { - StringBuilder sb = new StringBuilder(); - // append provider - AppendProtocol(sb); - AppendDomainController(sb); - AppendCNPath(sb, objName); - if (domainController) + DirectorySearcher deSearch = new DirectorySearcher { - AppendOUPath(sb, AdDcComputers); - } - else - { - AppendCNPath(sb, Computers); - - } - AppendDomainPath(sb, RootDomain); - - return sb.ToString(); - } + Filter = string.Format("(&(objectCategory=computer)(name={0}))", computerName) + }; + + SearchResult results = deSearch.FindOne(); + + return results.GetDirectoryEntry(); + } private string GetTenantComputerPath(string objName, string organizationId) { @@ -1772,7 +1728,7 @@ namespace WebsitePanel.Providers.RemoteDesktopServices AppendProtocol(sb); AppendDomainController(sb); AppendCNPath(sb, objName); - AppendCNPath(sb, RdsServersOU); + AppendOUPath(sb, RdsServersOU); AppendOUPath(sb, organizationId); AppendOUPath(sb, RootOU); AppendDomainPath(sb, RootDomain); @@ -1798,7 +1754,7 @@ namespace WebsitePanel.Providers.RemoteDesktopServices AppendProtocol(sb); AppendDomainController(sb); - AppendCNPath(sb, RdsServersRootOU); + AppendOUPath(sb, RdsServersRootOU); AppendOUPath(sb, ComputersRootOU); AppendDomainPath(sb, RootDomain); @@ -1812,7 +1768,7 @@ namespace WebsitePanel.Providers.RemoteDesktopServices AppendProtocol(sb); AppendDomainController(sb); AppendCNPath(sb, name); - AppendCNPath(sb, RdsServersRootOU); + AppendOUPath(sb, RdsServersRootOU); AppendOUPath(sb, ComputersRootOU); AppendDomainPath(sb, RootDomain); @@ -1836,7 +1792,7 @@ namespace WebsitePanel.Providers.RemoteDesktopServices AppendProtocol(sb); AppendDomainController(sb); - AppendCNPath(sb, RdsServersOU); + AppendOUPath(sb, RdsServersOU); AppendOUPath(sb, organizationId); AppendOUPath(sb, RootOU); AppendDomainPath(sb, RootDomain); diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionUsers.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionUsers.ascx.cs index 5bcd026b..8af9191a 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionUsers.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSEditCollectionUsers.ascx.cs @@ -77,6 +77,12 @@ namespace WebsitePanel.Portal.RDS { usersQuota.QuotaAvailable = tenantStats.AllocatedRdsUsers - tenantStats.CreatedRdsUsers; } + + if (cntx.Quotas.ContainsKey(Quotas.RDS_USERS)) + { + int rdsUsersCount = ES.Services.RDS.GetOrganizationRdsUsersCount(PanelRequest.ItemID); + users.ButtonAddEnabled = (!(cntx.Quotas[Quotas.RDS_USERS].QuotaAllocatedValue <= rdsUsersCount) || (cntx.Quotas[Quotas.RDS_USERS].QuotaAllocatedValue == -1)); + } } private bool SaveRdsUsers() diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/UserControls/RDSCollectionUsers.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/UserControls/RDSCollectionUsers.ascx.cs index 40c4311a..76837a86 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/UserControls/RDSCollectionUsers.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/UserControls/RDSCollectionUsers.ascx.cs @@ -42,6 +42,18 @@ namespace WebsitePanel.Portal.RDS.UserControls { public const string DirectionString = "DirectionString"; + public bool ButtonAddEnabled + { + get + { + return btnAdd.Enabled; + } + set + { + btnAdd.Enabled = value; + } + } + protected enum SelectedState { All, @@ -74,14 +86,7 @@ namespace WebsitePanel.Portal.RDS.UserControls }"; Page.ClientScript.RegisterClientScriptBlock(typeof(RDSCollectionUsers), "SelectAllCheckboxes", script, true); - } - - PackageContext cntx = PackagesHelper.GetCachedPackageContext(PanelSecurity.PackageId); - if (cntx.Quotas.ContainsKey(Quotas.RDS_USERS)) - { - int rdsUsersCount = ES.Services.RDS.GetOrganizationRdsUsersCount(PanelRequest.ItemID); - btnAdd.Enabled = (!(cntx.Quotas[Quotas.RDS_USERS].QuotaAllocatedValue <= rdsUsersCount) || (cntx.Quotas[Quotas.RDS_USERS].QuotaAllocatedValue == -1)); - } + } } protected void btnAdd_Click(object sender, EventArgs e) From 50e902b94d17a98d4d0fc1eb9e7322fb55656abc Mon Sep 17 00:00:00 2001 From: vfedosevich Date: Wed, 11 Mar 2015 05:34:35 -0700 Subject: [PATCH 33/46] webdav portal create new ability added --- .../Config/Entities/OfficeOnlineCollection.cs | 2 + .../WebConfigSections/OfficeOnlineElement.cs | 8 ++ .../OfficeOnlineElementCollection.cs | 8 ++ .../Entities/Owa/CheckFileInfo.cs | 7 +- .../Interfaces/Owa/IWopiServer.cs | 6 +- .../Managers/WebDavManager.cs | 4 +- .../Owa/CobaltSessionManager.cs | 17 ++- .../Owa/WopiServer.cs | 42 ++++-- .../App_Start/RouteConfig.cs | 14 ++ .../App_Start/Routes/FileSystemRouteNames.cs | 3 + .../Content/OwaFiles/New.docx | Bin 0 -> 12551 bytes .../Content/OwaFiles/New.pptx | Bin 0 -> 31787 bytes .../Content/OwaFiles/New.xlsx | Bin 0 -> 7344 bytes .../Content/Site.css | 10 ++ .../Controllers/Api/OwaController.cs | 14 +- .../Controllers/FileSystemController.cs | 31 +++++ .../Resources/UI.Designer.cs | 72 ++++++++++ .../Resources/UI.resx | 24 ++++ .../Scripts/appScripts/dialogs.js | 16 ++- .../Scripts/appScripts/fileBrowsing.js | 41 +++++- .../Scripts/appScripts/wsp-webdav.js | 1 + .../Scripts/appScripts/wsp.js | 126 ++++++++++++++++++ .../Views/FileSystem/ShowContent.cshtml | 35 ++++- .../FileSystem/_ShowContentTopMenu.cshtml | 13 +- .../WebsitePanel.WebDavPortal/Web.config | 14 +- .../WebsitePanel.WebDavPortal.csproj | 3 + 26 files changed, 473 insertions(+), 38 deletions(-) create mode 100644 WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/OwaFiles/New.docx create mode 100644 WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/OwaFiles/New.pptx create mode 100644 WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/OwaFiles/New.xlsx create mode 100644 WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/wsp-webdav.js diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/OfficeOnlineCollection.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/OfficeOnlineCollection.cs index 47e614ed..c7f2d45d 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/OfficeOnlineCollection.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/Entities/OfficeOnlineCollection.cs @@ -13,12 +13,14 @@ namespace WebsitePanel.WebDav.Core.Config.Entities { IsEnabled = ConfigSection.OfficeOnline.IsEnabled; Url = ConfigSection.OfficeOnline.Url; + NewFilePath = ConfigSection.OfficeOnline.CobaltNewFilePath; CobaltFileTtl = ConfigSection.OfficeOnline.CobaltFileTtl; _officeExtensions = ConfigSection.OfficeOnline.Cast().ToList(); } public bool IsEnabled { get; private set; } public string Url { get; private set; } + public string NewFilePath { get; private set; } public int CobaltFileTtl { get; private set; } public IEnumerator GetEnumerator() diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/OfficeOnlineElement.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/OfficeOnlineElement.cs index 560b6964..823fc98a 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/OfficeOnlineElement.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/OfficeOnlineElement.cs @@ -8,6 +8,7 @@ namespace WebsitePanel.WebDavPortal.WebConfigSections private const string OwaViewKey = "OwaView"; private const string OwaEditorKey = "OwaEditor"; private const string OwaMobileViewKey = "OwaMobileView"; + private const string OwaNewFileViewKey = "OwaNewFileView"; [ConfigurationProperty(ExtensionKey, IsKey = true, IsRequired = true)] public string Extension @@ -37,5 +38,12 @@ namespace WebsitePanel.WebDavPortal.WebConfigSections get { return this[OwaMobileViewKey].ToString(); } set { this[OwaMobileViewKey] = value; } } + + [ConfigurationProperty(OwaNewFileViewKey, IsKey = true, IsRequired = true)] + public string OwaNewFileView + { + get { return this[OwaNewFileViewKey].ToString(); } + set { this[OwaNewFileViewKey] = value; } + } } } \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/OfficeOnlineElementCollection.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/OfficeOnlineElementCollection.cs index 03f570c5..51603c99 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/OfficeOnlineElementCollection.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Config/WebConfigSections/OfficeOnlineElementCollection.cs @@ -9,6 +9,7 @@ namespace WebsitePanel.WebDavPortal.WebConfigSections private const string UrlKey = "url"; private const string IsEnabledKey = "isEnabled"; private const string CobaltFileTtlKey = "cobaltFileTtl"; + private const string CobaltNewFilePathKey = "cobaltNewFilePath"; [ConfigurationProperty(UrlKey, IsKey = true, IsRequired = true)] public string Url @@ -24,6 +25,13 @@ namespace WebsitePanel.WebDavPortal.WebConfigSections set { this[IsEnabledKey] = value; } } + [ConfigurationProperty(CobaltNewFilePathKey, IsKey = true, IsRequired = true)] + public string CobaltNewFilePath + { + get { return this[CobaltNewFilePathKey].ToString(); } + set { this[CobaltNewFilePathKey] = value; } + } + [ConfigurationProperty(CobaltFileTtlKey, IsKey = true, IsRequired = true)] public int CobaltFileTtl { diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Entities/Owa/CheckFileInfo.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Entities/Owa/CheckFileInfo.cs index 076cb1e3..e5e72685 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Entities/Owa/CheckFileInfo.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Entities/Owa/CheckFileInfo.cs @@ -37,6 +37,10 @@ namespace WebsitePanel.WebDav.Core.Entities.Owa public bool RestrictedWebViewOnly { get; set; } [DataMember] public string ClientUrl { get; set; } + [DataMember] + public bool CloseButtonClosesWindow { get; set; } + //[DataMember] + //public string CloseUrl { get; set; } //[DataMember] //public bool UserCanNotWriteRelative { get; set; } @@ -59,8 +63,7 @@ namespace WebsitePanel.WebDav.Core.Entities.Owa //public string BreadcrumbFolderUrl { get; set; } //[DataMember] //public string ClientUrl { get; set; } - //[DataMember] - //public bool CloseButtonClosesWindow { get; set; } + //[DataMember] //public string CloseUrl { get; set; } //[DataMember] diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Interfaces/Owa/IWopiServer.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Interfaces/Owa/IWopiServer.cs index 6f35d7ff..058ad936 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Interfaces/Owa/IWopiServer.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Interfaces/Owa/IWopiServer.cs @@ -1,4 +1,4 @@ -using System.Web.Mvc; +using WebsitePanel.EnterpriseServer.Base.HostedSolution; using WebsitePanel.WebDav.Core.Client; using WebsitePanel.WebDav.Core.Entities.Owa; @@ -6,7 +6,7 @@ namespace WebsitePanel.WebDav.Core.Interfaces.Owa { public interface IWopiServer { - CheckFileInfo GetCheckFileInfo(string path); - FileResult GetFile(string path); + CheckFileInfo GetCheckFileInfo(WebDavAccessToken token); + byte[] GetFileBytes(int accessTokenId); } } \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Managers/WebDavManager.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Managers/WebDavManager.cs index d3f837a7..7b59436e 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Managers/WebDavManager.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Managers/WebDavManager.cs @@ -240,9 +240,9 @@ namespace WebsitePanel.WebDav.Core.Managers return _currentFolder.GetResource(resourceName); } - catch (InvalidOperationException exception) + catch (Exception) { - throw new ResourceNotFoundException("Resource not found", exception); + return null; } } diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Owa/CobaltSessionManager.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Owa/CobaltSessionManager.cs index 2684bf83..e9f16955 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Owa/CobaltSessionManager.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Owa/CobaltSessionManager.cs @@ -2,8 +2,10 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; +using System.IO; using System.Linq; using System.Runtime.Caching; +using System.Web; using Cobalt; using WebsitePanel.WebDav.Core.Client; using WebsitePanel.WebDav.Core.Config; @@ -72,9 +74,20 @@ namespace WebsitePanel.WebDav.Core.Owa var token = _tokenManager.GetToken(accessTokenId); - var fileBytes = _webDavManager.GetFileBytes(token.FilePath); + Atom atom; - var atom = new AtomFromByteArray(fileBytes); + if (_webDavManager.FileExist(token.FilePath)) + { + var fileBytes = _webDavManager.GetFileBytes(token.FilePath); + + atom = new AtomFromByteArray(fileBytes); + } + else + { + var filePath = HttpContext.Current.Server.MapPath(WebDavAppConfigManager.Instance.OfficeOnline.NewFilePath + Path.GetExtension(token.FilePath)); + + atom = new AtomFromByteArray(File.ReadAllBytes(filePath)); + } Cobalt.Metrics o1; cobaltFile.GetCobaltFilePartition(FilePartitionId.Content).SetStream(RootId.Default.Value, atom, out o1); diff --git a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Owa/WopiServer.cs b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Owa/WopiServer.cs index dada9bab..860d3528 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Owa/WopiServer.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDav.Core/Owa/WopiServer.cs @@ -6,6 +6,8 @@ using System.Runtime.Serialization.Json; using System.Text; using System.Web; using System.Web.Mvc; +using Cobalt; +using WebsitePanel.EnterpriseServer.Base.HostedSolution; using WebsitePanel.WebDav.Core.Client; using WebsitePanel.WebDav.Core.Config; using WebsitePanel.WebDav.Core.Entities.Owa; @@ -22,27 +24,30 @@ namespace WebsitePanel.WebDav.Core.Owa private readonly IWebDavManager _webDavManager; private readonly IAccessTokenManager _tokenManager; private readonly IWebDavAuthorizationService _webDavAuthorizationService; + private readonly IWopiFileManager _fileManager; - public WopiServer(IWebDavManager webDavManager, IAccessTokenManager tokenManager, IWebDavAuthorizationService webDavAuthorizationService) + + public WopiServer(IWebDavManager webDavManager, IAccessTokenManager tokenManager, IWebDavAuthorizationService webDavAuthorizationService, IWopiFileManager fileManager) { _webDavManager = webDavManager; _tokenManager = tokenManager; _webDavAuthorizationService = webDavAuthorizationService; + _fileManager = fileManager; } - public CheckFileInfo GetCheckFileInfo(string path) + public CheckFileInfo GetCheckFileInfo(WebDavAccessToken token) { - var resource = _webDavManager.GetResource(path); + var resource = _webDavManager.GetResource(token.FilePath); - var permissions = _webDavAuthorizationService.GetPermissions(WspContext.User, path); + var permissions = _webDavAuthorizationService.GetPermissions(WspContext.User, token.FilePath); var readOnly = permissions.HasFlag(WebDavPermissions.Write) == false || permissions.HasFlag(WebDavPermissions.OwaEdit) == false; var cFileInfo = new CheckFileInfo { - BaseFileName = resource.DisplayName.Split(new []{'/'},StringSplitOptions.RemoveEmptyEntries).LastOrDefault(), + BaseFileName = resource == null ? token.FilePath.Split('/').Last() : resource.DisplayName.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries).LastOrDefault(), OwnerId = WspContext.User.Login, - Size = resource.ContentLength, + Size = resource == null ? 0 : resource.ContentLength, Version = DateTime.Now.ToString("s"), SupportsCoauth = true, SupportsCobalt = true, @@ -53,17 +58,34 @@ namespace WebsitePanel.WebDav.Core.Owa SupportsUpdate = true, UserCanWrite = !readOnly, ReadOnly = readOnly, - RestrictedWebViewOnly = false + RestrictedWebViewOnly = false, + CloseButtonClosesWindow = true }; + if (resource != null) + { + cFileInfo.ClientUrl = _webDavManager.GetFileUrl(token.FilePath); + } + return cFileInfo; } - public FileResult GetFile(string path) + public byte[] GetFileBytes(int accessTokenId) { - var fileBytes = _webDavManager.GetFileBytes(path); + var token = _tokenManager.GetToken(accessTokenId); - return new FileContentResult(fileBytes, MediaTypeNames.Application.Octet); + if (_webDavManager.FileExist(token.FilePath)) + { + return _webDavManager.GetFileBytes(token.FilePath); + } + + var cobaltFile = _fileManager.Get(token.FilePath) ?? _fileManager.Create(accessTokenId); + + var stream = new MemoryStream(); + + new GenericFda(cobaltFile.CobaltEndpoint, null).GetContentStream().CopyTo(stream); + + return stream.ToArray(); } } } \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/RouteConfig.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/RouteConfig.cs index a5dc75e8..bf48c585 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/RouteConfig.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/RouteConfig.cs @@ -46,6 +46,20 @@ namespace WebsitePanel.WebDavPortal #region Enterprise storage + routes.MapRoute( + name: FileSystemRouteNames.ItemExist, + url: "storage/item-exist/{org}/{*pathPart}", + defaults: + new { controller = "FileSystem", action = "ItemExist", pathPart = UrlParameter.Optional } + ); + + routes.MapRoute( + name: FileSystemRouteNames.NewWebDavItem, + url: "storage/new/{org}/{*pathPart}", + defaults: + new { controller = "FileSystem", action = "NewWebDavItem", pathPart = UrlParameter.Optional } + ); + routes.MapRoute( name: FileSystemRouteNames.SearchFiles, url: "storage/search/{org}/{*pathPart}", diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/Routes/FileSystemRouteNames.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/Routes/FileSystemRouteNames.cs index 9a6832b2..acb38f0c 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/Routes/FileSystemRouteNames.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/Routes/FileSystemRouteNames.cs @@ -12,6 +12,9 @@ namespace WebsitePanel.WebDavPortal.UI.Routes public const string ShowContentDetails = "ShowContentDetailsRoute"; public const string ShowOfficeOnlinePath_ = "ShowOfficeOnlineRoute"; public const string ViewOfficeOnline = "ViewOfficeOnlineRoute"; + public const string NewFileOfficeOnline = "NewFileOfficeOnlineRoute"; + public const string NewWebDavItem = "NewWebDavItemRoute"; + public const string ItemExist = "ItemExistRoute"; public const string EditOfficeOnline = "EditOfficeOnlineRoute"; public const string ShowAdditionalContent = "ShowAdditionalContentRoute"; diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/OwaFiles/New.docx b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/OwaFiles/New.docx new file mode 100644 index 0000000000000000000000000000000000000000..b5ca5258e0054cc72c44f556f116ff31994d5fd7 GIT binary patch literal 12551 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 literal 0 HcmV?d00001 diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/OwaFiles/New.pptx b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/OwaFiles/New.pptx new file mode 100644 index 0000000000000000000000000000000000000000..cc17054824adfca46442ef0878da94aca44c60d5 GIT binary patch literal 31787 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 literal 0 HcmV?d00001 diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/OwaFiles/New.xlsx b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/OwaFiles/New.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..31991b64fe90d2177676a400e9e66bc400ac61de GIT binary patch literal 7344 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 N6fj%eU54-f{ts5#g#G{k literal 0 HcmV?d00001 diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css index 988dabfa..4f95621b 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css @@ -251,12 +251,17 @@ tr.selected-file { .file-actions-menu .file-deletion { display: none; + margin-right: 10px; } .file-actions-menu .file-upload { display: inline-block; } +.create-new-item { + margin-top: -2px; +} + #message-area { margin-top: 15px; } @@ -336,6 +341,11 @@ tr.selected-file { top: 20%; } + +.small-processing { + display: none; +} + /* Theme Mods */ input,div{border-radius:0px!important;} diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/Api/OwaController.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/Api/OwaController.cs index 4b0e2a87..761214ef 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/Api/OwaController.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/Api/OwaController.cs @@ -54,22 +54,24 @@ namespace WebsitePanel.WebDavPortal.Controllers.Api { var token = _tokenManager.GetToken(accessTokenId); - var fileInfo = _wopiServer.GetCheckFileInfo(token.FilePath); + var fileInfo = _wopiServer.GetCheckFileInfo(token); - var urlPart = Url.Route(FileSystemRouteNames.ShowContentPath, new { org = WspContext.User.OrganizationId, pathPart = token.FilePath }); + if (fileInfo.Size <= 1) + { + return fileInfo; + } + + var urlPart = Url.Route(FileSystemRouteNames.ShowContentPath, new {org = WspContext.User.OrganizationId, pathPart = token.FilePath}); var url = new Uri(Request.RequestUri, urlPart).ToString(); fileInfo.DownloadUrl = url; - fileInfo.ClientUrl = _webDavManager.GetFileUrl(token.FilePath); return fileInfo; } public HttpResponseMessage GetFile(int accessTokenId) { - var token = _tokenManager.GetToken(accessTokenId); - - var bytes = _webDavManager.GetFileBytes(token.FilePath); + var bytes = _wopiServer.GetFileBytes(accessTokenId); var result = new HttpResponseMessage(HttpStatusCode.OK); diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/FileSystemController.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/FileSystemController.cs index 9d4016e1..0940d23a 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/FileSystemController.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Controllers/FileSystemController.cs @@ -303,6 +303,36 @@ namespace WebsitePanel.WebDavPortal.Controllers return Json(model); } + public ActionResult NewWebDavItem(string org, string pathPart) + { + var permissions = _webDavAuthorizationService.GetPermissions(WspContext.User, pathPart); + + var owaOpener = WebDavAppConfigManager.Instance.OfficeOnline.FirstOrDefault(x => x.Extension == Path.GetExtension(pathPart)); + + if (permissions.HasFlag(WebDavPermissions.Write) == false || (owaOpener != null && permissions.HasFlag(WebDavPermissions.OwaEdit) == false)) + { + return new RedirectToRouteResult(FileSystemRouteNames.ShowContentPath, null); + } + + if (owaOpener != null) + { + return ShowOfficeDocument(org, pathPart, owaOpener.OwaNewFileView); + } + + return new RedirectToRouteResult(FileSystemRouteNames.ShowContentPath, null); + } + + [HttpPost] + public JsonResult ItemExist(string org, string pathPart, string newItemName) + { + var exist = _webdavManager.FileExist(string.Format("{0}/{1}", pathPart, newItemName)); + + return new JsonResult() + { + Data = !exist + }; + } + #region Owa Actions public ActionResult ShowOfficeDocument(string org, string pathPart, string owaOpenerUri) @@ -345,6 +375,7 @@ namespace WebsitePanel.WebDavPortal.Controllers return ShowOfficeDocument(org, pathPart, owaOpener.OwaEditor); } + #endregion private void FillContentModel(IEnumerable items, string organizationId) diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.Designer.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.Designer.cs index 0aa9d823..f7a90c29 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.Designer.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.Designer.cs @@ -105,6 +105,15 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to Create. + /// + public static string Create { + get { + return ResourceManager.GetString("Create", resourceCulture); + } + } + /// /// Looks up a localized string similar to Delete. /// @@ -141,6 +150,15 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to Enter file name. + /// + public static string EnterFileName { + get { + return ResourceManager.GetString("EnterFileName", resourceCulture); + } + } + /// /// Looks up a localized string similar to Error. /// @@ -150,6 +168,15 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to Excel workbook. + /// + public static string ExcelWorkbook { + get { + return ResourceManager.GetString("ExcelWorkbook", resourceCulture); + } + } + /// /// Looks up a localized string similar to File. /// @@ -159,6 +186,24 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to File name. + /// + public static string FileName { + get { + return ResourceManager.GetString("FileName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to File extension will be added automatically. + /// + public static string FileNameExtensionHint { + get { + return ResourceManager.GetString("FileNameExtensionHint", resourceCulture); + } + } + /// /// Looks up a localized string similar to File Upload. /// @@ -186,6 +231,15 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to File already exist. + /// + public static string ItemExist { + get { + return ResourceManager.GetString("ItemExist", resourceCulture); + } + } + /// /// Looks up a localized string similar to {0} items was removed.. /// @@ -249,6 +303,15 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to Powerpoint presentation. + /// + public static string PowerPointPresentation { + get { + return ResourceManager.GetString("PowerPointPresentation", resourceCulture); + } + } + /// /// Looks up a localized string similar to Processing. /// @@ -339,6 +402,15 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to Word document. + /// + public static string WordDocument { + get { + return ResourceManager.GetString("WordDocument", resourceCulture); + } + } + /// /// Looks up a localized string similar to Yes. /// diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.resx b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.resx index 7d3fbf56..624df9ea 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.resx +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.resx @@ -132,6 +132,9 @@ Confirm + + Create + Delete @@ -144,12 +147,24 @@ Are you sure you want to delete {0} item(s)? + + Enter file name + Error + + Excel workbook + File + + File name + + + File extension will be added automatically + File Upload @@ -159,6 +174,9 @@ Info + + File already exist + {0} items was removed. @@ -180,6 +198,9 @@ Please wait... + + Powerpoint presentation + Processing @@ -210,6 +231,9 @@ Upload + + Word document + Yes diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/dialogs.js b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/dialogs.js index 25693b41..64823404 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/dialogs.js +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/dialogs.js @@ -1,5 +1,9 @@ function WspDialogs() { - this.settings = { dialogId: "#confirm-dialog", processDialogId: "#processDialog" }; + this.settings = { + dialogId: "#confirm-dialog", + processDialogId: "#processDialog", + inlineProcessDialog: '.glyphicon-refresh' + }; } WspDialogs.prototype = @@ -36,6 +40,14 @@ WspDialogs.prototype = hideProcessDialog: function() { $(this.settings.processDialogId).modal('hide'); -} + }, + + showInlineProcessing: function(itemId) { + $(itemId).parent().find(this.settings.inlineProcessDialog).show(); + }, + + hideInlineProcessing: function (itemId) { + $(itemId).parent().find(this.settings.inlineProcessDialog).hide(); + } }; diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/fileBrowsing.js b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/fileBrowsing.js index f14edab4..114e103d 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/fileBrowsing.js +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/fileBrowsing.js @@ -2,8 +2,15 @@ this.settings = { deletionBlockSelector: ".file-actions-menu .file-deletion", deletionUrl: "storage/files-group-action/delete", + fileExistUrl: "storage/fileExist", textDateModified: "Date modified", - textSize: "Size" + textSize: "Size", + textItemExist: "File already exists", + textItemExistFunc: function() { + return textItemExist; + } , + createNewItemDialogId: "#createNewItemDialog", + createNewItemButtonId: "#create-button" }; this.itemsTable = null; this.searchTable = null; @@ -272,6 +279,38 @@ WspFileBrowser.prototype = { var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; var i = Math.floor(Math.log(bytes) / Math.log(k)); return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i]; + }, + + showCreateNewItemDialog: function (extension, target) { + $(this.settings.createNewItemButtonId).data('extension', extension); + $(this.settings.createNewItemButtonId).data('target', target); + + $(this.settings.createNewItemDialogId + " input").val(""); + + $(this.settings.createNewItemDialogId).modal(); + }, + + hideCreateNewItemDialog: function () { + $(this.settings.createNewItemDialogId).modal('hide'); + }, + + uniqueFileNameFieldRule: function(fieldId) { + + return { + url: this.settings.fileExistUrl, + type: "post", + data: { + newItemName: function() { + return $(fieldId).val() + $(wsp.fileBrowser.settings.createNewItemButtonId).data('extension'); + } + }, + beforeSend: function(response) { + wsp.dialogs.showInlineProcessing(fieldId); + }, + complete: function() { + wsp.dialogs.hideInlineProcessing(fieldId); + } + }; } }; diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/wsp-webdav.js b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/wsp-webdav.js new file mode 100644 index 00000000..5f282702 --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/wsp-webdav.js @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/wsp.js b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/wsp.js index 41f36ed8..ce9fb0a4 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/wsp.js +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/wsp.js @@ -78,6 +78,132 @@ $('#drag-and-drop-area #file-input').click(function (e) { }); + +$("#create-button").click(function (e) { + + if ($('#filenameForm').valid()) { + + var fileName = $('#createNewItemDialog #filename').val() + $(this).data('extension'); + + $(this).attr('href', $(this).data('href') + '/' + fileName); + + $(this).attr('target', $(this).data('target')); + + wsp.fileBrowser.hideCreateNewItemDialog(); + //; + } else { + e.preventDefault(); + } +}); + +$.fn.clearValidation = function () { var v = $(this).validate(); $('[name]', this).each(function () { v.successList.push(this); v.showErrors(); }); v.resetForm(); v.reset(); $(this).find('.form-group').removeClass('has-error'); }; + +$(document).ready(function() { + //bootstrap jquery validate styles fix + $.validator.setDefaults({ + highlight: function(element) { + $(element).closest('.form-group').addClass('has-error'); + }, + unhighlight: function(element) { + $(element).closest('.form-group').removeClass('has-error'); + }, + errorElement: 'span', + errorClass: 'help-block', + errorPlacement: function(error, element) { + if (element.parent('.input-group').length) { + error.insertAfter(element.parent()); + } else { + error.insertAfter(element); + } + } + }); + + $.validator.addMethod("synchronousRemote", function (value, element, param) { + if (this.optional(element)) { + return "dependency-mismatch"; + } + + var previous = this.previousValue(element); + if (!this.settings.messages[element.name]) { + this.settings.messages[element.name] = {}; + } + previous.originalMessage = this.settings.messages[element.name].remote; + this.settings.messages[element.name].remote = previous.message; + + param = typeof param === "string" && { url: param } || param; + + if (previous.old === value) { + return previous.valid; + } + + previous.old = value; + var validator = this; + this.startRequest(element); + var data = {}; + data[element.name] = value; + var valid = "pending"; + $.ajax($.extend(true, { + url: param, + async: false, + mode: "abort", + port: "validate" + element.name, + dataType: "json", + data: data, + success: function (response) { + validator.settings.messages[element.name].remote = previous.originalMessage; + valid = response === true || response === "true"; + if (valid) { + var submitted = validator.formSubmitted; + validator.prepareElement(element); + validator.formSubmitted = submitted; + validator.successList.push(element); + delete validator.invalid[element.name]; + validator.showErrors(); + } else { + var errors = {}; + var message = response || validator.defaultMessage(element, "remote"); + errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message; + validator.invalid[element.name] = true; + validator.showErrors(errors); + } + previous.valid = valid; + validator.stopRequest(element, valid); + } + }, param)); + return valid; + }, "Please fix this field."); + + + $('#filenameForm').validate({ + onkeyup: false, + onclick: false, + async: false, + rules: { + filename: { + required: true, + synchronousRemote: wsp.fileBrowser.uniqueFileNameFieldRule("#filename") + } + }, + messages: { + filename: { + synchronousRemote: wsp.fileBrowser.settings.textItemExist + } + } + }); + +}); + + +$(".create-new-item li a").click(function () { + + $("#filenameForm").clearValidation(); + + wsp.fileBrowser.showCreateNewItemDialog($(this).data('extension'), $(this).data('target')); + + $("#filename").focus(); +}); + + function isMobileDevice() { return (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase())); } diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/ShowContent.cshtml b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/ShowContent.cshtml index af490ffc..e62225b2 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/ShowContent.cshtml +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/ShowContent.cshtml @@ -26,7 +26,10 @@ else @section scripts{ @if (Model.UserSettings.WebDavViewType == FolderViewTypes.BigIcons) @@ -47,9 +50,37 @@ else { } } + +@section popups{ + +} \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentTopMenu.cshtml b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentTopMenu.cshtml index 496ac682..fdba3215 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentTopMenu.cshtml +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ShowContentTopMenu.cshtml @@ -56,6 +56,17 @@ data-target-title-text="@UI.DeleteFileQuestion" data-target-content="@UI.DialogsContentConfrimFileDeletion">@UI.Delete
+ }
-} \ No newline at end of file +} diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Web.config b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Web.config index 3f07e5e5..b33b3e60 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Web.config +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Web.config @@ -85,13 +85,13 @@ - - - - - - - + + + + + + + diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebsitePanel.WebDavPortal.csproj b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebsitePanel.WebDavPortal.csproj index 6ccbc782..8c5bfd40 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebsitePanel.WebDavPortal.csproj +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/WebsitePanel.WebDavPortal.csproj @@ -369,6 +369,8 @@ + + @@ -376,6 +378,7 @@ + From ca66183c2977e754a0d4f207ce7fd16e6edca590 Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Wed, 11 Mar 2015 08:36:39 -0400 Subject: [PATCH 34/46] Added tag build-2.1.0.611 for changeset 5404111417ed From 227f0c99cc641275259fb51d479a3c0d16c523af Mon Sep 17 00:00:00 2001 From: vfedosevich Date: Wed, 11 Mar 2015 06:05:14 -0700 Subject: [PATCH 35/46] webdav portal merge fix --- .../Resources/UI.Designer.cs | 63 +++++++++++++++++++ .../Resources/UI.resx | 21 +++++++ 2 files changed, 84 insertions(+) diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.Designer.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.Designer.cs index 4a5a4578..f9a6db66 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.Designer.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.Designer.cs @@ -123,6 +123,15 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to Create. + /// + public static string Create { + get { + return ResourceManager.GetString("Create", resourceCulture); + } + } + /// /// Looks up a localized string similar to Delete. /// @@ -159,6 +168,15 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to Please enter file name. + /// + public static string EnterFileName { + get { + return ResourceManager.GetString("EnterFileName", resourceCulture); + } + } + /// /// Looks up a localized string similar to Error. /// @@ -177,6 +195,15 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to Excel workbook. + /// + public static string ExcelWorkbook { + get { + return ResourceManager.GetString("ExcelWorkbook", resourceCulture); + } + } + /// /// Looks up a localized string similar to File. /// @@ -186,6 +213,15 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to File name. + /// + public static string FileName { + get { + return ResourceManager.GetString("FileName", resourceCulture); + } + } + /// /// Looks up a localized string similar to File Upload. /// @@ -213,6 +249,15 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to File already exist. + /// + public static string ItemExist { + get { + return ResourceManager.GetString("ItemExist", resourceCulture); + } + } + /// /// Looks up a localized string similar to {0} items was removed.. /// @@ -303,6 +348,15 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to Powerpoint presentation. + /// + public static string PowerPointPresentation { + get { + return ResourceManager.GetString("PowerPointPresentation", resourceCulture); + } + } + /// /// Looks up a localized string similar to Processing. /// @@ -402,6 +456,15 @@ namespace WebsitePanel.WebDavPortal.Resources { } } + /// + /// Looks up a localized string similar to Word document. + /// + public static string WordDocument { + get { + return ResourceManager.GetString("WordDocument", resourceCulture); + } + } + /// /// Looks up a localized string similar to Yes. /// diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.resx b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.resx index 2ffe1406..56929bcc 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.resx +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Resources/UI.resx @@ -138,6 +138,9 @@ Confirm + + Create + Delete @@ -150,15 +153,24 @@ Are you sure you want to delete {0} item(s)? + + Please enter file name + Error EB + + Excel workbook + File + + File name + File Upload @@ -168,6 +180,9 @@ Info + + File already exist + {0} items was removed. @@ -198,6 +213,9 @@ Please wait... + + Powerpoint presentation + Processing @@ -231,6 +249,9 @@ Upload + + Word document + Yes From 7e76b087b40ed313761647e8c3e41758a0712585 Mon Sep 17 00:00:00 2001 From: vfedosevich Date: Wed, 11 Mar 2015 07:00:40 -0700 Subject: [PATCH 36/46] webdav portal css fixes --- .../App_Start/BundleConfig.cs | 4 + .../Content/Site.css | 4 + .../Scripts/appScripts/fileBrowsing.js | 7 +- .../Scripts/appScripts/wsp-webdav.js | 125 +++++++++++++++++- .../Scripts/appScripts/wsp.js | 120 +---------------- .../Views/FileSystem/ShowContent.cshtml | 5 +- .../ShowContentSearchResultTable.cshtml | 1 + 7 files changed, 145 insertions(+), 121 deletions(-) diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/BundleConfig.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/BundleConfig.cs index 8b6dd2c9..d3be4e58 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/BundleConfig.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/App_Start/BundleConfig.cs @@ -35,6 +35,10 @@ namespace WebsitePanel.WebDavPortal "~/Scripts/appScripts/wsp.js" )); + bundles.Add(new ScriptBundle("~/bundles/appScripts-webdav").Include( + "~/Scripts/appScripts/wsp-webdav.js" + )); + bundles.Add(new ScriptBundle("~/bundles/bigIconsScripts").Include( "~/Scripts/appScripts/recalculateResourseHeight.js" )); diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css index 4f95621b..65108355 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css @@ -346,6 +346,10 @@ tr.selected-file { display: none; } +#filenameForm input { + max-width: 100%; +} + /* Theme Mods */ input,div{border-radius:0px!important;} diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/fileBrowsing.js b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/fileBrowsing.js index 114e103d..d7a33633 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/fileBrowsing.js +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/fileBrowsing.js @@ -10,7 +10,8 @@ return textItemExist; } , createNewItemDialogId: "#createNewItemDialog", - createNewItemButtonId: "#create-button" + createNewItemButtonId: "#create-button", + createNewItemTitleId: '#create-dalog-label' }; this.itemsTable = null; this.searchTable = null; @@ -281,12 +282,14 @@ WspFileBrowser.prototype = { return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i]; }, - showCreateNewItemDialog: function (extension, target) { + showCreateNewItemDialog: function (extension, target, title) { $(this.settings.createNewItemButtonId).data('extension', extension); $(this.settings.createNewItemButtonId).data('target', target); $(this.settings.createNewItemDialogId + " input").val(""); + $(this.settings.createNewItemTitleId).text($(this.settings.createNewItemTitleId).data('title') + " " + title); + $(this.settings.createNewItemDialogId).modal(); }, diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/wsp-webdav.js b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/wsp-webdav.js index 5f282702..90c6f7d8 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/wsp-webdav.js +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/wsp-webdav.js @@ -1 +1,124 @@ - \ No newline at end of file +//Toggle file select + Ctrl multiselect +$(document).on('click', '.element-container', function (e) { + if (e.ctrlKey) { + $(this).toggleClass("selected-file"); + } else { + + wsp.fileBrowser.clearAllSelectedItems(); + + wsp.fileBrowser.selectItem(this); + } + + wsp.fileBrowser.refreshDeletionBlock(); +}); + +$(document).on('touchstart', '.element-container', function (e) { + var now = new Date().getTime(); + var lastTouch = $(this).data('lastTouch') || now + 1; + var delta = now - lastTouch; + + if (delta < 300 && delta > 0) { + wsp.fileBrowser.openItem(this); + $(this).data('lastTouch', 0); + } + + $(this).data('lastTouch', now); +}); + +//Double click file open +$(document).on('dblclick', '.element-container', function (e) { + wsp.fileBrowser.openItem(this); + + var links = $(this).find('.file-link'); + + if (links.length != 0 && $(links[0]).hasClass('processing-dialog')) { + wsp.dialogs.showProcessDialog(); + } +}); + + +//Delete button click +$(document).on('click', '.file-deletion #delete-button', function (e) { + var dialogId = $(this).data('target'); + var buttonText = $(this).data('target-positive-button-text'); + var content = $(this).data('target-content'); + var title = $(this).data('target-title-text'); + + content = jQuery.validator.format(content, wsp.fileBrowser.getSelectedItemsCount()); + + wsp.dialogs.showConfirmDialog(title, content, buttonText, wsp.fileBrowser.deleteSelectedItems, dialogId); +}); + + +$(document).click(function (event) { + if (!$(event.target).closest('.element-container, .prevent-deselect').length) { + wsp.fileBrowser.clearAllSelectedItems(); + wsp.fileBrowser.refreshDeletionBlock(); + } +}); + +$('#drag-and-drop-area').click(function (e) { + $('#file-input').click(); +}); + +$('#drag-and-drop-area #file-input').click(function (e) { + e.stopPropagation(); +}); + + + +$("#create-button").click(function (e) { + + if ($('#filenameForm').valid()) { + + var fileName = $('#createNewItemDialog #filename').val() + $(this).data('extension'); + + $(this).attr('href', $(this).data('href') + '/' + fileName); + + $(this).attr('target', $(this).data('target')); + + wsp.fileBrowser.hideCreateNewItemDialog(); + //; + } else { + e.preventDefault(); + } +}); + +$(document).ready(function () { + + $('#filenameForm').validate({ + onkeyup: false, + onclick: false, + async: false, + rules: { + filename: { + required: true, + synchronousRemote: wsp.fileBrowser.uniqueFileNameFieldRule("#filename") + } + }, + messages: { + filename: { + synchronousRemote: wsp.fileBrowser.settings.textItemExist + } + } + }); + +}); + +$('#filename').keydown(function (event) { + if (event.keyCode == 13) { + event.preventDefault(); + return false; + } + return true; +}); + + +$(".create-new-item li a").click(function () { + + $("#filenameForm").clearValidation(); + + wsp.fileBrowser.showCreateNewItemDialog($(this).data('extension'), $(this).data('target'), $(this).text()); + + $("#filename").focus(); +}); diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/wsp.js b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/wsp.js index ce9fb0a4..a45da0f1 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/wsp.js +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/wsp.js @@ -10,94 +10,6 @@ $(document).on('click', '.processing-dialog', function (e) { }); -//Toggle file select + Ctrl multiselect -$(document).on('click', '.element-container', function (e) { - if (e.ctrlKey) { - $(this).toggleClass("selected-file"); - } else { - - wsp.fileBrowser.clearAllSelectedItems(); - - wsp.fileBrowser.selectItem(this); - } - - wsp.fileBrowser.refreshDeletionBlock(); -}); - -$(document).on('touchstart', '.element-container', function(e) { - var now = new Date().getTime(); - var lastTouch = $(this).data('lastTouch') || now + 1; - var delta = now - lastTouch; - - if (delta < 300 && delta > 0) { - wsp.fileBrowser.openItem(this); - $(this).data('lastTouch', 0); - } - - $(this).data('lastTouch', now); -}); - -//Double click file open -$(document).on('dblclick', '.element-container', function (e) { - wsp.fileBrowser.openItem(this); - - var links = $(this).find('.file-link'); - - if (links.length != 0 && $(links[0]).hasClass('processing-dialog')) { - wsp.dialogs.showProcessDialog(); - } -}); - - -//Delete button click -$(document).on('click', '.file-deletion #delete-button', function (e) { - var dialogId = $(this).data('target'); - var buttonText = $(this).data('target-positive-button-text'); - var content = $(this).data('target-content'); - var title = $(this).data('target-title-text'); - - content = jQuery.validator.format(content, wsp.fileBrowser.getSelectedItemsCount()); - - wsp.dialogs.showConfirmDialog(title, content, buttonText, wsp.fileBrowser.deleteSelectedItems, dialogId); -}); - - -$(document).click(function(event) { - if (!$(event.target).closest('.element-container, .prevent-deselect').length) { - wsp.fileBrowser.clearAllSelectedItems(); - wsp.fileBrowser.refreshDeletionBlock(); - } -}); - -$('#drag-and-drop-area').click(function (e) { - $('#file-input').click(); -}); - -$('#drag-and-drop-area #file-input').click(function (e) { - e.stopPropagation(); -}); - - - -$("#create-button").click(function (e) { - - if ($('#filenameForm').valid()) { - - var fileName = $('#createNewItemDialog #filename').val() + $(this).data('extension'); - - $(this).attr('href', $(this).data('href') + '/' + fileName); - - $(this).attr('target', $(this).data('target')); - - wsp.fileBrowser.hideCreateNewItemDialog(); - //; - } else { - e.preventDefault(); - } -}); - -$.fn.clearValidation = function () { var v = $(this).validate(); $('[name]', this).each(function () { v.successList.push(this); v.showErrors(); }); v.resetForm(); v.reset(); $(this).find('.form-group').removeClass('has-error'); }; - $(document).ready(function() { //bootstrap jquery validate styles fix $.validator.setDefaults({ @@ -118,7 +30,7 @@ $(document).ready(function() { } }); - $.validator.addMethod("synchronousRemote", function (value, element, param) { + $.validator.addMethod("synchronousRemote", function(value, element, param) { if (this.optional(element)) { return "dependency-mismatch"; } @@ -149,7 +61,7 @@ $(document).ready(function() { port: "validate" + element.name, dataType: "json", data: data, - success: function (response) { + success: function(response) { validator.settings.messages[element.name].remote = previous.originalMessage; valid = response === true || response === "true"; if (valid) { @@ -172,36 +84,10 @@ $(document).ready(function() { }, param)); return valid; }, "Please fix this field."); - - - $('#filenameForm').validate({ - onkeyup: false, - onclick: false, - async: false, - rules: { - filename: { - required: true, - synchronousRemote: wsp.fileBrowser.uniqueFileNameFieldRule("#filename") - } - }, - messages: { - filename: { - synchronousRemote: wsp.fileBrowser.settings.textItemExist - } - } - }); - }); -$(".create-new-item li a").click(function () { - - $("#filenameForm").clearValidation(); - - wsp.fileBrowser.showCreateNewItemDialog($(this).data('extension'), $(this).data('target')); - - $("#filename").focus(); -}); +$.fn.clearValidation = function () { var v = $(this).validate(); $('[name]', this).each(function () { v.successList.push(this); v.showErrors(); }); v.resetForm(); v.reset(); $(this).find('.form-group').removeClass('has-error'); }; function isMobileDevice() { diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/ShowContent.cshtml b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/ShowContent.cshtml index e62225b2..db3e1da3 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/ShowContent.cshtml +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/ShowContent.cshtml @@ -25,12 +25,15 @@ else @section scripts{ + + + @Scripts.Render("~/bundles/appScripts-webdav") @if (Model.UserSettings.WebDavViewType == FolderViewTypes.BigIcons) { @@ -62,7 +65,7 @@ else
0) + { + ddlRdsController.SelectedValue = ddlRdsController.Items[0].Value; + } } private void SaveSettings() @@ -207,6 +227,16 @@ namespace WebsitePanel.Portal result = ES.Services.System.SetSystemSettings( WSP.SystemSettings.FILEMANAGER_SETTINGS, settings); + if (result < 0) + { + ShowResultMessage(result); + return; + } + + settings = new WSP.SystemSettings(); + settings[RDS_MAIN_CONTROLLER] = ddlRdsController.SelectedValue; + result = ES.Services.System.SetSystemSettings(WSP.SystemSettings.RDS_SETTINGS, settings); + if (result < 0) { ShowResultMessage(result); diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx.designer.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx.designer.cs index 6b3cb964..d8358733 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx.designer.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx.designer.cs @@ -1,31 +1,3 @@ -// Copyright (c) 2015, Outercurve Foundation. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// - Neither the name of the Outercurve Foundation nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - //------------------------------------------------------------------------------ // // This code was generated by a tool. @@ -220,6 +192,42 @@ namespace WebsitePanel.Portal { /// protected global::System.Web.UI.WebControls.Literal litFileManagerEditableExtensions; + /// + /// RdsSettings control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::WebsitePanel.Portal.CollapsiblePanel RdsSettings; + + /// + /// PanelRdsSettings control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Panel PanelRdsSettings; + + /// + /// lblRdsController control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Localize lblRdsController; + + /// + /// ddlRdsController control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.DropDownList ddlRdsController; + /// /// btnSaveSettings control. /// From e70da870c6f2750c920b224ec565fa1bfcad112f Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Thu, 12 Mar 2015 14:23:49 -0400 Subject: [PATCH 44/46] Added tag build-2.1.0.613 for changeset 3caeed743a87 From de337fe5f3fa717c1d7c5e3288bcd8371f6dd041 Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Thu, 12 Mar 2015 14:41:05 -0400 Subject: [PATCH 45/46] Added tag build-2.1.0.614 for changeset 4a18c479a6ea From 9064cb2eb8c1541bfd416f07cd57e87cfdab6352 Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Thu, 12 Mar 2015 14:48:06 -0400 Subject: [PATCH 46/46] Added tag build-2.1.0.615 for changeset e48f0bc074d1