From 9c8bf9708a21ce7fce04a075d3d79df6967a5586 Mon Sep 17 00:00:00 2001 From: pavelbannov Date: Tue, 20 Sep 2022 23:22:27 +0300 Subject: [PATCH] Payment: UsersInRoomStatistic --- .../Quota/ITenantQuotaFeatureChecker.cs | 2 +- common/ASC.Core.Common/Tenants/TenantQuota.cs | 2 +- .../ASC.Files/Core/Core/UsersInRoomFeature.cs | 65 +++++++++++++++ .../ASC.People/Server/Api/UserController.cs | 82 ++++++++++--------- products/ASC.People/Server/GlobalUsings.cs | 3 + products/ASC.People/Server/Startup.cs | 5 ++ .../PublicResources/Resource.Designer.cs | 9 ++ .../PublicResources/Resource.resx | 3 + 8 files changed, 131 insertions(+), 40 deletions(-) create mode 100644 products/ASC.Files/Core/Core/UsersInRoomFeature.cs diff --git a/common/ASC.Core.Common/Quota/ITenantQuotaFeatureChecker.cs b/common/ASC.Core.Common/Quota/ITenantQuotaFeatureChecker.cs index 3063816758..14b72e96f6 100644 --- a/common/ASC.Core.Common/Quota/ITenantQuotaFeatureChecker.cs +++ b/common/ASC.Core.Common/Quota/ITenantQuotaFeatureChecker.cs @@ -35,7 +35,7 @@ public interface ITenantQuotaFeatureChecker public abstract class TenantQuotaFeatureChecker : ITenantQuotaFeatureChecker where T : TenantQuotaFeature where T1 : IComparable { protected readonly ITenantQuotaFeatureStat _tenantQuotaFeatureStatistic; - private readonly TenantManager _tenantManager; + protected readonly TenantManager _tenantManager; public abstract string Exception { get; } diff --git a/common/ASC.Core.Common/Tenants/TenantQuota.cs b/common/ASC.Core.Common/Tenants/TenantQuota.cs index 6f96de4c64..c48e8fe364 100644 --- a/common/ASC.Core.Common/Tenants/TenantQuota.cs +++ b/common/ASC.Core.Common/Tenants/TenantQuota.cs @@ -368,7 +368,7 @@ public class TenantQuota : IMapFrom internal string GetFeature(string name) { - return _featuresList.FirstOrDefault(f => f.StartsWith($"{name}")); + return _featuresList.FirstOrDefault(f => string.Equals(f.Split(':')[0], $"{name}", StringComparison.OrdinalIgnoreCase)); } internal void ReplaceFeature(string name, T value) diff --git a/products/ASC.Files/Core/Core/UsersInRoomFeature.cs b/products/ASC.Files/Core/Core/UsersInRoomFeature.cs new file mode 100644 index 0000000000..890c89983d --- /dev/null +++ b/products/ASC.Files/Core/Core/UsersInRoomFeature.cs @@ -0,0 +1,65 @@ +// (c) Copyright Ascensio System SIA 2010-2022 +// +// This program is a free software product. +// You can redistribute it and/or modify it under the terms +// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software +// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended +// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of +// any third-party rights. +// +// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see +// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html +// +// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021. +// +// The interactive user interfaces in modified source and object code versions of the Program must +// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3. +// +// Pursuant to Section 7(b) of the License you must retain the original Product logo when +// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under +// trademark law for use of our trademarks. +// +// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing +// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0 +// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + +namespace ASC.Files.Core.Core; + +public class UsersInRoomChecker : TenantQuotaFeatureChecker +{ + public override string Exception => Resource.TariffsFeature_usersInRoom_exception; + + public UsersInRoomChecker(ITenantQuotaFeatureStat tenantQuotaFeatureStatistic, TenantManager tenantManager) : base(tenantQuotaFeatureStatistic, tenantManager) + { + } +} + +public class UsersInRoomStatistic : ITenantQuotaFeatureStat +{ + private readonly IServiceProvider _serviceProvider; + + public UsersInRoomStatistic(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + public Task GetValue() + { + return Task.FromResult(0); + } + + public async Task GetValue(T roomId) + { + var folderDao = _serviceProvider.GetService>(); + var securityDao = _serviceProvider.GetService>(); + var folder = await folderDao.GetFolderAsync(roomId); + + if (folder == null) + { + return 0; + } + + return await securityDao.GetPureShareRecordsAsync(folder).CountAsync(); + } +} \ No newline at end of file diff --git a/products/ASC.People/Server/Api/UserController.cs b/products/ASC.People/Server/Api/UserController.cs index d22db9a2c5..fb16c6372d 100644 --- a/products/ASC.People/Server/Api/UserController.cs +++ b/products/ASC.People/Server/Api/UserController.cs @@ -61,6 +61,8 @@ public class UserController : PeopleControllerBase private readonly EmailValidationKeyProvider _validationKeyProvider; private readonly CountManagerChecker _countManagerChecker; private readonly CountUserChecker _countUserChecker; + private readonly UsersInRoomChecker _usersInRoomChecker; + private readonly UsersInRoomStatistic _usersInRoomStatistic; public UserController( ICache cache, @@ -99,7 +101,9 @@ public class UserController : PeopleControllerBase IDaoFactory daoFactory, EmailValidationKeyProvider validationKeyProvider, CountManagerChecker countManagerChecker, - CountUserChecker activeUsersChecker) + CountUserChecker activeUsersChecker, + UsersInRoomChecker usersInRoomChecker, + UsersInRoomStatistic usersInRoomStatistic) : base(userManager, permissionContext, apiContext, userPhotoManager, httpClientFactory, httpContextAccessor) { _cache = cache; @@ -133,6 +137,8 @@ public class UserController : PeopleControllerBase _validationKeyProvider = validationKeyProvider; _countManagerChecker = countManagerChecker; _countUserChecker = activeUsersChecker; + _usersInRoomChecker = usersInRoomChecker; + _usersInRoomStatistic = usersInRoomStatistic; } [HttpPost("active")] @@ -202,39 +208,39 @@ public class UserController : PeopleControllerBase var success = int.TryParse(inDto.RoomId, out var id); - if (inDto.FromInviteLink && !string.IsNullOrEmpty(inDto.RoomId)) - { - var employeeType = inDto.IsVisitor ? EmployeeType.Visitor : EmployeeType.User; - var resultWithEmail = _validationKeyProvider.ValidateEmailKey(inDto.Email + ConfirmType.LinkInvite + ((int)employeeType + inDto.RoomAccess + inDto.RoomId), inDto.Key, - _validationKeyProvider.ValidEmailKeyInterval); - var resultWithoutEmail = _validationKeyProvider.ValidateEmailKey(string.Empty + ConfirmType.LinkInvite + ((int)employeeType + inDto.RoomAccess + inDto.RoomId), inDto.Key, - _validationKeyProvider.ValidEmailKeyInterval); - - if (resultWithEmail != EmailValidationKeyProvider.ValidationResult.Ok && resultWithoutEmail != EmailValidationKeyProvider.ValidationResult.Ok) - { - throw new SecurityException("Invalid data"); - } - - if (success) - { - var folderDao = _daoFactory.GetFolderDao(); - var folder = await folderDao.GetFolderAsync(id); - - if (folder == null) - { - throw new ItemNotFoundException("Virtual room not found"); - } - } - else - { - var folderDao = _daoFactory.GetFolderDao(); - var folder = await folderDao.GetFolderAsync(inDto.RoomId); - - if (folder == null) - { - throw new ItemNotFoundException("Virtual room not found"); - } - } + if (inDto.FromInviteLink && !string.IsNullOrEmpty(inDto.RoomId)) + { + var employeeType = inDto.IsVisitor ? EmployeeType.Visitor : EmployeeType.User; + var resultWithEmail = _validationKeyProvider.ValidateEmailKey(inDto.Email + ConfirmType.LinkInvite + ((int)employeeType + inDto.RoomAccess + inDto.RoomId), inDto.Key, + _validationKeyProvider.ValidEmailKeyInterval); + var resultWithoutEmail = _validationKeyProvider.ValidateEmailKey(string.Empty + ConfirmType.LinkInvite + ((int)employeeType + inDto.RoomAccess + inDto.RoomId), inDto.Key, + _validationKeyProvider.ValidEmailKeyInterval); + + if (resultWithEmail != EmailValidationKeyProvider.ValidationResult.Ok && resultWithoutEmail != EmailValidationKeyProvider.ValidationResult.Ok) + { + throw new SecurityException("Invalid data"); + } + + if (success) + { + var folderDao = _daoFactory.GetFolderDao(); + var folder = await folderDao.GetFolderAsync(id); + + if (folder == null) + { + throw new ItemNotFoundException("Virtual room not found"); + } + } + else + { + var folderDao = _daoFactory.GetFolderDao(); + var folder = await folderDao.GetFolderAsync(inDto.RoomId); + + if (folder == null) + { + throw new ItemNotFoundException("Virtual room not found"); + } + } } inDto.PasswordHash = (inDto.PasswordHash ?? "").Trim(); @@ -287,13 +293,13 @@ public class UserController : PeopleControllerBase { if (success) { - _fileSecurity.ShareAsync(id, FileEntryType.Folder, user.Id, (Files.Core.Security.FileShare)inDto.RoomAccess) - .GetAwaiter().GetResult(); + _usersInRoomChecker.CheckAdd(await _usersInRoomStatistic.GetValue(id) + 1); + await _fileSecurity.ShareAsync(id, FileEntryType.Folder, user.Id, (Files.Core.Security.FileShare)inDto.RoomAccess); } else { - _fileSecurity.ShareAsync(inDto.RoomId, FileEntryType.Folder, user.Id, (Files.Core.Security.FileShare)inDto.RoomAccess) - .GetAwaiter().GetResult(); + _usersInRoomChecker.CheckAdd(await _usersInRoomStatistic.GetValue(inDto.RoomId) + 1); + await _fileSecurity.ShareAsync(inDto.RoomId, FileEntryType.Folder, user.Id, (Files.Core.Security.FileShare)inDto.RoomAccess); } var messageAction = inDto.IsVisitor ? MessageAction.GuestCreatedAndAddedToRoom : MessageAction.UserCreatedAndAddedToRoom; diff --git a/products/ASC.People/Server/GlobalUsings.cs b/products/ASC.People/Server/GlobalUsings.cs index 15be4c9845..6aebedaf21 100644 --- a/products/ASC.People/Server/GlobalUsings.cs +++ b/products/ASC.People/Server/GlobalUsings.cs @@ -40,6 +40,8 @@ global using ASC.Common.Utils; global using ASC.Common.Web; global using ASC.Core; global using ASC.Core.Common.EF; +global using ASC.Core.Common.Quota; +global using ASC.Core.Common.Quota.Features; global using ASC.Core.Common.Settings; global using ASC.Core.Tenants; global using ASC.Core.Users; @@ -48,6 +50,7 @@ global using ASC.FederatedLogin; global using ASC.FederatedLogin.LoginProviders; global using ASC.FederatedLogin.Profile; global using ASC.Files.Core; +global using ASC.Files.Core.Core; global using ASC.Files.Core.EF; global using ASC.Files.Core.Security; global using ASC.MessagingSystem.Core; diff --git a/products/ASC.People/Server/Startup.cs b/products/ASC.People/Server/Startup.cs index 9e24d23794..9042270187 100644 --- a/products/ASC.People/Server/Startup.cs +++ b/products/ASC.People/Server/Startup.cs @@ -39,5 +39,10 @@ public class Startup : BaseStartup base.ConfigureServices(services); services.AddBaseDbContextPool(); + + services.AddScoped(); + + services.AddScoped, UsersInRoomStatistic>(); + services.AddScoped(); } } \ No newline at end of file diff --git a/web/ASC.Web.Core/PublicResources/Resource.Designer.cs b/web/ASC.Web.Core/PublicResources/Resource.Designer.cs index 1a34aeca80..50e805d10a 100644 --- a/web/ASC.Web.Core/PublicResources/Resource.Designer.cs +++ b/web/ASC.Web.Core/PublicResources/Resource.Designer.cs @@ -2328,6 +2328,15 @@ namespace ASC.Web.Core.PublicResources { } } + /// + /// Looks up a localized string similar to The number of users in room should not exceed {0}. + /// + public static string TariffsFeature_usersInRoom_exception { + get { + return ResourceManager.GetString("TariffsFeature_usersInRoom_exception", resourceCulture); + } + } + /// /// Looks up a localized string similar to Branding & customization. /// diff --git a/web/ASC.Web.Core/PublicResources/Resource.resx b/web/ASC.Web.Core/PublicResources/Resource.resx index 08ab6fdbfd..87263229f8 100644 --- a/web/ASC.Web.Core/PublicResources/Resource.resx +++ b/web/ASC.Web.Core/PublicResources/Resource.resx @@ -891,4 +891,7 @@ The file size should not exceed {0} + + The number of users in room should not exceed {0} + \ No newline at end of file