Merge pull request #779 from ONLYOFFICE/feature/user-quota

Feature/user quota
This commit is contained in:
Pavel Bannov 2022-10-07 17:09:52 +03:00 committed by GitHub
commit d0682bb467
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 1223 additions and 1282 deletions

View File

@ -34,10 +34,13 @@ namespace ASC.ActiveDirectory.Base.Data;
public class LdapObjectExtension public class LdapObjectExtension
{ {
private readonly TenantUtil _tenantUtil; private readonly TenantUtil _tenantUtil;
private readonly SettingsManager _settingsManager;
private readonly ILogger<LdapObjectExtension> _logger; private readonly ILogger<LdapObjectExtension> _logger;
public LdapObjectExtension(TenantUtil tenantUtil, ILogger<LdapObjectExtension> logger)
public LdapObjectExtension(TenantUtil tenantUtil, SettingsManager settingsManager, ILogger<LdapObjectExtension> logger)
{ {
_tenantUtil = tenantUtil; _tenantUtil = tenantUtil;
_settingsManager = settingsManager;
_logger = logger; _logger = logger;
} }
public string GetAttribute(LdapObject ldapObject, string attribute) public string GetAttribute(LdapObject ldapObject, string attribute)
@ -145,6 +148,8 @@ public class LdapObjectExtension
var emails = GetContacts(ldapUser, Mapping.AdditionalMail, settings); var emails = GetContacts(ldapUser, Mapping.AdditionalMail, settings);
var skype = GetContacts(ldapUser, Mapping.Skype, settings); var skype = GetContacts(ldapUser, Mapping.Skype, settings);
var quotaSettings = _settingsManager.Load<TenantUserQuotaSettings>();
var quota = settings.LdapMapping.ContainsKey(Mapping.UserQuotaLimit) ? ByteConverter.ConvertSizeToBytes(GetAttribute(ldapUser, settings.LdapMapping[Mapping.UserQuotaLimit])) : quotaSettings.DefaultUserQuota;
if (string.IsNullOrEmpty(userName)) if (string.IsNullOrEmpty(userName))
{ {
@ -168,7 +173,8 @@ public class LdapObjectExtension
Title = !string.IsNullOrEmpty(title) ? title : string.Empty, Title = !string.IsNullOrEmpty(title) ? title : string.Empty,
Location = !string.IsNullOrEmpty(location) ? location : string.Empty, Location = !string.IsNullOrEmpty(location) ? location : string.Empty,
WorkFromDate = _tenantUtil.DateTimeNow(), WorkFromDate = _tenantUtil.DateTimeNow(),
ContactsList = contacts ContactsList = contacts,
LdapQouta = quota
}; };
if (!string.IsNullOrEmpty(firstName)) if (!string.IsNullOrEmpty(firstName))

View File

@ -57,7 +57,9 @@ public class LdapSettings : ISettings<LdapSettings>, ICloneable
AdditionalPhone, AdditionalPhone,
AdditionalMobilePhone, AdditionalMobilePhone,
AdditionalMail, AdditionalMail,
Skype Skype,
UserQuotaLimit
} }
public enum AccessRight public enum AccessRight

View File

@ -69,6 +69,7 @@ global using ASC.Security.Cryptography;
global using ASC.Web.Core; global using ASC.Web.Core;
global using ASC.Web.Core.PublicResources; global using ASC.Web.Core.PublicResources;
global using ASC.Web.Core.Users; global using ASC.Web.Core.Users;
global using ASC.Web.Core.Utility;
global using ASC.Web.Studio.Utility; global using ASC.Web.Studio.Utility;
global using Microsoft.EntityFrameworkCore; global using Microsoft.EntityFrameworkCore;
@ -81,3 +82,5 @@ global using Novell.Directory.Ldap;
global using Novell.Directory.Ldap.Controls; global using Novell.Directory.Ldap.Controls;
global using Novell.Directory.Ldap.Rfc2251; global using Novell.Directory.Ldap.Rfc2251;
global using Novell.Directory.Ldap.Utilclass; global using Novell.Directory.Ldap.Utilclass;
global using ByteConverter = ASC.Core.Common.ByteConverter;

View File

@ -155,6 +155,13 @@ public class LdapUserManager
portalUserInfo = _userManager.SaveUserInfo(ldapUserInfo); portalUserInfo = _userManager.SaveUserInfo(ldapUserInfo);
var quotaSettings = _settingsManager.Load<TenantUserQuotaSettings>();
if (quotaSettings.EnableUserQuota)
{
_settingsManager.SaveForUser(new UserQuotaSettings { UserQuota = ldapUserInfo.LdapQouta }, ldapUserInfo.Id);
}
var passwordHash = LdapUtils.GeneratePassword(); var passwordHash = LdapUtils.GeneratePassword();
_logger.DebugSetUserPassword(portalUserInfo.Id); _logger.DebugSetUserPassword(portalUserInfo.Id);

View File

@ -56,6 +56,8 @@ public class EmployeeFullDto : EmployeeDto
public MobilePhoneActivationStatus MobilePhoneActivationStatus { get; set; } public MobilePhoneActivationStatus MobilePhoneActivationStatus { get; set; }
public bool IsSSO { get; set; } public bool IsSSO { get; set; }
public DarkThemeSettingsEnum? Theme { get; set; } public DarkThemeSettingsEnum? Theme { get; set; }
public long QuotaLimit { get; set; }
public double UsedSpace { get; set; }
public static new EmployeeFullDto GetSample() public static new EmployeeFullDto GetSample()
{ {
@ -97,6 +99,8 @@ public class EmployeeFullDtoHelper : EmployeeDtoHelper
private readonly WebItemSecurity _webItemSecurity; private readonly WebItemSecurity _webItemSecurity;
private readonly ApiDateTimeHelper _apiDateTimeHelper; private readonly ApiDateTimeHelper _apiDateTimeHelper;
private readonly WebItemManager _webItemManager; private readonly WebItemManager _webItemManager;
private readonly SettingsManager _settingsManager;
private readonly IQuotaService _quotaService;
public EmployeeFullDtoHelper( public EmployeeFullDtoHelper(
ApiContext context, ApiContext context,
@ -106,13 +110,17 @@ public class EmployeeFullDtoHelper : EmployeeDtoHelper
CommonLinkUtility commonLinkUtility, CommonLinkUtility commonLinkUtility,
DisplayUserSettingsHelper displayUserSettingsHelper, DisplayUserSettingsHelper displayUserSettingsHelper,
ApiDateTimeHelper apiDateTimeHelper, ApiDateTimeHelper apiDateTimeHelper,
WebItemManager webItemManager) WebItemManager webItemManager,
SettingsManager settingsManager,
IQuotaService quotaService)
: base(context, displayUserSettingsHelper, userPhotoManager, commonLinkUtility, userManager) : base(context, displayUserSettingsHelper, userPhotoManager, commonLinkUtility, userManager)
{ {
_context = context; _context = context;
_webItemSecurity = webItemSecurity; _webItemSecurity = webItemSecurity;
_apiDateTimeHelper = apiDateTimeHelper; _apiDateTimeHelper = apiDateTimeHelper;
_webItemManager = webItemManager; _webItemManager = webItemManager;
_settingsManager = settingsManager;
_quotaService = quotaService;
} }
public static Expression<Func<User, UserInfo>> GetExpression(ApiContext apiContext) public static Expression<Func<User, UserInfo>> GetExpression(ApiContext apiContext)
@ -187,10 +195,20 @@ public class EmployeeFullDtoHelper : EmployeeDtoHelper
IsOwner = userInfo.IsOwner(_context.Tenant), IsOwner = userInfo.IsOwner(_context.Tenant),
IsLDAP = userInfo.IsLDAP(), IsLDAP = userInfo.IsLDAP(),
IsSSO = userInfo.IsSSO() IsSSO = userInfo.IsSSO()
}; };
await Init(result, userInfo); await Init(result, userInfo);
var quotaSettings = _settingsManager.Load<TenantUserQuotaSettings>();
if (quotaSettings.EnableUserQuota)
{
result.UsedSpace = Math.Max(0, _quotaService.FindUserQuotaRows(_context.Tenant.Id, userInfo.Id).Where(r => !string.IsNullOrEmpty(r.Tag)).Sum(r => r.Counter));
var userQuotaSettings = _settingsManager.LoadForUser<UserQuotaSettings>(userInfo);
result.QuotaLimit = userQuotaSettings != null ? userQuotaSettings.UserQuota : quotaSettings.DefaultUserQuota;
}
if (userInfo.Sex.HasValue) if (userInfo.Sex.HasValue)
{ {
result.Sex = userInfo.Sex.Value ? "male" : "female"; result.Sex = userInfo.Sex.Value ? "male" : "female";

View File

@ -41,4 +41,46 @@ public static class ByteConverter
return bytes < MB ? bytes * MB : bytes; return bytes < MB ? bytes * MB : bytes;
} }
public static long ConvertSizeToBytes(string size)
{
long bytes = 0;
try
{
var regex = new Regex(@"\d+|\w+");
var matches = regex.Matches(size);
if (matches.Count > 0)
{
var num = int.Parse(matches[0].Value);
var unit = matches[1].Value.ToLower();
switch (unit)
{
case "bytes":
bytes = num;
break;
case "kb":
bytes = num * 1024;
break;
case "mb":
bytes = Convert.ToInt64(num * Math.Pow(1024, 2));
break;
case "gb":
bytes = Convert.ToInt64(num * Math.Pow(1024, 3));
break;
case "tb":
bytes = Convert.ToInt64(num * Math.Pow(1024, 4));
break;
case "pb":
bytes = Convert.ToInt64(num * Math.Pow(1024, 5));
break;
}
return bytes;
}
}
catch (Exception)
{
}
return -1;
}
} }

View File

@ -31,6 +31,7 @@ class QuotaServiceCache
{ {
internal const string KeyQuota = "quota"; internal const string KeyQuota = "quota";
internal const string KeyQuotaRows = "quotarows"; internal const string KeyQuotaRows = "quotarows";
internal const string KeyUserQuotaRows = "userquotarows";
internal readonly ICache Cache; internal readonly ICache Cache;
internal readonly ICacheNotify<QuotaCacheItem> CacheNotify; internal readonly ICacheNotify<QuotaCacheItem> CacheNotify;
internal readonly bool QuotaCacheEnabled; internal readonly bool QuotaCacheEnabled;
@ -122,7 +123,12 @@ class CachedQuotaService : IQuotaService
public void SetTenantQuotaRow(TenantQuotaRow row, bool exchange) public void SetTenantQuotaRow(TenantQuotaRow row, bool exchange)
{ {
Service.SetTenantQuotaRow(row, exchange); Service.SetTenantQuotaRow(row, exchange);
CacheNotify.Publish(new QuotaCacheItem { Key = GetKey(row.Tenant) }, CacheNotifyAction.InsertOrUpdate); CacheNotify.Publish(new QuotaCacheItem { Key = GetKey(row.Tenant) }, CacheNotifyAction.Any);
if (row.UserId != Guid.Empty)
{
CacheNotify.Publish(new QuotaCacheItem { Key = GetKey(row.Tenant, row.UserId) }, CacheNotifyAction.Any);
}
} }
public IEnumerable<TenantQuotaRow> FindTenantQuotaRows(int tenantId) public IEnumerable<TenantQuotaRow> FindTenantQuotaRows(int tenantId)
@ -139,8 +145,27 @@ class CachedQuotaService : IQuotaService
return result; return result;
} }
public IEnumerable<TenantQuotaRow> FindUserQuotaRows(int tenantId, Guid userId)
{
var key = GetKey(tenantId, userId);
var result = Cache.Get<IEnumerable<TenantQuotaRow>>(key);
if (result == null)
{
result = Service.FindUserQuotaRows(tenantId, userId);
Cache.Insert(key, result, DateTime.UtcNow.Add(_cacheExpiration));
}
return result;
}
public string GetKey(int tenant) public string GetKey(int tenant)
{ {
return QuotaServiceCache.KeyQuotaRows + tenant; return QuotaServiceCache.KeyQuotaRows + tenant;
} }
public string GetKey(int tenant, Guid userId)
{
return QuotaServiceCache.KeyQuotaRows + tenant + userId;
}
} }

View File

@ -31,6 +31,7 @@ public interface IQuotaService
{ {
IEnumerable<TenantQuota> GetTenantQuotas(); IEnumerable<TenantQuota> GetTenantQuotas();
IEnumerable<TenantQuotaRow> FindTenantQuotaRows(int tenantId); IEnumerable<TenantQuotaRow> FindTenantQuotaRows(int tenantId);
IEnumerable<TenantQuotaRow> FindUserQuotaRows(int tenantId, Guid userId);
TenantQuota GetTenantQuota(int id); TenantQuota GetTenantQuota(int id);
TenantQuota SaveTenantQuota(TenantQuota quota); TenantQuota SaveTenantQuota(TenantQuota quota);
void RemoveTenantQuota(int id); void RemoveTenantQuota(int id);

View File

@ -71,6 +71,7 @@ public sealed class UserInfo : IDirectRecipient, ICloneable, IMapFrom<User>
public string MobilePhone { get; set; } public string MobilePhone { get; set; }
public MobilePhoneActivationStatus MobilePhoneActivationStatus { get; set; } public MobilePhoneActivationStatus MobilePhoneActivationStatus { get; set; }
public string Sid { get; set; } // LDAP user identificator public string Sid { get; set; } // LDAP user identificator
public long LdapQouta { get; set; } // LDAP user quota attribute
public string SsoNameId { get; set; } // SSO SAML user identificator public string SsoNameId { get; set; } // SSO SAML user identificator
public string SsoSessionId { get; set; } // SSO SAML user session identificator public string SsoSessionId { get; set; } // SSO SAML user session identificator
public DateTime CreateDate { get; set; } public DateTime CreateDate { get; set; }

View File

@ -31,7 +31,6 @@ class DbQuotaService : IQuotaService
{ {
private readonly IDbContextFactory<CoreDbContext> _dbContextFactory; private readonly IDbContextFactory<CoreDbContext> _dbContextFactory;
private readonly IMapper _mapper; private readonly IMapper _mapper;
public DbQuotaService(IDbContextFactory<CoreDbContext> dbContextManager, IMapper mapper) public DbQuotaService(IDbContextFactory<CoreDbContext> dbContextManager, IMapper mapper)
{ {
_dbContextFactory = dbContextManager; _dbContextFactory = dbContextManager;
@ -102,27 +101,46 @@ class DbQuotaService : IQuotaService
using var coreDbContext = _dbContextFactory.CreateDbContext(); using var coreDbContext = _dbContextFactory.CreateDbContext();
using var tx = coreDbContext.Database.BeginTransaction(); using var tx = coreDbContext.Database.BeginTransaction();
var counter = coreDbContext.QuotaRows AddQuota(coreDbContext, Guid.Empty);
.Where(r => r.Path == row.Path && r.Tenant == row.Tenant)
if (row.UserId != Guid.Empty)
{
AddQuota(coreDbContext, row.UserId);
}
tx.Commit();
});
void AddQuota(CoreDbContext coreDbContext, Guid userId)
{
var dbTenantQuotaRow = _mapper.Map<TenantQuotaRow, DbQuotaRow>(row);
dbTenantQuotaRow.UserId = userId;
if (exchange)
{
var counter = coreDbContext.QuotaRows
.Where(r => r.Path == row.Path && r.Tenant == row.Tenant && r.UserId == userId)
.Select(r => r.Counter) .Select(r => r.Counter)
.Take(1) .Take(1)
.FirstOrDefault(); .FirstOrDefault();
var dbQuotaRow = _mapper.Map<TenantQuotaRow, DbQuotaRow>(row); dbTenantQuotaRow.Counter = counter + row.Counter;
dbQuotaRow.Counter = exchange ? counter + row.Counter : row.Counter; }
dbQuotaRow.LastModified = DateTime.UtcNow;
coreDbContext.AddOrUpdate(r => r.QuotaRows, dbQuotaRow); coreDbContext.AddOrUpdate(r => r.QuotaRows, dbTenantQuotaRow);
coreDbContext.SaveChanges(); coreDbContext.SaveChanges();
}
tx.Commit();
});
} }
public IEnumerable<TenantQuotaRow> FindTenantQuotaRows(int tenantId) public IEnumerable<TenantQuotaRow> FindTenantQuotaRows(int tenantId)
{
return FindUserQuotaRows(tenantId, Guid.Empty);
}
public IEnumerable<TenantQuotaRow> FindUserQuotaRows(int tenantId, Guid userId)
{ {
using var coreDbContext = _dbContextFactory.CreateDbContext(); using var coreDbContext = _dbContextFactory.CreateDbContext();
IQueryable<DbQuotaRow> q = coreDbContext.QuotaRows; var q = coreDbContext.QuotaRows.Where(r => r.UserId == userId);
if (tenantId != Tenant.DefaultTenant) if (tenantId != Tenant.DefaultTenant)
{ {

View File

@ -254,6 +254,11 @@ public class DbSettingsManager
return LoadSettingsFor<T>(TenantID, userId); return LoadSettingsFor<T>(TenantID, userId);
} }
public T LoadForUser<T>(UserInfo user) where T : class, ISettings<T>
{
return LoadSettingsFor<T>(TenantID, user.Id);
}
public T LoadForDefaultTenant<T>() where T : class, ISettings<T> public T LoadForDefaultTenant<T>() where T : class, ISettings<T>
{ {
return LoadForTenant<T>(Tenant.DefaultTenant); return LoadForTenant<T>(Tenant.DefaultTenant);
@ -279,6 +284,11 @@ public class DbSettingsManager
return SaveSettingsFor(data, TenantID, userId); return SaveSettingsFor(data, TenantID, userId);
} }
public bool SaveForUser<T>(T data, UserInfo user) where T : class, ISettings<T>
{
return SaveSettingsFor(data, TenantID, user.Id);
}
public bool SaveForDefaultTenant<T>(T data) where T : class, ISettings<T> public bool SaveForDefaultTenant<T>(T data) where T : class, ISettings<T>
{ {
return SaveForTenant(data, Tenant.DefaultTenant); return SaveForTenant(data, Tenant.DefaultTenant);

View File

@ -33,10 +33,10 @@ public class DbQuotaRow : BaseEntity, IMapFrom<TenantQuotaRow>
public long Counter { get; set; } public long Counter { get; set; }
public string Tag { get; set; } public string Tag { get; set; }
public DateTime LastModified { get; set; } public DateTime LastModified { get; set; }
public Guid UserId { get; set; }
public override object[] GetKeys() public override object[] GetKeys()
{ {
return new object[] { Tenant, Path }; return new object[] { Tenant, UserId, Path };
} }
} }
@ -55,7 +55,7 @@ public static class DbQuotaRowExtension
{ {
modelBuilder.Entity<DbQuotaRow>(entity => modelBuilder.Entity<DbQuotaRow>(entity =>
{ {
entity.HasKey(e => new { e.Tenant, e.Path }) entity.HasKey(e => new { e.Tenant, e.UserId, e.Path })
.HasName("PRIMARY"); .HasName("PRIMARY");
entity.ToTable("tenants_quotarow") entity.ToTable("tenants_quotarow")
@ -85,6 +85,12 @@ public static class DbQuotaRowExtension
.HasColumnType("varchar(1024)") .HasColumnType("varchar(1024)")
.HasCharSet("utf8") .HasCharSet("utf8")
.UseCollation("utf8_general_ci"); .UseCollation("utf8_general_ci");
entity.Property(e => e.UserId)
.HasColumnName("user_id")
.HasColumnType("char(36)")
.HasCharSet("utf8")
.UseCollation("utf8_general_ci");
}); });
} }
public static void PgSqlAddDbQuotaRow(this ModelBuilder modelBuilder) public static void PgSqlAddDbQuotaRow(this ModelBuilder modelBuilder)
@ -117,6 +123,11 @@ public static class DbQuotaRowExtension
.HasColumnName("tag") .HasColumnName("tag")
.HasMaxLength(1024) .HasMaxLength(1024)
.HasDefaultValueSql("'0'"); .HasDefaultValueSql("'0'");
entity.Property(e => e.UserId)
.HasColumnName("user_id")
.HasMaxLength(36)
.HasDefaultValueSql("NULL");
}); });
} }
} }

View File

@ -33,4 +33,6 @@ public class TenantQuotaRow : IMapFrom<DbQuotaRow>
public string Path { get; set; } public string Path { get; set; }
public long Counter { get; set; } public long Counter { get; set; }
public string Tag { get; set; } public string Tag { get; set; }
public Guid UserId { get; set; }
public DateTime LastModified { get; set; }
} }

View File

@ -0,0 +1,50 @@
// (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.Core.Tenants;
[Serializable]
public class TenantUserQuotaSettings : ISettings<TenantUserQuotaSettings>
{
public bool EnableUserQuota { get; set; }
public long DefaultUserQuota { get; set; }
public TenantUserQuotaSettings GetDefault()
{
return new TenantUserQuotaSettings
{
EnableUserQuota = false,
DefaultUserQuota = -1
};
}
[JsonIgnore]
public Guid ID
{
get { return new Guid("{5FE28053-BCD4-466B-8A4B-71B612F0D6FC}"); }
}
}

View File

@ -73,7 +73,6 @@ public sealed class Constants
private readonly IConfiguration _configuration; private readonly IConfiguration _configuration;
#region system group and category groups #region system group and category groups
public static readonly Guid SysGroupCategoryId = new Guid("{7717039D-FBE9-45ad-81C1-68A1AA10CE1F}"); public static readonly Guid SysGroupCategoryId = new Guid("{7717039D-FBE9-45ad-81C1-68A1AA10CE1F}");

View File

@ -0,0 +1,47 @@
// (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.Core.Users;
[Serializable]
public class UserQuotaSettings : ISettings<UserQuotaSettings>
{
public long UserQuota { get; set; }
public UserQuotaSettings GetDefault()
{
return new UserQuotaSettings
{
UserQuota = -1
};
}
[JsonIgnore]
public Guid ID
{
get { return new Guid("{5A097CFA-1A8E-45CB-A4BB-FE8D2B5E5908}"); }
}
}

View File

@ -139,6 +139,8 @@ public class StorageFactory
private readonly SettingsManager _settingsManager; private readonly SettingsManager _settingsManager;
private readonly StorageSettingsHelper _storageSettingsHelper; private readonly StorageSettingsHelper _storageSettingsHelper;
private readonly TenantManager _tenantManager; private readonly TenantManager _tenantManager;
private readonly UserManager _userManager;
private readonly AuthContext _authContext;
private readonly CoreBaseSettings _coreBaseSettings; private readonly CoreBaseSettings _coreBaseSettings;
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
@ -148,6 +150,8 @@ public class StorageFactory
SettingsManager settingsManager, SettingsManager settingsManager,
StorageSettingsHelper storageSettingsHelper, StorageSettingsHelper storageSettingsHelper,
TenantManager tenantManager, TenantManager tenantManager,
UserManager userManager,
AuthContext authContext,
CoreBaseSettings coreBaseSettings) CoreBaseSettings coreBaseSettings)
{ {
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
@ -155,6 +159,8 @@ public class StorageFactory
_settingsManager = settingsManager; _settingsManager = settingsManager;
_storageSettingsHelper = storageSettingsHelper; _storageSettingsHelper = storageSettingsHelper;
_tenantManager = tenantManager; _tenantManager = tenantManager;
_userManager = userManager;
_authContext = authContext;
_coreBaseSettings = coreBaseSettings; _coreBaseSettings = coreBaseSettings;
} }
@ -167,7 +173,7 @@ public class StorageFactory
{ {
int.TryParse(tenant, out var tenantId); int.TryParse(tenant, out var tenantId);
return GetStorage(configpath, tenant, module, new TenantQuotaController(tenantId, _tenantManager)); return GetStorage(configpath, tenant, module, new TenantQuotaController(tenantId, _tenantManager, _authContext));
} }
public IDataStore GetStorage(string configpath, string tenant, string module, IQuotaController controller) public IDataStore GetStorage(string configpath, string tenant, string module, IQuotaController controller)
@ -214,7 +220,7 @@ public class StorageFactory
int.TryParse(tenant, out var tenantId); int.TryParse(tenant, out var tenantId);
return GetDataStore(tenant, module, consumer, new TenantQuotaController(tenantId, _tenantManager)); return GetDataStore(tenant, module, consumer, new TenantQuotaController(tenantId, _tenantManager, _authContext));
} }
private IDataStore GetDataStore(string tenant, string module, DataStoreConsumer consumer, IQuotaController controller) private IDataStore GetDataStore(string tenant, string module, DataStoreConsumer consumer, IQuotaController controller)

View File

@ -44,16 +44,18 @@ public class TenantQuotaController : IQuotaController
private readonly int _tenant; private readonly int _tenant;
private readonly TenantManager _tenantManager; private readonly TenantManager _tenantManager;
private readonly AuthContext _authContext;
private readonly Lazy<long> _lazyCurrentSize; private readonly Lazy<long> _lazyCurrentSize;
private long _currentSize; private long _currentSize;
public TenantQuotaController(int tenant, TenantManager tenantManager) public TenantQuotaController(int tenant, TenantManager tenantManager, AuthContext authContext)
{ {
_tenant = tenant; _tenant = tenant;
_tenantManager = tenantManager; _tenantManager = tenantManager;
_lazyCurrentSize = new Lazy<long>(() => _tenantManager.FindTenantQuotaRows(tenant) _lazyCurrentSize = new Lazy<long>(() => _tenantManager.FindTenantQuotaRows(tenant)
.Where(r => UsedInQuota(r.Tag)) .Where(r => UsedInQuota(r.Tag))
.Sum(r => r.Counter)); .Sum(r => r.Counter));
_authContext = authContext;
} }
#region IQuotaController Members #region IQuotaController Members
@ -67,7 +69,7 @@ public class TenantQuotaController : IQuotaController
CurrentSize += size; CurrentSize += size;
} }
SetTenantQuotaRow(module, domain, size, dataTag, true); SetTenantQuotaRow(module, domain, size, dataTag, true, _authContext.CurrentAccount.ID);
} }
public void QuotaUsedDelete(string module, string domain, string dataTag, long size) public void QuotaUsedDelete(string module, string domain, string dataTag, long size)
@ -78,7 +80,7 @@ public class TenantQuotaController : IQuotaController
CurrentSize += size; CurrentSize += size;
} }
SetTenantQuotaRow(module, domain, size, dataTag, true); SetTenantQuotaRow(module, domain, size, dataTag, true, _authContext.CurrentAccount.ID);
} }
public void QuotaUsedSet(string module, string domain, string dataTag, long size) public void QuotaUsedSet(string module, string domain, string dataTag, long size)
@ -89,7 +91,7 @@ public class TenantQuotaController : IQuotaController
CurrentSize += size; CurrentSize += size;
} }
SetTenantQuotaRow(module, domain, size, dataTag, false); SetTenantQuotaRow(module, domain, size, dataTag, false, Guid.Empty);
} }
public void QuotaUsedCheck(long size) public void QuotaUsedCheck(long size)
@ -120,11 +122,12 @@ public class TenantQuotaController : IQuotaController
return CurrentSize; return CurrentSize;
} }
private void SetTenantQuotaRow(string module, string domain, long size, string dataTag, bool exchange) private void SetTenantQuotaRow(string module, string domain, long size, string dataTag, bool exchange, Guid userId)
{ {
_tenantManager.SetTenantQuotaRow( _tenantManager.SetTenantQuotaRow(
new TenantQuotaRow { Tenant = _tenant, Path = $"/{module}/{domain}", Counter = size, Tag = dataTag }, new TenantQuotaRow { Tenant = _tenant, Path = $"/{module}/{domain}", Counter = size, Tag = dataTag, UserId = userId, LastModified = DateTime.UtcNow },
exchange); exchange);
} }
private bool UsedInQuota(string tag) private bool UsedInQuota(string tag)

View File

@ -0,0 +1,223 @@
// <auto-generated />
using System;
using ASC.Core.Common.EF;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace ASC.Migrations.MySql.Migrations.CoreDb
{
[DbContext(typeof(CoreDbContext))]
[Migration("20221007105933_CoreDbContext_Upgrade1")]
partial class CoreDbContext_Upgrade1
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.7")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("ASC.Core.Common.EF.DbButton", b =>
{
b.Property<int>("TariffId")
.HasColumnType("int")
.HasColumnName("tariff_id");
b.Property<string>("PartnerId")
.HasColumnType("varchar(50)")
.HasColumnName("partner_id")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<string>("ButtonUrl")
.IsRequired()
.HasColumnType("text")
.HasColumnName("button_url")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.HasKey("TariffId", "PartnerId")
.HasName("PRIMARY");
b.ToTable("tenants_buttons", (string)null);
b.HasAnnotation("MySql:CharSet", "utf8");
});
modelBuilder.Entity("ASC.Core.Common.EF.DbQuota", b =>
{
b.Property<int>("Tenant")
.HasColumnType("int")
.HasColumnName("tenant");
b.Property<int>("ActiveUsers")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasColumnName("active_users")
.HasDefaultValueSql("'0'");
b.Property<string>("AvangateId")
.HasColumnType("varchar(128)")
.HasColumnName("avangate_id")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<string>("Description")
.HasColumnType("varchar(128)")
.HasColumnName("description")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<string>("Features")
.HasColumnType("text")
.HasColumnName("features");
b.Property<long>("MaxFileSize")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasColumnName("max_file_size")
.HasDefaultValueSql("'0'");
b.Property<long>("MaxTotalSize")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasColumnName("max_total_size")
.HasDefaultValueSql("'0'");
b.Property<string>("Name")
.HasColumnType("varchar(128)")
.HasColumnName("name")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<decimal>("Price")
.ValueGeneratedOnAdd()
.HasColumnType("decimal(10,2)")
.HasColumnName("price")
.HasDefaultValueSql("'0.00'");
b.Property<bool>("Visible")
.ValueGeneratedOnAdd()
.HasColumnType("tinyint(1)")
.HasColumnName("visible")
.HasDefaultValueSql("'0'");
b.HasKey("Tenant")
.HasName("PRIMARY");
b.ToTable("tenants_quota", (string)null);
b.HasAnnotation("MySql:CharSet", "utf8");
b.HasData(
new
{
Tenant = -1,
ActiveUsers = 10000,
AvangateId = "0",
Features = "domain,audit,controlpanel,healthcheck,ldap,sso,whitelabel,branding,ssbranding,update,support,portals:10000,discencryption,privacyroom,restore",
MaxFileSize = 102400L,
MaxTotalSize = 10995116277760L,
Name = "default",
Price = 0m,
Visible = false
});
});
modelBuilder.Entity("ASC.Core.Common.EF.DbQuotaRow", b =>
{
b.Property<int>("Tenant")
.HasColumnType("int")
.HasColumnName("tenant");
b.Property<Guid>("UserId")
.HasColumnType("char(36)")
.HasColumnName("user_id")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<string>("Path")
.HasColumnType("varchar(255)")
.HasColumnName("path")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<long>("Counter")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasColumnName("counter")
.HasDefaultValueSql("'0'");
b.Property<DateTime>("LastModified")
.HasColumnType("timestamp")
.HasColumnName("last_modified");
b.Property<string>("Tag")
.HasColumnType("varchar(1024)")
.HasColumnName("tag")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.HasKey("Tenant", "UserId", "Path")
.HasName("PRIMARY");
b.HasIndex("LastModified")
.HasDatabaseName("last_modified");
b.ToTable("tenants_quotarow", (string)null);
b.HasAnnotation("MySql:CharSet", "utf8");
});
modelBuilder.Entity("ASC.Core.Common.EF.DbTariff", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasColumnName("id");
b.Property<string>("Comment")
.HasColumnType("varchar(255)")
.HasColumnName("comment")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<DateTime>("CreateOn")
.HasColumnType("timestamp")
.HasColumnName("create_on");
b.Property<int>("Quantity")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasColumnName("quantity")
.HasDefaultValueSql("'1'");
b.Property<DateTime>("Stamp")
.HasColumnType("datetime")
.HasColumnName("stamp");
b.Property<int>("Tariff")
.HasColumnType("int")
.HasColumnName("tariff");
b.Property<int>("Tenant")
.HasColumnType("int")
.HasColumnName("tenant");
b.HasKey("Id");
b.HasIndex("Tenant")
.HasDatabaseName("tenant");
b.ToTable("tenants_tariff", (string)null);
b.HasAnnotation("MySql:CharSet", "utf8");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,47 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ASC.Migrations.MySql.Migrations.CoreDb
{
public partial class CoreDbContext_Upgrade1 : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropPrimaryKey(
name: "PRIMARY",
table: "tenants_quotarow");
migrationBuilder.AddColumn<Guid>(
name: "user_id",
table: "tenants_quotarow",
type: "char(36)",
nullable: false,
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"),
collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8");
migrationBuilder.AddPrimaryKey(
name: "PRIMARY",
table: "tenants_quotarow",
columns: new[] { "tenant", "user_id", "path" });
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropPrimaryKey(
name: "PRIMARY",
table: "tenants_quotarow");
migrationBuilder.DropColumn(
name: "user_id",
table: "tenants_quotarow");
migrationBuilder.AddPrimaryKey(
name: "PRIMARY",
table: "tenants_quotarow",
columns: new[] { "tenant", "path" });
}
}
}

View File

@ -16,7 +16,7 @@ namespace ASC.Migrations.MySql.Migrations
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("ProductVersion", "6.0.4") .HasAnnotation("ProductVersion", "6.0.7")
.HasAnnotation("Relational:MaxIdentifierLength", 64); .HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("ASC.Core.Common.EF.DbButton", b => modelBuilder.Entity("ASC.Core.Common.EF.DbButton", b =>
@ -121,7 +121,7 @@ namespace ASC.Migrations.MySql.Migrations
MaxFileSize = 102400L, MaxFileSize = 102400L,
MaxTotalSize = 10995116277760L, MaxTotalSize = 10995116277760L,
Name = "default", Name = "default",
Price = 0.00m, Price = 0m,
Visible = false Visible = false
}); });
}); });
@ -132,6 +132,12 @@ namespace ASC.Migrations.MySql.Migrations
.HasColumnType("int") .HasColumnType("int")
.HasColumnName("tenant"); .HasColumnName("tenant");
b.Property<Guid>("UserId")
.HasColumnType("char(36)")
.HasColumnName("user_id")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<string>("Path") b.Property<string>("Path")
.HasColumnType("varchar(255)") .HasColumnType("varchar(255)")
.HasColumnName("path") .HasColumnName("path")
@ -154,7 +160,7 @@ namespace ASC.Migrations.MySql.Migrations
.UseCollation("utf8_general_ci") .UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8"); .HasAnnotation("MySql:CharSet", "utf8");
b.HasKey("Tenant", "Path") b.HasKey("Tenant", "UserId", "Path")
.HasName("PRIMARY"); .HasName("PRIMARY");
b.HasIndex("LastModified") b.HasIndex("LastModified")

View File

@ -21,376 +21,6 @@ namespace ASC.Migrations.MySql.Migrations
.HasAnnotation("ProductVersion", "6.0.4") .HasAnnotation("ProductVersion", "6.0.4")
.HasAnnotation("Relational:MaxIdentifierLength", 64); .HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("ASC.Core.Common.EF.Model.DbTenant", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasColumnName("id");
b.Property<string>("Alias")
.IsRequired()
.HasColumnType("varchar(100)")
.HasColumnName("alias")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<bool>("Calls")
.ValueGeneratedOnAdd()
.HasColumnType("tinyint(1)")
.HasColumnName("calls")
.HasDefaultValueSql("'1'");
b.Property<DateTime>("CreationDateTime")
.HasColumnType("datetime")
.HasColumnName("creationdatetime");
b.Property<int>("Industry")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasColumnName("industry")
.HasDefaultValueSql("'0'");
b.Property<string>("Language")
.IsRequired()
.ValueGeneratedOnAdd()
.HasColumnType("char(10)")
.HasColumnName("language")
.HasDefaultValueSql("'en-US'")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<DateTime>("LastModified")
.HasColumnType("timestamp")
.HasColumnName("last_modified");
b.Property<string>("MappedDomain")
.HasColumnType("varchar(100)")
.HasColumnName("mappeddomain")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("varchar(255)")
.HasColumnName("name")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<string>("OwnerId")
.HasColumnType("varchar(38)")
.HasColumnName("owner_id")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<string>("PaymentId")
.HasColumnType("varchar(38)")
.HasColumnName("payment_id")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<bool>("Spam")
.ValueGeneratedOnAdd()
.HasColumnType("tinyint(1)")
.HasColumnName("spam")
.HasDefaultValueSql("'1'");
b.Property<int>("Status")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasColumnName("status")
.HasDefaultValueSql("'0'");
b.Property<DateTime?>("StatusChanged")
.HasColumnType("datetime")
.HasColumnName("statuschanged");
b.Property<string>("TimeZone")
.HasColumnType("varchar(50)")
.HasColumnName("timezone")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<int>("TrustedDomainsEnabled")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasColumnName("trusteddomainsenabled")
.HasDefaultValueSql("'1'");
b.Property<string>("TrustedDomainsRaw")
.HasColumnType("varchar(1024)")
.HasColumnName("trusteddomains")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<int>("Version")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasColumnName("version")
.HasDefaultValueSql("'2'");
b.Property<DateTime?>("Version_Changed")
.HasColumnType("datetime")
.HasColumnName("version_changed");
b.HasKey("Id");
b.HasIndex("Alias")
.IsUnique()
.HasDatabaseName("alias");
b.HasIndex("LastModified")
.HasDatabaseName("last_modified");
b.HasIndex("MappedDomain")
.HasDatabaseName("mappeddomain");
b.HasIndex("Version")
.HasDatabaseName("version");
b.ToTable("tenants_tenants", (string)null);
b.HasAnnotation("MySql:CharSet", "utf8");
b.HasData(
new
{
Id = 1,
Alias = "localhost",
Calls = false,
CreationDateTime = new DateTime(2021, 3, 9, 17, 46, 59, 97, DateTimeKind.Utc).AddTicks(4317),
Industry = 0,
LastModified = new DateTime(2022, 7, 8, 0, 0, 0, 0, DateTimeKind.Unspecified),
Name = "Web Office",
OwnerId = "66faa6e4-f133-11ea-b126-00ffeec8b4ef",
Spam = false,
Status = 0,
TrustedDomainsEnabled = 0,
Version = 0
});
});
modelBuilder.Entity("ASC.Core.Common.EF.Model.DbWebstudioSettings", b =>
{
b.Property<int>("TenantId")
.HasColumnType("int")
.HasColumnName("TenantID");
b.Property<string>("Id")
.HasColumnType("varchar(64)")
.HasColumnName("ID")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<string>("UserId")
.HasColumnType("varchar(64)")
.HasColumnName("UserID")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<string>("Data")
.IsRequired()
.HasColumnType("mediumtext")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.HasKey("TenantId", "Id", "UserId")
.HasName("PRIMARY");
b.HasIndex("Id")
.HasDatabaseName("ID");
b.ToTable("webstudio_settings", (string)null);
b.HasAnnotation("MySql:CharSet", "utf8");
b.HasData(
new
{
TenantId = 1,
Id = "9a925891-1f92-4ed7-b277-d6f649739f06",
UserId = "00000000-0000-0000-0000-000000000000",
Data = "{\"Completed\":false}"
});
});
modelBuilder.Entity("ASC.Core.Common.EF.User", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("varchar(38)")
.HasColumnName("id")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<int>("ActivationStatus")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasColumnName("activation_status")
.HasDefaultValueSql("'0'");
b.Property<DateTime?>("BirthDate")
.HasColumnType("datetime")
.HasColumnName("bithdate");
b.Property<string>("Contacts")
.HasColumnType("varchar(1024)")
.HasColumnName("contacts")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<DateTime>("CreateDate")
.HasColumnType("timestamp")
.HasColumnName("create_on");
b.Property<string>("CultureName")
.HasColumnType("varchar(20)")
.HasColumnName("culture")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<string>("Email")
.HasColumnType("varchar(255)")
.HasColumnName("email")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("varchar(64)")
.HasColumnName("firstname")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<DateTime>("LastModified")
.HasColumnType("datetime")
.HasColumnName("last_modified");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("varchar(64)")
.HasColumnName("lastname")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<string>("Location")
.HasColumnType("varchar(255)")
.HasColumnName("location")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<string>("MobilePhone")
.HasColumnType("varchar(255)")
.HasColumnName("phone")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<int>("MobilePhoneActivation")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasColumnName("phone_activation")
.HasDefaultValueSql("'0'");
b.Property<string>("Notes")
.HasColumnType("varchar(512)")
.HasColumnName("notes")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<bool>("Removed")
.ValueGeneratedOnAdd()
.HasColumnType("tinyint(1)")
.HasColumnName("removed")
.HasDefaultValueSql("'0'");
b.Property<bool?>("Sex")
.HasColumnType("tinyint(1)")
.HasColumnName("sex");
b.Property<string>("Sid")
.HasColumnType("varchar(512)")
.HasColumnName("sid")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<string>("SsoNameId")
.HasColumnType("varchar(512)")
.HasColumnName("sso_name_id")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<string>("SsoSessionId")
.HasColumnType("varchar(512)")
.HasColumnName("sso_session_id")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<int>("Status")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasColumnName("status")
.HasDefaultValueSql("'1'");
b.Property<int>("Tenant")
.HasColumnType("int")
.HasColumnName("tenant");
b.Property<DateTime?>("TerminatedDate")
.HasColumnType("datetime")
.HasColumnName("terminateddate");
b.Property<string>("Title")
.HasColumnType("varchar(64)")
.HasColumnName("title")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<string>("UserName")
.IsRequired()
.HasColumnType("varchar(255)")
.HasColumnName("username")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<DateTime?>("WorkFromDate")
.HasColumnType("datetime")
.HasColumnName("workfromdate");
b.HasKey("Id")
.HasName("PRIMARY");
b.HasIndex("Email")
.HasDatabaseName("email");
b.HasIndex("LastModified")
.HasDatabaseName("last_modified");
b.HasIndex("Tenant", "UserName")
.HasDatabaseName("username");
b.ToTable("core_user", (string)null);
b.HasAnnotation("MySql:CharSet", "utf8");
b.HasData(
new
{
Id = "66faa6e4-f133-11ea-b126-00ffeec8b4ef",
ActivationStatus = 0,
CreateDate = new DateTime(2022, 7, 8, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "",
FirstName = "Administrator",
LastModified = new DateTime(2021, 3, 9, 9, 52, 55, 765, DateTimeKind.Utc).AddTicks(1420),
LastName = "",
MobilePhoneActivation = 0,
Removed = false,
Status = 1,
Tenant = 1,
UserName = "administrator",
WorkFromDate = new DateTime(2021, 3, 9, 9, 52, 55, 764, DateTimeKind.Utc).AddTicks(9157)
});
});
modelBuilder.Entity("ASC.MessagingSystem.EF.Model.AuditEvent", b => modelBuilder.Entity("ASC.MessagingSystem.EF.Model.AuditEvent", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")

View File

@ -1,4 +1,29 @@
using System; // (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
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
@ -45,56 +70,6 @@ namespace ASC.Migrations.MySql.Migrations
}) })
.Annotation("MySql:CharSet", "utf8"); .Annotation("MySql:CharSet", "utf8");
migrationBuilder.CreateTable(
name: "core_user",
columns: table => new
{
id = table.Column<string>(type: "varchar(38)", nullable: false, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
tenant = table.Column<int>(type: "int", nullable: false),
username = table.Column<string>(type: "varchar(255)", nullable: false, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
firstname = table.Column<string>(type: "varchar(64)", nullable: false, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
lastname = table.Column<string>(type: "varchar(64)", nullable: false, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
sex = table.Column<bool>(type: "tinyint(1)", nullable: true),
bithdate = table.Column<DateTime>(type: "datetime", nullable: true),
status = table.Column<int>(type: "int", nullable: false, defaultValueSql: "'1'"),
activation_status = table.Column<int>(type: "int", nullable: false, defaultValueSql: "'0'"),
email = table.Column<string>(type: "varchar(255)", nullable: true, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
workfromdate = table.Column<DateTime>(type: "datetime", nullable: true),
terminateddate = table.Column<DateTime>(type: "datetime", nullable: true),
title = table.Column<string>(type: "varchar(64)", nullable: true, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
culture = table.Column<string>(type: "varchar(20)", nullable: true, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
contacts = table.Column<string>(type: "varchar(1024)", nullable: true, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
phone = table.Column<string>(type: "varchar(255)", nullable: true, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
phone_activation = table.Column<int>(type: "int", nullable: false, defaultValueSql: "'0'"),
location = table.Column<string>(type: "varchar(255)", nullable: true, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
notes = table.Column<string>(type: "varchar(512)", nullable: true, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
sid = table.Column<string>(type: "varchar(512)", nullable: true, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
sso_name_id = table.Column<string>(type: "varchar(512)", nullable: true, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
sso_session_id = table.Column<string>(type: "varchar(512)", nullable: true, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
removed = table.Column<bool>(type: "tinyint(1)", nullable: false, defaultValueSql: "'0'"),
create_on = table.Column<DateTime>(type: "timestamp", nullable: false),
last_modified = table.Column<DateTime>(type: "datetime", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PRIMARY", x => x.id);
})
.Annotation("MySql:CharSet", "utf8");
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
name: "login_events", name: "login_events",
columns: table => new columns: table => new
@ -126,98 +101,11 @@ namespace ASC.Migrations.MySql.Migrations
}) })
.Annotation("MySql:CharSet", "utf8"); .Annotation("MySql:CharSet", "utf8");
migrationBuilder.CreateTable(
name: "tenants_tenants",
columns: table => new
{
id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
name = table.Column<string>(type: "varchar(255)", nullable: false, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
alias = table.Column<string>(type: "varchar(100)", nullable: false, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
mappeddomain = table.Column<string>(type: "varchar(100)", nullable: true, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
version = table.Column<int>(type: "int", nullable: false, defaultValueSql: "'2'"),
version_changed = table.Column<DateTime>(type: "datetime", nullable: true),
language = table.Column<string>(type: "char(10)", nullable: false, defaultValueSql: "'en-US'", collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
timezone = table.Column<string>(type: "varchar(50)", nullable: true, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
trusteddomains = table.Column<string>(type: "varchar(1024)", nullable: true, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
trusteddomainsenabled = table.Column<int>(type: "int", nullable: false, defaultValueSql: "'1'"),
status = table.Column<int>(type: "int", nullable: false, defaultValueSql: "'0'"),
statuschanged = table.Column<DateTime>(type: "datetime", nullable: true),
creationdatetime = table.Column<DateTime>(type: "datetime", nullable: false),
owner_id = table.Column<string>(type: "varchar(38)", nullable: true, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
payment_id = table.Column<string>(type: "varchar(38)", nullable: true, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
industry = table.Column<int>(type: "int", nullable: false, defaultValueSql: "'0'"),
last_modified = table.Column<DateTime>(type: "timestamp", nullable: false),
spam = table.Column<bool>(type: "tinyint(1)", nullable: false, defaultValueSql: "'1'"),
calls = table.Column<bool>(type: "tinyint(1)", nullable: false, defaultValueSql: "'1'")
},
constraints: table =>
{
table.PrimaryKey("PK_tenants_tenants", x => x.id);
})
.Annotation("MySql:CharSet", "utf8");
migrationBuilder.CreateTable(
name: "webstudio_settings",
columns: table => new
{
TenantID = table.Column<int>(type: "int", nullable: false),
ID = table.Column<string>(type: "varchar(64)", nullable: false, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
UserID = table.Column<string>(type: "varchar(64)", nullable: false, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
Data = table.Column<string>(type: "mediumtext", nullable: false, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8")
},
constraints: table =>
{
table.PrimaryKey("PRIMARY", x => new { x.TenantID, x.ID, x.UserID });
})
.Annotation("MySql:CharSet", "utf8");
migrationBuilder.InsertData(
table: "core_user",
columns: new[] { "id", "bithdate", "contacts", "create_on", "culture", "email", "firstname", "last_modified", "lastname", "location", "phone", "notes", "sex", "sid", "sso_name_id", "sso_session_id", "status", "tenant", "terminateddate", "title", "username", "workfromdate" },
values: new object[] { "66faa6e4-f133-11ea-b126-00ffeec8b4ef", null, null, new DateTime(2022, 7, 8, 0, 0, 0, 0, DateTimeKind.Unspecified), null, "", "Administrator", new DateTime(2021, 3, 9, 9, 52, 55, 765, DateTimeKind.Utc).AddTicks(1420), "", null, null, null, null, null, null, null, 1, 1, null, null, "administrator", new DateTime(2021, 3, 9, 9, 52, 55, 764, DateTimeKind.Utc).AddTicks(9157) });
migrationBuilder.InsertData(
table: "tenants_tenants",
columns: new[] { "id", "alias", "creationdatetime", "last_modified", "mappeddomain", "name", "owner_id", "payment_id", "statuschanged", "timezone", "trusteddomains", "version_changed" },
values: new object[] { 1, "localhost", new DateTime(2021, 3, 9, 17, 46, 59, 97, DateTimeKind.Utc).AddTicks(4317), new DateTime(2022, 7, 8, 0, 0, 0, 0, DateTimeKind.Unspecified), null, "Web Office", "66faa6e4-f133-11ea-b126-00ffeec8b4ef", null, null, null, null, null });
migrationBuilder.InsertData(
table: "webstudio_settings",
columns: new[] { "ID", "TenantID", "UserID", "Data" },
values: new object[] { "9a925891-1f92-4ed7-b277-d6f649739f06", 1, "00000000-0000-0000-0000-000000000000", "{\"Completed\":false}" });
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "date", name: "date",
table: "audit_events", table: "audit_events",
columns: new[] { "tenant_id", "date" }); columns: new[] { "tenant_id", "date" });
migrationBuilder.CreateIndex(
name: "email",
table: "core_user",
column: "email");
migrationBuilder.CreateIndex(
name: "last_modified",
table: "core_user",
column: "last_modified");
migrationBuilder.CreateIndex(
name: "username",
table: "core_user",
columns: new[] { "tenant", "username" });
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "date", name: "date",
table: "login_events", table: "login_events",
@ -227,32 +115,6 @@ namespace ASC.Migrations.MySql.Migrations
name: "tenant_id", name: "tenant_id",
table: "login_events", table: "login_events",
columns: new[] { "tenant_id", "user_id" }); columns: new[] { "tenant_id", "user_id" });
migrationBuilder.CreateIndex(
name: "alias",
table: "tenants_tenants",
column: "alias",
unique: true);
migrationBuilder.CreateIndex(
name: "last_modified",
table: "tenants_tenants",
column: "last_modified");
migrationBuilder.CreateIndex(
name: "mappeddomain",
table: "tenants_tenants",
column: "mappeddomain");
migrationBuilder.CreateIndex(
name: "version",
table: "tenants_tenants",
column: "version");
migrationBuilder.CreateIndex(
name: "ID",
table: "webstudio_settings",
column: "ID");
} }
protected override void Down(MigrationBuilder migrationBuilder) protected override void Down(MigrationBuilder migrationBuilder)
@ -260,17 +122,8 @@ namespace ASC.Migrations.MySql.Migrations
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "audit_events"); name: "audit_events");
migrationBuilder.DropTable(
name: "core_user");
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "login_events"); name: "login_events");
migrationBuilder.DropTable(
name: "tenants_tenants");
migrationBuilder.DropTable(
name: "webstudio_settings");
} }
} }
} }

View File

@ -16,7 +16,7 @@ namespace ASC.Migrations.MySql.Migrations
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("ProductVersion", "6.0.4") .HasAnnotation("ProductVersion", "6.0.7")
.HasAnnotation("Relational:MaxIdentifierLength", 64); .HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("ASC.Core.Common.EF.Model.DbTenant", b => modelBuilder.Entity("ASC.Core.Common.EF.Model.DbTenant", b =>

View File

@ -16,7 +16,7 @@ namespace ASC.Migrations.MySql.Migrations
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("ProductVersion", "6.0.4") .HasAnnotation("ProductVersion", "6.0.7")
.HasAnnotation("Relational:MaxIdentifierLength", 64); .HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("ASC.Core.Common.EF.Acl", b => modelBuilder.Entity("ASC.Core.Common.EF.Acl", b =>

View File

@ -0,0 +1,212 @@
// <auto-generated />
using System;
using ASC.Core.Common.EF;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace ASC.Migrations.PostgreSql.Migrations.CoreDb
{
[DbContext(typeof(CoreDbContext))]
[Migration("20221007105933_CoreDbContext_Upgrade1")]
partial class CoreDbContext_Upgrade1
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.HasAnnotation("ProductVersion", "6.0.7")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
modelBuilder.Entity("ASC.Core.Common.EF.DbButton", b =>
{
b.Property<int>("TariffId")
.HasColumnType("integer")
.HasColumnName("tariff_id");
b.Property<string>("PartnerId")
.HasMaxLength(50)
.HasColumnType("character varying(50)")
.HasColumnName("partner_id");
b.Property<string>("ButtonUrl")
.IsRequired()
.HasColumnType("text")
.HasColumnName("button_url");
b.HasKey("TariffId", "PartnerId")
.HasName("tenants_buttons_pkey");
b.ToTable("tenants_buttons", "onlyoffice");
});
modelBuilder.Entity("ASC.Core.Common.EF.DbQuota", b =>
{
b.Property<int>("Tenant")
.HasColumnType("integer")
.HasColumnName("tenant");
b.Property<int>("ActiveUsers")
.HasColumnType("integer")
.HasColumnName("active_users");
b.Property<string>("AvangateId")
.ValueGeneratedOnAdd()
.HasMaxLength(128)
.HasColumnType("character varying(128)")
.HasColumnName("avangate_id")
.HasDefaultValueSql("NULL");
b.Property<string>("Description")
.HasColumnType("character varying")
.HasColumnName("description");
b.Property<string>("Features")
.HasColumnType("text")
.HasColumnName("features");
b.Property<long>("MaxFileSize")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasColumnName("max_file_size")
.HasDefaultValueSql("'0'");
b.Property<long>("MaxTotalSize")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasColumnName("max_total_size")
.HasDefaultValueSql("'0'");
b.Property<string>("Name")
.HasColumnType("character varying")
.HasColumnName("name");
b.Property<decimal>("Price")
.ValueGeneratedOnAdd()
.HasColumnType("numeric(10,2)")
.HasColumnName("price")
.HasDefaultValueSql("0.00");
b.Property<bool>("Visible")
.HasColumnType("boolean")
.HasColumnName("visible");
b.HasKey("Tenant")
.HasName("tenants_quota_pkey");
b.ToTable("tenants_quota", "onlyoffice");
b.HasData(
new
{
Tenant = -1,
ActiveUsers = 10000,
AvangateId = "0",
Features = "domain,audit,controlpanel,healthcheck,ldap,sso,whitelabel,branding,ssbranding,update,support,portals:10000,discencryption,privacyroom,restore",
MaxFileSize = 102400L,
MaxTotalSize = 10995116277760L,
Name = "default",
Price = 0m,
Visible = false
});
});
modelBuilder.Entity("ASC.Core.Common.EF.DbQuotaRow", b =>
{
b.Property<int>("Tenant")
.HasColumnType("integer")
.HasColumnName("tenant");
b.Property<string>("Path")
.HasMaxLength(255)
.HasColumnType("character varying(255)")
.HasColumnName("path");
b.Property<long>("Counter")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasColumnName("counter")
.HasDefaultValueSql("'0'");
b.Property<DateTime>("LastModified")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("last_modified")
.HasDefaultValueSql("CURRENT_TIMESTAMP");
b.Property<string>("Tag")
.ValueGeneratedOnAdd()
.HasMaxLength(1024)
.HasColumnType("character varying(1024)")
.HasColumnName("tag")
.HasDefaultValueSql("'0'");
b.Property<Guid>("UserId")
.ValueGeneratedOnAdd()
.HasMaxLength(36)
.HasColumnType("uuid")
.HasColumnName("user_id")
.HasDefaultValueSql("NULL");
b.HasKey("Tenant", "Path")
.HasName("tenants_quotarow_pkey");
b.HasIndex("LastModified")
.HasDatabaseName("last_modified_tenants_quotarow");
b.ToTable("tenants_quotarow", "onlyoffice");
});
modelBuilder.Entity("ASC.Core.Common.EF.DbTariff", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("Comment")
.ValueGeneratedOnAdd()
.HasMaxLength(255)
.HasColumnType("character varying(255)")
.HasColumnName("comment")
.HasDefaultValueSql("NULL");
b.Property<DateTime>("CreateOn")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("create_on")
.HasDefaultValueSql("CURRENT_TIMESTAMP");
b.Property<int>("Quantity")
.HasColumnType("integer")
.HasColumnName("quantity");
b.Property<DateTime>("Stamp")
.HasColumnType("timestamp with time zone")
.HasColumnName("stamp");
b.Property<int>("Tariff")
.HasColumnType("integer")
.HasColumnName("tariff");
b.Property<int>("Tenant")
.HasColumnType("integer")
.HasColumnName("tenant");
b.HasKey("Id");
b.HasIndex("Tenant")
.HasDatabaseName("tenant_tenants_tariff");
b.ToTable("tenants_tariff", "onlyoffice");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,50 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ASC.Migrations.PostgreSql.Migrations.CoreDb
{
public partial class CoreDbContext_Upgrade1 : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "users_quotarow",
schema: "onlyoffice");
migrationBuilder.AddColumn<Guid>(
name: "user_id",
schema: "onlyoffice",
table: "tenants_quotarow",
type: "uuid",
maxLength: 36,
nullable: false,
defaultValueSql: "NULL");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "user_id",
schema: "onlyoffice",
table: "tenants_quotarow");
migrationBuilder.CreateTable(
name: "users_quotarow",
schema: "onlyoffice",
columns: table => new
{
tenant = table.Column<int>(type: "integer", nullable: false),
UserId = table.Column<Guid>(type: "uuid", nullable: false),
path = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: false),
counter = table.Column<long>(type: "bigint", nullable: false, defaultValueSql: "'0'"),
tag = table.Column<string>(type: "character varying(36)", maxLength: 36, nullable: true, defaultValueSql: "'0'")
},
constraints: table =>
{
table.PrimaryKey("tenants_userquotarow_pkey", x => new { x.tenant, x.UserId, x.path });
});
}
}
}

View File

@ -18,7 +18,7 @@ namespace ASC.Migrations.PostgreSql.Migrations
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.HasAnnotation("ProductVersion", "6.0.4") .HasAnnotation("ProductVersion", "6.0.7")
.HasAnnotation("Relational:MaxIdentifierLength", 63); .HasAnnotation("Relational:MaxIdentifierLength", 63);
modelBuilder.Entity("ASC.Core.Common.EF.DbButton", b => modelBuilder.Entity("ASC.Core.Common.EF.DbButton", b =>
@ -109,7 +109,7 @@ namespace ASC.Migrations.PostgreSql.Migrations
MaxFileSize = 102400L, MaxFileSize = 102400L,
MaxTotalSize = 10995116277760L, MaxTotalSize = 10995116277760L,
Name = "default", Name = "default",
Price = 0.00m, Price = 0m,
Visible = false Visible = false
}); });
}); });
@ -144,6 +144,13 @@ namespace ASC.Migrations.PostgreSql.Migrations
.HasColumnName("tag") .HasColumnName("tag")
.HasDefaultValueSql("'0'"); .HasDefaultValueSql("'0'");
b.Property<Guid>("UserId")
.ValueGeneratedOnAdd()
.HasMaxLength(36)
.HasColumnType("uuid")
.HasColumnName("user_id")
.HasDefaultValueSql("NULL");
b.HasKey("Tenant", "Path") b.HasKey("Tenant", "Path")
.HasName("tenants_quotarow_pkey"); .HasName("tenants_quotarow_pkey");

View File

@ -23,408 +23,6 @@ namespace ASC.Migrations.PostgreSql.Migrations
.HasAnnotation("ProductVersion", "6.0.4") .HasAnnotation("ProductVersion", "6.0.4")
.HasAnnotation("Relational:MaxIdentifierLength", 63); .HasAnnotation("Relational:MaxIdentifierLength", 63);
modelBuilder.Entity("ASC.Core.Common.EF.Model.DbTenant", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("Alias")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("character varying(100)")
.HasColumnName("alias");
b.Property<bool>("Calls")
.ValueGeneratedOnAdd()
.HasColumnType("boolean")
.HasColumnName("calls")
.HasDefaultValueSql("true");
b.Property<DateTime>("CreationDateTime")
.HasColumnType("timestamp with time zone")
.HasColumnName("creationdatetime");
b.Property<int>("Industry")
.HasColumnType("integer")
.HasColumnName("industry");
b.Property<string>("Language")
.IsRequired()
.ValueGeneratedOnAdd()
.HasMaxLength(10)
.HasColumnType("character(10)")
.HasColumnName("language")
.HasDefaultValueSql("'en-US'")
.IsFixedLength();
b.Property<DateTime>("LastModified")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("last_modified")
.HasDefaultValueSql("CURRENT_TIMESTAMP");
b.Property<string>("MappedDomain")
.ValueGeneratedOnAdd()
.HasMaxLength(100)
.HasColumnType("character varying(100)")
.HasColumnName("mappeddomain")
.HasDefaultValueSql("NULL");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(255)
.HasColumnType("character varying(255)")
.HasColumnName("name");
b.Property<Guid?>("OwnerId")
.ValueGeneratedOnAdd()
.HasMaxLength(38)
.HasColumnType("uuid")
.HasColumnName("owner_id")
.HasDefaultValueSql("NULL");
b.Property<string>("PaymentId")
.ValueGeneratedOnAdd()
.HasMaxLength(38)
.HasColumnType("character varying(38)")
.HasColumnName("payment_id")
.HasDefaultValueSql("NULL");
b.Property<bool>("Spam")
.ValueGeneratedOnAdd()
.HasColumnType("boolean")
.HasColumnName("spam")
.HasDefaultValueSql("true");
b.Property<int>("Status")
.HasColumnType("integer")
.HasColumnName("status");
b.Property<DateTime?>("StatusChanged")
.HasColumnType("timestamp with time zone")
.HasColumnName("statuschanged");
b.Property<string>("TimeZone")
.ValueGeneratedOnAdd()
.HasMaxLength(50)
.HasColumnType("character varying(50)")
.HasColumnName("timezone")
.HasDefaultValueSql("NULL");
b.Property<int>("TrustedDomainsEnabled")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("trusteddomainsenabled")
.HasDefaultValueSql("1");
b.Property<string>("TrustedDomainsRaw")
.ValueGeneratedOnAdd()
.HasMaxLength(1024)
.HasColumnType("character varying(1024)")
.HasColumnName("trusteddomains")
.HasDefaultValueSql("NULL");
b.Property<int>("Version")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("version")
.HasDefaultValueSql("2");
b.Property<DateTime?>("Version_Changed")
.HasColumnType("timestamp with time zone")
.HasColumnName("version_changed");
b.HasKey("Id");
b.HasIndex("Alias")
.IsUnique()
.HasDatabaseName("alias");
b.HasIndex("LastModified")
.HasDatabaseName("last_modified_tenants_tenants");
b.HasIndex("MappedDomain")
.HasDatabaseName("mappeddomain");
b.HasIndex("Version")
.HasDatabaseName("version");
b.ToTable("tenants_tenants", "onlyoffice");
b.HasData(
new
{
Id = 1,
Alias = "localhost",
Calls = false,
CreationDateTime = new DateTime(2021, 3, 9, 17, 46, 59, 97, DateTimeKind.Utc).AddTicks(4317),
Industry = 0,
LastModified = new DateTime(2022, 7, 8, 0, 0, 0, 0, DateTimeKind.Unspecified),
Name = "Web Office",
OwnerId = new Guid("66faa6e4-f133-11ea-b126-00ffeec8b4ef"),
Spam = false,
Status = 0,
TrustedDomainsEnabled = 0,
Version = 0
});
});
modelBuilder.Entity("ASC.Core.Common.EF.Model.DbWebstudioSettings", b =>
{
b.Property<int>("TenantId")
.HasColumnType("integer")
.HasColumnName("TenantID");
b.Property<Guid>("Id")
.HasMaxLength(64)
.HasColumnType("uuid")
.HasColumnName("ID");
b.Property<Guid>("UserId")
.HasMaxLength(64)
.HasColumnType("uuid")
.HasColumnName("UserID");
b.Property<string>("Data")
.IsRequired()
.HasColumnType("text");
b.HasKey("TenantId", "Id", "UserId")
.HasName("webstudio_settings_pkey");
b.HasIndex("Id")
.HasDatabaseName("ID");
b.ToTable("webstudio_settings", "onlyoffice");
b.HasData(
new
{
TenantId = 1,
Id = new Guid("9a925891-1f92-4ed7-b277-d6f649739f06"),
UserId = new Guid("00000000-0000-0000-0000-000000000000"),
Data = "{\"Completed\":false}"
});
});
modelBuilder.Entity("ASC.Core.Common.EF.User", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasMaxLength(38)
.HasColumnType("uuid")
.HasColumnName("id");
b.Property<int>("ActivationStatus")
.HasColumnType("integer")
.HasColumnName("activation_status");
b.Property<DateTime?>("BirthDate")
.HasColumnType("timestamp with time zone")
.HasColumnName("bithdate");
b.Property<string>("Contacts")
.ValueGeneratedOnAdd()
.HasMaxLength(1024)
.HasColumnType("character varying(1024)")
.HasColumnName("contacts")
.HasDefaultValueSql("NULL");
b.Property<DateTime>("CreateDate")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("create_on")
.HasDefaultValueSql("CURRENT_TIMESTAMP");
b.Property<string>("CultureName")
.ValueGeneratedOnAdd()
.HasMaxLength(20)
.HasColumnType("character varying(20)")
.HasColumnName("culture")
.HasDefaultValueSql("NULL");
b.Property<string>("Email")
.ValueGeneratedOnAdd()
.HasMaxLength(255)
.HasColumnType("character varying(255)")
.HasColumnName("email")
.HasDefaultValueSql("NULL");
b.Property<string>("FirstName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)")
.HasColumnName("firstname");
b.Property<DateTime>("LastModified")
.HasColumnType("timestamp with time zone")
.HasColumnName("last_modified");
b.Property<string>("LastName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)")
.HasColumnName("lastname");
b.Property<string>("Location")
.ValueGeneratedOnAdd()
.HasMaxLength(255)
.HasColumnType("character varying(255)")
.HasColumnName("location")
.HasDefaultValueSql("NULL");
b.Property<string>("MobilePhone")
.ValueGeneratedOnAdd()
.HasMaxLength(255)
.HasColumnType("character varying(255)")
.HasColumnName("phone")
.HasDefaultValueSql("NULL");
b.Property<int>("MobilePhoneActivation")
.HasColumnType("integer")
.HasColumnName("phone_activation");
b.Property<string>("Notes")
.ValueGeneratedOnAdd()
.HasMaxLength(512)
.HasColumnType("character varying(512)")
.HasColumnName("notes")
.HasDefaultValueSql("NULL");
b.Property<bool>("Removed")
.HasColumnType("boolean")
.HasColumnName("removed");
b.Property<bool?>("Sex")
.HasColumnType("boolean")
.HasColumnName("sex");
b.Property<string>("Sid")
.ValueGeneratedOnAdd()
.HasMaxLength(512)
.HasColumnType("character varying(512)")
.HasColumnName("sid")
.HasDefaultValueSql("NULL");
b.Property<string>("SsoNameId")
.ValueGeneratedOnAdd()
.HasMaxLength(512)
.HasColumnType("character varying(512)")
.HasColumnName("sso_name_id")
.HasDefaultValueSql("NULL");
b.Property<string>("SsoSessionId")
.ValueGeneratedOnAdd()
.HasMaxLength(512)
.HasColumnType("character varying(512)")
.HasColumnName("sso_session_id")
.HasDefaultValueSql("NULL");
b.Property<int>("Status")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("status")
.HasDefaultValueSql("1");
b.Property<int>("Tenant")
.HasColumnType("integer")
.HasColumnName("tenant");
b.Property<DateTime?>("TerminatedDate")
.HasColumnType("timestamp with time zone")
.HasColumnName("terminateddate");
b.Property<string>("Title")
.ValueGeneratedOnAdd()
.HasMaxLength(64)
.HasColumnType("character varying(64)")
.HasColumnName("title")
.HasDefaultValueSql("NULL");
b.Property<string>("UserName")
.IsRequired()
.HasMaxLength(255)
.HasColumnType("character varying(255)")
.HasColumnName("username");
b.Property<DateTime?>("WorkFromDate")
.HasColumnType("timestamp with time zone")
.HasColumnName("workfromdate");
b.HasKey("Id");
b.HasIndex("Email")
.HasDatabaseName("email");
b.HasIndex("LastModified")
.HasDatabaseName("last_modified_core_user");
b.HasIndex("UserName", "Tenant")
.HasDatabaseName("username");
b.ToTable("core_user", "onlyoffice");
b.HasData(
new
{
Id = new Guid("66faa6e4-f133-11ea-b126-00ffeec8b4ef"),
ActivationStatus = 0,
CreateDate = new DateTime(2022, 7, 8, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "",
FirstName = "Administrator",
LastModified = new DateTime(2021, 3, 9, 9, 52, 55, 765, DateTimeKind.Utc).AddTicks(1420),
LastName = "",
MobilePhoneActivation = 0,
Removed = false,
Status = 1,
Tenant = 1,
UserName = "administrator",
WorkFromDate = new DateTime(2021, 3, 9, 9, 52, 55, 764, DateTimeKind.Utc).AddTicks(9157)
});
});
modelBuilder.Entity("ASC.Core.Common.EF.UserGroup", b =>
{
b.Property<int>("Tenant")
.HasColumnType("integer")
.HasColumnName("tenant");
b.Property<Guid>("Userid")
.HasMaxLength(38)
.HasColumnType("uuid")
.HasColumnName("userid");
b.Property<Guid>("UserGroupId")
.HasMaxLength(38)
.HasColumnType("uuid")
.HasColumnName("groupid");
b.Property<int>("RefType")
.HasColumnType("integer")
.HasColumnName("ref_type");
b.Property<DateTime>("LastModified")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("last_modified")
.HasDefaultValueSql("CURRENT_TIMESTAMP");
b.Property<bool>("Removed")
.HasColumnType("boolean")
.HasColumnName("removed");
b.HasKey("Tenant", "Userid", "UserGroupId", "RefType")
.HasName("core_usergroup_pkey");
b.HasIndex("LastModified")
.HasDatabaseName("last_modified_core_usergroup");
b.ToTable("core_usergroup", "onlyoffice");
});
modelBuilder.Entity("ASC.MessagingSystem.EF.Model.AuditEvent", b => modelBuilder.Entity("ASC.MessagingSystem.EF.Model.AuditEvent", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")

View File

@ -1,5 +1,31 @@
using System; // (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
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable #nullable disable
@ -37,59 +63,6 @@ namespace ASC.Migrations.PostgreSql.Migrations
table.PrimaryKey("PK_audit_events", x => x.id); table.PrimaryKey("PK_audit_events", x => x.id);
}); });
migrationBuilder.CreateTable(
name: "core_user",
schema: "onlyoffice",
columns: table => new
{
id = table.Column<Guid>(type: "uuid", maxLength: 38, nullable: false),
tenant = table.Column<int>(type: "integer", nullable: false),
username = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: false),
firstname = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
lastname = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
sex = table.Column<bool>(type: "boolean", nullable: true),
bithdate = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
status = table.Column<int>(type: "integer", nullable: false, defaultValueSql: "1"),
activation_status = table.Column<int>(type: "integer", nullable: false),
email = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: true, defaultValueSql: "NULL"),
workfromdate = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
terminateddate = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
title = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true, defaultValueSql: "NULL"),
culture = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: true, defaultValueSql: "NULL"),
contacts = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: true, defaultValueSql: "NULL"),
phone = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: true, defaultValueSql: "NULL"),
phone_activation = table.Column<int>(type: "integer", nullable: false),
location = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: true, defaultValueSql: "NULL"),
notes = table.Column<string>(type: "character varying(512)", maxLength: 512, nullable: true, defaultValueSql: "NULL"),
sid = table.Column<string>(type: "character varying(512)", maxLength: 512, nullable: true, defaultValueSql: "NULL"),
sso_name_id = table.Column<string>(type: "character varying(512)", maxLength: 512, nullable: true, defaultValueSql: "NULL"),
sso_session_id = table.Column<string>(type: "character varying(512)", maxLength: 512, nullable: true, defaultValueSql: "NULL"),
removed = table.Column<bool>(type: "boolean", nullable: false),
create_on = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "CURRENT_TIMESTAMP"),
last_modified = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_core_user", x => x.id);
});
migrationBuilder.CreateTable(
name: "core_usergroup",
schema: "onlyoffice",
columns: table => new
{
tenant = table.Column<int>(type: "integer", nullable: false),
userid = table.Column<Guid>(type: "uuid", maxLength: 38, nullable: false),
groupid = table.Column<Guid>(type: "uuid", maxLength: 38, nullable: false),
ref_type = table.Column<int>(type: "integer", nullable: false),
removed = table.Column<bool>(type: "boolean", nullable: false),
last_modified = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "CURRENT_TIMESTAMP")
},
constraints: table =>
{
table.PrimaryKey("core_usergroup_pkey", x => new { x.tenant, x.userid, x.groupid, x.ref_type });
});
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
name: "login_events", name: "login_events",
schema: "onlyoffice", schema: "onlyoffice",
@ -114,100 +87,12 @@ namespace ASC.Migrations.PostgreSql.Migrations
table.PrimaryKey("PK_login_events", x => x.id); table.PrimaryKey("PK_login_events", x => x.id);
}); });
migrationBuilder.CreateTable(
name: "tenants_tenants",
schema: "onlyoffice",
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
name = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: false),
alias = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
mappeddomain = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true, defaultValueSql: "NULL"),
version = table.Column<int>(type: "integer", nullable: false, defaultValueSql: "2"),
version_changed = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
language = table.Column<string>(type: "character(10)", fixedLength: true, maxLength: 10, nullable: false, defaultValueSql: "'en-US'"),
timezone = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true, defaultValueSql: "NULL"),
trusteddomains = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: true, defaultValueSql: "NULL"),
trusteddomainsenabled = table.Column<int>(type: "integer", nullable: false, defaultValueSql: "1"),
status = table.Column<int>(type: "integer", nullable: false),
statuschanged = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
creationdatetime = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
owner_id = table.Column<Guid>(type: "uuid", maxLength: 38, nullable: true, defaultValueSql: "NULL"),
payment_id = table.Column<string>(type: "character varying(38)", maxLength: 38, nullable: true, defaultValueSql: "NULL"),
industry = table.Column<int>(type: "integer", nullable: false),
last_modified = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "CURRENT_TIMESTAMP"),
spam = table.Column<bool>(type: "boolean", nullable: false, defaultValueSql: "true"),
calls = table.Column<bool>(type: "boolean", nullable: false, defaultValueSql: "true")
},
constraints: table =>
{
table.PrimaryKey("PK_tenants_tenants", x => x.id);
});
migrationBuilder.CreateTable(
name: "webstudio_settings",
schema: "onlyoffice",
columns: table => new
{
TenantID = table.Column<int>(type: "integer", nullable: false),
ID = table.Column<Guid>(type: "uuid", maxLength: 64, nullable: false),
UserID = table.Column<Guid>(type: "uuid", maxLength: 64, nullable: false),
Data = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("webstudio_settings_pkey", x => new { x.TenantID, x.ID, x.UserID });
});
migrationBuilder.InsertData(
schema: "onlyoffice",
table: "core_user",
columns: new[] { "id", "activation_status", "bithdate", "create_on", "email", "firstname", "last_modified", "lastname", "phone_activation", "removed", "sex", "status", "tenant", "terminateddate", "username", "workfromdate" },
values: new object[] { new Guid("66faa6e4-f133-11ea-b126-00ffeec8b4ef"), 0, null, new DateTime(2022, 7, 8, 0, 0, 0, 0, DateTimeKind.Unspecified), "", "Administrator", new DateTime(2021, 3, 9, 9, 52, 55, 765, DateTimeKind.Utc).AddTicks(1420), "", 0, false, null, 1, 1, null, "administrator", new DateTime(2021, 3, 9, 9, 52, 55, 764, DateTimeKind.Utc).AddTicks(9157) });
migrationBuilder.InsertData(
schema: "onlyoffice",
table: "tenants_tenants",
columns: new[] { "id", "alias", "creationdatetime", "industry", "last_modified", "name", "owner_id", "status", "statuschanged", "version_changed" },
values: new object[] { 1, "localhost", new DateTime(2021, 3, 9, 17, 46, 59, 97, DateTimeKind.Utc).AddTicks(4317), 0, new DateTime(2022, 7, 8, 0, 0, 0, 0, DateTimeKind.Unspecified), "Web Office", new Guid("66faa6e4-f133-11ea-b126-00ffeec8b4ef"), 0, null, null });
migrationBuilder.InsertData(
schema: "onlyoffice",
table: "webstudio_settings",
columns: new[] { "ID", "TenantID", "UserID", "Data" },
values: new object[] { new Guid("9a925891-1f92-4ed7-b277-d6f649739f06"), 1, new Guid("00000000-0000-0000-0000-000000000000"), "{\"Completed\":false}" });
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "date", name: "date",
schema: "onlyoffice", schema: "onlyoffice",
table: "audit_events", table: "audit_events",
columns: new[] { "tenant_id", "date" }); columns: new[] { "tenant_id", "date" });
migrationBuilder.CreateIndex(
name: "email",
schema: "onlyoffice",
table: "core_user",
column: "email");
migrationBuilder.CreateIndex(
name: "last_modified_core_user",
schema: "onlyoffice",
table: "core_user",
column: "last_modified");
migrationBuilder.CreateIndex(
name: "username",
schema: "onlyoffice",
table: "core_user",
columns: new[] { "username", "tenant" });
migrationBuilder.CreateIndex(
name: "last_modified_core_usergroup",
schema: "onlyoffice",
table: "core_usergroup",
column: "last_modified");
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "date_login_events", name: "date_login_events",
schema: "onlyoffice", schema: "onlyoffice",
@ -219,37 +104,6 @@ namespace ASC.Migrations.PostgreSql.Migrations
schema: "onlyoffice", schema: "onlyoffice",
table: "login_events", table: "login_events",
columns: new[] { "user_id", "tenant_id" }); columns: new[] { "user_id", "tenant_id" });
migrationBuilder.CreateIndex(
name: "alias",
schema: "onlyoffice",
table: "tenants_tenants",
column: "alias",
unique: true);
migrationBuilder.CreateIndex(
name: "last_modified_tenants_tenants",
schema: "onlyoffice",
table: "tenants_tenants",
column: "last_modified");
migrationBuilder.CreateIndex(
name: "mappeddomain",
schema: "onlyoffice",
table: "tenants_tenants",
column: "mappeddomain");
migrationBuilder.CreateIndex(
name: "version",
schema: "onlyoffice",
table: "tenants_tenants",
column: "version");
migrationBuilder.CreateIndex(
name: "ID",
schema: "onlyoffice",
table: "webstudio_settings",
column: "ID");
} }
protected override void Down(MigrationBuilder migrationBuilder) protected override void Down(MigrationBuilder migrationBuilder)
@ -258,25 +112,9 @@ namespace ASC.Migrations.PostgreSql.Migrations
name: "audit_events", name: "audit_events",
schema: "onlyoffice"); schema: "onlyoffice");
migrationBuilder.DropTable(
name: "core_user",
schema: "onlyoffice");
migrationBuilder.DropTable(
name: "core_usergroup",
schema: "onlyoffice");
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "login_events", name: "login_events",
schema: "onlyoffice"); schema: "onlyoffice");
migrationBuilder.DropTable(
name: "tenants_tenants",
schema: "onlyoffice");
migrationBuilder.DropTable(
name: "webstudio_settings",
schema: "onlyoffice");
} }
} }
} }

View File

@ -18,7 +18,7 @@ namespace ASC.Migrations.PostgreSql.Migrations
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.HasAnnotation("ProductVersion", "6.0.4") .HasAnnotation("ProductVersion", "6.0.7")
.HasAnnotation("Relational:MaxIdentifierLength", 63); .HasAnnotation("Relational:MaxIdentifierLength", 63);
modelBuilder.Entity("ASC.Core.Common.EF.Model.DbTenant", b => modelBuilder.Entity("ASC.Core.Common.EF.Model.DbTenant", b =>

View File

@ -18,7 +18,7 @@ namespace ASC.Migrations.PostgreSql.Migrations
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.HasAnnotation("ProductVersion", "6.0.4") .HasAnnotation("ProductVersion", "6.0.7")
.HasAnnotation("Relational:MaxIdentifierLength", 63); .HasAnnotation("Relational:MaxIdentifierLength", 63);
modelBuilder.Entity("ASC.Core.Common.EF.Acl", b => modelBuilder.Entity("ASC.Core.Common.EF.Acl", b =>

View File

@ -140,7 +140,7 @@ public class FilesUserSpaceUsage : IUserSpaceUsage
using var filesDbContext = _dbContextFactory.CreateDbContext(); using var filesDbContext = _dbContextFactory.CreateDbContext();
return await filesDbContext.Files return await filesDbContext.Files
.Where(r => r.TenantId == tenantId && (r.ParentId == my || r.ParentId == trash)) .Where(r => r.TenantId == tenantId && r.CreateBy == userId && (r.ParentId == my || r.ParentId == trash))
.SumAsync(r => r.ContentLength); .SumAsync(r => r.ContentLength);
} }
} }

View File

@ -28,7 +28,7 @@ namespace ASC.Files.Core.Data;
public class AbstractDao public class AbstractDao
{ {
protected readonly ICache _cache;
private int _tenantID; private int _tenantID;
protected internal int TenantID protected internal int TenantID
{ {
@ -43,6 +43,7 @@ public class AbstractDao
} }
} }
protected readonly ICache _cache;
protected readonly IDbContextFactory<FilesDbContext> _dbContextFactory; protected readonly IDbContextFactory<FilesDbContext> _dbContextFactory;
protected readonly UserManager _userManager; protected readonly UserManager _userManager;
protected readonly TenantManager _tenantManager; protected readonly TenantManager _tenantManager;

View File

@ -45,6 +45,7 @@ internal class FileDao : AbstractDao, IFileDao<int>
private readonly Settings _settings; private readonly Settings _settings;
private readonly IMapper _mapper; private readonly IMapper _mapper;
private readonly ThumbnailSettings _thumbnailSettings; private readonly ThumbnailSettings _thumbnailSettings;
private readonly IQuotaService _quotaService;
public FileDao( public FileDao(
ILogger<FileDao> logger, ILogger<FileDao> logger,
@ -72,7 +73,8 @@ internal class FileDao : AbstractDao, IFileDao<int>
CrossDao crossDao, CrossDao crossDao,
Settings settings, Settings settings,
IMapper mapper, IMapper mapper,
ThumbnailSettings thumbnailSettings) ThumbnailSettings thumbnailSettings,
IQuotaService quotaService)
: base( : base(
dbContextManager, dbContextManager,
userManager, userManager,
@ -101,6 +103,7 @@ internal class FileDao : AbstractDao, IFileDao<int>
_settings = settings; _settings = settings;
_mapper = mapper; _mapper = mapper;
_thumbnailSettings = thumbnailSettings; _thumbnailSettings = thumbnailSettings;
_quotaService = quotaService;
} }
public Task InvalidateCacheAsync(int fileId) public Task InvalidateCacheAsync(int fileId)
@ -416,6 +419,25 @@ internal class FileDao : AbstractDao, IFileDao<int>
} }
} }
var quotaSettings = _settingsManager.Load<TenantUserQuotaSettings>();
if (quotaSettings.EnableUserQuota)
{
var user = _userManager.GetUsers(file.Id == default ? _authContext.CurrentAccount.ID : file.CreateBy);
var userQuotaSettings = _settingsManager.LoadForUser<UserQuotaSettings>(user);
var quotaLimit = userQuotaSettings.UserQuota;
if (quotaLimit != -1)
{
var userUsedSpace = Math.Max(0, _quotaService.FindUserQuotaRows(TenantID, user.Id).Where(r => !string.IsNullOrEmpty(r.Tag)).Sum(r => r.Counter));
if (quotaLimit - userUsedSpace < file.ContentLength)
{
throw FileSizeComment.GetPersonalFreeSpaceException(quotaLimit);
}
}
}
var isNew = false; var isNew = false;
List<int> parentFoldersIds; List<int> parentFoldersIds;
DbFile toInsert = null; DbFile toInsert = null;

View File

@ -129,6 +129,7 @@ global using ASC.Web.Core.ModuleManagement.Common;
global using ASC.Web.Core.PublicResources; global using ASC.Web.Core.PublicResources;
global using ASC.Web.Core.Subscriptions; global using ASC.Web.Core.Subscriptions;
global using ASC.Web.Core.Users; global using ASC.Web.Core.Users;
global using ASC.Web.Core.Utility;
global using ASC.Web.Core.Utility.Skins; global using ASC.Web.Core.Utility.Skins;
global using ASC.Web.Core.WhiteLabel; global using ASC.Web.Core.WhiteLabel;
global using ASC.Web.Files; global using ASC.Web.Files;

View File

@ -35,6 +35,7 @@ public class UserController : PeopleControllerBase
private readonly ICache _cache; private readonly ICache _cache;
private readonly TenantManager _tenantManager; private readonly TenantManager _tenantManager;
private readonly GlobalSpace _globalSpace;
private readonly Constants _constants; private readonly Constants _constants;
private readonly CookiesManager _cookiesManager; private readonly CookiesManager _cookiesManager;
private readonly CoreBaseSettings _coreBaseSettings; private readonly CoreBaseSettings _coreBaseSettings;
@ -64,10 +65,12 @@ public class UserController : PeopleControllerBase
private readonly SettingsManager _settingsManager; private readonly SettingsManager _settingsManager;
private readonly RoomLinkService _roomLinkService; private readonly RoomLinkService _roomLinkService;
private readonly FileSecurity _fileSecurity; private readonly FileSecurity _fileSecurity;
private readonly IQuotaService _quotaService;
public UserController( public UserController(
ICache cache, ICache cache,
TenantManager tenantManager, TenantManager tenantManager,
GlobalSpace globalSpace,
Constants constants, Constants constants,
CookiesManager cookiesManager, CookiesManager cookiesManager,
CoreBaseSettings coreBaseSettings, CoreBaseSettings coreBaseSettings,
@ -102,11 +105,13 @@ public class UserController : PeopleControllerBase
IHttpContextAccessor httpContextAccessor, IHttpContextAccessor httpContextAccessor,
SettingsManager settingsManager, SettingsManager settingsManager,
RoomLinkService roomLinkService, RoomLinkService roomLinkService,
FileSecurity fileSecurity) FileSecurity fileSecurity,
IQuotaService quotaService)
: base(userManager, permissionContext, apiContext, userPhotoManager, httpClientFactory, httpContextAccessor) : base(userManager, permissionContext, apiContext, userPhotoManager, httpClientFactory, httpContextAccessor)
{ {
_cache = cache; _cache = cache;
_tenantManager = tenantManager; _tenantManager = tenantManager;
_globalSpace = globalSpace;
_constants = constants; _constants = constants;
_cookiesManager = cookiesManager; _cookiesManager = cookiesManager;
_coreBaseSettings = coreBaseSettings; _coreBaseSettings = coreBaseSettings;
@ -136,6 +141,7 @@ public class UserController : PeopleControllerBase
_settingsManager = settingsManager; _settingsManager = settingsManager;
_roomLinkService = roomLinkService; _roomLinkService = roomLinkService;
_fileSecurity = fileSecurity; _fileSecurity = fileSecurity;
_quotaService = quotaService;
} }
[HttpPost("active")] [HttpPost("active")]
@ -1064,6 +1070,42 @@ public class UserController : PeopleControllerBase
} }
} }
[HttpPut("quota")]
public async IAsyncEnumerable<EmployeeFullDto> UpdateUserQuota(UpdateMembersQuotaRequestDto inDto)
{
var users = inDto.UserIds
.Where(userId => !_userManager.IsSystemUser(userId))
.Select(userId => _userManager.GetUsers(userId))
.ToList();
foreach (var user in users)
{
if (inDto.Quota != -1)
{
var usedSpace = Math.Max(0,
_quotaService.FindUserQuotaRows(
_tenantManager.GetCurrentTenant().Id,
user.Id
)
.Where(r => !string.IsNullOrEmpty(r.Tag)).Sum(r => r.Counter));
var tenanSpaceQuota = _tenantExtra.GetTenantQuota().MaxTotalSize;
if (tenanSpaceQuota < inDto.Quota || usedSpace > inDto.Quota)
{
continue;
}
}
var quotaSettings = _settingsManager.Load<TenantUserQuotaSettings>();
_settingsManager.SaveForUser(new UserQuotaSettings { UserQuota = inDto.Quota }, user);
yield return await _employeeFullDtoHelper.GetFull(user);
}
}
private void UpdateDepartments(IEnumerable<Guid> department, UserInfo user) private void UpdateDepartments(IEnumerable<Guid> department, UserInfo user)
{ {
if (!_permissionContext.CheckPermissions(Constants.Action_EditGroups)) if (!_permissionContext.CheckPermissions(Constants.Action_EditGroups))

View File

@ -0,0 +1,33 @@
// (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.People.ApiModels.RequestDto;
public class UpdateMembersQuotaRequestDto
{
public IEnumerable<Guid> UserIds { get; set; }
public long Quota { get; set; }
}

View File

@ -39,6 +39,7 @@ global using ASC.Common.Caching;
global using ASC.Common.Utils; global using ASC.Common.Utils;
global using ASC.Common.Web; global using ASC.Common.Web;
global using ASC.Core; global using ASC.Core;
global using ASC.Core.Common;
global using ASC.Core.Common.Settings; global using ASC.Core.Common.Settings;
global using ASC.Core.Tenants; global using ASC.Core.Tenants;
global using ASC.Core.Users; global using ASC.Core.Users;
@ -64,6 +65,8 @@ global using ASC.Web.Core;
global using ASC.Web.Core.Mobile; global using ASC.Web.Core.Mobile;
global using ASC.Web.Core.PublicResources; global using ASC.Web.Core.PublicResources;
global using ASC.Web.Core.Users; global using ASC.Web.Core.Users;
global using ASC.Web.Core.Utility;
global using ASC.Web.Files.Classes;
global using ASC.Web.Studio.Core; global using ASC.Web.Studio.Core;
global using ASC.Web.Studio.Core.Notify; global using ASC.Web.Studio.Core.Notify;
global using ASC.Web.Studio.UserControls.Statistics; global using ASC.Web.Studio.UserControls.Statistics;

View File

@ -63,6 +63,7 @@ public class SettingsController : BaseSettingsController
private readonly DnsSettings _dnsSettings; private readonly DnsSettings _dnsSettings;
private readonly AdditionalWhiteLabelSettingsHelper _additionalWhiteLabelSettingsHelper; private readonly AdditionalWhiteLabelSettingsHelper _additionalWhiteLabelSettingsHelper;
private readonly CustomColorThemesSettingsHelper _customColorThemesSettingsHelper; private readonly CustomColorThemesSettingsHelper _customColorThemesSettingsHelper;
private readonly QuotaSyncOperation _quotaSyncOperation;
public SettingsController( public SettingsController(
ILoggerProvider option, ILoggerProvider option,
@ -99,7 +100,8 @@ public class SettingsController : BaseSettingsController
IHttpContextAccessor httpContextAccessor, IHttpContextAccessor httpContextAccessor,
DnsSettings dnsSettings, DnsSettings dnsSettings,
AdditionalWhiteLabelSettingsHelper additionalWhiteLabelSettingsHelper, AdditionalWhiteLabelSettingsHelper additionalWhiteLabelSettingsHelper,
CustomColorThemesSettingsHelper customColorThemesSettingsHelper CustomColorThemesSettingsHelper customColorThemesSettingsHelper,
QuotaSyncOperation quotaSyncOperation
) : base(apiContext, memoryCache, webItemManager, httpContextAccessor) ) : base(apiContext, memoryCache, webItemManager, httpContextAccessor)
{ {
_log = option.CreateLogger("ASC.Api"); _log = option.CreateLogger("ASC.Api");
@ -132,6 +134,7 @@ public class SettingsController : BaseSettingsController
_constants = constants; _constants = constants;
_dnsSettings = dnsSettings; _dnsSettings = dnsSettings;
_additionalWhiteLabelSettingsHelper = additionalWhiteLabelSettingsHelper; _additionalWhiteLabelSettingsHelper = additionalWhiteLabelSettingsHelper;
_quotaSyncOperation = quotaSyncOperation;
_customColorThemesSettingsHelper = customColorThemesSettingsHelper; _customColorThemesSettingsHelper = customColorThemesSettingsHelper;
} }
@ -268,6 +271,16 @@ public class SettingsController : BaseSettingsController
return new QuotaDto(Tenant, _coreBaseSettings, _coreConfiguration, _tenantExtra, _tenantStatisticsProvider, _authContext, _settingsManager, WebItemManager, _constants); return new QuotaDto(Tenant, _coreBaseSettings, _coreConfiguration, _tenantExtra, _tenantStatisticsProvider, _authContext, _settingsManager, WebItemManager, _constants);
} }
[HttpPost("userquotasettings")]
public object SaveUserQuotaSettings(UserQuotaSettingsRequestsDto inDto)
{
_permissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
_settingsManager.Save(new TenantUserQuotaSettings { EnableUserQuota = inDto.EnableUserQuota, DefaultUserQuota = inDto.DefaultUserQuota });
return Resource.SuccessfullySaveSettingsMessage;
}
[AllowAnonymous] [AllowAnonymous]
[AllowNotPayment] [AllowNotPayment]
[HttpGet("cultures")] [HttpGet("cultures")]
@ -317,39 +330,19 @@ public class SettingsController : BaseSettingsController
return _dnsSettings.SaveDnsSettings(model.DnsName, model.Enable); return _dnsSettings.SaveDnsSettings(model.DnsName, model.Enable);
} }
//[HttpGet("recalculatequota")] [HttpGet("recalculatequota")]
//public void RecalculateQuota() public void RecalculateQuota()
//{ {
// SecurityContext.DemandPermissions(Tenant, SecutiryConstants.EditPortalSettings); _permissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
_quotaSyncOperation.RecalculateQuota(_tenantManager.GetCurrentTenant());
}
// var operations = quotaTasks.GetTasks() [HttpGet("checkrecalculatequota")]
// .Where(t => t.GetProperty<int>(QuotaSync.IdKey) == Tenant.Id); public bool CheckRecalculateQuota()
{
// if (operations.Any(o => o.Status <= DistributedTaskStatus.Running)) _permissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
// { return _quotaSyncOperation.CheckRecalculateQuota(_tenantManager.GetCurrentTenant());
// throw new InvalidOperationException(Resource.LdapSettingsTooManyOperations); }
// }
// var op = new QuotaSync(Tenant.Id, ServiceProvider);
// quotaTasks.QueueTask(op.RunJob, op.GetDistributedTask());
//}
//[HttpGet("checkrecalculatequota")]
//public bool CheckRecalculateQuota()
//{
// PermissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
// var task = quotaTasks.GetTasks().FirstOrDefault(t => t.GetProperty<int>(QuotaSync.IdKey) == Tenant.Id);
// if (task != null && task.Status == DistributedTaskStatus.Completed)
// {
// quotaTasks.RemoveTask(task.Id);
// return false;
// }
// return task != null;
//}
[HttpGet("logo")] [HttpGet("logo")]
public object GetLogo() public object GetLogo()
@ -434,8 +427,8 @@ public class SettingsController : BaseSettingsController
{ {
settings.Selected = inDto.Selected.Value; settings.Selected = inDto.Selected.Value;
_settingsManager.Save(settings); _settingsManager.Save(settings);
_messageService.Send(MessageAction.ColorThemeChanged); _messageService.Send(MessageAction.ColorThemeChanged);
} }
return new CustomColorThemesSettingsDto(settings, _customColorThemesSettingsHelper.Limit); return new CustomColorThemesSettingsDto(settings, _customColorThemesSettingsHelper.Limit);
} }

View File

@ -0,0 +1,34 @@
// (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.Web.Api.ApiModel.RequestsDto;
public class UserQuotaSettingsRequestsDto
{
public bool EnableUserQuota { get; set; }
public long DefaultUserQuota { get; set; }
}

View File

@ -120,6 +120,7 @@ global using ASC.Web.Core.WhiteLabel;
global using ASC.Web.Files.Services.DocumentService; global using ASC.Web.Files.Services.DocumentService;
global using ASC.Web.Studio.Core; global using ASC.Web.Studio.Core;
global using ASC.Web.Studio.Core.Notify; global using ASC.Web.Studio.Core.Notify;
global using ASC.Web.Studio.Core.Quota;
global using ASC.Web.Studio.Core.SMS; global using ASC.Web.Studio.Core.SMS;
global using ASC.Web.Studio.Core.Statistic; global using ASC.Web.Studio.Core.Statistic;
global using ASC.Web.Studio.Core.TFA; global using ASC.Web.Studio.Core.TFA;

View File

@ -2004,6 +2004,33 @@ namespace ASC.Web.Core.PublicResources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Failed to set the memory quota - the memory quota you set is greater than portals quota..
/// </summary>
public static string QuotaGreaterPortalError {
get {
return ResourceManager.GetString("QuotaGreaterPortalError", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed to set the memory quota - some users cannot use this quota..
/// </summary>
public static string QuotaGroupError {
get {
return ResourceManager.GetString("QuotaGroupError", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed to set the memory quota - the memory quota you set is less than used memory..
/// </summary>
public static string QuotaLessUsedMemoryError {
get {
return ResourceManager.GetString("QuotaLessUsedMemoryError", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Data reassign process for {0} is not complete.. /// Looks up a localized string similar to Data reassign process for {0} is not complete..
/// </summary> /// </summary>

View File

@ -828,4 +828,13 @@
<data name="MessageRoomInvitationsSentOnEmail" xml:space="preserve"> <data name="MessageRoomInvitationsSentOnEmail" xml:space="preserve">
<value>Virtual room {0} invitations sent successfully.</value> <value>Virtual room {0} invitations sent successfully.</value>
</data> </data>
<data name="QuotaGreaterPortalError" xml:space="preserve">
<value>Failed to set the memory quota - the memory quota you set is greater than portals quota.</value>
</data>
<data name="QuotaGroupError" xml:space="preserve">
<value>Failed to set the memory quota - some users cannot use this quota.</value>
</data>
<data name="QuotaLessUsedMemoryError" xml:space="preserve">
<value>Failed to set the memory quota - the memory quota you set is less than used memory.</value>
</data>
</root> </root>

View File

@ -26,64 +26,124 @@
namespace ASC.Web.Studio.Core.Quota; namespace ASC.Web.Studio.Core.Quota;
public class QuotaSync [Singletone(Additional = typeof(QuotaSyncOperationExtension))]
public class QuotaSyncOperation
{ {
public const string TenantIdKey = "tenantID";
protected DistributedTask TaskInfo { get; private set; } public const string CUSTOM_DISTRIBUTED_TASK_QUEUE_NAME = "ldapOperation";
private readonly int _tenantId;
private readonly DistributedTaskQueue _progressQueue;
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
public QuotaSync(int tenantId, IServiceProvider serviceProvider) public QuotaSyncOperation(IServiceProvider serviceProvider, IDistributedTaskQueueFactory queueFactory)
{ {
_tenantId = tenantId; ;
TaskInfo = new DistributedTask();
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
_progressQueue = queueFactory.CreateQueue(CUSTOM_DISTRIBUTED_TASK_QUEUE_NAME);
} }
public void RecalculateQuota(Tenant tenant)
public void RunJob()//DistributedTask distributedTask, CancellationToken cancellationToken)
{ {
using var scope = _serviceProvider.CreateScope(); var item = _progressQueue.GetAllTasks<QuotaSyncJob>().FirstOrDefault(t => t.TenantId == tenant.Id);
var scopeClass = scope.ServiceProvider.GetService<QuotaSyncJob>(); if (item != null && item.IsCompleted)
scopeClass.RunJob(_tenantId);
}
public virtual DistributedTask GetDistributedTask()
{
TaskInfo[TenantIdKey] = _tenantId;
return TaskInfo;
}
}
class QuotaSyncJob
{
private readonly TenantManager _tenantManager;
private readonly StorageFactoryConfig _storageFactoryConfig;
private readonly StorageFactory _storageFactory;
public QuotaSyncJob(TenantManager tenantManager, StorageFactoryConfig storageFactoryConfig, StorageFactory storageFactory)
{
_tenantManager = tenantManager;
_storageFactoryConfig = storageFactoryConfig;
_storageFactory = storageFactory;
}
public void RunJob(int tenantId)
{
_tenantManager.SetCurrentTenant(tenantId);
var storageModules = _storageFactoryConfig.GetModuleList(string.Empty);
foreach (var module in storageModules)
{ {
var storage = _storageFactory.GetStorage(tenantId.ToString(), module); _progressQueue.DequeueTask(item.Id);
storage.ResetQuotaAsync("").Wait(); item = null;
}
var domains = _storageFactoryConfig.GetDomainList(string.Empty, module); if (item == null)
foreach (var domain in domains) {
{ item = _serviceProvider.GetRequiredService<QuotaSyncJob>();
storage.ResetQuotaAsync(domain).Wait(); item.InitJob(tenant);
} _progressQueue.EnqueueTask(item);
}
item.PublishChanges();
}
public bool CheckRecalculateQuota(Tenant tenant)
{
var item = _progressQueue.GetAllTasks<QuotaSyncJob>().FirstOrDefault(t => t.TenantId == tenant.Id);
if (item != null && item.IsCompleted)
{
_progressQueue.DequeueTask(item.Id);
return false;
}
return item != null;
}
public static class QuotaSyncOperationExtension
{
public static void Register(DIHelper services)
{
services.TryAdd<QuotaSyncJob>();
} }
} }
}
public class QuotaSyncJob : DistributedTaskProgress
{
private readonly IServiceScopeFactory _serviceScopeFactory;
private int? _tenantId;
public int TenantId
{
get
{
return _tenantId ?? this[nameof(_tenantId)];
}
private set
{
_tenantId = value;
this[nameof(_tenantId)] = value;
}
}
public QuotaSyncJob(IServiceScopeFactory serviceScopeFactory)
{
_serviceScopeFactory = serviceScopeFactory;
}
public void InitJob(Tenant tenant)
{
TenantId = tenant.Id;
}
protected override void DoJob()
{
try
{
using var scope = _serviceScopeFactory.CreateScope();
var _tenantManager = scope.ServiceProvider.GetRequiredService<TenantManager>();
var _storageFactoryConfig = scope.ServiceProvider.GetRequiredService<StorageFactoryConfig>();
var _storageFactory = scope.ServiceProvider.GetRequiredService<StorageFactory>();
_tenantManager.SetCurrentTenant(TenantId);
var storageModules = _storageFactoryConfig.GetModuleList(string.Empty);
foreach (var module in storageModules)
{
var storage = _storageFactory.GetStorage(TenantId.ToString(), module);
storage.ResetQuotaAsync("").Wait();
var domains = _storageFactoryConfig.GetDomainList(string.Empty, module);
foreach (var domain in domains)
{
storage.ResetQuotaAsync(domain).Wait();
}
}
}
catch (Exception ex)
{
Status = DistributedTaskStatus.Failted;
Exception = ex;
}
finally
{
IsCompleted = true;
}
PublishChanges();
}
} }

View File

@ -139,7 +139,7 @@ public class SmsManager
{ {
if (await _smsSender.SendSMSAsync(mobilePhone, string.Format(Resource.SmsAuthenticationMessageToUser, key))) if (await _smsSender.SendSMSAsync(mobilePhone, string.Format(Resource.SmsAuthenticationMessageToUser, key)))
{ {
_tenantManager.SetTenantQuotaRow(new TenantQuotaRow { Tenant = _tenantManager.GetCurrentTenant().Id, Path = "/sms", Counter = 1 }, true); _tenantManager.SetTenantQuotaRow(new TenantQuotaRow { Tenant = _tenantManager.GetCurrentTenant().Id, Path = "/sms", Counter = 1, LastModified = DateTime.UtcNow }, true);
} }
} }