Merge branch 'hotfix/v1.0.1' into bugfix/62456
This commit is contained in:
commit
aa13ea9013
@ -24,10 +24,6 @@
|
||||
// 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 System.Linq;
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
|
||||
using JsonConverter = System.Text.Json.Serialization.JsonConverter;
|
||||
|
||||
namespace ASC.Api.Core;
|
||||
|
@ -76,13 +76,6 @@ public class CustomEndpointDataSource : EndpointDataSource
|
||||
|
||||
public static class EndpointExtension
|
||||
{
|
||||
private static readonly IReadOnlyList<string> _methodList = new List<string>
|
||||
{
|
||||
"POST",
|
||||
"PUT",
|
||||
"DELETE"
|
||||
};
|
||||
|
||||
public static async Task<IEndpointRouteBuilder> MapCustomAsync(this IEndpointRouteBuilder endpoints, bool webhooksEnabled = false, IServiceProvider serviceProvider = null)
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
@ -109,7 +102,7 @@ public static class EndpointExtension
|
||||
var httpMethodMetadata = r.Metadata.OfType<HttpMethodMetadata>().FirstOrDefault();
|
||||
var disabled = r.Metadata.OfType<WebhookDisableAttribute>().FirstOrDefault();
|
||||
|
||||
if (disabled == null)
|
||||
if (disabled == null && httpMethodMetadata != null)
|
||||
{
|
||||
foreach (var httpMethod in httpMethodMetadata.HttpMethods)
|
||||
{
|
||||
@ -118,7 +111,7 @@ public static class EndpointExtension
|
||||
}
|
||||
return result;
|
||||
})
|
||||
.Where(r => _methodList.Contains(r.Method))
|
||||
.Where(r => DbWorker.MethodList.Contains(r.Method))
|
||||
.DistinctBy(r => $"{r.Method}|{r.Route}")
|
||||
.ToList();
|
||||
|
||||
|
@ -51,7 +51,9 @@ public class WebhooksGlobalFilterAttribute : ResultFilterAttribute, IDisposable
|
||||
|
||||
public override async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
|
||||
{
|
||||
if (!await Skip(context.HttpContext))
|
||||
var skip = await Skip(context.HttpContext);
|
||||
|
||||
if (!skip)
|
||||
{
|
||||
_bodyStream = context.HttpContext.Response.Body;
|
||||
context.HttpContext.Response.Body = _stream;
|
||||
@ -59,7 +61,7 @@ public class WebhooksGlobalFilterAttribute : ResultFilterAttribute, IDisposable
|
||||
|
||||
await base.OnResultExecutionAsync(context, next);
|
||||
|
||||
if (context.Cancel || await Skip(context.HttpContext))
|
||||
if (context.Cancel || skip)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -113,6 +115,11 @@ public class WebhooksGlobalFilterAttribute : ResultFilterAttribute, IDisposable
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!DbWorker.MethodList.Contains(method))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var webhook = await _dbWorker.GetWebhookAsync(method, routePattern);
|
||||
if (webhook == null || _settingsManager.Load<WebHooksSettings>().Ids.Contains(webhook.Id))
|
||||
{
|
||||
|
@ -30,16 +30,15 @@ public class IPGeolocationInfo
|
||||
{
|
||||
public string Key { get; set; }
|
||||
public string City { get; set; }
|
||||
public double TimezoneOffset { get; set; }
|
||||
public float TimezoneOffset { get; set; }
|
||||
public string TimezoneName { get; set; }
|
||||
public string IPStart { get; set; }
|
||||
public string IPEnd { get; set; }
|
||||
public IPAddress IPStart { get; set; }
|
||||
public IPAddress IPEnd { get; set; }
|
||||
|
||||
|
||||
public static readonly IPGeolocationInfo Default = new IPGeolocationInfo
|
||||
{
|
||||
Key = string.Empty,
|
||||
IPStart = string.Empty,
|
||||
IPEnd = string.Empty,
|
||||
City = string.Empty,
|
||||
TimezoneName = string.Empty,
|
||||
};
|
||||
|
@ -326,6 +326,17 @@ public class TenantManager
|
||||
return result;
|
||||
}
|
||||
|
||||
public Dictionary<string, decimal> GetProductPriceInfo(string productId)
|
||||
{
|
||||
if (string.IsNullOrEmpty(productId))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var prices = TariffService.GetProductPriceInfo(new[] { productId });
|
||||
return prices.ContainsKey(productId) ? prices[productId] : null;
|
||||
}
|
||||
|
||||
public TenantQuota SaveTenantQuota(TenantQuota quota)
|
||||
{
|
||||
quota = QuotaService.SaveTenantQuota(quota);
|
||||
|
@ -1,130 +1,132 @@
|
||||
// (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.Core;
|
||||
|
||||
[Scope]
|
||||
public class RegionHelper
|
||||
{
|
||||
private readonly TenantManager _tenantManager;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly GeolocationHelper _geolocationHelper;
|
||||
private readonly UserManager _userManager;
|
||||
|
||||
public RegionHelper(
|
||||
TenantManager tenantManager,
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
GeolocationHelper geolocationHelper,
|
||||
UserManager userManager)
|
||||
{
|
||||
_tenantManager = tenantManager;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_geolocationHelper = geolocationHelper;
|
||||
_userManager = userManager;
|
||||
}
|
||||
|
||||
public RegionInfo GetCurrentRegionInfo()
|
||||
{
|
||||
var priceInfo = _tenantManager.GetProductPriceInfo();
|
||||
var defaultRegion = GetDefaultRegionInfo();
|
||||
|
||||
var countryCode = _httpContextAccessor.HttpContext.Request.Query["country"];
|
||||
|
||||
var currentRegion = GetRegionInfo(countryCode) ?? FindRegionInfo();
|
||||
|
||||
if (currentRegion != null && !currentRegion.Name.Equals(defaultRegion.Name))
|
||||
{
|
||||
if (priceInfo.Values.Any(value => value.ContainsKey(currentRegion.ISOCurrencySymbol)))
|
||||
{
|
||||
return currentRegion;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultRegion;
|
||||
}
|
||||
public RegionInfo GetDefaultRegionInfo()
|
||||
{
|
||||
return GetRegionInfo("US");
|
||||
}
|
||||
|
||||
public string GetCurrencyFromRequest()
|
||||
{
|
||||
var regionInfo = GetDefaultRegionInfo();
|
||||
var geoinfo = _geolocationHelper.GetIPGeolocationFromHttpContext();
|
||||
|
||||
if (!string.IsNullOrEmpty(geoinfo.Key))
|
||||
{
|
||||
try
|
||||
{
|
||||
regionInfo = new RegionInfo(geoinfo.Key);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
return regionInfo.ISOCurrencySymbol;
|
||||
}
|
||||
|
||||
private RegionInfo FindRegionInfo()
|
||||
{
|
||||
RegionInfo regionInfo = null;
|
||||
|
||||
var tenant = _tenantManager.GetCurrentTenant();
|
||||
var geoinfo = _geolocationHelper.GetIPGeolocationFromHttpContext();
|
||||
|
||||
if (geoinfo != null)
|
||||
{
|
||||
regionInfo = GetRegionInfo(geoinfo.Key);
|
||||
}
|
||||
|
||||
if (regionInfo == null)
|
||||
{
|
||||
var owner = _userManager.GetUsers(tenant.OwnerId);
|
||||
var culture = string.IsNullOrEmpty(owner.CultureName) ? tenant.GetCulture() : owner.GetCulture();
|
||||
regionInfo = GetRegionInfo(culture.Name);
|
||||
}
|
||||
|
||||
return regionInfo;
|
||||
}
|
||||
|
||||
private RegionInfo GetRegionInfo(string isoTwoLetterCountryCode)
|
||||
{
|
||||
RegionInfo regionInfo = null;
|
||||
|
||||
if (!string.IsNullOrEmpty(isoTwoLetterCountryCode))
|
||||
{
|
||||
try
|
||||
{
|
||||
regionInfo = new RegionInfo(isoTwoLetterCountryCode);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return regionInfo;
|
||||
}
|
||||
}
|
||||
// (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;
|
||||
|
||||
[Scope]
|
||||
public class RegionHelper
|
||||
{
|
||||
private readonly TenantManager _tenantManager;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly GeolocationHelper _geolocationHelper;
|
||||
private readonly UserManager _userManager;
|
||||
|
||||
public RegionHelper(
|
||||
TenantManager tenantManager,
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
GeolocationHelper geolocationHelper,
|
||||
UserManager userManager)
|
||||
{
|
||||
_tenantManager = tenantManager;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_geolocationHelper = geolocationHelper;
|
||||
_userManager = userManager;
|
||||
}
|
||||
|
||||
public RegionInfo GetCurrentRegionInfo(IDictionary<string, Dictionary<string, decimal>> priceInfo = null)
|
||||
{
|
||||
var defaultRegion = GetDefaultRegionInfo();
|
||||
|
||||
var countryCode = _httpContextAccessor.HttpContext.Request.Query["country"];
|
||||
|
||||
var currentRegion = GetRegionInfo(countryCode) ?? FindRegionInfo();
|
||||
|
||||
if (currentRegion != null && !currentRegion.Name.Equals(defaultRegion.Name))
|
||||
{
|
||||
priceInfo ??= _tenantManager.GetProductPriceInfo();
|
||||
|
||||
if (priceInfo.Values.Any(value => value.ContainsKey(currentRegion.ISOCurrencySymbol)))
|
||||
{
|
||||
return currentRegion;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultRegion;
|
||||
}
|
||||
|
||||
public RegionInfo GetDefaultRegionInfo()
|
||||
{
|
||||
return GetRegionInfo("US");
|
||||
}
|
||||
|
||||
public string GetCurrencyFromRequest()
|
||||
{
|
||||
var regionInfo = GetDefaultRegionInfo();
|
||||
var geoinfo = _geolocationHelper.GetIPGeolocationFromHttpContext();
|
||||
|
||||
if (!string.IsNullOrEmpty(geoinfo.Key))
|
||||
{
|
||||
try
|
||||
{
|
||||
regionInfo = new RegionInfo(geoinfo.Key);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
return regionInfo.ISOCurrencySymbol;
|
||||
}
|
||||
|
||||
private RegionInfo FindRegionInfo()
|
||||
{
|
||||
RegionInfo regionInfo = null;
|
||||
|
||||
var tenant = _tenantManager.GetCurrentTenant();
|
||||
var geoinfo = _geolocationHelper.GetIPGeolocationFromHttpContext();
|
||||
|
||||
if (geoinfo != null)
|
||||
{
|
||||
regionInfo = GetRegionInfo(geoinfo.Key);
|
||||
}
|
||||
|
||||
if (regionInfo == null)
|
||||
{
|
||||
var owner = _userManager.GetUsers(tenant.OwnerId);
|
||||
var culture = string.IsNullOrEmpty(owner.CultureName) ? tenant.GetCulture() : owner.GetCulture();
|
||||
regionInfo = GetRegionInfo(culture.Name);
|
||||
}
|
||||
|
||||
return regionInfo;
|
||||
}
|
||||
|
||||
private RegionInfo GetRegionInfo(string isoTwoLetterCountryCode)
|
||||
{
|
||||
RegionInfo regionInfo = null;
|
||||
|
||||
if (!string.IsNullOrEmpty(isoTwoLetterCountryCode))
|
||||
{
|
||||
try
|
||||
{
|
||||
regionInfo = new RegionInfo(isoTwoLetterCountryCode);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return regionInfo;
|
||||
}
|
||||
}
|
@ -26,7 +26,7 @@
|
||||
|
||||
namespace ASC.Core.Data;
|
||||
|
||||
[Scope]
|
||||
[Scope(Additional = typeof(DbQuotaServiceExtensions))]
|
||||
class DbQuotaService : IQuotaService
|
||||
{
|
||||
private readonly IDbContextFactory<CoreDbContext> _dbContextFactory;
|
||||
@ -41,19 +41,14 @@ class DbQuotaService : IQuotaService
|
||||
{
|
||||
using var coreDbContext = _dbContextFactory.CreateDbContext();
|
||||
|
||||
return coreDbContext.Quotas
|
||||
.ProjectTo<TenantQuota>(_mapper.ConfigurationProvider)
|
||||
.ToList();
|
||||
return _mapper.Map<List<DbQuota>, List<TenantQuota>>(coreDbContext.Quotas.ToList());
|
||||
}
|
||||
|
||||
public TenantQuota GetTenantQuota(int id)
|
||||
{
|
||||
using var coreDbContext = _dbContextFactory.CreateDbContext();
|
||||
|
||||
return coreDbContext.Quotas
|
||||
.Where(r => r.Tenant == id)
|
||||
.ProjectTo<TenantQuota>(_mapper.ConfigurationProvider)
|
||||
.SingleOrDefault();
|
||||
return _mapper.Map<DbQuota, TenantQuota>(coreDbContext.Quotas.SingleOrDefault(r => r.Tenant == id));
|
||||
}
|
||||
|
||||
public TenantQuota SaveTenantQuota(TenantQuota quota)
|
||||
@ -135,4 +130,12 @@ class DbQuotaService : IQuotaService
|
||||
|
||||
return q.ProjectTo<TenantQuotaRow>(_mapper.ConfigurationProvider).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public static class DbQuotaServiceExtensions
|
||||
{
|
||||
public static void Register(DIHelper services)
|
||||
{
|
||||
services.TryAdd<TenantQuotaPriceResolver>();
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ namespace ASC.Core.Common.EF.Context;
|
||||
public class CustomDbContext : DbContext
|
||||
{
|
||||
public DbSet<MobileAppInstall> MobileAppInstall { get; set; }
|
||||
public DbSet<DbipLocation> DbipLocation { get; set; }
|
||||
public DbSet<DbIPLookup> DbIPLookup { get; set; }
|
||||
public DbSet<Regions> Regions { get; set; }
|
||||
|
||||
public CustomDbContext(DbContextOptions<CustomDbContext> options) : base(options) { }
|
||||
@ -39,7 +39,7 @@ public class CustomDbContext : DbContext
|
||||
ModelBuilderWrapper
|
||||
.From(modelBuilder, Database)
|
||||
.AddMobileAppInstall()
|
||||
.AddDbipLocation()
|
||||
.AddDbIPLookup()
|
||||
.AddRegions();
|
||||
}
|
||||
}
|
||||
|
155
common/ASC.Core.Common/EF/Model/DbIPLookup.cs
Normal file
155
common/ASC.Core.Common/EF/Model/DbIPLookup.cs
Normal file
@ -0,0 +1,155 @@
|
||||
// (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.Common.EF.Model;
|
||||
|
||||
public class DbIPLookup
|
||||
{
|
||||
public string AddrType { get; set; } //ipv4, ipv6
|
||||
public byte[] IPStart { get; set; }
|
||||
public byte[] IPEnd { get; set; }
|
||||
public string Continent { get; set; }
|
||||
public string Country { get; set; }
|
||||
public string StateProvCode { get; set; }
|
||||
public string StateProv { get; set; }
|
||||
public string District { get; set; }
|
||||
public string City { get; set; }
|
||||
public string ZipCode { get; set; }
|
||||
public float Latitude { get; set; }
|
||||
public float Longitude { get; set; }
|
||||
public int? GeonameId { get; set; }
|
||||
public float TimezoneOffset { get; set; }
|
||||
public string TimezoneName { get; set; }
|
||||
public string WeatherCode { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public static class DbIPLookupExtension
|
||||
{
|
||||
public static ModelBuilderWrapper AddDbIPLookup(this ModelBuilderWrapper modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.Add(MySqlAddDbIPLookup, Provider.MySql)
|
||||
.Add(PgSqlAddDbIPLookup, Provider.PostgreSql);
|
||||
|
||||
return modelBuilder;
|
||||
}
|
||||
|
||||
public static void MySqlAddDbIPLookup(this ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<DbIPLookup>(entity =>
|
||||
{
|
||||
entity.ToTable("dbip_lookup")
|
||||
.HasCharSet("utf8mb4");
|
||||
|
||||
entity.HasKey(nameof(DbIPLookup.AddrType), nameof(DbIPLookup.IPStart));
|
||||
|
||||
entity.Property(e => e.AddrType)
|
||||
.IsRequired()
|
||||
.HasColumnName("addr_type")
|
||||
.HasColumnType("enum('ipv4','ipv6')");
|
||||
|
||||
entity.Property(e => e.IPStart)
|
||||
.IsRequired()
|
||||
.HasColumnName("ip_start")
|
||||
.HasColumnType("varbinary(16)");
|
||||
|
||||
entity.Property(e => e.IPEnd)
|
||||
.IsRequired()
|
||||
.HasColumnName("ip_end")
|
||||
.HasColumnType("varbinary(16)");
|
||||
|
||||
entity.Property(e => e.Continent)
|
||||
.IsRequired()
|
||||
.HasColumnName("continent")
|
||||
.HasColumnType("char(2)");
|
||||
|
||||
entity.Property(e => e.Country)
|
||||
.IsRequired()
|
||||
.HasColumnName("country")
|
||||
.HasColumnType("char(2)");
|
||||
|
||||
entity.Property(e => e.StateProvCode)
|
||||
.HasColumnName("stateprov_code")
|
||||
.HasColumnType("varchar(15)");
|
||||
|
||||
entity.Property(e => e.StateProv)
|
||||
.IsRequired()
|
||||
.HasColumnName("stateprov")
|
||||
.HasColumnType("varchar(80)");
|
||||
|
||||
entity.Property(e => e.District)
|
||||
.IsRequired()
|
||||
.HasColumnName("district")
|
||||
.HasColumnType("varchar(80)");
|
||||
|
||||
|
||||
entity.Property(e => e.City)
|
||||
.IsRequired()
|
||||
.HasColumnName("city")
|
||||
.HasColumnType("varchar(80)");
|
||||
|
||||
entity.Property(e => e.ZipCode)
|
||||
.HasColumnName("zipcode")
|
||||
.HasColumnType("varchar(20)");
|
||||
|
||||
entity.Property(e => e.Latitude)
|
||||
.IsRequired()
|
||||
.HasColumnName("latitude")
|
||||
.HasColumnType("float");
|
||||
|
||||
entity.Property(e => e.Longitude)
|
||||
.IsRequired()
|
||||
.HasColumnName("longitude")
|
||||
.HasColumnType("float");
|
||||
|
||||
entity.Property(e => e.GeonameId)
|
||||
.IsRequired(false)
|
||||
.HasColumnName("geoname_id")
|
||||
.HasColumnType("int(10)");
|
||||
|
||||
entity.Property(e => e.TimezoneOffset)
|
||||
.IsRequired()
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("timezone_offset");
|
||||
|
||||
entity.Property(e => e.TimezoneName)
|
||||
.IsRequired()
|
||||
.HasColumnName("timezone_name")
|
||||
.HasColumnType("varchar(64)");
|
||||
|
||||
entity.Property(e => e.WeatherCode)
|
||||
.IsRequired()
|
||||
.HasColumnName("weather_code")
|
||||
.HasColumnType("varchar(10)");
|
||||
});
|
||||
|
||||
}
|
||||
public static void PgSqlAddDbIPLookup(this ModelBuilder modelBuilder)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
@ -1,225 +0,0 @@
|
||||
// (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.Common.EF.Model;
|
||||
|
||||
public class DbipLocation
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string AddrType { get; set; }
|
||||
public string IPStart { get; set; }
|
||||
public string IPEnd { get; set; }
|
||||
public string Country { get; set; }
|
||||
public string StateProv { get; set; }
|
||||
public string District { get; set; }
|
||||
public string City { get; set; }
|
||||
public string ZipCode { get; set; }
|
||||
public long? Latitude { get; set; }
|
||||
public long? Longitude { get; set; }
|
||||
public int? GeonameId { get; set; }
|
||||
public double? TimezoneOffset { get; set; }
|
||||
public string TimezoneName { get; set; }
|
||||
public int Processed { get; set; }
|
||||
}
|
||||
|
||||
public static class DbipLocationExtension
|
||||
{
|
||||
public static ModelBuilderWrapper AddDbipLocation(this ModelBuilderWrapper modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.Add(MySqlAddDbipLocation, Provider.MySql)
|
||||
.Add(PgSqlAddDbipLocation, Provider.PostgreSql);
|
||||
|
||||
return modelBuilder;
|
||||
}
|
||||
|
||||
public static void MySqlAddDbipLocation(this ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<DbipLocation>(entity =>
|
||||
{
|
||||
entity.ToTable("dbip_location")
|
||||
.HasCharSet("utf8");
|
||||
|
||||
entity.HasIndex(e => e.IPStart)
|
||||
.HasDatabaseName("ip_start");
|
||||
|
||||
entity.Property(e => e.Id).HasColumnName("id");
|
||||
|
||||
entity.Property(e => e.AddrType)
|
||||
.IsRequired()
|
||||
.HasColumnName("addr_type")
|
||||
.HasColumnType("enum('ipv4','ipv6')")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.City)
|
||||
.IsRequired()
|
||||
.HasColumnName("city")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.Country)
|
||||
.IsRequired()
|
||||
.HasColumnName("country")
|
||||
.HasColumnType("varchar(2)")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.District)
|
||||
.HasColumnName("district")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.GeonameId)
|
||||
.HasColumnName("geoname_id")
|
||||
.IsRequired(false)
|
||||
.HasDefaultValueSql("NULL");
|
||||
|
||||
entity.Property(e => e.IPEnd)
|
||||
.IsRequired()
|
||||
.HasColumnName("ip_end")
|
||||
.HasColumnType("varchar(39)")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.IPStart)
|
||||
.IsRequired()
|
||||
.HasColumnName("ip_start")
|
||||
.HasColumnType("varchar(39)")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.Latitude)
|
||||
.HasColumnName("latitude")
|
||||
.HasColumnType("float")
|
||||
.IsRequired(false)
|
||||
.HasDefaultValueSql("NULL");
|
||||
|
||||
entity.Property(e => e.Longitude)
|
||||
.HasColumnName("longitude")
|
||||
.HasColumnType("float")
|
||||
.IsRequired(false)
|
||||
.HasDefaultValueSql("NULL");
|
||||
|
||||
entity.Property(e => e.Processed)
|
||||
.HasColumnName("processed")
|
||||
.HasDefaultValueSql("'1'");
|
||||
|
||||
entity.Property(e => e.StateProv)
|
||||
.IsRequired()
|
||||
.HasColumnName("stateprov")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.TimezoneName)
|
||||
.HasColumnName("timezone_name")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.TimezoneOffset)
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("timezone_offset")
|
||||
.IsRequired(false)
|
||||
.HasDefaultValueSql("NULL");
|
||||
|
||||
entity.Property(e => e.ZipCode)
|
||||
.HasColumnName("zipcode")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
});
|
||||
|
||||
}
|
||||
public static void PgSqlAddDbipLocation(this ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.HasPostgresEnum("onlyoffice", "enum_dbip_location", new[] { "ipv4", "ipv6" });
|
||||
modelBuilder.Entity<DbipLocation>(entity =>
|
||||
{
|
||||
entity.ToTable("dbip_location", "onlyoffice");
|
||||
|
||||
entity.HasIndex(e => e.IPStart)
|
||||
.HasDatabaseName("ip_start");
|
||||
|
||||
entity.Property(e => e.Id).HasColumnName("id");
|
||||
|
||||
entity.Property(e => e.City)
|
||||
.IsRequired()
|
||||
.HasColumnName("city")
|
||||
.HasMaxLength(255);
|
||||
|
||||
entity.Property(e => e.Country)
|
||||
.IsRequired()
|
||||
.HasColumnName("country")
|
||||
.HasMaxLength(2);
|
||||
|
||||
entity.Property(e => e.District)
|
||||
.HasColumnName("district")
|
||||
.HasMaxLength(255)
|
||||
.HasDefaultValueSql("NULL");
|
||||
|
||||
entity.Property(e => e.GeonameId).HasColumnName("geoname_id");
|
||||
|
||||
entity.Property(e => e.IPEnd)
|
||||
.IsRequired()
|
||||
.HasColumnName("ip_end")
|
||||
.HasMaxLength(39);
|
||||
|
||||
entity.Property(e => e.IPStart)
|
||||
.IsRequired()
|
||||
.HasColumnName("ip_start")
|
||||
.HasMaxLength(39);
|
||||
|
||||
entity.Property(e => e.Latitude).HasColumnName("latitude");
|
||||
|
||||
entity.Property(e => e.Longitude).HasColumnName("longitude");
|
||||
|
||||
entity.Property(e => e.Processed)
|
||||
.HasColumnName("processed")
|
||||
.HasDefaultValueSql("1");
|
||||
|
||||
entity.Property(e => e.StateProv)
|
||||
.IsRequired()
|
||||
.HasColumnName("stateprov")
|
||||
.HasMaxLength(255);
|
||||
|
||||
entity.Property(e => e.TimezoneName)
|
||||
.HasColumnName("timezone_name")
|
||||
.HasMaxLength(255)
|
||||
.HasDefaultValueSql("NULL");
|
||||
|
||||
entity.Property(e => e.TimezoneOffset).HasColumnName("timezone_offset");
|
||||
|
||||
entity.Property(e => e.ZipCode)
|
||||
.HasColumnName("zipcode")
|
||||
.HasMaxLength(255)
|
||||
.HasDefaultValueSql("NULL");
|
||||
});
|
||||
}
|
||||
}
|
@ -26,45 +26,69 @@
|
||||
|
||||
namespace ASC.Geolocation;
|
||||
|
||||
// hack for EF Core
|
||||
public static class EntityFrameworkHelper
|
||||
{
|
||||
public static int Compare(this byte[] b1, byte[] b2)
|
||||
{
|
||||
throw new Exception("This method can only be used in EF LINQ Context");
|
||||
}
|
||||
}
|
||||
|
||||
[Scope]
|
||||
public class GeolocationHelper
|
||||
{
|
||||
private readonly CreatorDbContext _creatorDbContext;
|
||||
private readonly IDbContextFactory<CustomDbContext> _dbContextFactory;
|
||||
private readonly ILogger<GeolocationHelper> _logger;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly ICache _cache;
|
||||
|
||||
public GeolocationHelper(
|
||||
CreatorDbContext creatorDbContext,
|
||||
IDbContextFactory<CustomDbContext> dbContextFactory,
|
||||
ILogger<GeolocationHelper> logger,
|
||||
IHttpContextAccessor httpContextAccessor)
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
ICache cache)
|
||||
{
|
||||
_creatorDbContext = creatorDbContext;
|
||||
_dbContextFactory = dbContextFactory;
|
||||
_logger = logger;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_cache = cache;
|
||||
}
|
||||
|
||||
public IPGeolocationInfo GetIPGeolocation(string ip)
|
||||
public IPGeolocationInfo GetIPGeolocation(IPAddress address)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var dbContext = _creatorDbContext.CreateDbContext<CustomDbContext>(nameConnectionString: "teamlabsite");
|
||||
var ipformatted = FormatIP(ip);
|
||||
var q = dbContext.DbipLocation
|
||||
.Where(r => r.IPStart.CompareTo(ipformatted) <= 0)
|
||||
.Where(r => ipformatted.CompareTo(r.IPEnd) <= 0)
|
||||
|
||||
var cacheKey = $"ip_geolocation_info_${address}";
|
||||
var fromCache = _cache.Get<IPGeolocationInfo>(cacheKey);
|
||||
|
||||
if (fromCache != null) return fromCache;
|
||||
|
||||
using var dbContext = _dbContextFactory.CreateDbContext();
|
||||
|
||||
var addrType = address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork ? "ipv4" : "ipv6";
|
||||
|
||||
var result = dbContext.DbIPLookup
|
||||
.Where(r => r.AddrType == addrType && r.IPStart.Compare(address.GetAddressBytes()) <= 0)
|
||||
.OrderByDescending(r => r.IPStart)
|
||||
.Select(r => new IPGeolocationInfo
|
||||
{
|
||||
City = r.City,
|
||||
IPEnd = r.IPEnd,
|
||||
IPStart = r.IPStart,
|
||||
IPEnd = new IPAddress(r.IPEnd),
|
||||
IPStart = new IPAddress(r.IPStart),
|
||||
Key = r.Country,
|
||||
TimezoneOffset = r.TimezoneOffset ?? 0,
|
||||
TimezoneOffset = r.TimezoneOffset,
|
||||
TimezoneName = r.TimezoneName
|
||||
})
|
||||
.FirstOrDefault();
|
||||
|
||||
return q ?? IPGeolocationInfo.Default;
|
||||
if (result != null)
|
||||
{
|
||||
_cache.Insert(cacheKey, result, TimeSpan.FromSeconds(15));
|
||||
}
|
||||
|
||||
return result ?? IPGeolocationInfo.Default;
|
||||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
@ -84,44 +108,10 @@ public class GeolocationHelper
|
||||
{
|
||||
_logger.DebugRemoteIpAddress(ip.ToString());
|
||||
|
||||
return GetIPGeolocation(ip.ToString());
|
||||
return GetIPGeolocation(ip);
|
||||
}
|
||||
}
|
||||
|
||||
return IPGeolocationInfo.Default;
|
||||
}
|
||||
|
||||
private static string FormatIP(string ip)
|
||||
{
|
||||
ip = (ip ?? "").Trim();
|
||||
if (ip.Contains('.'))
|
||||
{
|
||||
//ip v4
|
||||
if (ip.Length == 15)
|
||||
{
|
||||
return ip;
|
||||
}
|
||||
|
||||
return string.Join(".", ip.Split(':')[0].Split('.').Select(s => ("00" + s).Substring(s.Length - 1)).ToArray());
|
||||
}
|
||||
else if (ip.Contains(':'))
|
||||
{
|
||||
//ip v6
|
||||
if (ip.Length == 39)
|
||||
{
|
||||
return ip;
|
||||
}
|
||||
var index = ip.IndexOf("::");
|
||||
if (0 <= index)
|
||||
{
|
||||
ip = ip.Insert(index + 2, new string(':', 8 - ip.Split(':').Length));
|
||||
}
|
||||
|
||||
return string.Join(":", ip.Split(':').Select(s => ("0000" + s).Substring(s.Length)).ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("Unknown ip " + ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
namespace ASC.Core.Common.Log;
|
||||
internal static partial class GeolocationHelperLogger
|
||||
{
|
||||
[LoggerMessage(Level = LogLevel.Error, Message = "This is remote ip address {remoteIp}")]
|
||||
[LoggerMessage(Level = LogLevel.Debug, Message = "This is remote ip address {remoteIp}")]
|
||||
public static partial void DebugRemoteIpAddress(this ILogger<GeolocationHelper> logger, string remoteIp);
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Error, Message = "GetIPGeolocation")]
|
||||
|
@ -42,6 +42,7 @@ public class TenantQuota : IMapFrom<DbQuota>
|
||||
public int Tenant { get; set; }
|
||||
public string Name { get; set; }
|
||||
public decimal Price { get; set; }
|
||||
public string PriceCurrencySymbol { get; set; }
|
||||
public string ProductId { get; set; }
|
||||
public bool Visible { get; set; }
|
||||
|
||||
@ -373,7 +374,8 @@ public class TenantQuota : IMapFrom<DbQuota>
|
||||
|
||||
public void Mapping(Profile profile)
|
||||
{
|
||||
profile.CreateMap<DbQuota, TenantQuota>();
|
||||
profile.CreateMap<DbQuota, TenantQuota>()
|
||||
.ForMember(dest => dest.Price, o => o.MapFrom<TenantQuotaPriceResolver>());
|
||||
}
|
||||
|
||||
public TenantQuotaFeature<T> GetFeature<T>(string name)
|
||||
|
58
common/ASC.Core.Common/Tenants/TenantQuotaPriceResolver.cs
Normal file
58
common/ASC.Core.Common/Tenants/TenantQuotaPriceResolver.cs
Normal file
@ -0,0 +1,58 @@
|
||||
// (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.Common.Tenants;
|
||||
|
||||
[Scope]
|
||||
internal class TenantQuotaPriceResolver : IValueResolver<DbQuota, TenantQuota, decimal>
|
||||
{
|
||||
private readonly TenantManager _tenantManager;
|
||||
private readonly RegionHelper _regionHelper;
|
||||
|
||||
public TenantQuotaPriceResolver(TenantManager tenantManager, RegionHelper regionHelper)
|
||||
{
|
||||
_tenantManager = tenantManager;
|
||||
_regionHelper = regionHelper;
|
||||
}
|
||||
|
||||
public decimal Resolve(DbQuota source, TenantQuota destination, decimal destMember, ResolutionContext context)
|
||||
{
|
||||
var priceInfo = _tenantManager.GetProductPriceInfo(source.ProductId);
|
||||
|
||||
if (priceInfo != null)
|
||||
{
|
||||
var currentRegion = _regionHelper.GetCurrentRegionInfo(new Dictionary<string, Dictionary<string, decimal>>() { { source.ProductId, priceInfo } });
|
||||
destination.PriceCurrencySymbol = currentRegion.CurrencySymbol;
|
||||
|
||||
if (priceInfo.ContainsKey(currentRegion.ISOCurrencySymbol))
|
||||
{
|
||||
return priceInfo[currentRegion.ISOCurrencySymbol];
|
||||
}
|
||||
}
|
||||
|
||||
return source.Price;
|
||||
}
|
||||
}
|
@ -43,6 +43,7 @@ public class TenantsModuleSpecifics : ModuleSpecificsBase
|
||||
{
|
||||
DateColumns = new Dictionary<string, bool> {{"creationdatetime", false}, {"statuschanged", false}, {"version_changed", false}}
|
||||
},
|
||||
new TableInfo("tenants_tariffrow", "tenant") {InsertMethod = InsertMethod.Replace},
|
||||
new TableInfo("tenants_quotarow", "tenant") {InsertMethod = InsertMethod.Replace},
|
||||
new TableInfo("core_user", "tenant", "id", IdType.Guid)
|
||||
{
|
||||
@ -58,6 +59,7 @@ public class TenantsModuleSpecifics : ModuleSpecificsBase
|
||||
new RelationInfo("tenants_tenants", "id", "tenants_quota", "tenant"),
|
||||
new RelationInfo("tenants_tenants", "id", "tenants_tariff", "tenant"),
|
||||
new RelationInfo("tenants_tenants", "id", "tenants_tariff", "tariff"),
|
||||
new RelationInfo("tenants_tariff", "id", "tenants_tariffrow", "tariff_id"),
|
||||
new RelationInfo("core_user", "id", "tenants_tenants", "owner_id", null, null, RelationImportance.Low)
|
||||
};
|
||||
|
||||
|
@ -31,6 +31,13 @@ namespace ASC.Webhooks.Core;
|
||||
[Scope]
|
||||
public class DbWorker
|
||||
{
|
||||
public static readonly IReadOnlyList<string> MethodList = new List<string>
|
||||
{
|
||||
"POST",
|
||||
"PUT",
|
||||
"DELETE"
|
||||
};
|
||||
|
||||
private readonly IDbContextFactory<WebhooksDbContext> _dbContextFactory;
|
||||
private readonly TenantManager _tenantManager;
|
||||
private readonly AuthContext _authContext;
|
||||
|
@ -243,7 +243,7 @@ public class ConnectionsController : ControllerBase
|
||||
{
|
||||
try
|
||||
{
|
||||
var location = _geolocationHelper.GetIPGeolocation(ip);
|
||||
var location = _geolocationHelper.GetIPGeolocation(IPAddress.Parse(ip));
|
||||
if (string.IsNullOrEmpty(location.Key))
|
||||
{
|
||||
return new string[] { string.Empty, string.Empty };
|
||||
|
@ -30,40 +30,33 @@ namespace ASC.Web.Api.Core;
|
||||
public class QuotaHelper
|
||||
{
|
||||
private readonly TenantManager _tenantManager;
|
||||
private readonly RegionHelper _regionHelper;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
public QuotaHelper(TenantManager tenantManager, RegionHelper regionHelper, IServiceProvider serviceProvider)
|
||||
public QuotaHelper(TenantManager tenantManager, IServiceProvider serviceProvider)
|
||||
{
|
||||
_tenantManager = tenantManager;
|
||||
_regionHelper = regionHelper;
|
||||
_serviceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
public async IAsyncEnumerable<QuotaDto> GetQuotas()
|
||||
{
|
||||
var quotaList = _tenantManager.GetTenantQuotas(false);
|
||||
var priceInfo = _tenantManager.GetProductPriceInfo();
|
||||
var currentRegion = _regionHelper.GetCurrentRegionInfo();
|
||||
|
||||
foreach (var quota in quotaList)
|
||||
{
|
||||
yield return await ToQuotaDto(quota, priceInfo, currentRegion);
|
||||
yield return await ToQuotaDto(quota);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<QuotaDto> GetCurrentQuota(bool refresh = false)
|
||||
{
|
||||
var quota = _tenantManager.GetCurrentTenantQuota(refresh);
|
||||
var priceInfo = _tenantManager.GetProductPriceInfo();
|
||||
var currentRegion = _regionHelper.GetCurrentRegionInfo();
|
||||
|
||||
return await ToQuotaDto(quota, priceInfo, currentRegion, true, true);
|
||||
return await ToQuotaDto(quota, true, true);
|
||||
}
|
||||
|
||||
private async Task<QuotaDto> ToQuotaDto(TenantQuota quota, IDictionary<string, Dictionary<string, decimal>> priceInfo, RegionInfo currentRegion, bool getUsed = false, bool allFeatures = false)
|
||||
private async Task<QuotaDto> ToQuotaDto(TenantQuota quota, bool getUsed = false, bool allFeatures = false)
|
||||
{
|
||||
var price = GetPrice(quota, priceInfo, currentRegion);
|
||||
var features = await GetFeatures(quota, getUsed, allFeatures).ToListAsync();
|
||||
|
||||
return new QuotaDto
|
||||
@ -77,27 +70,14 @@ public class QuotaHelper
|
||||
|
||||
Price = new PriceDto
|
||||
{
|
||||
Value = price,
|
||||
CurrencySymbol = currentRegion.CurrencySymbol
|
||||
Value = quota.Price,
|
||||
CurrencySymbol = quota.PriceCurrencySymbol
|
||||
},
|
||||
|
||||
Features = features
|
||||
};
|
||||
}
|
||||
|
||||
private decimal GetPrice(TenantQuota quota, IDictionary<string, Dictionary<string, decimal>> priceInfo, RegionInfo currentRegion)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(quota.Name) && priceInfo.ContainsKey(quota.Name))
|
||||
{
|
||||
var prices = priceInfo[quota.Name];
|
||||
if (prices.ContainsKey(currentRegion.ISOCurrencySymbol))
|
||||
{
|
||||
return prices[currentRegion.ISOCurrencySymbol];
|
||||
}
|
||||
}
|
||||
return quota.Price;
|
||||
}
|
||||
|
||||
private async IAsyncEnumerable<TenantQuotaFeatureDto> GetFeatures(TenantQuota quota, bool getUsed, bool all)
|
||||
{
|
||||
var assembly = GetType().Assembly;
|
||||
|
Loading…
Reference in New Issue
Block a user