From f0fc434447b362b1340e3ff1af4ec7fbea27d736 Mon Sep 17 00:00:00 2001 From: gazizova-vlada Date: Mon, 14 Feb 2022 16:33:27 +0300 Subject: [PATCH 1/6] Web:Studio:Added PortalRenaming component. Removed the TeamTemplate component from the Customization component. --- .../categories/common/customization.js | 32 ++----------------- .../categories/common/portal-renaming.js | 7 ++++ 2 files changed, 9 insertions(+), 30 deletions(-) create mode 100644 web/ASC.Web.Client/src/components/pages/Settings/categories/common/portal-renaming.js diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/customization.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/customization.js index 7115616ad7..7bba5f6512 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/customization.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/customization.js @@ -14,6 +14,7 @@ import { AppServerConfig } from "@appserver/common/constants"; import withCultureNames from "@appserver/common/hoc/withCultureNames"; import LanguageAndTimeZone from "./language-and-time-zone"; import CustomTitles from "./custom-titles"; +import PortalRenaming from "./portal-renaming"; import { Base } from "@appserver/components/themes"; import { Consumer } from "@appserver/components/utils/context"; @@ -218,36 +219,7 @@ class Customization extends React.Component {
-
- - {t("TeamTemplate")} - - -
- - {`${customNames.name}`} - - - {t("TeamTemplateSettingsDescription")} - - - - {t("Common:LearnMore")} - - +
)} diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/portal-renaming.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/portal-renaming.js new file mode 100644 index 0000000000..8ff2e76b75 --- /dev/null +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/portal-renaming.js @@ -0,0 +1,7 @@ +import React from "react"; + +const PortalRenaming = () => { + return
; +}; + +export default PortalRenaming; From e3b894a21a2f95da2f21edc6bad23ebd9199d2ab Mon Sep 17 00:00:00 2001 From: pavelbannov Date: Thu, 17 Feb 2022 14:47:50 +0300 Subject: [PATCH 2/6] ResManager: fix --- .../ASC.Resource.Manager.csproj | 15 ++++++++------- common/ASC.Resource.Manager/Startup.cs | 4 ++++ common/ASC.Resource.Manager/appsettings.json | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/common/ASC.Resource.Manager/ASC.Resource.Manager.csproj b/common/ASC.Resource.Manager/ASC.Resource.Manager.csproj index 10b385694e..f57668cb2e 100644 --- a/common/ASC.Resource.Manager/ASC.Resource.Manager.csproj +++ b/common/ASC.Resource.Manager/ASC.Resource.Manager.csproj @@ -2,7 +2,7 @@ Exe - net5.0-windows + net6.0-windows true @@ -13,12 +13,13 @@ - - - - - - + + + + + + + diff --git a/common/ASC.Resource.Manager/Startup.cs b/common/ASC.Resource.Manager/Startup.cs index cac504124c..63d6326328 100644 --- a/common/ASC.Resource.Manager/Startup.cs +++ b/common/ASC.Resource.Manager/Startup.cs @@ -2,6 +2,8 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Hosting.Internal; namespace ASC.Resource.Manager { @@ -24,6 +26,8 @@ namespace ASC.Resource.Manager services.AddLogging(); diHelper.Configure(services); services.AddSingleton(Configuration); + services.AddSingleton(); + diHelper.TryAdd(); //LogNLogExtension.ConfigureLog(diHelper); } diff --git a/common/ASC.Resource.Manager/appsettings.json b/common/ASC.Resource.Manager/appsettings.json index c1942e82d2..53bbdfa7c9 100644 --- a/common/ASC.Resource.Manager/appsettings.json +++ b/common/ASC.Resource.Manager/appsettings.json @@ -26,7 +26,7 @@ "ConnectionStrings": { "default": { "name": "default", - "connectionString": "Server=localhost;Database=teamlab_translate;User ID=dev;Password=dev;Pooling=true;Character Set=utf8;AutoEnlist=false;SSL Mode=none", + "connectionString": "Server=localhost;Database=teamlab_translate;User ID=root;Password=root;Pooling=true;Character Set=utf8;AutoEnlist=false;SSL Mode=none", "providerName": "MySql.Data.MySqlClient" } }, From 1ef4b329396f39f3b471d2ab5c6575bc6201f732 Mon Sep 17 00:00:00 2001 From: pavelbannov Date: Thu, 17 Feb 2022 15:55:42 +0300 Subject: [PATCH 3/6] Settings: added update dns settings method --- .../Controllers/SettingsController.cs | 13 +- web/ASC.Web.Api/Core/DnsSettings.cs | 165 ++++++++++++++++++ web/ASC.Web.Api/Models/DnsSettingsModel.cs | 8 + .../PublicResources/Resource.Designer.cs | 27 +++ .../PublicResources/Resource.de.resx | 13 +- .../PublicResources/Resource.es.resx | 13 +- .../PublicResources/Resource.fr.resx | 13 +- .../PublicResources/Resource.it.resx | 13 +- .../PublicResources/Resource.resx | 13 +- .../PublicResources/Resource.ru.resx | 13 +- 10 files changed, 278 insertions(+), 13 deletions(-) create mode 100644 web/ASC.Web.Api/Core/DnsSettings.cs create mode 100644 web/ASC.Web.Api/Models/DnsSettingsModel.cs diff --git a/web/ASC.Web.Api/Controllers/SettingsController.cs b/web/ASC.Web.Api/Controllers/SettingsController.cs index e678e7c4d9..c4f230dea8 100644 --- a/web/ASC.Web.Api/Controllers/SettingsController.cs +++ b/web/ASC.Web.Api/Controllers/SettingsController.cs @@ -63,6 +63,7 @@ using ASC.FederatedLogin.LoginProviders; using ASC.IPSecurity; using ASC.MessagingSystem; using ASC.Security.Cryptography; +using ASC.Web.Api.Core; using ASC.Web.Api.Models; using ASC.Web.Api.Routing; using ASC.Web.Core; @@ -174,6 +175,7 @@ namespace ASC.Api.Settings private InstanceCrypto InstanceCrypto { get; } private Signature Signature { get; } private DbWorker WebhookDbWorker { get; } + private DnsSettings DnsSettings { get; } public IHttpClientFactory ClientFactory { get; } public SettingsController( @@ -240,6 +242,7 @@ namespace ASC.Api.Settings InstanceCrypto instanceCrypto, Signature signature, DbWorker dbWorker, + DnsSettings dnsSettings, IHttpClientFactory clientFactory) { Log = option.Get("ASC.Api"); @@ -302,6 +305,7 @@ namespace ASC.Api.Settings TelegramHelper = telegramHelper; PaymentManager = paymentManager; WebhookDbWorker = dbWorker; + DnsSettings = dnsSettings; Constants = constants; InstanceCrypto = instanceCrypto; Signature = signature; @@ -730,6 +734,13 @@ namespace ASC.Api.Settings return Dns.GetHostName().ToLowerInvariant(); } + [Update("dns")] + public object SaveDnsSettings(DnsSettingsModel model) + { + return DnsSettings.SaveDnsSettings(model.DnsName, model.Enable); + } + + [Read("greetingsettings")] public ContentResult GetGreetingSettings() { @@ -1113,7 +1124,7 @@ namespace ASC.Api.Settings { var logoDict = new Dictionary(); - foreach(var l in model.Logo) + foreach (var l in model.Logo) { logoDict.Add(Int32.Parse(l.Key), l.Value); } diff --git a/web/ASC.Web.Api/Core/DnsSettings.cs b/web/ASC.Web.Api/Core/DnsSettings.cs new file mode 100644 index 0000000000..e33a51d32e --- /dev/null +++ b/web/ASC.Web.Api/Core/DnsSettings.cs @@ -0,0 +1,165 @@ +using System; +using System.Text; + +using ASC.Common; +using ASC.Core; +using ASC.Core.Tenants; +using ASC.MessagingSystem; +using ASC.Web.Core.PublicResources; +using ASC.Web.Studio.Core; +using ASC.Web.Studio.Core.Notify; +using ASC.Web.Studio.Utility; + +namespace ASC.Web.Api.Core +{ + [Scope] + public class DnsSettings + { + private readonly PermissionContext _permissionContext; + private readonly TenantManager _tenantManager; + private readonly UserManager _userManager; + private readonly CoreBaseSettings _coreBaseSettings; + private readonly CoreSettings _coreSettings; + private readonly StudioNotifyService _studioNotifyService; + private readonly CommonLinkUtility _commonLinkUtility; + private readonly MessageService _messageService; + private readonly TenantExtra _tenantExtra; + + public DnsSettings( + PermissionContext permissionContext, + TenantManager tenantManager, + UserManager userManager, + CoreBaseSettings coreBaseSettings, + CoreSettings coreSettings, + StudioNotifyService studioNotifyService, + CommonLinkUtility commonLinkUtility, + MessageService messageService, + TenantExtra tenantExtra) + { + _permissionContext = permissionContext; + _tenantManager = tenantManager; + _userManager = userManager; + _coreBaseSettings = coreBaseSettings; + _coreSettings = coreSettings; + _studioNotifyService = studioNotifyService; + _commonLinkUtility = commonLinkUtility; + _messageService = messageService; + _tenantExtra = tenantExtra; + } + + protected bool EnableDomain + { + get { return _coreBaseSettings.Standalone || _tenantExtra.GetTenantQuota().HasDomain; } + } + + public string SaveDnsSettings(string dnsName, bool enableDns) + { + try + { + if (!EnableDomain || !SetupInfo.IsVisibleSettings()) throw new Exception(Resource.ErrorNotAllowedOption); + + _permissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings); + + var tenant = _tenantManager.GetCurrentTenant(); + + if (!enableDns || string.IsNullOrEmpty(dnsName)) + { + dnsName = null; + } + + if (dnsName == null || CheckCustomDomain(dnsName)) + { + if (_coreBaseSettings.Standalone) + { + tenant.MappedDomain = dnsName; + _tenantManager.SaveTenant(tenant); + return null; + } + + if (tenant.MappedDomain != dnsName) + { + var portalAddress = $"http://{tenant.TenantAlias ?? string.Empty}.{ _coreSettings.BaseDomain}"; + + var u = _userManager.GetUsers(tenant.OwnerId); + _studioNotifyService.SendMsgDnsChange(tenant, GenerateDnsChangeConfirmUrl(u.Email, dnsName, tenant.TenantAlias, ConfirmType.DnsChange), portalAddress, dnsName); + + _messageService.Send(MessageAction.DnsSettingsUpdated); + return string.Format(Resource.DnsChangeMsg, string.Format("{0}", u.Email.HtmlEncode())); + } + + return null; + } + + throw new Exception(Resource.ErrorNotCorrectTrustedDomain); + } + catch (Exception e) + { + throw new Exception(e.Message.HtmlEncode()); + } + } + + private bool CheckCustomDomain(string domain) + { + if (string.IsNullOrEmpty(domain)) + { + return false; + } + if (!string.IsNullOrEmpty(TenantBaseDomain) && + (domain.EndsWith(TenantBaseDomain, StringComparison.InvariantCultureIgnoreCase) || domain.Equals(TenantBaseDomain.TrimStart('.'), StringComparison.InvariantCultureIgnoreCase))) + { + return false; + } + Uri test; + if (Uri.TryCreate(domain.Contains(Uri.SchemeDelimiter) ? domain : Uri.UriSchemeHttp + Uri.SchemeDelimiter + domain, UriKind.Absolute, out test)) + { + try + { + _tenantManager.CheckTenantAddress(test.Host); + } + catch (TenantTooShortException ex) + { + var minLength = ex.MinLength; + var maxLength = ex.MaxLength; + if (minLength > 0 && maxLength > 0) + { + throw new TenantTooShortException(string.Format(Resource.ErrorTenantTooShortFormat, minLength, maxLength)); + } + + throw new TenantTooShortException(Resource.ErrorTenantTooShort); + } + catch (TenantIncorrectCharsException) + { + } + return true; + } + return false; + } + + private string GenerateDnsChangeConfirmUrl(string email, string dnsName, string tenantAlias, ConfirmType confirmType) + { + var postfix = string.Join(string.Empty, new[] { dnsName, tenantAlias }); + + var sb = new StringBuilder(); + sb.Append(_commonLinkUtility.GetConfirmationUrl(email, confirmType, postfix)); + if (!string.IsNullOrEmpty(dnsName)) + { + sb.AppendFormat("&dns={0}", dnsName); + } + if (!string.IsNullOrEmpty(tenantAlias)) + { + sb.AppendFormat("&alias={0}", tenantAlias); + } + return sb.ToString(); + } + + protected string TenantBaseDomain + { + get + { + return string.IsNullOrEmpty(_coreSettings.BaseDomain) + ? string.Empty + : $".{_coreSettings.BaseDomain}"; + } + } + } +} diff --git a/web/ASC.Web.Api/Models/DnsSettingsModel.cs b/web/ASC.Web.Api/Models/DnsSettingsModel.cs new file mode 100644 index 0000000000..deb858e659 --- /dev/null +++ b/web/ASC.Web.Api/Models/DnsSettingsModel.cs @@ -0,0 +1,8 @@ +namespace ASC.Web.Api.Models +{ + public class DnsSettingsModel + { + public string DnsName { get; set; } + public bool Enable { get; set; } + } +} diff --git a/web/ASC.Web.Core/PublicResources/Resource.Designer.cs b/web/ASC.Web.Core/PublicResources/Resource.Designer.cs index e2dd44b9f9..e066e03f99 100644 --- a/web/ASC.Web.Core/PublicResources/Resource.Designer.cs +++ b/web/ASC.Web.Core/PublicResources/Resource.Designer.cs @@ -1509,6 +1509,15 @@ namespace ASC.Web.Core.PublicResources { } } + /// + /// Ищет локализованную строку, похожую на A link to confirm the operation has been sent to {0} (the email address of the portal owner).. + /// + public static string DnsChangeMsg { + get { + return ResourceManager.GetString("DnsChangeMsg", resourceCulture); + } + } + /// /// Ищет локализованную строку, похожую на Incorrect Instance id.. /// @@ -1752,6 +1761,24 @@ namespace ASC.Web.Core.PublicResources { } } + /// + /// Ищет локализованную строку, похожую на The tenant domain can not be empty.. + /// + public static string ErrorTenantTooShort { + get { + return ResourceManager.GetString("ErrorTenantTooShort", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на The domain name must be between {0} and {1} characters long.. + /// + public static string ErrorTenantTooShortFormat { + get { + return ResourceManager.GetString("ErrorTenantTooShortFormat", resourceCulture); + } + } + /// /// Ищет локализованную строку, похожую на The user could not be found. /// diff --git a/web/ASC.Web.Core/PublicResources/Resource.de.resx b/web/ASC.Web.Core/PublicResources/Resource.de.resx index ad7fdf107a..3e248fae0c 100644 --- a/web/ASC.Web.Core/PublicResources/Resource.de.resx +++ b/web/ASC.Web.Core/PublicResources/Resource.de.resx @@ -53,10 +53,10 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.9.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=6.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.9.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=6.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Das Feld mit dem Prüfcode darf nicht leer sein @@ -545,6 +545,9 @@ Einstellbar + + Der Link zum Bestätigen der Operation wurde an {0} verschickt (die E-Mail-Adresse des Portalbesitzers). + Falsche Instanz-ID. @@ -626,6 +629,12 @@ Anforderungslimit wurde überschritten + + Die Mandantendomäne darf nicht leer sein. + + + Der Domänenname muss zwischen {0} und {1} Zeichen lang sein. + Der Benutzer konnte nicht gefunden werden diff --git a/web/ASC.Web.Core/PublicResources/Resource.es.resx b/web/ASC.Web.Core/PublicResources/Resource.es.resx index 7b9705d5df..b07fe18432 100644 --- a/web/ASC.Web.Core/PublicResources/Resource.es.resx +++ b/web/ASC.Web.Core/PublicResources/Resource.es.resx @@ -53,10 +53,10 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.9.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=6.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.9.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=6.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Campo de código de validación no puede estar vacío @@ -508,6 +508,9 @@ Personalizado + + Un enlace para confirmar la operación ha sido enviada al :correo electrónico (la dirección del correo electrónico del propietario del portal). + Id. incorrecta de instancia @@ -589,6 +592,12 @@ Límite de solicitudes es excedido + + El dominio de espacio empresarial no puede estar vacío. + + + El nombre del dominio debe tener entre {0} y {1} caracteres. + Usuario no ha sido encontrado diff --git a/web/ASC.Web.Core/PublicResources/Resource.fr.resx b/web/ASC.Web.Core/PublicResources/Resource.fr.resx index be5d53085c..47ed83fe50 100644 --- a/web/ASC.Web.Core/PublicResources/Resource.fr.resx +++ b/web/ASC.Web.Core/PublicResources/Resource.fr.resx @@ -53,10 +53,10 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.9.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=6.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.9.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=6.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Le champ du code de validation ne peut pas être vide @@ -541,6 +541,9 @@ Personnel + + Un lien pour confirmer l'opération a été envoyé à {0}(l'adresse e-mail du propriétaire du portail). + Identifiant de l'instance n'est pas valide. @@ -622,6 +625,12 @@ Le délai de requête est dépassé + + L'hôte du domaine ne peut pas être vide + + + Le nom de domaine doit contenir de {0} à {1} caractères. + Il est impossible de trouver l'utilisateur diff --git a/web/ASC.Web.Core/PublicResources/Resource.it.resx b/web/ASC.Web.Core/PublicResources/Resource.it.resx index 9ace76e441..42981731e4 100644 --- a/web/ASC.Web.Core/PublicResources/Resource.it.resx +++ b/web/ASC.Web.Core/PublicResources/Resource.it.resx @@ -53,10 +53,10 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.9.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=6.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.9.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=6.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Il campo Valida codice non può essere vuoto @@ -503,6 +503,9 @@ Personalizzato + + Un collegamento per confermare l'operazione è stato inviato all'indirizzo {0} (l'indirizzo email del proprietario del portale). + ID istanza errato. @@ -584,6 +587,12 @@ Il limite di richieste è stato superato + + Il dominio Tenant non può essere vuoto. + + + Il nome del dominio deve essere composto da {0} a {1} caratteri. + L'utente non è stato trovato diff --git a/web/ASC.Web.Core/PublicResources/Resource.resx b/web/ASC.Web.Core/PublicResources/Resource.resx index 2418ceb74f..ba4022bef5 100644 --- a/web/ASC.Web.Core/PublicResources/Resource.resx +++ b/web/ASC.Web.Core/PublicResources/Resource.resx @@ -53,10 +53,10 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.9.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=6.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.9.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=6.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Validation code field cannot be empty @@ -541,6 +541,9 @@ Custom + + A link to confirm the operation has been sent to {0} (the email address of the portal owner). + Incorrect Instance id. @@ -622,6 +625,12 @@ Request limit is exceeded + + The tenant domain can not be empty. + + + The domain name must be between {0} and {1} characters long. + The user could not be found diff --git a/web/ASC.Web.Core/PublicResources/Resource.ru.resx b/web/ASC.Web.Core/PublicResources/Resource.ru.resx index 55eab9829c..1804ced5c4 100644 --- a/web/ASC.Web.Core/PublicResources/Resource.ru.resx +++ b/web/ASC.Web.Core/PublicResources/Resource.ru.resx @@ -53,10 +53,10 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.9.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=6.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.9.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=6.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Поле кода подтверждения не может быть пустым @@ -541,6 +541,9 @@ Пользовательский + + Ссылка для подтверждения операции была отправлена на {0} (адрес электронной почты владельца портала). + Неправильный ID экземпляра. @@ -622,6 +625,12 @@ Превышен лимит запросов + + Домен клиента не может быть пустым + + + Доменное имя должно содержать от {0} до {1} символов. + Пользователь не найден From 91c3fa878b741d8b03daf53fa39bf6b03f1f7827 Mon Sep 17 00:00:00 2001 From: pavelbannov Date: Thu, 17 Feb 2022 16:39:47 +0300 Subject: [PATCH 4/6] Portal: portalrename method --- .../Controllers/PortalController.cs | 89 +++++++++++++++++++ web/ASC.Web.Api/Models/PortalRenameModel.cs | 7 ++ .../PublicResources/Resource.Designer.cs | 18 ++++ .../PublicResources/Resource.de.resx | 6 ++ .../PublicResources/Resource.es.resx | 6 ++ .../PublicResources/Resource.fr.resx | 6 ++ .../PublicResources/Resource.it.resx | 6 ++ .../PublicResources/Resource.resx | 6 ++ .../PublicResources/Resource.ru.resx | 6 ++ 9 files changed, 150 insertions(+) create mode 100644 web/ASC.Web.Api/Models/PortalRenameModel.cs diff --git a/web/ASC.Web.Api/Controllers/PortalController.cs b/web/ASC.Web.Api/Controllers/PortalController.cs index ae40c0e318..5fe966c9d8 100644 --- a/web/ASC.Web.Api/Controllers/PortalController.cs +++ b/web/ASC.Web.Api/Controllers/PortalController.cs @@ -17,9 +17,12 @@ using ASC.Web.Api.Models; using ASC.Web.Api.Routing; using ASC.Web.Core; using ASC.Web.Core.Files; +using ASC.Web.Core.Helpers; using ASC.Web.Core.Mobile; +using ASC.Web.Core.PublicResources; using ASC.Web.Core.Utility; using ASC.Web.Studio.Core; +using ASC.Web.Studio.Core.Notify; using ASC.Web.Studio.UserControls.Management; using ASC.Web.Studio.Utility; @@ -55,6 +58,10 @@ namespace ASC.Web.Api.Controllers private LicenseReader LicenseReader { get; } private SetupInfo SetupInfo { get; } private DocumentServiceLicense DocumentServiceLicense { get; } + private CoreSettings CoreSettings { get; } + private PermissionContext PermissionContext { get; } + private ApiSystemHelper ApiSystemHelper { get; } + private StudioNotifyService StudioNotifyService { get; } private TenantExtra TenantExtra { get; set; } public ILog Log { get; } public IHttpClientFactory ClientFactory { get; } @@ -79,6 +86,10 @@ namespace ASC.Web.Api.Controllers LicenseReader licenseReader, SetupInfo setupInfo, DocumentServiceLicense documentServiceLicense, + CoreSettings coreSettings, + PermissionContext permissionContext, + ApiSystemHelper apiSystemHelper, + StudioNotifyService studioNotifyService, IHttpClientFactory clientFactory ) { @@ -99,6 +110,10 @@ namespace ASC.Web.Api.Controllers LicenseReader = licenseReader; SetupInfo = setupInfo; DocumentServiceLicense = documentServiceLicense; + CoreSettings = coreSettings; + PermissionContext = permissionContext; + ApiSystemHelper = apiSystemHelper; + StudioNotifyService = studioNotifyService; TenantExtra = tenantExtra; ClientFactory = clientFactory; } @@ -279,5 +294,79 @@ namespace ASC.Web.Api.Controllers var currentUser = UserManager.GetUsers(SecurityContext.CurrentAccount.ID); MobileAppInstallRegistrator.RegisterInstall(currentUser.Email, type); } + + [Update("portalrename")] + public object UpdatePortalName(PortalRenameModel model) + { + var enabled = SetupInfo.IsVisibleSettings("PortalRename"); + + if (!enabled) + throw new SecurityException(Resource.PortalAccessSettingsTariffException); + + if (CoreBaseSettings.Personal) + throw new Exception(Resource.ErrorAccessDenied); + + PermissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings); + + var alias = model.Alias; + if (string.IsNullOrEmpty(alias)) throw new ArgumentException(); + + var tenant = TenantManager.GetCurrentTenant(); + var user = UserManager.GetUsers(SecurityContext.CurrentAccount.ID); + + var localhost = CoreSettings.BaseDomain == "localhost" || tenant.TenantAlias == "localhost"; + + var newAlias = alias.ToLowerInvariant(); + var oldAlias = tenant.TenantAlias; + var oldVirtualRootPath = CommonLinkUtility.GetFullAbsolutePath("~").TrimEnd('/'); + + if (!string.Equals(newAlias, oldAlias, StringComparison.InvariantCultureIgnoreCase)) + { + if (!string.IsNullOrEmpty(ApiSystemHelper.ApiSystemUrl)) + { + ApiSystemHelper.ValidatePortalName(newAlias, user.ID); + } + else + { + TenantManager.CheckTenantAddress(newAlias.Trim()); + } + + + if (!string.IsNullOrEmpty(ApiSystemHelper.ApiCacheUrl)) + { + ApiSystemHelper.AddTenantToCache(newAlias, user.ID); + } + + tenant.TenantAlias = alias; + tenant = TenantManager.SaveTenant(tenant); + + + if (!string.IsNullOrEmpty(ApiSystemHelper.ApiCacheUrl)) + { + ApiSystemHelper.RemoveTenantFromCache(oldAlias, user.ID); + } + + if (!localhost || string.IsNullOrEmpty(tenant.MappedDomain)) + { + StudioNotifyService.PortalRenameNotify(tenant, oldVirtualRootPath); + } + } + else + { + return null; + } + + var reference = string.Format("{0}{1}{2}/{3}", + ApiContext.HttpContextAccessor.HttpContext.Request?.Scheme ?? Uri.UriSchemeHttp, + Uri.SchemeDelimiter, + tenant.GetTenantDomain(CoreSettings), + CommonLinkUtility.GetConfirmationUrlRelative(tenant.TenantId, user.Email, ConfirmType.Auth)); + + return new + { + message = Resource.SuccessfullyPortalRenameMessage, + reference = reference + }; + } } } \ No newline at end of file diff --git a/web/ASC.Web.Api/Models/PortalRenameModel.cs b/web/ASC.Web.Api/Models/PortalRenameModel.cs new file mode 100644 index 0000000000..cde107cf03 --- /dev/null +++ b/web/ASC.Web.Api/Models/PortalRenameModel.cs @@ -0,0 +1,7 @@ +namespace ASC.Web.Api.Models +{ + public class PortalRenameModel + { + public string Alias { get; set; } + } +} diff --git a/web/ASC.Web.Core/PublicResources/Resource.Designer.cs b/web/ASC.Web.Core/PublicResources/Resource.Designer.cs index e066e03f99..546910c18c 100644 --- a/web/ASC.Web.Core/PublicResources/Resource.Designer.cs +++ b/web/ASC.Web.Core/PublicResources/Resource.Designer.cs @@ -1977,6 +1977,15 @@ namespace ASC.Web.Core.PublicResources { } } + /// + /// Ищет локализованную строку, похожую на This feature enabled on free tariff only. + /// + public static string PortalAccessSettingsTariffException { + get { + return ResourceManager.GetString("PortalAccessSettingsTariffException", resourceCulture); + } + } + /// /// Ищет локализованную строку, похожую на Portal Access. /// @@ -2103,6 +2112,15 @@ namespace ASC.Web.Core.PublicResources { } } + /// + /// Ищет локализованную строку, похожую на Portal has been renamed successfully. + /// + public static string SuccessfullyPortalRenameMessage { + get { + return ResourceManager.GetString("SuccessfullyPortalRenameMessage", resourceCulture); + } + } + /// /// Ищет локализованную строку, похожую на Welcome Page settings have been successfully saved. /// diff --git a/web/ASC.Web.Core/PublicResources/Resource.de.resx b/web/ASC.Web.Core/PublicResources/Resource.de.resx index 3e248fae0c..d3528e71ea 100644 --- a/web/ASC.Web.Core/PublicResources/Resource.de.resx +++ b/web/ASC.Web.Core/PublicResources/Resource.de.resx @@ -701,6 +701,9 @@ Der verfügbare Speicherplatz ist überschritten + + Diese Funktion ist nur für den kostenlosen Tarif verfügbar + Zugang zum Portal @@ -743,6 +746,9 @@ Ungültige Feldzuordnung + + Portal wurde erfolgreich umbenannt + Die Begrüßungseinstellungen wurden erfolgreich gespeichert diff --git a/web/ASC.Web.Core/PublicResources/Resource.es.resx b/web/ASC.Web.Core/PublicResources/Resource.es.resx index b07fe18432..72d596244a 100644 --- a/web/ASC.Web.Core/PublicResources/Resource.es.resx +++ b/web/ASC.Web.Core/PublicResources/Resource.es.resx @@ -664,6 +664,9 @@ Cuota de espacio en disco excedida + + Esta característica se proporciona sólo en portales gratuitos + Acceso a portal @@ -706,6 +709,9 @@ Cartografía de campos no válida + + El portal ha sido renombrado con éxito + Los ajustes de bienvenida han sido guardados con éxito diff --git a/web/ASC.Web.Core/PublicResources/Resource.fr.resx b/web/ASC.Web.Core/PublicResources/Resource.fr.resx index 47ed83fe50..58ff6d9ce2 100644 --- a/web/ASC.Web.Core/PublicResources/Resource.fr.resx +++ b/web/ASC.Web.Core/PublicResources/Resource.fr.resx @@ -699,6 +699,9 @@ Quota d'espace disque est dépassé + + Cette fonctionalité n'est activée que pour le tarif gratuit + Accès au portail @@ -741,6 +744,9 @@ Mappage des champs non valides + + Le portail a été renommé avec succès + Les paramètres de la page d'accueil ont été enregistrés avec succès diff --git a/web/ASC.Web.Core/PublicResources/Resource.it.resx b/web/ASC.Web.Core/PublicResources/Resource.it.resx index 42981731e4..ae0823fb06 100644 --- a/web/ASC.Web.Core/PublicResources/Resource.it.resx +++ b/web/ASC.Web.Core/PublicResources/Resource.it.resx @@ -656,6 +656,9 @@ Quota di spazio su disco superata + + Questa funzione è attiva solo per il piano tariffario gratuito + Accesso al portale @@ -698,6 +701,9 @@ Mappatura campi non valida + + Il portale è stato rinominato con successo. + Le impostazioni della pagina di saluto sono state salvate con successo diff --git a/web/ASC.Web.Core/PublicResources/Resource.resx b/web/ASC.Web.Core/PublicResources/Resource.resx index ba4022bef5..9ace57e689 100644 --- a/web/ASC.Web.Core/PublicResources/Resource.resx +++ b/web/ASC.Web.Core/PublicResources/Resource.resx @@ -697,6 +697,9 @@ Disk space quota exceeded + + This feature enabled on free tariff only + Portal Access @@ -739,6 +742,9 @@ Invalid fields mapping + + Portal has been renamed successfully + Welcome Page settings have been successfully saved diff --git a/web/ASC.Web.Core/PublicResources/Resource.ru.resx b/web/ASC.Web.Core/PublicResources/Resource.ru.resx index 1804ced5c4..c6e0650df8 100644 --- a/web/ASC.Web.Core/PublicResources/Resource.ru.resx +++ b/web/ASC.Web.Core/PublicResources/Resource.ru.resx @@ -697,6 +697,9 @@ Превышена квота на размер дискового пространства + + Эта функция доступна только для бесплатного тарифа + Доступ к порталу @@ -739,6 +742,9 @@ Недопустимое сопоставление полей + + Портал успешно переименован + Настройки страницы приветствия успешно сохранены From c998797aede0bab0770768ae4727035b9b00b3c7 Mon Sep 17 00:00:00 2001 From: pavelbannov Date: Thu, 17 Feb 2022 18:25:07 +0300 Subject: [PATCH 5/6] Settings: update password settings --- .../Controllers/SettingsController.cs | 24 +++++++++++++++--- .../Models/PasswordSettingsModel.cs | 25 +++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 web/ASC.Web.Api/Models/PasswordSettingsModel.cs diff --git a/web/ASC.Web.Api/Controllers/SettingsController.cs b/web/ASC.Web.Api/Controllers/SettingsController.cs index c4f230dea8..287a34f21c 100644 --- a/web/ASC.Web.Api/Controllers/SettingsController.cs +++ b/web/ASC.Web.Api/Controllers/SettingsController.cs @@ -900,11 +900,29 @@ namespace ASC.Api.Settings [Read("security/password", Check = false)] [Authorize(AuthenticationSchemes = "confirm", Roles = "Everyone")] - public object GetPasswordSettings() + public PasswordSettings GetPasswordSettings() { - var UserPasswordSettings = SettingsManager.Load(); + return SettingsManager.Load(); + } + + [Update("security/password")] + public PasswordSettings UpdatePasswordSettings(PasswordSettingsModel model) + { + PermissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings); + + var userPasswordSettings = SettingsManager.Load(); + + userPasswordSettings.MinLength = model.MinLength; + userPasswordSettings.UpperCase = model.UpperCase; + userPasswordSettings.Digits = model.Digits; + userPasswordSettings.SpecSymbols = model.SpecSymbols; + + SettingsManager.Save(userPasswordSettings); + + MessageService.Send(MessageAction.PasswordStrengthSettingsUpdated); + + return userPasswordSettings; - return UserPasswordSettings; } [Update("security")] diff --git a/web/ASC.Web.Api/Models/PasswordSettingsModel.cs b/web/ASC.Web.Api/Models/PasswordSettingsModel.cs new file mode 100644 index 0000000000..2d50f9a22b --- /dev/null +++ b/web/ASC.Web.Api/Models/PasswordSettingsModel.cs @@ -0,0 +1,25 @@ +namespace ASC.Web.Api.Models +{ + public class PasswordSettingsModel + { + /// + /// Minimal length password has + /// + public int MinLength { get; set; } + + /// + /// Password must contains upper case + /// + public bool UpperCase { get; set; } + + /// + /// Password must contains digits + /// + public bool Digits { get; set; } + + /// + /// Password must contains special symbols + /// + public bool SpecSymbols { get; set; } + } +} From f068f60a953fc21ee1222ba033b93d543309740d Mon Sep 17 00:00:00 2001 From: gazizova-vlada Date: Fri, 18 Feb 2022 10:59:38 +0300 Subject: [PATCH 6/6] Web:Studio:Added languageDefaultFromSessionStorage and timezoneDefaultFromSessionStorage keys to sessionStorage. Fixed showReminder output. --- .../common/language-and-time-zone.js | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/language-and-time-zone.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/language-and-time-zone.js index bf53dc2f9a..971edf1487 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/language-and-time-zone.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/language-and-time-zone.js @@ -79,7 +79,9 @@ const StyledComponent = styled.div` `; let languageFromSessionStorage = ""; +let languageDefaultFromSessionStorage = ""; let timezoneFromSessionStorage = ""; +let timezoneDefaultFromSessionStorage = ""; const settingNames = ["language", "timezone"]; @@ -108,8 +110,13 @@ class LanguageAndTimeZone extends React.Component { ); languageFromSessionStorage = getFromSessionStorage("language"); + languageDefaultFromSessionStorage = getFromSessionStorage( + "languageDefault" + ); timezoneFromSessionStorage = getFromSessionStorage("timezone"); - + timezoneDefaultFromSessionStorage = getFromSessionStorage( + "timezoneDefault" + ); setDocumentTitle(t("Customization")); this.state = { @@ -117,9 +124,9 @@ class LanguageAndTimeZone extends React.Component { isLoading: false, timezones, timezone: timezoneFromSessionStorage || timezone, - timezoneDefault: timezone, + timezoneDefault: timezoneDefaultFromSessionStorage || timezone, language: languageFromSessionStorage || language, - languageDefault: language, + languageDefault: languageDefaultFromSessionStorage || language, isLoadingGreetingSave: false, isLoadingGreetingRestore: false, hasChanged: false, @@ -134,16 +141,7 @@ class LanguageAndTimeZone extends React.Component { portalTimeZoneId, getPortalTimezones, } = this.props; - const { timezones, isLoadedData, showReminder } = this.state; - - if ( - (languageFromSessionStorage || timezoneFromSessionStorage) && - !showReminder - ) { - this.setState({ - showReminder: true, - }); - } + const { timezones, isLoadedData } = this.state; if (!timezones.length) { getPortalTimezones().then(() => { @@ -225,11 +223,9 @@ class LanguageAndTimeZone extends React.Component { this.setState({ language }); if (this.settingIsEqualInitialValue("language", language)) { saveToSessionStorage("language", ""); + saveToSessionStorage("languageDefault", ""); } else { saveToSessionStorage("language", language); - this.setState({ - showReminder: true, - }); } this.checkChanges(); }; @@ -238,11 +234,9 @@ class LanguageAndTimeZone extends React.Component { this.setState({ timezone }); if (this.settingIsEqualInitialValue("timezone", timezone)) { saveToSessionStorage("timezone", ""); + saveToSessionStorage("timezoneDefault", ""); } else { saveToSessionStorage("timezone", timezone); - this.setState({ - showReminder: true, - }); } this.checkChanges(); @@ -272,6 +266,9 @@ class LanguageAndTimeZone extends React.Component { timezoneDefault: this.state.timezone, languageDefault: this.state.language, }); + + saveToSessionStorage("languageDefault", language); + saveToSessionStorage("timezoneDefault", timezone); }; onCancelClick = () => { @@ -317,6 +314,7 @@ class LanguageAndTimeZone extends React.Component { if (hasChanged !== this.state.hasChanged) { this.setState({ hasChanged: hasChanged, + showReminder: hasChanged, }); } };