DocSpace-buildtools/common/services/ASC.ApiSystem/Classes/CommonMethods.cs

329 lines
12 KiB
C#
Raw Normal View History

2022-04-22 13:24:54 +00:00
// (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.ApiSystem.Controllers;
[Scope]
public class CommonMethods
{
private IHttpContextAccessor HttpContextAccessor { get; }
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
private IConfiguration Configuration { get; }
2020-02-18 13:48:38 +00:00
2022-07-18 15:30:08 +00:00
private ILogger<CommonMethods> Log { get; }
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
private CoreSettings CoreSettings { get; }
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
private CommonLinkUtility CommonLinkUtility { get; }
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
private EmailValidationKeyProvider EmailValidationKeyProvider { get; }
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
private TimeZoneConverter TimeZoneConverter { get; }
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
private CommonConstants CommonConstants { get; }
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
private HostedSolution HostedSolution { get; }
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
private IMemoryCache MemoryCache { get; }
2020-10-26 14:23:23 +00:00
2022-04-22 13:24:54 +00:00
private CoreBaseSettings CoreBaseSettings { get; }
2020-10-26 14:23:23 +00:00
2022-04-22 13:24:54 +00:00
private TenantManager TenantManager { get; }
2020-09-18 07:59:23 +00:00
2022-04-22 13:24:54 +00:00
private IHttpClientFactory ClientFactory { get; }
public CommonMethods(
IHttpContextAccessor httpContextAccessor,
IConfiguration configuration,
2022-07-18 15:30:08 +00:00
ILogger<CommonMethods> log,
2022-04-22 13:24:54 +00:00
CoreSettings coreSettings,
CommonLinkUtility commonLinkUtility,
EmailValidationKeyProvider emailValidationKeyProvider,
TimeZoneConverter timeZoneConverter, CommonConstants commonConstants,
IMemoryCache memoryCache,
HostedSolution hostedSolution,
2022-04-22 13:24:54 +00:00
CoreBaseSettings coreBaseSettings,
TenantManager tenantManager,
IHttpClientFactory clientFactory)
{
HttpContextAccessor = httpContextAccessor;
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
Configuration = configuration;
2020-02-18 13:48:38 +00:00
2022-07-18 15:30:08 +00:00
Log = log;
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
CoreSettings = coreSettings;
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
CommonLinkUtility = commonLinkUtility;
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
EmailValidationKeyProvider = emailValidationKeyProvider;
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
TimeZoneConverter = timeZoneConverter;
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
CommonConstants = commonConstants;
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
MemoryCache = memoryCache;
2022-04-22 13:24:54 +00:00
CoreBaseSettings = coreBaseSettings;
2022-04-22 13:24:54 +00:00
TenantManager = tenantManager;
2022-04-22 13:24:54 +00:00
ClientFactory = clientFactory;
HostedSolution = hostedSolution;
HostedSolution.Init(CommonConstants.BaseDbConnKeyString);
2022-04-22 13:24:54 +00:00
}
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
public object ToTenantWrapper(Tenant t)
{
return new
2020-02-18 13:48:38 +00:00
{
2022-04-22 13:24:54 +00:00
created = t.CreationDateTime,
domain = t.GetTenantDomain(CoreSettings),
hostedRegion = t.HostedRegion,
industry = t.Industry,
language = t.Language,
name = t.Name == "" ? Resource.PortalName : t.Name,
2022-04-22 13:24:54 +00:00
ownerId = t.OwnerId,
paymentId = t.PaymentId,
portalName = t.Alias,
status = t.Status.ToString(),
tenantId = t.Id,
timeZoneName = TimeZoneConverter.GetTimeZone(t.TimeZone).DisplayName,
};
}
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
public string CreateReference(string requestUriScheme, string tenantDomain, string email, bool first = false, string module = "", bool sms = false)
{
var url = CommonLinkUtility.GetConfirmationUrlRelative(email, ConfirmType.Auth, (first ? "true" : "") + module + (sms ? "true" : ""));
return $"{requestUriScheme}{Uri.SchemeDelimiter}{tenantDomain}/{url}{(first ? "&first=true" : "")}{(string.IsNullOrEmpty(module) ? "" : "&module=" + module)}{(sms ? "&sms=true" : "")}";
}
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
public bool SendCongratulations(string requestUriScheme, Tenant tenant, bool skipWelcome, out string url)
{
var validationKey = EmailValidationKeyProvider.GetEmailKey(tenant.Id, tenant.OwnerId.ToString() + ConfirmType.Auth);
url = string.Format("{0}{1}{2}{3}{4}?userid={5}&key={6}",
requestUriScheme,
Uri.SchemeDelimiter,
tenant.GetTenantDomain(CoreSettings),
CommonConstants.WebApiBaseUrl,
"portal/sendcongratulations",
tenant.OwnerId,
validationKey);
if (skipWelcome)
2020-02-18 13:48:38 +00:00
{
2022-07-18 15:30:08 +00:00
Log.LogDebug("congratulations skiped");
2022-04-22 13:24:54 +00:00
return false;
}
2021-10-12 10:14:33 +00:00
2022-04-22 13:24:54 +00:00
var request = new HttpRequestMessage();
request.Method = HttpMethod.Post;
request.RequestUri = new Uri(url);
2022-04-22 13:24:54 +00:00
request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/x-www-form-urlencoded"));
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
try
{
var httpClient = ClientFactory.CreateClient();
using var response = httpClient.Send(request);
using var stream = response.Content.ReadAsStream();
using var reader = new StreamReader(stream, Encoding.UTF8);
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
var result = reader.ReadToEnd();
2020-02-18 13:48:38 +00:00
2022-07-18 15:30:08 +00:00
Log.LogDebug("congratulations result = {0}", result);
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
var resObj = JObject.Parse(result);
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
if (resObj["errors"] != null && resObj["errors"].HasValues)
2020-02-18 13:48:38 +00:00
{
2022-04-22 13:24:54 +00:00
throw new Exception(result);
2020-02-18 13:48:38 +00:00
}
}
2022-04-22 13:24:54 +00:00
catch (Exception ex)
{
2022-07-18 15:30:08 +00:00
Log.LogError(ex, "SendCongratulations error");
2020-02-18 13:48:38 +00:00
return false;
}
2022-04-22 13:24:54 +00:00
url = null;
return true;
}
public bool GetTenant(IModel model, out Tenant tenant)
{
if (CoreBaseSettings.Standalone && model != null && !string.IsNullOrWhiteSpace((model.PortalName ?? "")))
2020-09-18 07:59:23 +00:00
{
2022-04-22 13:24:54 +00:00
tenant = TenantManager.GetTenant((model.PortalName ?? "").Trim());
return true;
}
if (model != null && model.TenantId.HasValue)
{
tenant = HostedSolution.GetTenant(model.TenantId.Value);
return true;
2020-02-18 13:48:38 +00:00
}
2022-04-22 13:24:54 +00:00
if (model != null && !string.IsNullOrWhiteSpace((model.PortalName ?? "")))
2020-02-18 13:48:38 +00:00
{
2022-04-22 13:24:54 +00:00
tenant = HostedSolution.GetTenant((model.PortalName ?? "").Trim());
return true;
}
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
tenant = null;
return false;
}
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
public bool IsTestEmail(string email)
{
//the point is not needed in gmail.com
email = Regex.Replace(email ?? "", "\\.*(?=\\S*(@gmail.com$))", "").ToLower();
if (string.IsNullOrEmpty(email) || string.IsNullOrEmpty(CommonConstants.AutotestSecretEmails))
return false;
var regex = new Regex(CommonConstants.AutotestSecretEmails, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled);
return regex.IsMatch(email);
}
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
public bool CheckMuchRegistration(TenantModel model, string clientIP, Stopwatch sw)
{
if (IsTestEmail(model.Email)) return false;
2020-02-18 13:48:38 +00:00
2022-07-18 15:30:08 +00:00
Log.LogDebug("clientIP = {0}", clientIP);
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
var cacheKey = "ip_" + clientIP;
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
if (MemoryCache.TryGetValue(cacheKey, out int ipAttemptsCount))
2020-02-18 13:48:38 +00:00
{
2022-04-22 13:24:54 +00:00
MemoryCache.Remove(cacheKey);
}
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
ipAttemptsCount++;
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
MemoryCache.Set(
// String that represents the name of the cache item,
// could be any string
cacheKey,
// Something to store in the cache
ipAttemptsCount,
new MemoryCacheEntryOptions
{
// Will not use absolute cache expiration
AbsoluteExpiration = DateTime.MaxValue,
// Cache will expire after one hour
// You can change this time interval according
// to your requriements
SlidingExpiration = CommonConstants.MaxAttemptsTimeInterval,
// Cache will not be removed before expired
Priority = CacheItemPriority.NeverRemove
});
if (ipAttemptsCount <= CommonConstants.MaxAttemptsCount) return false;
2022-07-18 15:30:08 +00:00
Log.LogDebug("PortalName = {0}; Too much reqests from ip: {1}", model.PortalName, clientIP);
2022-04-22 13:24:54 +00:00
sw.Stop();
return true;
}
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
public string GetClientIp()
{
return HttpContextAccessor.HttpContext.Connection.RemoteIpAddress.ToString();
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
//TODO: check old version
2020-02-18 13:48:38 +00:00
2022-04-22 13:24:54 +00:00
//if (request.Properties.ContainsKey("MS_HttpContext"))
//{
// return ((HttpContextWrapper)request.Properties["MS_HttpContext"]).Request.UserHostAddress;
//}
//if (request.Properties.ContainsKey(RemoteEndpointMessageProperty.Name))
//{
// var prop = (RemoteEndpointMessageProperty)request.Properties[RemoteEndpointMessageProperty.Name];
// return prop.Address;
//}
//return null;
}
public bool ValidateRecaptcha(string response, RecaptchaType recaptchaType, string ip)
{
try
{
string privateKey;
switch (recaptchaType)
2021-11-29 11:11:03 +00:00
{
2022-04-22 13:24:54 +00:00
case RecaptchaType.AndroidV2:
privateKey = Configuration["recaptcha:private-key:android"];
break;
case RecaptchaType.iOSV2:
privateKey = Configuration["recaptcha:private-key:ios"];
break;
default:
privateKey = Configuration["recaptcha:private-key"];
break;
}
2021-11-29 11:11:03 +00:00
2022-04-22 13:24:54 +00:00
var data = $"secret={privateKey}&remoteip={ip}&response={response}";
var url = Configuration["recaptcha:verify-url"] ?? "https://www.recaptcha.net/recaptcha/api/siteverify";
2021-10-12 10:14:33 +00:00
2022-04-22 13:24:54 +00:00
var request = new HttpRequestMessage();
request.RequestUri = new Uri(url);
request.Method = HttpMethod.Post;
request.Content = new StringContent(data, Encoding.UTF8, "application/x-www-form-urlencoded");
2021-10-12 10:14:33 +00:00
2022-04-22 13:24:54 +00:00
var httpClient = ClientFactory.CreateClient();
using var httpClientResponse = httpClient.Send(request);
using var stream = httpClientResponse.Content.ReadAsStream();
using var reader = new StreamReader(stream);
var resp = reader.ReadToEnd();
var resObj = JObject.Parse(resp);
if (resObj["success"] != null && resObj.Value<bool>("success"))
{
return true;
2020-02-18 13:48:38 +00:00
}
2022-04-22 13:24:54 +00:00
else
2020-02-18 13:48:38 +00:00
{
2022-07-18 15:30:08 +00:00
Log.LogDebug("Recaptcha error: {0}", resp);
2020-02-18 13:48:38 +00:00
}
2022-04-22 13:24:54 +00:00
if (resObj["error-codes"] != null && resObj["error-codes"].HasValues)
{
2022-07-18 15:30:08 +00:00
Log.LogDebug("Recaptcha api returns errors: {0}", resp);
2022-04-22 13:24:54 +00:00
}
}
catch (Exception ex)
{
2022-07-18 15:30:08 +00:00
Log.LogError(ex, "ValidateRecaptcha");
2020-02-18 13:48:38 +00:00
}
2022-04-22 13:24:54 +00:00
return false;
2020-02-18 13:48:38 +00:00
}
2022-04-22 13:24:54 +00:00
}