Merge branch 'feature/stripe' of github.com:ONLYOFFICE/AppServer into feature/stripe

This commit is contained in:
Tatiana Lopaeva 2022-09-21 12:43:09 +03:00
commit 54a47a00df
8 changed files with 131 additions and 40 deletions

View File

@ -35,7 +35,7 @@ public interface ITenantQuotaFeatureChecker
public abstract class TenantQuotaFeatureChecker<T, T1> : ITenantQuotaFeatureChecker where T : TenantQuotaFeature<T1> where T1 : IComparable<T1>
{
protected readonly ITenantQuotaFeatureStat<T, T1> _tenantQuotaFeatureStatistic;
private readonly TenantManager _tenantManager;
protected readonly TenantManager _tenantManager;
public abstract string Exception { get; }

View File

@ -368,7 +368,7 @@ public class TenantQuota : IMapFrom<DbQuota>
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<T>(string name, T value)

View File

@ -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<UsersInRoomFeature, int>
{
public override string Exception => Resource.TariffsFeature_usersInRoom_exception;
public UsersInRoomChecker(ITenantQuotaFeatureStat<UsersInRoomFeature, int> tenantQuotaFeatureStatistic, TenantManager tenantManager) : base(tenantQuotaFeatureStatistic, tenantManager)
{
}
}
public class UsersInRoomStatistic : ITenantQuotaFeatureStat<UsersInRoomFeature, int>
{
private readonly IServiceProvider _serviceProvider;
public UsersInRoomStatistic(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public Task<int> GetValue()
{
return Task.FromResult(0);
}
public async Task<int> GetValue<T>(T roomId)
{
var folderDao = _serviceProvider.GetService<IFolderDao<T>>();
var securityDao = _serviceProvider.GetService<ISecurityDao<T>>();
var folder = await folderDao.GetFolderAsync(roomId);
if (folder == null)
{
return 0;
}
return await securityDao.GetPureShareRecordsAsync(folder).CountAsync();
}
}

View File

@ -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<int>();
var folder = await folderDao.GetFolderAsync(id);
if (folder == null)
{
throw new ItemNotFoundException("Virtual room not found");
}
}
else
{
var folderDao = _daoFactory.GetFolderDao<string>();
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<int>();
var folder = await folderDao.GetFolderAsync(id);
if (folder == null)
{
throw new ItemNotFoundException("Virtual room not found");
}
}
else
{
var folderDao = _daoFactory.GetFolderDao<string>();
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;

View File

@ -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;

View File

@ -39,5 +39,10 @@ public class Startup : BaseStartup
base.ConfigureServices(services);
services.AddBaseDbContextPool<FilesDbContext>();
services.AddScoped<UsersInRoomChecker>();
services.AddScoped<ITenantQuotaFeatureStat<UsersInRoomFeature, int>, UsersInRoomStatistic>();
services.AddScoped<UsersInRoomStatistic>();
}
}

View File

@ -2328,6 +2328,15 @@ namespace ASC.Web.Core.PublicResources {
}
}
/// <summary>
/// Looks up a localized string similar to The number of users in room should not exceed {0}.
/// </summary>
public static string TariffsFeature_usersInRoom_exception {
get {
return ResourceManager.GetString("TariffsFeature_usersInRoom_exception", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Branding &amp; customization.
/// </summary>

View File

@ -891,4 +891,7 @@
<data name="TariffsFeature_file_size_exception" xml:space="preserve">
<value>The file size should not exceed {0}</value>
</data>
<data name="TariffsFeature_usersInRoom_exception" xml:space="preserve">
<value>The number of users in room should not exceed {0}</value>
</data>
</root>