merge from feature/backend-refactor

This commit is contained in:
Alexey Bannov 2022-04-12 22:04:10 +03:00
commit 4828678e03
99 changed files with 2634 additions and 3037 deletions

View File

@ -28,12 +28,12 @@ using SecurityContext = ASC.Core.SecurityContext;
namespace ASC.Api.Core.Auth;
[Scope(Additional = typeof(ConfirmAuthHandlerExtension))]
[Transient]
public class ConfirmAuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
private readonly SecurityContext _securityContext;
private readonly UserManager _userManager;
private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly EmailValidationKeyModelHelper _emailValidationKeyModelHelper;
public ConfirmAuthHandler(
IOptionsMonitor<AuthenticationSchemeOptions> options,
@ -50,20 +50,17 @@ public class ConfirmAuthHandler : AuthenticationHandler<AuthenticationSchemeOpti
ISystemClock clock,
SecurityContext securityContext,
UserManager userManager,
IServiceScopeFactory serviceScopeFactory) :
EmailValidationKeyModelHelper emailValidationKeyModelHelper) :
base(options, logger, encoder, clock)
{
_securityContext = securityContext;
_userManager = userManager;
_serviceScopeFactory = serviceScopeFactory;
_emailValidationKeyModelHelper = emailValidationKeyModelHelper;
}
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
{
using var scope = _serviceScopeFactory.CreateScope();
var emailValidationKeyHelper = scope.ServiceProvider.GetService<EmailValidationKeyModelHelper>();
var emailValidationKeyModel = emailValidationKeyHelper.GetModel();
var emailValidationKeyModel = _emailValidationKeyModelHelper.GetModel();
if (!emailValidationKeyModel.Type.HasValue)
{
@ -75,7 +72,7 @@ public class ConfirmAuthHandler : AuthenticationHandler<AuthenticationSchemeOpti
EmailValidationKeyProvider.ValidationResult checkKeyResult;
try
{
checkKeyResult = emailValidationKeyHelper.Validate(emailValidationKeyModel);
checkKeyResult = _emailValidationKeyModelHelper.Validate(emailValidationKeyModel);
}
catch (ArgumentNullException)
{
@ -126,12 +123,4 @@ public class ConfirmAuthHandler : AuthenticationHandler<AuthenticationSchemeOpti
return Task.FromResult(result);
}
}
public static class ConfirmAuthHandlerExtension
{
public static void Register(DIHelper services)
{
services.TryAdd<EmailValidationKeyModelHelper>();
}
}

View File

@ -26,9 +26,23 @@
namespace ASC.Core.Billing;
[Singletone]
public class LicenseReaderConfig
{
public readonly string LicensePath;
public LicenseReaderConfig(IConfiguration configuration)
{
LicensePath = configuration["license:file:path"] ?? "";
}
}
[Scope]
public class LicenseReader
{
private readonly UserManager _userManager;
private readonly TenantManager _tenantManager;
private readonly PaymentManager _paymentManager;
private readonly CoreSettings _coreSettings;
private readonly ILog _logger;
public readonly string LicensePath;
private readonly string _licensePathTemp;
@ -41,15 +55,14 @@ public class LicenseReader
TenantManager tenantManager,
PaymentManager paymentManager,
CoreSettings coreSettings,
IConfiguration configuration,
LicenseReaderConfig licenseReaderConfig,
ILog logger)
{
_userManager = userManager;
_tenantManager = tenantManager;
_paymentManager = paymentManager;
_coreSettings = coreSettings;
_configuration = configuration;
LicensePath = _configuration["license:file:path"] ?? "";
LicensePath = licenseReaderConfig.LicensePath;
_licensePathTemp = LicensePath + ".tmp";
_logger = logger;
}
@ -336,10 +349,4 @@ public class LicenseReader
//return _date;
}
}
private readonly UserManager _userManager;
private readonly TenantManager _tenantManager;
private readonly PaymentManager _paymentManager;
private readonly CoreSettings _coreSettings;
private readonly IConfiguration _configuration;
}

View File

@ -24,34 +24,42 @@
// 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.Configuration;
public class AmiPublicDnsSyncService : IServiceController
[Scope]
public class AmiPublicDnsSyncService : BackgroundService
{
public static IServiceProvider ServiceProvider { get; set; }
private TenantManager _tenantManager;
private CoreBaseSettings _coreBaseSettings;
private IHttpClientFactory _clientFactory;
public void Start()
public AmiPublicDnsSyncService(TenantManager tenantManager, CoreBaseSettings coreBaseSettings, IHttpClientFactory clientFactory)
{
Synchronize();
_tenantManager = tenantManager;
_coreBaseSettings = coreBaseSettings;
_clientFactory = clientFactory;
}
public void Stop() { }
public static void Synchronize()
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
using var scope = ServiceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<AmiPublicDnsSyncServiceScope>();
var (tenantManager, coreBaseSettings, clientFactory) = scopeClass;
if (coreBaseSettings.Standalone)
Synchronize();
return Task.CompletedTask;
}
private void Synchronize()
{
if (_coreBaseSettings.Standalone)
{
var tenants = tenantManager.GetTenants(false).Where(t => MappedDomainNotSettedByUser(t.MappedDomain));
var tenants = _tenantManager.GetTenants(false).Where(t => MappedDomainNotSettedByUser(t.MappedDomain));
if (tenants.Any())
{
var dnsname = GetAmiPublicDnsName(clientFactory);
var dnsname = GetAmiPublicDnsName(_clientFactory);
foreach (var tenant in tenants.Where(t => !string.IsNullOrEmpty(dnsname) && t.MappedDomain != dnsname))
{
tenant.MappedDomain = dnsname;
tenantManager.SaveTenant(tenant);
_tenantManager.SaveTenant(tenant);
}
}
}
@ -89,23 +97,4 @@ public class AmiPublicDnsSyncService : IServiceController
return null;
}
}
public class AmiPublicDnsSyncServiceScope
{
private TenantManager _tenantManager;
private CoreBaseSettings _coreBaseSettings;
private IHttpClientFactory _clientFactory;
public AmiPublicDnsSyncServiceScope(TenantManager tenantManager, CoreBaseSettings coreBaseSettings, IHttpClientFactory clientFactory)
{
_tenantManager = tenantManager;
_coreBaseSettings = coreBaseSettings;
_clientFactory = clientFactory;
}
public void Deconstruct(out TenantManager tenantManager, out CoreBaseSettings coreBaseSettings, out IHttpClientFactory clientFactory)
{
(tenantManager, coreBaseSettings, clientFactory) = (_tenantManager, _coreBaseSettings, _clientFactory);
}
}

View File

@ -29,17 +29,28 @@ using NotifyContext = ASC.Notify.Context;
namespace ASC.Core;
public static class WorkContext
[Singletone]
public class WorkContext
{
private static readonly object _syncRoot = new object();
private readonly IServiceProvider _serviceProvider;
private readonly IConfiguration _configuration;
private readonly IOptionsMonitor<ILog> _options;
private readonly DispatchEngine _dispatchEngine;
private readonly JabberSender _jabberSender;
private readonly AWSSender _awsSender;
private readonly SmtpSender _smtpSender;
private readonly NotifyServiceSender _notifyServiceSender;
private readonly TelegramSender _telegramSender;
private static bool _notifyStarted;
private static bool? _isMono;
private static string _monoVersion;
public static NotifyContext NotifyContext { get; private set; }
public NotifyContext NotifyContext { get; private set; }
public NotifyEngine NotifyEngine { get; private set; }
public static string[] DefaultClientSenders => new[] { Constants.NotifyEMailSenderSysName, };
public static string[] DefaultClientSenders => new[] { Constants.NotifyEMailSenderSysName };
public static bool IsMono
{
@ -67,8 +78,34 @@ public static class WorkContext
public static string MonoVersion => IsMono ? _monoVersion : null;
public WorkContext(
IServiceProvider serviceProvider,
IConfiguration configuration,
IOptionsMonitor<ILog> options,
DispatchEngine dispatchEngine,
NotifyEngine notifyEngine,
NotifyContext notifyContext,
JabberSender jabberSender,
AWSSender awsSender,
SmtpSender smtpSender,
NotifyServiceSender notifyServiceSender,
TelegramSender telegramSender
)
{
_serviceProvider = serviceProvider;
_configuration = configuration;
_options = options;
_dispatchEngine = dispatchEngine;
NotifyEngine = notifyEngine;
NotifyContext = notifyContext;
_jabberSender = jabberSender;
_awsSender = awsSender;
_smtpSender = smtpSender;
_notifyServiceSender = notifyServiceSender;
_telegramSender = telegramSender;
}
public static void NotifyStartUp(IServiceProvider serviceProvider)
public void NotifyStartUp()
{
if (_notifyStarted)
{
@ -82,22 +119,15 @@ public static class WorkContext
return;
}
var configuration = serviceProvider.GetService<IConfiguration>();
var cacheNotify = serviceProvider.GetService<ICacheNotify<NotifyMessage>>();
var cacheInvoke = serviceProvider.GetService<ICacheNotify<NotifyInvoke>>();
var options = serviceProvider.GetService<IOptionsMonitor<ILog>>();
INotifySender jabberSender = _notifyServiceSender;
INotifySender emailSender = _notifyServiceSender;
INotifySender telegramSender = _telegramSender;
NotifyContext = new NotifyContext(serviceProvider);
INotifySender jabberSender = new NotifyServiceSender(cacheNotify, cacheInvoke);
INotifySender emailSender = new NotifyServiceSender(cacheNotify, cacheInvoke);
INotifySender telegramSender = new TelegramSender(options, serviceProvider);
var postman = configuration["core:notify:postman"];
var postman = _configuration["core:notify:postman"];
if ("ases".Equals(postman, StringComparison.InvariantCultureIgnoreCase) || "smtp".Equals(postman, StringComparison.InvariantCultureIgnoreCase))
{
jabberSender = new JabberSender(serviceProvider);
jabberSender = _jabberSender;
var properties = new Dictionary<string, string>
{
@ -105,60 +135,73 @@ public static class WorkContext
};
if ("ases".Equals(postman, StringComparison.InvariantCultureIgnoreCase))
{
emailSender = new AWSSender(serviceProvider, options);
properties["accessKey"] = configuration["ses:accessKey"];
properties["secretKey"] = configuration["ses:secretKey"];
properties["refreshTimeout"] = configuration["ses:refreshTimeout"];
emailSender = _awsSender;
properties["accessKey"] = _configuration["ses:accessKey"];
properties["secretKey"] = _configuration["ses:secretKey"];
properties["refreshTimeout"] = _configuration["ses:refreshTimeout"];
}
else
{
emailSender = new SmtpSender(serviceProvider, options);
emailSender = _smtpSender;
}
emailSender.Init(properties);
}
NotifyContext.NotifyService.RegisterSender(Constants.NotifyEMailSenderSysName, new EmailSenderSink(emailSender, serviceProvider, options));
NotifyContext.NotifyService.RegisterSender(Constants.NotifyMessengerSenderSysName, new JabberSenderSink(jabberSender, serviceProvider));
NotifyContext.NotifyService.RegisterSender(Constants.NotifyTelegramSenderSysName, new TelegramSenderSink(telegramSender, serviceProvider));
NotifyContext.RegisterSender(_dispatchEngine, Constants.NotifyEMailSenderSysName, new EmailSenderSink(emailSender, _serviceProvider));
NotifyContext.RegisterSender(_dispatchEngine, Constants.NotifyMessengerSenderSysName, new JabberSenderSink(jabberSender, _serviceProvider));
NotifyContext.RegisterSender(_dispatchEngine, Constants.NotifyTelegramSenderSysName, new TelegramSenderSink(telegramSender, _serviceProvider));
NotifyEngine.AddAction<NotifyTransferRequest>();
NotifyContext.NotifyEngine.BeforeTransferRequest += NotifyEngine_BeforeTransferRequest;
NotifyContext.NotifyEngine.AfterTransferRequest += NotifyEngine_AfterTransferRequest;
_notifyStarted = true;
}
}
public static void RegisterSendMethod(Action<DateTime> method, string cron)
public void RegisterSendMethod(Action<DateTime> method, string cron)
{
NotifyContext.NotifyEngine.RegisterSendMethod(method, cron);
NotifyEngine.RegisterSendMethod(method, cron);
}
public static void UnregisterSendMethod(Action<DateTime> method)
public void UnregisterSendMethod(Action<DateTime> method)
{
NotifyContext.NotifyEngine.UnregisterSendMethod(method);
NotifyEngine.UnregisterSendMethod(method);
}
private static void NotifyEngine_BeforeTransferRequest(NotifyEngine sender, NotifyRequest request, IServiceScope serviceScope)
}
[Scope]
public class NotifyTransferRequest : INotifyEngineAction
{
private readonly TenantManager _tenantManager;
public NotifyTransferRequest(TenantManager tenantManager)
{
request.Properties.Add("Tenant", serviceScope.ServiceProvider.GetService<TenantManager>().GetCurrentTenant(false));
_tenantManager = tenantManager;
}
private static void NotifyEngine_AfterTransferRequest(NotifyEngine sender, NotifyRequest request, IServiceScope scope)
public void AfterTransferRequest(NotifyRequest request)
{
if ((request.Properties.Contains("Tenant") ? request.Properties["Tenant"] : null) is Tenant tenant)
{
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
tenantManager.SetCurrentTenant(tenant);
_tenantManager.SetCurrentTenant(tenant);
}
}
public void BeforeTransferRequest(NotifyRequest request)
{
request.Properties.Add("Tenant", _tenantManager.GetCurrentTenant(false));
}
}
public static class WorkContextExtension
{
public static void Register(DIHelper dIHelper)
{
dIHelper.TryAdd<NotifyTransferRequest>();
dIHelper.TryAdd<TelegramHelper>();
dIHelper.TryAdd<EmailSenderSinkScope>();
dIHelper.TryAdd<JabberSenderSinkScope>();
dIHelper.TryAdd<TelegramSenderSinkMessageCreator>();
dIHelper.TryAdd<JabberSenderSinkMessageCreator>();
dIHelper.TryAdd<EmailSenderSinkMessageCreator>();
}
}

View File

@ -149,17 +149,17 @@ public class DbSettingsManager
}
}
public bool SaveSettings<T>(T settings, int tenantId) where T : ISettings
public bool SaveSettings<T>(T settings, int tenantId) where T : class, ISettings<T>
{
return SaveSettingsFor(settings, tenantId, Guid.Empty);
}
public T LoadSettings<T>(int tenantId) where T : class, ISettings
public T LoadSettings<T>(int tenantId) where T : class, ISettings<T>
{
return LoadSettingsFor<T>(tenantId, Guid.Empty);
}
public void ClearCache<T>(int tenantId) where T : class, ISettings
public void ClearCache<T>(int tenantId) where T : class, ISettings<T>
{
var settings = LoadSettings<T>(tenantId);
var key = settings.ID.ToString() + tenantId + Guid.Empty;
@ -168,7 +168,7 @@ public class DbSettingsManager
}
public bool SaveSettingsFor<T>(T settings, int tenantId, Guid userId) where T : ISettings
public bool SaveSettingsFor<T>(T settings, int tenantId, Guid userId) where T : class, ISettings<T>
{
ArgumentNullException.ThrowIfNull(settings);
@ -176,8 +176,7 @@ public class DbSettingsManager
{
var key = settings.ID.ToString() + tenantId + userId;
var data = Serialize(settings);
var def = (T)settings.GetDefault(ServiceProvider);
var def = GetDefault<T>();
var defaultData = Serialize(def);
@ -228,11 +227,10 @@ public class DbSettingsManager
}
}
internal T LoadSettingsFor<T>(int tenantId, Guid userId) where T : class, ISettings
internal T LoadSettingsFor<T>(int tenantId, Guid userId) where T : class, ISettings<T>
{
var settingsInstance = ActivatorUtilities.CreateInstance<T>(ServiceProvider);
var key = settingsInstance.ID.ToString() + tenantId + userId;
var def = (T)settingsInstance.GetDefault(ServiceProvider);
var def = GetDefault<T>();
var key = def.ID.ToString() + tenantId + userId;
try
{
@ -243,7 +241,7 @@ public class DbSettingsManager
}
var result = WebstudioDbContext.WebstudioSettings
.Where(r => r.Id == settingsInstance.ID)
.Where(r => r.Id == def.ID)
.Where(r => r.TenantId == tenantId)
.Where(r => r.UserId == userId)
.Select(r => r.Data)
@ -270,57 +268,63 @@ public class DbSettingsManager
return def;
}
public T Load<T>() where T : class, ISettings
public T GetDefault<T>() where T : class, ISettings<T>
{
var settingsInstance = ActivatorUtilities.CreateInstance<T>(ServiceProvider);
return settingsInstance.GetDefault();
}
public T Load<T>() where T : class, ISettings<T>
{
return LoadSettings<T>(TenantID);
}
public T LoadForCurrentUser<T>() where T : class, ISettings
public T LoadForCurrentUser<T>() where T : class, ISettings<T>
{
return LoadForUser<T>(CurrentUserID);
}
public T LoadForUser<T>(Guid userId) where T : class, ISettings
public T LoadForUser<T>(Guid userId) where T : class, ISettings<T>
{
return LoadSettingsFor<T>(TenantID, userId);
}
public T LoadForDefaultTenant<T>() where T : class, ISettings
public T LoadForDefaultTenant<T>() where T : class, ISettings<T>
{
return LoadForTenant<T>(Tenant.DefaultTenant);
}
public T LoadForTenant<T>(int tenantId) where T : class, ISettings
public T LoadForTenant<T>(int tenantId) where T : class, ISettings<T>
{
return LoadSettings<T>(tenantId);
}
public virtual bool Save<T>(T data) where T : class, ISettings
public virtual bool Save<T>(T data) where T : class, ISettings<T>
{
return SaveSettings(data, TenantID);
}
public bool SaveForCurrentUser<T>(T data) where T : class, ISettings
public bool SaveForCurrentUser<T>(T data) where T : class, ISettings<T>
{
return SaveForUser(data, CurrentUserID);
}
public bool SaveForUser<T>(T data, Guid userId) where T : class, ISettings
public bool SaveForUser<T>(T data, Guid userId) where T : class, ISettings<T>
{
return SaveSettingsFor(data, TenantID, userId);
}
public bool SaveForDefaultTenant<T>(T data) where T : class, ISettings
public bool SaveForDefaultTenant<T>(T data) where T : class, ISettings<T>
{
return SaveForTenant(data, Tenant.DefaultTenant);
}
public bool SaveForTenant<T>(T data, int tenantId) where T : class, ISettings
public bool SaveForTenant<T>(T data, int tenantId) where T : class, ISettings<T>
{
return SaveSettings(data, tenantId);
}
public void ClearCache<T>() where T : class, ISettings
public void ClearCache<T>() where T : class, ISettings<T>
{
ClearCache<T>(TenantID);
}
@ -329,7 +333,7 @@ public class DbSettingsManager
{
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
PropertyNameCaseInsensitive = true,
};
return JsonSerializer.Deserialize<T>(data, options);

View File

@ -127,7 +127,7 @@ global using Microsoft.Extensions.Configuration;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Hosting;
global using Microsoft.Extensions.Logging;
global using Microsoft.Extensions.Options;
global using Microsoft.Extensions.Options;
global using MimeKit;

View File

@ -34,15 +34,14 @@ public class SenderChannel : ISenderChannel
public string SenderName { get; private set; }
public SenderChannel(Context context, string senderName, ISink decorateSink, ISink senderSink)
public SenderChannel(DispatchEngine dispatchEngine, string senderName, ISink decorateSink, ISink senderSink)
{
SenderName = senderName ?? throw new ArgumentNullException(nameof(senderName));
_firstSink = decorateSink;
_senderSink = senderSink ?? throw new ApplicationException($"channel with tag {senderName} not created sender sink");
context = context ?? throw new ArgumentNullException(nameof(context));
var dispatcherSink = new DispatchSink(SenderName, context.DispatchEngine);
var dispatcherSink = new DispatchSink(SenderName, dispatchEngine);
_firstSink = AddSink(_firstSink, dispatcherSink);
}

View File

@ -24,9 +24,9 @@
// 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.Notify;
[Singletone]
namespace ASC.Notify;
[Singletone]
public sealed class Context : INotifyRegistry
{
public const string SysRecipient = "_#" + SysRecipientId + "#_";
@ -34,33 +34,25 @@ public sealed class Context : INotifyRegistry
internal const string SysRecipientName = "SYS_RECIPIENT_NAME";
internal const string SysRecipientAddress = "SYS_RECIPIENT_ADDRESS";
private readonly Dictionary<string, ISenderChannel> _channels = new Dictionary<string, ISenderChannel>(2);
public NotifyEngine NotifyEngine { get; private set; }
public INotifyRegistry NotifyService => this;
public DispatchEngine DispatchEngine { get; private set; }
private readonly Dictionary<string, ISenderChannel> _channels = new Dictionary<string, ISenderChannel>(2);
private readonly IOptionsMonitor<ILog> _options;
public event Action<Context, INotifyClient> NotifyClientRegistration;
public Context(IOptionsMonitor<ILog> options)
{
_options = options;
}
private ILog Logger { get; set; }
public Context(IServiceProvider serviceProvider)
{
var options = serviceProvider.GetService<IOptionsMonitor<ILog>>();
Logger = options.CurrentValue;
NotifyEngine = new NotifyEngine(this, serviceProvider);
DispatchEngine = new DispatchEngine(this, serviceProvider.GetService<IConfiguration>(), options);
}
void INotifyRegistry.RegisterSender(string senderName, ISink senderSink)
public void RegisterSender(DispatchEngine dispatchEngine, string senderName, ISink senderSink)
{
lock (_channels)
{
_channels[senderName] = new SenderChannel(this, senderName, null, senderSink);
_channels[senderName] = new SenderChannel(dispatchEngine, senderName, null, senderSink);
}
}
void INotifyRegistry.UnregisterSender(string senderName)
public void UnregisterSender(string senderName)
{
lock (_channels)
{
@ -68,7 +60,7 @@ public sealed class Context : INotifyRegistry
}
}
ISenderChannel INotifyRegistry.GetSender(string senderName)
public ISenderChannel GetSender(string senderName)
{
lock (_channels)
{
@ -78,39 +70,12 @@ public sealed class Context : INotifyRegistry
}
}
INotifyClient INotifyRegistry.RegisterClient(INotifySource source, IServiceScope serviceScope)
public INotifyClient RegisterClient(NotifyEngineQueue notifyEngineQueue, INotifySource source)
{
//ValidateNotifySource(source);
var client = new NotifyClientImpl(this, source, serviceScope);
var client = new NotifyClientImpl(_options, notifyEngineQueue, source);
NotifyClientRegistration?.Invoke(this, client);
return client;
}
private void ValidateNotifySource(INotifySource source)
{
foreach (var a in source.GetActionProvider().GetActions())
{
IEnumerable<string> senderNames;
lock (_channels)
{
senderNames = _channels.Values.Select(s => s.SenderName);
}
foreach (var s in senderNames)
{
try
{
var pattern = source.GetPatternProvider().GetPattern(a, s);
if (pattern == null)
{
throw new NotifyException($"In notify source {source.Id} pattern not found for action {a.ID} and sender {s}");
}
}
catch (Exception error)
{
Logger.ErrorFormat("Source: {0}, action: {1}, sender: {2}, error: {3}", source.Id, a.ID, s, error);
}
}
}
}
}

View File

@ -30,17 +30,13 @@ public class EmailSenderSink : Sink
{
private static readonly string _senderName = Configuration.Constants.NotifyEMailSenderSysName;
private readonly INotifySender _sender;
private readonly IServiceProvider _serviceProvider;
public EmailSenderSink(INotifySender sender, IServiceProvider serviceProvider, IOptionsMonitor<ILog> options)
public EmailSenderSink(INotifySender sender, IServiceProvider serviceProvider)
{
_sender = sender ?? throw new ArgumentNullException(nameof(sender));
_serviceProvider = serviceProvider;
_logger = options.Get("ASC.Notify");
}
private readonly IServiceProvider _serviceProvider;
private readonly ILog _logger;
public override SendResponse ProcessMessage(INoticeMessage message)
{
@ -52,7 +48,8 @@ public class EmailSenderSink : Sink
var responce = new SendResponse(message, _senderName, default(SendResult));
try
{
var m = CreateNotifyMessage(message);
using var scope = _serviceProvider.CreateScope();
var m = scope.ServiceProvider.GetRequiredService<EmailSenderSinkMessageCreator>().CreateNotifyMessage(message, _senderName);
var result = _sender.Send(m);
responce.Result = result switch
@ -70,30 +67,39 @@ public class EmailSenderSink : Sink
return new SendResponse(message, _senderName, e);
}
}
}
[Scope]
public class EmailSenderSinkMessageCreator : SinkMessageCreator
{
private readonly TenantManager _tenantManager;
private readonly CoreConfiguration _coreConfiguration;
private readonly ILog _logger;
private NotifyMessage CreateNotifyMessage(INoticeMessage message)
public EmailSenderSinkMessageCreator(TenantManager tenantManager, CoreConfiguration coreConfiguration, IOptionsMonitor<ILog> options)
{
_tenantManager = tenantManager;
_coreConfiguration = coreConfiguration;
_logger = options.Get("ASC.Notify");
}
public override NotifyMessage CreateNotifyMessage(INoticeMessage message, string senderName)
{
var m = new NotifyMessage
{
Subject = message.Subject.Trim(' ', '\t', '\n', '\r'),
ContentType = message.ContentType,
Content = message.Body,
SenderType = _senderName,
SenderType = senderName,
CreationDate = DateTime.UtcNow.Ticks,
};
using var scope = _serviceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<EmailSenderSinkScope>();
var (tenantManager, configuration, options) = scopeClass;
var tenant = tenantManager.GetCurrentTenant(false);
var tenant = _tenantManager.GetCurrentTenant(false);
m.TenantId = tenant == null ? Tenant.DefaultTenant : tenant.Id;
var from = MailAddressUtils.Create(configuration.SmtpSettings.SenderAddress, configuration.SmtpSettings.SenderDisplayName);
var from = MailAddressUtils.Create(_coreConfiguration.SmtpSettings.SenderAddress, _coreConfiguration.SmtpSettings.SenderDisplayName);
var fromTag = message.Arguments.FirstOrDefault(x => x.Tag.Equals("MessageFrom"));
if ((configuration.SmtpSettings.IsDefaultSettings || string.IsNullOrEmpty(configuration.SmtpSettings.SenderDisplayName)) &&
if ((_coreConfiguration.SmtpSettings.IsDefaultSettings || string.IsNullOrEmpty(_coreConfiguration.SmtpSettings.SenderDisplayName)) &&
fromTag != null && fromTag.Value != null)
{
try
@ -121,7 +127,7 @@ public class EmailSenderSink : Sink
}
catch (Exception e)
{
_serviceProvider.GetService<IOptionsMonitor<ILog>>().Get("ASC.Notify").Error("Error creating reply to tag for: " + replyTag.Value, e);
_logger.Error("Error creating reply to tag for: " + replyTag.Value, e);
}
}
@ -151,25 +157,5 @@ public class EmailSenderSink : Sink
}
return m;
}
}
[Scope]
public class EmailSenderSinkScope
{
private readonly TenantManager _tenantManager;
private readonly CoreConfiguration _coreConfiguration;
private readonly IOptionsMonitor<ILog> _options;
public EmailSenderSinkScope(TenantManager tenantManager, CoreConfiguration coreConfiguration, IOptionsMonitor<ILog> options)
{
_tenantManager = tenantManager;
_coreConfiguration = coreConfiguration;
_options = options;
}
public void Deconstruct(out TenantManager tenantManager, out CoreConfiguration coreConfiguration, out IOptionsMonitor<ILog> optionsMonitor)
{
(tenantManager, coreConfiguration, optionsMonitor) = (_tenantManager, _coreConfiguration, _options);
}
}

View File

@ -25,7 +25,8 @@
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
namespace ASC.Notify.Engine;
[Singletone]
public class DispatchEngine
{
private readonly ILog _logger;
@ -47,7 +48,7 @@ public class DispatchEngine
var response = new SendResponse(message, senderName, SendResult.OK);
if (!_logOnly)
{
var sender = _context.NotifyService.GetSender(senderName);
var sender = _context.GetSender(senderName);
if (sender != null)
{
response = sender.DirectSend(message);

View File

@ -27,8 +27,7 @@
namespace ASC.Notify.Engine;
interface INotifyEngine
{
event Action<NotifyEngine, NotifyRequest, IServiceScope> AfterTransferRequest;
event Action<NotifyEngine, NotifyRequest, IServiceScope> BeforeTransferRequest;
void QueueRequest(NotifyRequest request, IServiceScope serviceScope);
{
void AddAction<T>() where T : INotifyEngineAction;
void QueueRequest(NotifyRequest request);
}

View File

@ -26,6 +26,13 @@
namespace ASC.Notify.Engine;
public interface INotifyEngineAction
{
void BeforeTransferRequest(NotifyRequest request);
void AfterTransferRequest(NotifyRequest request);
}
[Singletone]
public class NotifyEngine : INotifyEngine
{
private readonly ILog _logger;
@ -39,25 +46,27 @@ public class NotifyEngine : INotifyEngine
private readonly Dictionary<string, IPatternStyler> _stylers = new Dictionary<string, IPatternStyler>();
private readonly IPatternFormatter _sysTagFormatter = new ReplacePatternFormatter(@"_#(?<tagName>[A-Z0-9_\-.]+)#_", true);
private readonly TimeSpan _defaultSleep = TimeSpan.FromSeconds(10);
private readonly IServiceProvider _serviceProvider;
public event Action<NotifyEngine, NotifyRequest, IServiceScope> BeforeTransferRequest;
public event Action<NotifyEngine, NotifyRequest, IServiceScope> AfterTransferRequest;
private readonly IServiceScopeFactory _serviceScopeFactory;
internal readonly ICollection<Type> Actions;
public NotifyEngine(Context context, IServiceProvider serviceProvider)
public NotifyEngine(Context context, IOptionsMonitor<ILog> options, IServiceScopeFactory serviceScopeFactory)
{
Actions = new List<Type>();
_context = context ?? throw new ArgumentNullException(nameof(context));
_logger = serviceProvider.GetService<IOptionsMonitor<ILog>>().Get("ASC.Notify");
_serviceProvider = serviceProvider;
_logger = options.Get("ASC.Notify");
_serviceScopeFactory = serviceScopeFactory;
_notifyScheduler = new Thread(NotifyScheduler) { IsBackground = true, Name = "NotifyScheduler" };
_notifySender = new Thread(NotifySender) { IsBackground = true, Name = "NotifySender" };
}
public virtual void QueueRequest(NotifyRequest request, IServiceScope serviceScope)
public void AddAction<T>() where T : INotifyEngineAction
{
Actions.Add(typeof(T));
}
public void QueueRequest(NotifyRequest request)
{
BeforeTransferRequest?.Invoke(this, request, serviceScope);
lock (_requests)
{
if (!_notifySender.IsAlive)
@ -184,8 +193,12 @@ public class NotifyEngine : INotifyEngine
}
if (request != null)
{
using var scope = _serviceProvider.CreateScope();
AfterTransferRequest?.Invoke(this, request, scope);
using var scope = _serviceScopeFactory.CreateScope();
foreach (var action in Actions)
{
((INotifyEngineAction)scope.ServiceProvider.GetRequiredService(action)).AfterTransferRequest(request);
}
try
{
SendNotify(request, scope);
@ -351,7 +364,7 @@ public class NotifyEngine : INotifyEngine
{
foreach (var sendertag in request.SenderNames)
{
var channel = _context.NotifyService.GetSender(sendertag);
var channel = _context.GetSender(sendertag);
if (channel != null)
{
try
@ -633,4 +646,27 @@ public class NotifyEngine : INotifyEngine
return _method.GetHashCode();
}
}
}
[Scope]
public class NotifyEngineQueue
{
private readonly NotifyEngine _notifyEngine;
private readonly IServiceProvider _serviceProvider;
public NotifyEngineQueue(NotifyEngine notifyEngine, IServiceProvider serviceProvider)
{
_notifyEngine = notifyEngine;
_serviceProvider = serviceProvider;
}
public void QueueRequest(NotifyRequest request)
{
foreach (var action in _notifyEngine.Actions)
{
((INotifyEngineAction)_serviceProvider.GetRequiredService(action)).BeforeTransferRequest(request);
}
_notifyEngine.QueueRequest(request);
}
}

View File

@ -41,20 +41,23 @@ public class NotifyRequest
internal List<string> RequaredTags;
internal List<ISendInterceptor> Interceptors;
internal bool IsNeedCheckSubscriptions;
private readonly ILog _log;
private readonly IOptionsMonitor<ILog> _options;
public NotifyRequest(INotifySource notifySource, INotifyAction action, string objectID, IRecipient recipient)
public NotifyRequest(IOptionsMonitor<ILog> options, INotifySource notifySource, INotifyAction action, string objectID, IRecipient recipient)
{
Properties = new Hashtable();
Arguments = new List<ITagValue>();
RequaredTags = new List<string>();
Interceptors = new List<ISendInterceptor>();
_options = options;
NotifySource = notifySource ?? throw new ArgumentNullException(nameof(notifySource));
Recipient = recipient ?? throw new ArgumentNullException(nameof(recipient));
NotifyAction = action ?? throw new ArgumentNullException(nameof(action));
ObjectID = objectID;
IsNeedCheckSubscriptions = true;
_log = options.Get("ASC.Notify");
}
internal bool Intercept(InterceptorPlace place, IServiceScope serviceScope)
@ -73,7 +76,7 @@ public class NotifyRequest
}
catch (Exception err)
{
serviceScope.ServiceProvider.GetService<IOptionsMonitor<ILog>>().Get("ASC.Notify").ErrorFormat("{0} {1} {2}: {3}", interceptor.Name, NotifyAction, Recipient, err);
_log.ErrorFormat("{0} {1} {2}: {3}", interceptor.Name, NotifyAction, Recipient, err);
}
}
}
@ -103,7 +106,7 @@ public class NotifyRequest
{
ArgumentNullException.ThrowIfNull(recipient);
var newRequest = new NotifyRequest(NotifySource, NotifyAction, ObjectID, recipient)
var newRequest = new NotifyRequest(_options, NotifySource, NotifyAction, ObjectID, recipient)
{
SenderNames = SenderNames,
Patterns = Patterns,

View File

@ -28,8 +28,8 @@ namespace ASC.Notify;
public interface INotifyRegistry
{
INotifyClient RegisterClient(INotifySource source, IServiceScope serviceScope);
INotifyClient RegisterClient(NotifyEngineQueue notifyEngine, INotifySource source);
ISenderChannel GetSender(string senderName);
void RegisterSender(string senderName, ISink senderSink);
void RegisterSender(DispatchEngine dispatchEngine, string senderName, ISink senderSink);
void UnregisterSender(string senderName);
}

View File

@ -43,30 +43,16 @@ class JabberSenderSink : Sink
{
try
{
using var scope = _serviceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<JabberSenderSinkScope>();
(var userManager, var tenantManager) = scopeClass;
var result = SendResult.OK;
var username = userManager.GetUsers(new Guid(message.Recipient.ID)).UserName;
if (string.IsNullOrEmpty(username))
using var scope = _serviceProvider.CreateScope();
var m = scope.ServiceProvider.GetRequiredService<JabberSenderSinkMessageCreator>().CreateNotifyMessage(message, _senderName);
if (string.IsNullOrEmpty(m.Reciever))
{
result = SendResult.IncorrectRecipient;
}
else
{
var m = new NotifyMessage
{
Reciever = username,
Subject = message.Subject,
ContentType = message.ContentType,
Content = message.Body,
SenderType = _senderName,
CreationDate = DateTime.UtcNow.Ticks,
};
var tenant = tenantManager.GetCurrentTenant(false);
m.TenantId = tenant == null ? Tenant.DefaultTenant : tenant.Id;
_sender.Send(m);
}
@ -80,19 +66,33 @@ class JabberSenderSink : Sink
}
[Scope]
public class JabberSenderSinkScope
public class JabberSenderSinkMessageCreator : SinkMessageCreator
{
private readonly UserManager _userManager;
private readonly TenantManager _tenantManager;
public JabberSenderSinkScope(UserManager userManager, TenantManager tenantManager)
public JabberSenderSinkMessageCreator(UserManager userManager, TenantManager tenantManager)
{
_tenantManager = tenantManager;
_userManager = userManager;
}
public void Deconstruct(out UserManager userManager, out TenantManager tenantManager)
public override NotifyMessage CreateNotifyMessage(INoticeMessage message, string senderName)
{
(userManager, tenantManager) = (_userManager, _tenantManager);
}
var username = _userManager.GetUsers(new Guid(message.Recipient.ID)).UserName;
var m = new NotifyMessage
{
Reciever = username,
Subject = message.Subject,
ContentType = message.ContentType,
Content = message.Body,
SenderType = senderName,
CreationDate = DateTime.UtcNow.Ticks,
};
var tenant = _tenantManager.GetCurrentTenant(false);
m.TenantId = tenant == null ? Tenant.DefaultTenant : tenant.Id;
return m;
}
}

View File

@ -28,16 +28,17 @@ namespace ASC.Notify.Model;
class NotifyClientImpl : INotifyClient
{
private readonly Context _context;
private readonly InterceptorStorage _interceptors = new InterceptorStorage();
private readonly IOptionsMonitor<ILog> _options;
private readonly NotifyEngineQueue _notifyEngineQueue;
private readonly INotifySource _notifySource;
public readonly IServiceScope _serviceScope;
public NotifyClientImpl(Context context, INotifySource notifySource, IServiceScope serviceScope)
public NotifyClientImpl(IOptionsMonitor<ILog> options, NotifyEngineQueue notifyEngineQueue, INotifySource notifySource)
{
this._notifySource = notifySource ?? throw new ArgumentNullException(nameof(notifySource));
_serviceScope = serviceScope;
_context = context ?? throw new ArgumentNullException(nameof(context));
_options = options;
_notifyEngineQueue = notifyEngineQueue;
_notifySource = notifySource ?? throw new ArgumentNullException(nameof(notifySource));
}
public void SendNoticeToAsync(INotifyAction action, IRecipient[] recipients, string[] senderNames, params ITagValue[] args)
@ -113,7 +114,7 @@ class NotifyClientImpl : INotifyClient
private void SendAsync(NotifyRequest request)
{
request.Interceptors = _interceptors.GetAll();
_context.NotifyEngine.QueueRequest(request, _serviceScope);
_notifyEngineQueue.QueueRequest(request);
}
private NotifyRequest CreateRequest(INotifyAction action, string objectID, IRecipient recipient, ITagValue[] args, string[] senders, bool checkSubsciption)
@ -121,7 +122,7 @@ class NotifyClientImpl : INotifyClient
ArgumentNullException.ThrowIfNull(action);
ArgumentNullException.ThrowIfNull(recipient);
var request = new NotifyRequest(_notifySource, action, objectID, recipient)
var request = new NotifyRequest(_options, _notifySource, action, objectID, recipient)
{
SenderNames = senders,
IsNeedCheckSubscriptions = checkSubsciption

View File

@ -28,11 +28,12 @@ using CacheNotifyAction = ASC.Common.Caching.CacheNotifyAction;
namespace ASC.Core.Notify;
[Scope]
[Singletone]
public class NotifyServiceClient : INotifyService
{
private readonly ICacheNotify<NotifyMessage> _cacheNotify;
private readonly ICacheNotify<NotifyInvoke> _notifyInvoke;
public NotifyServiceClient(ICacheNotify<NotifyMessage> cacheNotify, ICacheNotify<NotifyInvoke> notifyInvoke)
{
_cacheNotify = cacheNotify;

View File

@ -33,10 +33,10 @@ class PushSenderSink : Sink
private readonly ILog _logger;
private bool _configured = true;
public PushSenderSink(IServiceProvider serviceProvider)
public PushSenderSink(IServiceProvider serviceProvider, IOptionsMonitor<ILog> options)
{
_serviceProvider = serviceProvider;
_logger = _serviceProvider.GetService<IOptionsMonitor<ILog>>().CurrentValue;
_logger = options.CurrentValue;
}
private readonly IServiceProvider _serviceProvider;

View File

@ -28,7 +28,7 @@ using Message = Amazon.SimpleEmail.Model.Message;
namespace ASC.Core.Notify.Senders;
[Singletone(Additional = typeof(AWSSenderExtension))]
[Singletone]
public class AWSSender : SmtpSender
{
private readonly object _locker = new object();
@ -39,8 +39,10 @@ public class AWSSender : SmtpSender
private TimeSpan _sendWindow = TimeSpan.MinValue;
private GetSendQuotaResponse _quota;
public AWSSender(IServiceProvider serviceProvider,
IOptionsMonitor<ILog> options) : base(serviceProvider, options)
public AWSSender(
IConfiguration configuration,
IServiceProvider serviceProvider,
IOptionsMonitor<ILog> options) : base(configuration, serviceProvider, options)
{
Logger = options.Get("ASC.Notify.AmazonSES");
}
@ -63,10 +65,10 @@ public class AWSSender : SmtpSender
{
Logger.DebugFormat("Tenant: {0}, To: {1}", m.TenantId, m.Reciever);
using var scope = ServiceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<AWSSenderScope>();
var (tenantManager, configuration) = scopeClass;
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
tenantManager.SetCurrentTenant(m.TenantId);
var configuration = scope.ServiceProvider.GetService<CoreConfiguration>();
if (!configuration.SmtpSettings.IsDefaultSettings)
{
UseCoreSettings = true;
@ -213,30 +215,4 @@ public class AWSSender : SmtpSender
{
return _quota == null || (DateTime.UtcNow - _lastRefresh) > _refreshTimeout;
}
}
[Scope]
public class AWSSenderScope
{
private readonly TenantManager _tenantManager;
private readonly CoreConfiguration _coreConfiguration;
public AWSSenderScope(TenantManager tenantManager, CoreConfiguration coreConfiguration)
{
_tenantManager = tenantManager;
_coreConfiguration = coreConfiguration;
}
public void Deconstruct(out TenantManager tenantManager, out CoreConfiguration coreConfiguration)
{
(tenantManager, coreConfiguration) = (_tenantManager, _coreConfiguration);
}
}
public static class AWSSenderExtension
{
public static void Register(DIHelper services)
{
services.TryAdd<AWSSenderScope>();
}
}

View File

@ -32,10 +32,10 @@ public class JabberSender : INotifySender
private readonly ILog _logger;
private readonly IServiceProvider _serviceProvider;
public JabberSender(IServiceProvider serviceProvider)
public JabberSender(IServiceProvider serviceProvider, IOptionsMonitor<ILog> optionsMonitor)
{
_serviceProvider = serviceProvider;
_logger = _serviceProvider.GetService<IOptionsMonitor<ILog>>().CurrentValue;
_logger = optionsMonitor.CurrentValue;
}
public void Init(IDictionary<string, string> properties) { }

View File

@ -26,13 +26,14 @@
namespace ASC.Core.Notify.Senders;
[Singletone]
public class NotifyServiceSender : INotifySender
{
public readonly NotifyServiceClient _notifyServiceClient;
public NotifyServiceSender(ICacheNotify<NotifyMessage> cacheNotify, ICacheNotify<NotifyInvoke> notifyInvoke)
public NotifyServiceSender(NotifyServiceClient notifyServiceClient)
{
_notifyServiceClient = new NotifyServiceClient(cacheNotify, notifyInvoke);
_notifyServiceClient = notifyServiceClient;
}
public void Init(IDictionary<string, string> properties) { }

View File

@ -26,7 +26,7 @@
namespace ASC.Core.Notify.Senders;
[Singletone(Additional = typeof(SmtpSenderExtension))]
[Singletone]
public class SmtpSender : INotifySender
{
protected ILog Logger { get; set; }
@ -41,11 +41,12 @@ public class SmtpSender : INotifySender
const int NetworkTimeout = 30000;
public SmtpSender(
IConfiguration configuration,
IServiceProvider serviceProvider,
IOptionsMonitor<ILog> options)
{
Logger = options.Get("ASC.Notify");
Configuration = serviceProvider.GetService<IConfiguration>();
Configuration = configuration;
ServiceProvider = serviceProvider;
}
@ -82,9 +83,10 @@ public class SmtpSender : INotifySender
public virtual NoticeSendResult Send(NotifyMessage m)
{
using var scope = ServiceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<SmtpSenderScope>();
var (tenantManager, configuration) = scopeClass;
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
tenantManager.SetCurrentTenant(m.TenantId);
var configuration = scope.ServiceProvider.GetService<CoreConfiguration>();
var smtpClient = GetSmtpClient();
var result = NoticeSendResult.TryOnceAgain;
@ -303,30 +305,4 @@ public class SmtpSender : INotifySender
return null;
}
}
}
[Scope]
public class SmtpSenderScope
{
private readonly TenantManager _tenantManager;
private readonly CoreConfiguration _coreConfiguration;
public SmtpSenderScope(TenantManager tenantManager, CoreConfiguration coreConfiguration)
{
_tenantManager = tenantManager;
_coreConfiguration = coreConfiguration;
}
public void Deconstruct(out TenantManager tenantManager, out CoreConfiguration coreConfiguration)
{
(tenantManager, coreConfiguration) = (_tenantManager, _coreConfiguration);
}
}
public static class SmtpSenderExtension
{
public static void Register(DIHelper services)
{
services.TryAdd<SmtpSenderScope>();
}
}

View File

@ -26,6 +26,7 @@
namespace ASC.Core.Notify.Senders;
[Singletone]
public class TelegramSender : INotifySender
{
private readonly ILog _logger;

View File

@ -26,6 +26,11 @@
namespace ASC.Notify.Sinks;
public abstract class SinkMessageCreator
{
public abstract NotifyMessage CreateNotifyMessage(INoticeMessage message, string senderName);
}
public abstract class Sink : ISink
{
public ISink NextSink { get; set; }

View File

@ -44,22 +44,9 @@ class TelegramSenderSink : Sink
try
{
const SendResult result = SendResult.OK;
var m = new NotifyMessage
{
Reciever = message.Recipient.ID,
Subject = message.Subject,
ContentType = message.ContentType,
Content = message.Body,
SenderType = _senderName,
CreationDate = DateTime.UtcNow.Ticks,
};
using var scope = _serviceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var tenant = tenantManager.GetCurrentTenant(false);
m.TenantId = tenant == null ? Tenant.DefaultTenant : tenant.Id;
var m = scope.ServiceProvider.GetRequiredService<TelegramSenderSinkMessageCreator>().CreateNotifyMessage(message, _senderName);
_sender.Send(m);
return new SendResponse(message, _senderName, result);
@ -69,4 +56,33 @@ class TelegramSenderSink : Sink
return new SendResponse(message, _senderName, ex);
}
}
}
[Scope]
public class TelegramSenderSinkMessageCreator : SinkMessageCreator
{
private readonly TenantManager _tenantManager;
public TelegramSenderSinkMessageCreator(TenantManager tenantManager)
{
_tenantManager = tenantManager;
}
public override NotifyMessage CreateNotifyMessage(INoticeMessage message, string senderName)
{
var m = new NotifyMessage
{
Reciever = message.Recipient.ID,
Subject = message.Subject,
ContentType = message.ContentType,
Content = message.Body,
SenderType = senderName,
CreationDate = DateTime.UtcNow.Ticks,
};
var tenant = _tenantManager.GetCurrentTenant(false);
m.TenantId = tenant == null ? Tenant.DefaultTenant : tenant.Id;
return m;
}
}

View File

@ -26,8 +26,8 @@
namespace ASC.Core.Common.Settings;
public interface ISettings
public interface ISettings<T> where T : ISettings<T>
{
Guid ID { get; }
ISettings GetDefault(IServiceProvider serviceProvider);
T GetDefault();
}

View File

@ -27,7 +27,7 @@
namespace ASC.Core.Tenants;
[Serializable]
public class TenantAuditSettings : ISettings
public class TenantAuditSettings : ISettings<TenantAuditSettings>
{
public const int MaxLifeTime = 180;
@ -37,7 +37,7 @@ public class TenantAuditSettings : ISettings
public static readonly Guid Guid = new Guid("{8337D0FB-AD67-4552-8297-802312E7F503}");
public Guid ID => Guid;
public ISettings GetDefault(IServiceProvider serviceProvider)
public TenantAuditSettings GetDefault()
{
return new TenantAuditSettings
{

View File

@ -28,14 +28,14 @@ namespace ASC.Core.Tenants;
[Serializable]
[DataContract]
public class TenantControlPanelSettings : ISettings
public class TenantControlPanelSettings : ISettings<TenantControlPanelSettings>
{
[DataMember(Name = "LimitedAccess")]
public bool LimitedAccess { get; set; }
public Guid ID => new Guid("{880585C4-52CD-4AE2-8DA4-3B8E2772753B}");
public ISettings GetDefault(IServiceProvider serviceProvider)
public TenantControlPanelSettings GetDefault()
{
return new TenantControlPanelSettings
{

View File

@ -27,12 +27,12 @@
namespace ASC.Core.Tenants;
[Serializable]
public class TenantCookieSettings : ISettings
public class TenantCookieSettings : ISettings<TenantCookieSettings>
{
public int Index { get; set; }
public int LifeTime { get; set; }
public ISettings GetDefault(IServiceProvider serviceProvider)
public TenantCookieSettings GetDefault()
{
return GetInstance();
}

View File

@ -27,13 +27,13 @@
namespace ASC.Web.Core.Users;
[Serializable]
public class DisplayUserSettings : ISettings
public class DisplayUserSettings : ISettings<DisplayUserSettings>
{
public Guid ID => new Guid("2EF59652-E1A7-4814-BF71-FEB990149428");
public bool IsDisableGettingStarted { get; set; }
public ISettings GetDefault(IServiceProvider serviceProvider)
public DisplayUserSettings GetDefault()
{
return new DisplayUserSettings
{

View File

@ -27,13 +27,13 @@
namespace ASC.Core.Tenants;
[Serializable]
public class PersonalQuotaSettings : ISettings
public class PersonalQuotaSettings : ISettings<PersonalQuotaSettings>
{
public long MaxSpace { get; set; }
public Guid ID => new Guid("{C634A747-C39B-4517-8698-B3B39BF2BD8E}");
public ISettings GetDefault(IServiceProvider serviceProvider)
public PersonalQuotaSettings GetDefault()
{
return new PersonalQuotaSettings
{

View File

@ -27,8 +27,11 @@
namespace ASC.Web.Core.WhiteLabel;
[Serializable]
public class MailWhiteLabelSettings : ISettings
public class MailWhiteLabelSettings : ISettings<MailWhiteLabelSettings>
{
private readonly MailWhiteLabelSettingsHelper _mailWhiteLabelSettingsHelper;
private readonly IConfiguration _configuration;
public bool FooterEnabled { get; set; }
public bool FooterSocialEnabled { get; set; }
public string SupportUrl { get; set; }
@ -39,29 +42,34 @@ public class MailWhiteLabelSettings : ISettings
public Guid ID => new Guid("{C3602052-5BA2-452A-BD2A-ADD0FAF8EB88}");
public ISettings GetDefault(IConfiguration configuration)
public MailWhiteLabelSettings(IConfiguration configuration)
{
var mailWhiteLabelSettingsHelper = new MailWhiteLabelSettingsHelper(configuration);
_mailWhiteLabelSettingsHelper = new MailWhiteLabelSettingsHelper(configuration);
_configuration = configuration;
}
return new MailWhiteLabelSettings
public MailWhiteLabelSettings()
{
}
public MailWhiteLabelSettings GetDefault()
{
return new MailWhiteLabelSettings(_configuration)
{
FooterEnabled = true,
FooterSocialEnabled = true,
SupportUrl = mailWhiteLabelSettingsHelper.DefaultMailSupportUrl,
SupportEmail = mailWhiteLabelSettingsHelper.DefaultMailSupportEmail,
SalesEmail = mailWhiteLabelSettingsHelper.DefaultMailSalesEmail,
DemoUrl = mailWhiteLabelSettingsHelper.DefaultMailDemoUrl,
SiteUrl = mailWhiteLabelSettingsHelper.DefaultMailSiteUrl
SupportUrl = _mailWhiteLabelSettingsHelper?.DefaultMailSupportUrl,
SupportEmail = _mailWhiteLabelSettingsHelper?.DefaultMailSupportEmail,
SalesEmail = _mailWhiteLabelSettingsHelper?.DefaultMailSalesEmail,
DemoUrl = _mailWhiteLabelSettingsHelper?.DefaultMailDemoUrl,
SiteUrl = _mailWhiteLabelSettingsHelper?.DefaultMailSiteUrl
};
}
public bool IsDefault(IConfiguration configuration)
public bool IsDefault()
{
if (!(GetDefault(configuration) is MailWhiteLabelSettings defaultSettings))
{
return false;
}
var defaultSettings = GetDefault();
return FooterEnabled == defaultSettings.FooterEnabled &&
FooterSocialEnabled == defaultSettings.FooterSocialEnabled &&
SupportUrl == defaultSettings.SupportUrl &&
@ -75,20 +83,18 @@ public class MailWhiteLabelSettings : ISettings
{
return settingsManager.LoadForDefaultTenant<MailWhiteLabelSettings>();
}
public static bool IsDefault(SettingsManager settingsManager, IConfiguration configuration)
{
return Instance(settingsManager).IsDefault(configuration);
}
public ISettings GetDefault(IServiceProvider serviceProvider)
public static bool IsDefault(SettingsManager settingsManager)
{
return GetDefault(serviceProvider.GetService<IConfiguration>());
return Instance(settingsManager).IsDefault();
}
}
[Singletone]
public class MailWhiteLabelSettingsHelper
{
private readonly IConfiguration _configuration;
public MailWhiteLabelSettingsHelper(IConfiguration configuration)
{
_configuration = configuration;
@ -143,6 +149,4 @@ public class MailWhiteLabelSettingsHelper
return !string.IsNullOrEmpty(url) ? url : "http://www.onlyoffice.com";
}
}
private readonly IConfiguration _configuration;
}

View File

@ -24,18 +24,48 @@
// 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 ASC.Notify.Engine;
namespace ASC.Data.Backup;
[Singletone(Additional = typeof(NotifyHelperExtension))]
[Scope]
public class NotifyHelper
{
private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly AuthManager _authManager;
private readonly NotifyEngineQueue _notifyEngineQueue;
private readonly WorkContext _workContext;
private readonly CommonLinkUtility _commonLinkUtility;
private readonly TenantLogoManager _tenantLogoManager;
private readonly UserManager _userManager;
private readonly StudioNotifyHelper _studioNotifyHelper;
private readonly StudioNotifySource _studioNotifySource;
private readonly DisplayUserSettingsHelper _displayUserSettingsHelper;
private readonly TenantManager _tenantManager;
public NotifyHelper(IServiceScopeFactory serviceScopeFactory)
public NotifyHelper(
UserManager userManager,
StudioNotifyHelper studioNotifyHelper,
StudioNotifySource studioNotifySource,
DisplayUserSettingsHelper displayUserSettingsHelper,
TenantManager tenantManager,
AuthManager authManager,
NotifyEngineQueue notifyEngineQueue,
WorkContext workContext,
CommonLinkUtility commonLinkUtility,
TenantLogoManager tenantLogoManager)
{
_serviceScopeFactory = serviceScopeFactory;
}
_userManager = userManager;
_studioNotifyHelper = studioNotifyHelper;
_studioNotifySource = studioNotifySource;
_displayUserSettingsHelper = displayUserSettingsHelper;
_tenantManager = tenantManager;
_authManager = authManager;
_notifyEngineQueue = notifyEngineQueue;
_workContext = workContext;
_commonLinkUtility = commonLinkUtility;
_tenantLogoManager = tenantLogoManager;
}
public void SendAboutTransferStart(Tenant tenant, string targetRegion, bool notifyUsers)
{
MigrationNotify(tenant, Actions.MigrationPortalStart, targetRegion, string.Empty, notifyUsers);
@ -52,35 +82,29 @@ public class NotifyHelper
}
public void SendAboutBackupCompleted(int tenantId, Guid userId)
{
using var scope = _serviceScopeFactory.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<NotifyHelperScope>();
var (userManager, studioNotifyHelper, studioNotifySource, displayUserSettingsHelper, tenantManager, _) = scopeClass;
tenantManager.SetCurrentTenant(tenantId);
{
_tenantManager.SetCurrentTenant(tenantId);
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifySource, scope);
var client = _workContext.NotifyContext.RegisterClient(_notifyEngineQueue, _studioNotifySource);
client.SendNoticeToAsync(
Actions.BackupCreated,
new[] { studioNotifyHelper.ToRecipient(userId) },
new[] { _studioNotifyHelper.ToRecipient(userId) },
new[] { StudioNotifyService.EMailSenderName },
new TagValue(Tags.OwnerName, userManager.GetUsers(userId).DisplayUserName(displayUserSettingsHelper)));
}
public void SendAboutRestoreStarted(Tenant tenant, bool notifyAllUsers)
{
using var scope = _serviceScopeFactory.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<NotifyHelperScope>();
var (userManager, studioNotifyHelper, studioNotifySource, displayUserSettingsHelper, tenantManager, _) = scopeClass;
tenantManager.SetCurrentTenant(tenant.Id);
new TagValue(Tags.OwnerName, _userManager.GetUsers(userId).DisplayUserName(_displayUserSettingsHelper)));
}
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifySource, scope);
public void SendAboutRestoreStarted(Tenant tenant, bool notifyAllUsers)
{
_tenantManager.SetCurrentTenant(tenant.Id);
var client = _workContext.NotifyContext.RegisterClient(_notifyEngineQueue, _studioNotifySource);
var owner = userManager.GetUsers(tenant.OwnerId);
var owner = _userManager.GetUsers(tenant.OwnerId);
var users =
notifyAllUsers
? studioNotifyHelper.RecipientFromEmail(userManager.GetUsers(EmployeeStatus.Active).Where(r => r.ActivationStatus == EmployeeActivationStatus.Activated).Select(u => u.Email).ToList(), false)
: owner.ActivationStatus == EmployeeActivationStatus.Activated ? studioNotifyHelper.RecipientFromEmail(owner.Email, false) : new IDirectRecipient[0];
? _studioNotifyHelper.RecipientFromEmail(_userManager.GetUsers(EmployeeStatus.Active).Where(r => r.ActivationStatus == EmployeeActivationStatus.Activated).Select(u => u.Email).ToList(), false)
: owner.ActivationStatus == EmployeeActivationStatus.Activated ? _studioNotifyHelper.RecipientFromEmail(owner.Email, false) : new IDirectRecipient[0];
client.SendNoticeToAsync(
Actions.RestoreStarted,
@ -89,22 +113,18 @@ public class NotifyHelper
}
public void SendAboutRestoreCompleted(Tenant tenant, bool notifyAllUsers)
{
using var scope = _serviceScopeFactory.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<NotifyHelperScope>();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var commonLinkUtility = scope.ServiceProvider.GetService<CommonLinkUtility>();
var (userManager, _, studioNotifySource, _, _, authManager) = scopeClass;
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifySource, scope);
{
_tenantManager.SetCurrentTenant(tenant);
var client = _workContext.NotifyContext.RegisterClient(_notifyEngineQueue, _studioNotifySource);
var users = notifyAllUsers
? userManager.GetUsers(EmployeeStatus.Active)
: new[] { userManager.GetUsers(tenantManager.GetCurrentTenant().OwnerId) };
? _userManager.GetUsers(EmployeeStatus.Active)
: new[] { _userManager.GetUsers(_tenantManager.GetCurrentTenant().OwnerId) };
foreach (var user in users)
{
var hash = authManager.GetUserPasswordStamp(user.Id).ToString("s");
var confirmationUrl = commonLinkUtility.GetConfirmationUrl(user.Email, ConfirmType.PasswordChange, hash);
var hash = _authManager.GetUserPasswordStamp(user.Id).ToString("s");
var confirmationUrl = _commonLinkUtility.GetConfirmationUrl(user.Email, ConfirmType.PasswordChange, hash);
Func<string> greenButtonText = () => BackupResource.ButtonSetPassword;
@ -118,20 +138,18 @@ public class NotifyHelper
}
private void MigrationNotify(Tenant tenant, INotifyAction action, string region, string url, bool notify, int? toTenantId = null)
{
using var scope = _serviceScopeFactory.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<NotifyHelperScope>();
var (userManager, studioNotifyHelper, studioNotifySource, _, _, authManager) = scopeClass;
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifySource, scope);
var commonLinkUtility = scope.ServiceProvider.GetService<CommonLinkUtility>();
{
_tenantManager.SetCurrentTenant(tenant);
var client = _workContext.NotifyContext.RegisterClient(_notifyEngineQueue, _studioNotifySource);
var users = userManager.GetUsers()
var users = _userManager.GetUsers()
.Where(u => notify ? u.ActivationStatus.HasFlag(EmployeeActivationStatus.Activated) : u.IsOwner(tenant))
.ToArray();
if (users.Length > 0)
{
var args = CreateArgs(scope, region, url);
var args = CreateArgs(region, url);
if (action == Actions.MigrationPortalSuccessV115)
{
foreach (var user in users)
@ -139,8 +157,8 @@ public class NotifyHelper
var currentArgs = new List<ITagValue>(args);
var newTenantId = toTenantId.HasValue ? toTenantId.Value : tenant.Id;
var hash = authManager.GetUserPasswordStamp(user.Id).ToString("s");
var confirmationUrl = url + "/" + commonLinkUtility.GetConfirmationUrlRelative(newTenantId, user.Email, ConfirmType.PasswordChange, hash);
var hash = _authManager.GetUserPasswordStamp(user.Id).ToString("s");
var confirmationUrl = url + "/" + _commonLinkUtility.GetConfirmationUrlRelative(newTenantId, user.Email, ConfirmType.PasswordChange, hash);
Func<string> greenButtonText = () => BackupResource.ButtonSetPassword;
currentArgs.Add(TagValues.GreenButton(greenButtonText, confirmationUrl));
@ -158,14 +176,14 @@ public class NotifyHelper
client.SendNoticeToAsync(
action,
null,
users.Select(u => studioNotifyHelper.ToRecipient(u.Id)).ToArray(),
users.Select(u => _studioNotifyHelper.ToRecipient(u.Id)).ToArray(),
new[] { StudioNotifyService.EMailSenderName },
args.ToArray());
}
}
}
private List<ITagValue> CreateArgs(IServiceScope scope, string region, string url)
private List<ITagValue> CreateArgs(string region, string url)
{
var args = new List<ITagValue>()
{
@ -176,61 +194,10 @@ public class NotifyHelper
if (!string.IsNullOrEmpty(url))
{
args.Add(new TagValue(CommonTags.VirtualRootPath, url));
args.Add(new TagValue(CommonTags.ProfileUrl, url + scope.ServiceProvider.GetService<CommonLinkUtility>().GetMyStaff()));
args.Add(new TagValue(CommonTags.LetterLogo, scope.ServiceProvider.GetService<TenantLogoManager>().GetLogoDark(true)));
args.Add(new TagValue(CommonTags.ProfileUrl, url + _commonLinkUtility.GetMyStaff()));
args.Add(new TagValue(CommonTags.LetterLogo, _tenantLogoManager.GetLogoDark(true)));
}
return args;
}
}
[Scope]
public class NotifyHelperScope
{
private readonly AuthManager _authManager;
private readonly UserManager _userManager;
private readonly StudioNotifyHelper _studioNotifyHelper;
private readonly StudioNotifySource _studioNotifySource;
private readonly DisplayUserSettingsHelper _displayUserSettingsHelper;
private TenantManager TenantManager { get; }
public NotifyHelperScope(
UserManager userManager,
StudioNotifyHelper studioNotifyHelper,
StudioNotifySource studioNotifySource,
DisplayUserSettingsHelper displayUserSettingsHelper,
TenantManager tenantManager,
AuthManager authManager)
{
_userManager = userManager;
_studioNotifyHelper = studioNotifyHelper;
_studioNotifySource = studioNotifySource;
_displayUserSettingsHelper = displayUserSettingsHelper;
TenantManager = tenantManager;
_authManager = authManager;
}
public void Deconstruct(
out UserManager userManager,
out StudioNotifyHelper studioNotifyHelper,
out StudioNotifySource studioNotifySource,
out DisplayUserSettingsHelper displayUserSettingsHelper,
out TenantManager tenantManager,
out AuthManager authManager)
{
userManager = _userManager;
studioNotifyHelper = _studioNotifyHelper;
studioNotifySource = _studioNotifySource;
displayUserSettingsHelper = _displayUserSettingsHelper;
tenantManager = TenantManager;
authManager = _authManager;
}
}
public static class NotifyHelperExtension
{
public static void Register(DIHelper services)
{
services.TryAdd<NotifyHelperScope>();
}
}

View File

@ -36,21 +36,21 @@ namespace ASC.Data.Reassigns
public class QueueWorker<T> where T : DistributedTaskProgress
{
protected IHttpContextAccessor HttpContextAccessor { get; }
protected IServiceProvider ServiceProvider { get; }
protected IServiceScopeFactory ServiceProvider { get; }
private readonly object _synchRoot = new object();
protected readonly DistributedTaskQueue Queue;
protected readonly IDictionary<string, StringValues> HttpHeaders;
public QueueWorker(
IHttpContextAccessor httpContextAccessor,
IServiceProvider serviceProvider,
IServiceScopeFactory serviceProvider,
IDistributedTaskQueueFactory queueFactory,
string queueName)
{
HttpContextAccessor = httpContextAccessor;
ServiceProvider = serviceProvider;
Queue = queueFactory.CreateQueue(queueName);
HttpHeaders = httpContextAccessor.HttpContext.Request?.Headers;
}
public static string GetProgressItemId(int tenantId, Guid userId)
@ -75,7 +75,7 @@ namespace ASC.Data.Reassigns
}
}
protected DistributedTaskProgress Start(int tenantId, Guid userId, Func<T> constructor)
protected T Start(int tenantId, Guid userId, T newTask)
{
lock (_synchRoot)
{
@ -89,7 +89,7 @@ namespace ASC.Data.Reassigns
if (task == null)
{
task = constructor();
task = newTask;
Queue.EnqueueTask(task);
}
@ -105,7 +105,7 @@ namespace ASC.Data.Reassigns
public QueueWorkerReassign(
IHttpContextAccessor httpContextAccessor,
IServiceProvider serviceProvider,
IServiceScopeFactory serviceProvider,
IDistributedTaskQueueFactory queueFactory) :
base(httpContextAccessor, serviceProvider, queueFactory, CUSTOM_DISTRIBUTED_TASK_QUEUE_NAME)
{
@ -113,13 +113,9 @@ namespace ASC.Data.Reassigns
public ReassignProgressItem Start(int tenantId, Guid fromUserId, Guid toUserId, Guid currentUserId, bool deleteProfile)
{
return Start(tenantId, fromUserId, () =>
{
var result = ServiceProvider.GetService<ReassignProgressItem>();
result.Init(tenantId, fromUserId, toUserId, currentUserId, deleteProfile);
var result = new ReassignProgressItem(ServiceProvider, HttpHeaders, tenantId, fromUserId, toUserId, currentUserId, deleteProfile);
return result;
}) as ReassignProgressItem;
return Start(tenantId, fromUserId, result);
}
}
@ -130,7 +126,7 @@ namespace ASC.Data.Reassigns
public QueueWorkerRemove(
IHttpContextAccessor httpContextAccessor,
IServiceProvider serviceProvider,
IServiceScopeFactory serviceProvider,
IDistributedTaskQueueFactory queueFactory) :
base(httpContextAccessor, serviceProvider, queueFactory, CUSTOM_DISTRIBUTED_TASK_QUEUE_NAME)
{
@ -138,13 +134,9 @@ namespace ASC.Data.Reassigns
public RemoveProgressItem Start(int tenantId, UserInfo user, Guid currentUserId, bool notify)
{
return Start(tenantId, user.Id, () =>
{
var result = ServiceProvider.GetService<RemoveProgressItem>();
result.Init(tenantId, user, currentUserId, notify);
var result = new RemoveProgressItem(ServiceProvider, HttpHeaders, tenantId, user, currentUserId, notify);
return result;
}) as RemoveProgressItem;
return Start(tenantId, user.Id, result);
}
}
}

View File

@ -33,7 +33,6 @@ namespace ASC.Data.Reassigns
public Guid ToUser { get; private set; }
private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly QueueWorkerRemove _queueWorkerRemove;
private readonly IDictionary<string, StringValues> _httpHeaders;
private int _tenantId;
private Guid _currentUserId;
@ -43,20 +42,16 @@ namespace ASC.Data.Reassigns
//private readonly ProjectsReassign _projectsReassign;
public ReassignProgressItem(
IServiceScopeFactory serviceScopeFactory,
IHttpContextAccessor httpContextAccessor,
QueueWorkerRemove queueWorkerRemove)
IServiceScopeFactory serviceScopeFactory,
IDictionary<string, StringValues> httpHeaders,
int tenantId, Guid fromUserId, Guid toUserId, Guid currentUserId, bool deleteProfile)
{
_serviceScopeFactory = serviceScopeFactory;
_queueWorkerRemove = queueWorkerRemove;
_httpHeaders = QueueWorker.GetHttpHeaders(httpContextAccessor.HttpContext.Request);
_httpHeaders = httpHeaders;
//_docService = Web.Files.Classes.Global.FileStorageService;
//_projectsReassign = new ProjectsReassign();
}
public void Init(int tenantId, Guid fromUserId, Guid toUserId, Guid currentUserId, bool deleteProfile)
{
_tenantId = tenantId;
FromUser = fromUserId;
ToUser = toUserId;
@ -76,7 +71,8 @@ namespace ASC.Data.Reassigns
protected override void DoJob()
{
using var scope = _serviceScopeFactory.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<ReassignProgressItemScope>();
var scopeClass = scope.ServiceProvider.GetService<ReassignProgressItemScope>();
var queueWorkerRemove = scope.ServiceProvider.GetService<QueueWorkerRemove>();
var (tenantManager, coreBaseSettings, messageService, studioNotifyService, securityContext, userManager, userPhotoManager, displayUserSettingsHelper, messageTarget, options) = scopeClass;
var logger = options.Get("ASC.Web");
tenantManager.SetCurrentTenant(_tenantId);
@ -126,7 +122,7 @@ namespace ASC.Data.Reassigns
if (_deleteProfile)
{
DeleteUserProfile(userManager, userPhotoManager, messageService, messageTarget, displayUserSettingsHelper);
DeleteUserProfile(userManager, userPhotoManager, messageService, messageTarget, displayUserSettingsHelper, queueWorkerRemove);
}
}
catch (Exception ex)
@ -178,14 +174,14 @@ namespace ASC.Data.Reassigns
studioNotifyService.SendMsgReassignsFailed(_currentUserId, fromUser, toUser, errorMessage);
}
private void DeleteUserProfile(UserManager userManager, UserPhotoManager userPhotoManager, MessageService messageService, MessageTarget messageTarget, DisplayUserSettingsHelper displayUserSettingsHelper)
private void DeleteUserProfile(UserManager userManager, UserPhotoManager userPhotoManager, MessageService messageService, MessageTarget messageTarget, DisplayUserSettingsHelper displayUserSettingsHelper, QueueWorkerRemove queueWorkerRemove)
{
var user = userManager.GetUsers(FromUser);
var userName = user.DisplayUserName(false, displayUserSettingsHelper);
userPhotoManager.RemovePhoto(user.Id);
userManager.DeleteUser(user.Id);
_queueWorkerRemove.Start(_tenantId, user, _currentUserId, false);
queueWorkerRemove.Start(_tenantId, user, _currentUserId, false);
if (_httpHeaders != null)
{

View File

@ -36,24 +36,22 @@ namespace ASC.Data.Reassigns
private readonly IServiceScopeFactory _serviceScopeFactory;
private int _tenantId;
private Guid _currentUserId;
private bool _notify;
//private readonly IFileStorageService _docService;
//private readonly MailGarbageEngine _mailEraser;
private bool _notify;
//private readonly IFileStorageService _docService;
//private readonly MailGarbageEngine _mailEraser;
public RemoveProgressItem(
IServiceScopeFactory serviceScopeFactory,
IHttpContextAccessor httpContextAccessor)
IDictionary<string, StringValues> httpHeaders,
int tenantId, UserInfo user, Guid currentUserId, bool notify)
{
_httpHeaders = QueueWorker.GetHttpHeaders(httpContextAccessor.HttpContext.Request);
_httpHeaders = httpHeaders;
_serviceScopeFactory = serviceScopeFactory;
//_docService = Web.Files.Classes.Global.FileStorageService;
//_mailEraser = new MailGarbageEngine();
}
public void Init(int tenantId, UserInfo user, Guid currentUserId, bool notify)
{
_tenantId = tenantId;
User = user;
FromUser = user.Id;

View File

@ -30,12 +30,14 @@ namespace ASC.Data.Storage.Configuration;
public class BaseStorageSettingsListener
{
private readonly IServiceProvider _serviceProvider;
private readonly ICacheNotify<ConsumerCacheItem> _cacheNotify;
private readonly object _locker;
private volatile bool _subscribed;
public BaseStorageSettingsListener(IServiceProvider serviceProvider)
public BaseStorageSettingsListener(IServiceProvider serviceProvider, ICacheNotify<ConsumerCacheItem> cacheNotify)
{
_serviceProvider = serviceProvider;
_cacheNotify = cacheNotify;
_locker = new object();
}
@ -55,12 +57,12 @@ public class BaseStorageSettingsListener
_subscribed = true;
_serviceProvider.GetService<ICacheNotify<ConsumerCacheItem>>().Subscribe((i) =>
_cacheNotify.Subscribe((i) =>
{
using var scope = _serviceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<BaseStorageSettingsListenerScope>();
var (storageSettingsHelper, settingsManager, cdnStorageSettings) = scopeClass;
var (storageSettingsHelper, settingsManager) = scopeClass;
var settings = settingsManager.LoadForTenant<StorageSettings>(i.TenantId);
if (i.Name == settings.Module)
{
@ -78,7 +80,7 @@ public class BaseStorageSettingsListener
}
[Serializable]
public abstract class BaseStorageSettings<T> : ISettings where T : class, ISettings, new()
public abstract class BaseStorageSettings<T> : ISettings<BaseStorageSettings<T>> where T : class, ISettings<T>, new()
{
public string Module { get; set; }
public Dictionary<string, string> Props { get; set; }
@ -86,25 +88,35 @@ public abstract class BaseStorageSettings<T> : ISettings where T : class, ISetti
public abstract Guid ID { get; }
internal ICacheNotify<DataStoreCacheItem> Cache { get; set; }
public ISettings GetDefault(IServiceProvider serviceProvider)
public BaseStorageSettings<T> GetDefault()
{
return new T();
throw new NotImplementedException();
}
}
[Serializable]
public class StorageSettings : BaseStorageSettings<StorageSettings>
public class StorageSettings : BaseStorageSettings<StorageSettings>, ISettings<StorageSettings>
{
public override Guid ID => new Guid("F13EAF2D-FA53-44F1-A6D6-A5AEDA46FA2B");
StorageSettings ISettings<StorageSettings>.GetDefault()
{
return new StorageSettings();
}
}
[Scope]
[Serializable]
public class CdnStorageSettings : BaseStorageSettings<CdnStorageSettings>
public class CdnStorageSettings : BaseStorageSettings<CdnStorageSettings>, ISettings<CdnStorageSettings>
{
public override Guid ID => new Guid("0E9AE034-F398-42FE-B5EE-F86D954E9FB2");
public override Func<DataStoreConsumer, DataStoreConsumer> Switch => d => d.Cdn;
CdnStorageSettings ISettings<CdnStorageSettings>.GetDefault()
{
return new CdnStorageSettings();
}
}
[Scope]
@ -159,21 +171,21 @@ public class StorageSettingsHelper
_httpContextAccessor = httpContextAccessor;
}
public bool Save<T>(BaseStorageSettings<T> baseStorageSettings) where T : class, ISettings, new()
public bool Save<T>(BaseStorageSettings<T> baseStorageSettings) where T : class, ISettings<T>, new()
{
ClearDataStoreCache();
return _settingsManager.Save(baseStorageSettings);
}
public void Clear<T>(BaseStorageSettings<T> baseStorageSettings) where T : class, ISettings, new()
public void Clear<T>(BaseStorageSettings<T> baseStorageSettings) where T : class, ISettings<T>, new()
{
baseStorageSettings.Module = null;
baseStorageSettings.Props = null;
Save(baseStorageSettings);
}
public DataStoreConsumer DataStoreConsumer<T>(BaseStorageSettings<T> baseStorageSettings) where T : class, ISettings, new()
public DataStoreConsumer DataStoreConsumer<T>(BaseStorageSettings<T> baseStorageSettings) where T : class, ISettings<T>, new()
{
if (string.IsNullOrEmpty(baseStorageSettings.Module) || baseStorageSettings.Props == null)
{
@ -197,7 +209,7 @@ public class StorageSettingsHelper
return _dataStoreConsumer;
}
public IDataStore DataStore<T>(BaseStorageSettings<T> baseStorageSettings) where T : class, ISettings, new()
public IDataStore DataStore<T>(BaseStorageSettings<T> baseStorageSettings) where T : class, ISettings<T>, new()
{
if (_dataStore != null)
{
@ -231,20 +243,17 @@ public class BaseStorageSettingsListenerScope
{
private readonly StorageSettingsHelper _storageSettingsHelper;
private readonly SettingsManager _settingsManager;
private readonly CdnStorageSettings _cdnStorageSettings;
public BaseStorageSettingsListenerScope(StorageSettingsHelper storageSettingsHelper, SettingsManager settingsManager, CdnStorageSettings cdnStorageSettings)
public BaseStorageSettingsListenerScope(StorageSettingsHelper storageSettingsHelper, SettingsManager settingsManager)
{
_storageSettingsHelper = storageSettingsHelper;
_settingsManager = settingsManager;
_cdnStorageSettings = cdnStorageSettings;
}
public void Deconstruct(out StorageSettingsHelper storageSettingsHelper, out SettingsManager settingsManager, out CdnStorageSettings cdnStorageSettings)
public void Deconstruct(out StorageSettingsHelper storageSettingsHelper, out SettingsManager settingsManager)
{
storageSettingsHelper = _storageSettingsHelper;
settingsManager = _settingsManager;
cdnStorageSettings = this._cdnStorageSettings;
}
}

View File

@ -30,16 +30,13 @@ namespace ASC.Data.Storage.Migration;
public class ServiceClientListener
{
private readonly ICacheNotify<MigrationProgress> _progressMigrationNotify;
private readonly IServiceProvider _serviceProvider;
private readonly ICache _cache;
public ServiceClientListener(
ICacheNotify<MigrationProgress> progressMigrationNotify,
IServiceProvider serviceProvider,
ICache cache)
{
_progressMigrationNotify = progressMigrationNotify;
_serviceProvider = serviceProvider;
_cache = cache;
ProgressListening();
@ -79,18 +76,15 @@ public class ServiceClient : IService
public ServiceClientListener ServiceClientListener { get; }
public ICacheNotify<MigrationCache> CacheMigrationNotify { get; }
public ICacheNotify<MigrationUploadCdn> UploadCdnMigrationNotify { get; }
public IServiceProvider ServiceProvider { get; }
public ServiceClient(
ServiceClientListener serviceClientListener,
ICacheNotify<MigrationCache> cacheMigrationNotify,
ICacheNotify<MigrationUploadCdn> uploadCdnMigrationNotify,
IServiceProvider serviceProvider)
ICacheNotify<MigrationUploadCdn> uploadCdnMigrationNotify)
{
ServiceClientListener = serviceClientListener;
CacheMigrationNotify = cacheMigrationNotify;
UploadCdnMigrationNotify = uploadCdnMigrationNotify;
ServiceProvider = serviceProvider;
}
public void Migrate(int tenant, StorageSettings storageSettings)
@ -128,6 +122,6 @@ public class ServiceClient : IService
public void StopMigrate()
{
CacheMigrationNotify.Publish(new MigrationCache(), Common.Caching.CacheNotifyAction.InsertOrUpdate);
CacheMigrationNotify.Publish(new MigrationCache(), Common.Caching.CacheNotifyAction.InsertOrUpdate);
}
}

View File

@ -26,24 +26,23 @@
namespace ASC.Data.Storage;
[Scope(Additional = typeof(StaticUploaderExtension))]
[Scope]
public class StaticUploader
{
public const string CUSTOM_DISTRIBUTED_TASK_QUEUE_NAME = "static_upload";
protected readonly DistributedTaskQueue Queue;
private ICache _cache;
private static readonly TaskScheduler _scheduler;
private static readonly CancellationTokenSource _tokenSource;
private static readonly object _locker;
private readonly IServiceProvider _serviceProvider;
private readonly TenantManager _tenantManager;
private readonly SettingsManager _settingsManager;
private readonly StorageSettingsHelper _storageSettingsHelper;
private readonly UploadOperation _uploadOperation;
static StaticUploader()
{
_scheduler = new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, 4).ConcurrentScheduler;
_locker = new object();
_tokenSource = new CancellationTokenSource();
}
@ -53,6 +52,7 @@ public class StaticUploader
TenantManager tenantManager,
SettingsManager settingsManager,
StorageSettingsHelper storageSettingsHelper,
UploadOperation uploadOperation,
ICache cache,
IDistributedTaskQueueFactory queueFactory)
{
@ -62,9 +62,10 @@ public class StaticUploader
_settingsManager = settingsManager;
_storageSettingsHelper = storageSettingsHelper;
Queue = queueFactory.CreateQueue(CUSTOM_DISTRIBUTED_TASK_QUEUE_NAME);
_uploadOperation = uploadOperation;
}
public string UploadFile(string relativePath, string mappedPath, Action<string> onComplete = null)
public async Task<string> UploadFileAsync(string relativePath, string mappedPath, Action<string> onComplete = null)
{
if (_tokenSource.Token.IsCancellationRequested)
{
@ -82,45 +83,26 @@ public class StaticUploader
}
var tenantId = _tenantManager.GetCurrentTenant().Id;
UploadOperation uploadOperation;
var key = GetCacheKey(tenantId.ToString(), relativePath);
lock (_locker)
{
uploadOperation = _cache.Get<UploadOperation>(key);
if (uploadOperation != null)
var result = _cache.Get<string>(key);
if (!string.IsNullOrEmpty(result))
{
return !string.IsNullOrEmpty(uploadOperation.Result) ? uploadOperation.Result : string.Empty;
return result;
}
uploadOperation = new UploadOperation(_serviceProvider, tenantId, relativePath, mappedPath);
_cache.Insert(key, uploadOperation, DateTime.MaxValue);
}
uploadOperation.DoJobAsync().Wait();
onComplete?.Invoke(uploadOperation.Result);
await _uploadOperation.DoJobAsync(tenantId, relativePath, mappedPath);
onComplete?.Invoke(_uploadOperation.Result);
return uploadOperation.Result;
}
public Task<string> UploadFileAsync(string relativePath, string mappedPath, Action<string> onComplete = null)
{
var tenantId = _tenantManager.GetCurrentTenant().Id;
var task = new Task<string>(() =>
lock (_locker)
{
using var scope = _serviceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<StaticUploaderScope>();
var (tenantManager, staticUploader, _, _, _) = scopeClass;
tenantManager.SetCurrentTenant(tenantId);
_cache.Insert(key, _uploadOperation.Result, DateTime.MaxValue);
}
return staticUploader.UploadFile(relativePath, mappedPath, onComplete);
}, TaskCreationOptions.LongRunning);
task.ConfigureAwait(false);
task.Start(_scheduler);
return task;
return _uploadOperation.Result;
}
public void UploadDir(string relativePath, string mappedPath)
@ -183,50 +165,53 @@ public class StaticUploader
}
}
[Scope]
public class UploadOperation
{
public string Result { get; private set; }
private readonly ILog _logger;
private readonly int _tenantId;
private readonly string _path;
private readonly string _mappedPath;
private readonly TenantManager _tenantManager;
private readonly SecurityContext _securityContext;
private readonly SettingsManager _settingsManager;
private readonly StorageSettingsHelper _storageSettingsHelper;
private readonly IServiceProvider _serviceProvider;
public UploadOperation(IServiceProvider serviceProvider, int tenantId, string path, string mappedPath)
public UploadOperation(
IOptionsMonitor<ILog> options,
TenantManager tenantManager,
SecurityContext securityContext,
SettingsManager settingsManager,
StorageSettingsHelper storageSettingsHelper)
{
_serviceProvider = serviceProvider;
_logger = _serviceProvider.GetService<IOptionsMonitor<ILog>>().CurrentValue;
_tenantId = tenantId;
_path = path.TrimStart('/');
_mappedPath = mappedPath;
_logger = options.CurrentValue;
Result = string.Empty;
_tenantManager = tenantManager;
_securityContext = securityContext;
_settingsManager = settingsManager;
_storageSettingsHelper = storageSettingsHelper;
}
public async Task<string> DoJobAsync()
public async Task<string> DoJobAsync(int tenantId, string path, string mappedPath)
{
try
{
using var scope = _serviceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<StaticUploaderScope>();
var (tenantManager, _, securityContext, settingsManager, storageSettingsHelper) = scopeClass;
var tenant = tenantManager.GetTenant(_tenantId);
tenantManager.SetCurrentTenant(tenant);
securityContext.AuthenticateMeWithoutCookie(tenant.OwnerId);
path = path.TrimStart('/');
var tenant = _tenantManager.GetTenant(tenantId);
_tenantManager.SetCurrentTenant(tenant);
_securityContext.AuthenticateMeWithoutCookie(tenant.OwnerId);
var dataStore = storageSettingsHelper.DataStore(settingsManager.Load<CdnStorageSettings>());
var dataStore = _storageSettingsHelper.DataStore(_settingsManager.Load<CdnStorageSettings>());
if (File.Exists(_mappedPath))
if (File.Exists(mappedPath))
{
if (!await dataStore.IsFileAsync(_path))
if (!await dataStore.IsFileAsync(path))
{
using var stream = File.OpenRead(_mappedPath);
await dataStore.SaveAsync(_path, stream);
using var stream = File.OpenRead(mappedPath);
await dataStore.SaveAsync(path, stream);
}
var uri = await dataStore.GetInternalUriAsync("", _path, TimeSpan.Zero, null);
Result = uri.AbsoluteUri.ToLower();
_logger.DebugFormat("UploadFile {0}", Result);
var uri = await dataStore.GetInternalUriAsync("", path, TimeSpan.Zero, null);
Result = uri.AbsoluteUri.ToLower();
_logger.DebugFormat("UploadFile {0}", Result);
return Result;
}
}
@ -260,7 +245,7 @@ public class UploadOperationProgress : DistributedTaskProgress
_relativePath = relativePath;
_mappedPath = mappedPath;
const string extensions = ".png|.jpeg|.jpg|.gif|.ico|.swf|.mp3|.ogg|.eot|.svg|.ttf|.woff|.woff2|.css|.less|.js";
const string extensions = ".png|.jpeg|.jpg|.gif|.ico|.swf|.mp3|.ogg|.eot|.svg|.ttf|.woff|.woff2|.css|.less|.js";
var extensionsArray = extensions.Split('|');
_directoryFiles = Directory.GetFiles(mappedPath, "*", SearchOption.AllDirectories)
@ -285,7 +270,7 @@ public class UploadOperationProgress : DistributedTaskProgress
foreach (var file in _directoryFiles)
{
var filePath = file.Substring(_mappedPath.TrimEnd('/').Length);
staticUploader.UploadFile(CrossPlatform.PathCombine(_relativePath, filePath), file, (res) => StepDone());
staticUploader.UploadFileAsync(CrossPlatform.PathCombine(_relativePath, filePath), file, (res) => StepDone()).Wait();
}
tenant.SetStatus(TenantStatus.Active);
@ -296,49 +281,4 @@ public class UploadOperationProgress : DistributedTaskProgress
{
return MemberwiseClone();
}
}
[Scope]
public class StaticUploaderScope
{
private readonly TenantManager _tenantManager;
private readonly StaticUploader _staticUploader;
private readonly SecurityContext _securityContext;
private readonly SettingsManager _settingsManager;
private readonly StorageSettingsHelper _storageSettingsHelper;
public StaticUploaderScope(TenantManager tenantManager,
StaticUploader staticUploader,
SecurityContext securityContext,
SettingsManager settingsManager,
StorageSettingsHelper storageSettingsHelper)
{
_tenantManager = tenantManager;
_staticUploader = staticUploader;
_securityContext = securityContext;
_settingsManager = settingsManager;
_storageSettingsHelper = storageSettingsHelper;
}
public void Deconstruct(
out TenantManager tenantManager,
out StaticUploader staticUploader,
out SecurityContext securityContext,
out SettingsManager settingsManager,
out StorageSettingsHelper storageSettingsHelper)
{
tenantManager = _tenantManager;
staticUploader = _staticUploader;
securityContext = _securityContext;
settingsManager = _settingsManager;
storageSettingsHelper = _storageSettingsHelper;
}
}
public static class StaticUploaderExtension
{
public static void Register(DIHelper services)
{
services.TryAdd<StaticUploaderScope>();
}
}
}

View File

@ -31,9 +31,9 @@ public class StorageFactoryConfig
{
public Configuration.Storage Section { get; }
public StorageFactoryConfig(IServiceProvider serviceProvider)
public StorageFactoryConfig(Configuration.Storage storage)
{
Section = serviceProvider.GetService<Configuration.Storage>();
Section = storage;
}
public IEnumerable<string> GetModuleList(string configpath, bool exceptDisabledMigration = false)
@ -236,7 +236,7 @@ public class StorageFactory
props = handler.Property.ToDictionary(r => r.Name, r => r.Value);
}
return ((IDataStore)ActivatorUtilities.CreateInstance(_serviceProvider, instanceType))
.Configure(tenant, handler, moduleElement, props)
.SetQuotaController(moduleElement.Count ? controller : null

View File

@ -32,23 +32,17 @@ public class StorageHandler
private readonly string _module;
private readonly string _domain;
private readonly bool _checkAuth;
private readonly IServiceProvider _serviceProvider;
public StorageHandler(IServiceProvider serviceProvider, string path, string module, string domain, bool checkAuth = true)
public StorageHandler(string path, string module, string domain, bool checkAuth = true)
{
_serviceProvider = serviceProvider;
_path = path;
_module = module;
_domain = domain;
_checkAuth = checkAuth;
}
public Task Invoke(HttpContext context)
public Task Invoke(HttpContext context, TenantManager tenantManager, SecurityContext securityContext, StorageFactory storageFactory, EmailValidationKeyProvider emailValidationKeyProvider)
{
using var scope = _serviceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<StorageHandlerScope>();
var (tenantManager, securityContext, storageFactory, emailValidationKeyProvider) = scopeClass;
if (_checkAuth && !securityContext.IsAuthenticated)
{
context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
@ -75,33 +69,33 @@ public class StorageHandler
}
}
return InternalInvoke(context, storage, path, header);
}
return InternalInvoke(context, storage, path, header);
}
private async Task InternalInvoke(HttpContext context, IDataStore storage, string path, string header)
{
if (!await storage.IsFileAsync(_domain, path))
{
private async Task InternalInvoke(HttpContext context, IDataStore storage, string path, string header)
{
if (!await storage.IsFileAsync(_domain, path))
{
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
return;
return;
}
var headers = header.Length > 0 ? header.Split('&').Select(HttpUtility.UrlDecode) : Array.Empty<string>();
if (storage.IsSupportInternalUri)
{
var uri = await storage.GetInternalUriAsync(_domain, path, TimeSpan.FromMinutes(15), headers);
var uri = await storage.GetInternalUriAsync(_domain, path, TimeSpan.FromMinutes(15), headers);
//TODO
//context.Response.Cache.SetAllowResponseInBrowserHistory(false);
//context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.Redirect(uri.ToString());
return;
return;
}
string encoding = null;
if (storage is DiscDataStore && await storage.IsFileAsync(_domain, path + ".gz"))
if (storage is DiscDataStore && await storage.IsFileAsync(_domain, path + ".gz"))
{
path += ".gz";
encoding = "gzip";
@ -146,30 +140,6 @@ public class StorageHandler
{
return (context.GetRouteValue(name) ?? "").ToString();
}
}
[Scope]
public class StorageHandlerScope
{
private readonly TenantManager _tenantManager;
private readonly SecurityContext _securityContext;
private readonly StorageFactory _storageFactory;
private readonly EmailValidationKeyProvider _emailValidationKeyProvider;
public StorageHandlerScope(TenantManager tenantManager, SecurityContext securityContext, StorageFactory storageFactory, EmailValidationKeyProvider emailValidationKeyProvider)
{
_tenantManager = tenantManager;
_securityContext = securityContext;
_storageFactory = storageFactory;
_emailValidationKeyProvider = emailValidationKeyProvider;
}
public void Deconstruct(out TenantManager tenantManager, out SecurityContext securityContext, out StorageFactory storageFactory, out EmailValidationKeyProvider emailValidationKeyProvider)
{
tenantManager = _tenantManager;
securityContext = _securityContext;
storageFactory = _storageFactory;
emailValidationKeyProvider = _emailValidationKeyProvider;
}
}
public static class StorageHandlerExtensions
@ -180,18 +150,18 @@ public static class StorageHandlerExtensions
var virtPath = pathUtils.ResolveVirtualPath(module, domain);
virtPath = virtPath.TrimStart('/');
var handler = new StorageHandler(builder.ServiceProvider, string.Empty, module, domain, !publicRoute);
var handler = new StorageHandler(string.Empty, module, domain, !publicRoute);
var url = virtPath + "{*pathInfo}";
if (!builder.DataSources.Any(r => r.Endpoints.Any(e => e.DisplayName == url)))
{
builder.Map(url, handler.Invoke);
builder.MapGet(url, handler.Invoke);
var newUrl = url.Replace("{0}", "{t1}/{t2}/{t3}");
if (newUrl != url)
{
builder.Map(url, handler.Invoke);
builder.MapGet(url, handler.Invoke);
}
}

View File

@ -173,20 +173,12 @@ public class Login
public class LoginHandler
{
private readonly RequestDelegate _next;
private readonly IServiceScopeFactory _serviceScopeFactory;
public LoginHandler(RequestDelegate next, IServiceScopeFactory serviceScopeFactory)
public LoginHandler(RequestDelegate next)
{
_next = next;
_serviceScopeFactory = serviceScopeFactory;
}
public async Task InvokeAsync(HttpContext context)
public async Task InvokeAsync(HttpContext context, Login login)
{
using var scope = _serviceScopeFactory.CreateScope();
var login = scope.ServiceProvider.GetService<Login>();
await login.InvokeAsync(context);
}
}

View File

@ -27,13 +27,13 @@
namespace ASC.IPSecurity;
[Serializable]
public class IPRestrictionsSettings : ISettings
public class IPRestrictionsSettings : ISettings<IPRestrictionsSettings>
{
public bool Enable { get; set; }
public Guid ID => new Guid("{2EDDDF64-F792-4498-A638-2E3E6EBB13C9}");
public ISettings GetDefault(IServiceProvider serviceProvider)
public IPRestrictionsSettings GetDefault()
{
return new IPRestrictionsSettings { Enable = false };
}

View File

@ -27,7 +27,7 @@
namespace ASC.ElasticSearch.Core;
[Serializable]
public class SearchSettings : ISettings
public class SearchSettings : ISettings<SearchSettings>
{
public string Data { get; set; }
public Guid ID => new Guid("{93784AB2-10B5-4C2F-9B36-F2662CCCF316}");
@ -52,7 +52,7 @@ public class SearchSettings : ISettings
private List<SearchSettingsItem> _items;
public ISettings GetDefault(IServiceProvider serviceProvider)
public SearchSettings GetDefault()
{
return new SearchSettings();
}

View File

@ -26,7 +26,7 @@
namespace ASC.ElasticSearch.Service;
[Singletone(Additional = typeof(ServiceExtension))]
[Singletone]
public class ElasticSearchService
{
private readonly IServiceProvider _serviceProvider;
@ -77,9 +77,8 @@ public class ElasticSearchService
Task.WhenAll(tasks).ContinueWith(r =>
{
using var scope = _serviceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<ServiceScope>();
var (tenantManager, settingsManager) = scopeClass;
var tenantManager = scope.ServiceProvider.GetRequiredService<TenantManager>();
var settingsManager = scope.ServiceProvider.GetRequiredService<SettingsManager>();
tenantManager.SetCurrentTenant(tenant);
settingsManager.ClearCache<SearchSettings>();
});
@ -93,30 +92,3 @@ public class ElasticSearchService
// };
//}
}
[Scope]
public class ServiceScope
{
private readonly TenantManager _tenantManager;
private readonly SettingsManager _settingsManager;
public ServiceScope(TenantManager tenantManager, SettingsManager settingsManager)
{
_tenantManager = tenantManager;
_settingsManager = settingsManager;
}
public void Deconstruct(out TenantManager tenantManager, out SettingsManager settingsManager)
{
tenantManager = _tenantManager;
settingsManager = _settingsManager;
}
}
internal static class ServiceExtension
{
public static void Register(DIHelper services)
{
services.TryAdd<ServiceScope>();
}
}

View File

@ -29,18 +29,13 @@ global using System.Reflection;
global using ASC.Api.Core;
global using ASC.Api.Core.Extensions;
global using ASC.Common;
global using ASC.Common.Caching;
global using ASC.Common.DependencyInjection;
global using ASC.Common.Mapping;
global using ASC.Common.Utils;
global using ASC.Core.Notify;
global using ASC.Notify;
global using ASC.Web.Studio.Core.Notify;
global using ASC.Web.Studio.Core.Notify;
global using Autofac.Extensions.DependencyInjection;
global using Autofac;
global using Microsoft.AspNetCore.Builder;
global using Microsoft.AspNetCore.Hosting;
global using Microsoft.Extensions.Hosting.WindowsServices;
global using StackExchange.Redis.Extensions.Core.Configuration;
global using StackExchange.Redis.Extensions.Newtonsoft;

View File

@ -37,7 +37,7 @@ builder.Host.ConfigureDefault(args, (hostContext, config, env, path) =>
config.AddJsonFile($"appsettings.services.json", true)
.AddJsonFile("notify.json")
.AddJsonFile($"notify.{env.EnvironmentName}.json", true);
},
},
(hostContext, services, diHelper) =>
{
services.AddHttpClient();
@ -56,6 +56,11 @@ var startup = new BaseWorkerStartup(builder.Configuration);
startup.ConfigureServices(builder.Services);
builder.Host.ConfigureContainer<ContainerBuilder>((context, builder) =>
{
builder.Register(context.Configuration);
});
var app = builder.Build();
startup.Configure(app);

View File

@ -45,7 +45,7 @@ public class WebhookSender
public async Task Send(WebhookRequest webhookRequest, CancellationToken cancellationToken)
{
using var scope = _scopeFactory.CreateScope();
var dbWorker = scope.ServiceProvider.GetService<DbWorker>();
var dbWorker = scope.ServiceProvider.GetRequiredService<DbWorker>();
var entry = dbWorker.ReadFromJournal(webhookRequest.Id);
var id = entry.Id;

View File

@ -27,7 +27,7 @@
namespace ASC.Web.Files.Classes;
[Serializable]
public class FilesSettings : ISettings
public class FilesSettings : ISettings<FilesSettings>
{
[JsonPropertyName("EnableThirdpartySettings")]
public bool EnableThirdpartySetting { get; set; }
@ -74,7 +74,7 @@ public class FilesSettings : ISettings
[JsonPropertyName("DownloadZip")]
public bool DownloadTarGzSetting { get; set; }
public ISettings GetDefault(IServiceProvider serviceProvider)
public FilesSettings GetDefault()
{
return new FilesSettings
{

View File

@ -45,16 +45,14 @@ public class CompressToArchive : ICompress
: compressToZip;
}
public static string GetExt(IServiceProvider serviceProvider, string ext)
public string GetExt(string ext)
{
if (_exts.Contains(ext))
{
return ext;
}
using var zip = serviceProvider.GetService<CompressToArchive>();
return zip.ArchiveExtension;
return ArchiveExtension;
}
public void SetStream(Stream stream)

View File

@ -27,18 +27,13 @@
namespace ASC.Web.Files.HttpHandlers;
public class ChunkedUploaderHandler
{
private readonly IServiceScopeFactory _serviceScopeFactory;
public ChunkedUploaderHandler(RequestDelegate next, IServiceScopeFactory serviceScopeFactory)
{
public ChunkedUploaderHandler(RequestDelegate next)
{
_serviceScopeFactory = serviceScopeFactory;
}
public async Task Invoke(HttpContext context)
public async Task Invoke(HttpContext context, ChunkedUploaderHandlerService chunkedUploaderHandlerService)
{
using var scope = _serviceScopeFactory.CreateScope();
var chunkedUploaderHandlerService = scope.ServiceProvider.GetService<ChunkedUploaderHandlerService>();
await chunkedUploaderHandlerService.Invoke(context).ConfigureAwait(false);
}
}

View File

@ -31,24 +31,21 @@ namespace ASC.Web.Files
{
public class FileHandler
{
private IServiceProvider ServiceProvider { get; }
public FileHandler(RequestDelegate next, IServiceProvider serviceProvider)
public FileHandler(RequestDelegate next)
{
ServiceProvider = serviceProvider;
}
public async Task Invoke(HttpContext context)
public async Task Invoke(HttpContext context, FileHandlerService fileHandlerService)
{
using var scope = ServiceProvider.CreateScope();
var fileHandlerService = scope.ServiceProvider.GetService<FileHandlerService>();
await fileHandlerService.Invoke(context).ConfigureAwait(false);
}
}
[Scope]
public class FileHandlerService
{
{
private readonly CompressToArchive _compressToArchive;
public string FileHandlerPath
{
get { return FilesLinkUtility.FileHandlerPath; }
@ -83,7 +80,6 @@ namespace ASC.Web.Files
public FileHandlerService(
FilesLinkUtility filesLinkUtility,
TenantExtra tenantExtra,
CookiesManager cookiesManager,
AuthContext authContext,
SecurityContext securityContext,
GlobalStore globalStore,
@ -106,7 +102,8 @@ namespace ASC.Web.Files
FFmpegService fFmpegService,
IServiceProvider serviceProvider,
TempStream tempStream,
SocketManager socketManager,
SocketManager socketManager,
CompressToArchive compressToArchive,
IHttpClientFactory clientFactory)
{
FilesLinkUtility = filesLinkUtility;
@ -131,6 +128,7 @@ namespace ASC.Web.Files
FFmpegService = fFmpegService;
ServiceProvider = serviceProvider;
SocketManager = socketManager;
_compressToArchive = compressToArchive;
TempStream = tempStream;
UserManager = userManager;
Logger = optionsMonitor.CurrentValue;
@ -205,7 +203,7 @@ namespace ASC.Web.Files
return;
}
var ext = CompressToArchive.GetExt(ServiceProvider, context.Request.Query["ext"]);
var ext = _compressToArchive.GetExt(context.Request.Query["ext"]);
var store = GlobalStore.GetStore();
var path = string.Format(@"{0}\{1}{2}", SecurityContext.CurrentAccount.ID, FileConstant.DownloadTitle, ext);
@ -1101,26 +1099,26 @@ namespace ASC.Web.Files
}
private async Task InternalWriteError(HttpContext context, Exception ex, bool responseMessage)
{
Logger.Error(ex);
if (responseMessage)
{
await context.Response.WriteAsync("error: " + ex.Message);
return;
}
context.Response.Redirect(PathProvider.StartURL + "#error/" + HttpUtility.UrlEncode(ex.Message), true);
return;
}
private Task InternalWriteOk<T>(HttpContext context, Folder<T> folder, File<T> file)
{
Logger.Error(ex);
if (responseMessage)
{
var message = string.Format(FilesCommonResource.MessageFileCreated, folder.Title);
if (FileUtility.CanWebRestrictedEditing(file.Title))
message = string.Format(FilesCommonResource.MessageFileCreatedForm, folder.Title);
await context.Response.WriteAsync("error: " + ex.Message);
return;
}
context.Response.Redirect(PathProvider.StartURL + "#error/" + HttpUtility.UrlEncode(ex.Message), true);
return;
}
return context.Response.WriteAsync("ok: " + message);
}
private Task InternalWriteOk<T>(HttpContext context, Folder<T> folder, File<T> file)
{
var message = string.Format(FilesCommonResource.MessageFileCreated, folder.Title);
if (FileUtility.CanWebRestrictedEditing(file.Title))
message = string.Format(FilesCommonResource.MessageFileCreatedForm, folder.Title);
return context.Response.WriteAsync("ok: " + message);
}
private async Task<File<T>> CreateFileFromTemplateAsync<T>(Folder<T> folder, string fileTitle, string docType)
{

View File

@ -28,21 +28,13 @@ namespace ASC.Web.Files.HttpHandlers
{
public class ThirdPartyAppHandler
{
private RequestDelegate Next { get; }
private IServiceProvider ServiceProvider { get; }
public ThirdPartyAppHandler(RequestDelegate next, IServiceProvider serviceProvider)
public ThirdPartyAppHandler(RequestDelegate next)
{
Next = next;
ServiceProvider = serviceProvider;
}
public async Task Invoke(HttpContext context)
public async Task Invoke(HttpContext context, ThirdPartyAppHandlerService thirdPartyAppHandlerService)
{
using var scope = ServiceProvider.CreateScope();
var thirdPartyAppHandlerService = scope.ServiceProvider.GetService<ThirdPartyAppHandlerService>();
await thirdPartyAppHandlerService.InvokeAsync(context);
await Next.Invoke(context);
}
}

View File

@ -28,17 +28,12 @@ namespace ASC.Web.Files.HttpHandlers
{
public class DocuSignHandler
{
private readonly IServiceScopeFactory _serviceScopeFactory;
public DocuSignHandler(RequestDelegate next, IServiceScopeFactory serviceScopeFactory)
public DocuSignHandler(RequestDelegate next)
{
_serviceScopeFactory = serviceScopeFactory;
}
public async Task Invoke(HttpContext context)
public async Task Invoke(HttpContext context, DocuSignHandlerService docuSignHandlerService)
{
using var scope = _serviceScopeFactory.CreateScope();
var docuSignHandlerService = scope.ServiceProvider.GetService<DocuSignHandlerService>();
await docuSignHandlerService.Invoke(context).ConfigureAwait(false);
}
}

View File

@ -24,36 +24,70 @@
// 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 ASC.Notify.Engine;
using Context = ASC.Notify.Context;
namespace ASC.Files.Core.Services.NotifyService;
[Scope(Additional = typeof(NotifyClientExtension))]
[Scope]
public class NotifyClient
{
private readonly IServiceProvider _serviceProvider;
private Context NotifyContext { get; }
public NotifyClient(IServiceProvider serviceProvider, Context notifyContext)
private readonly NotifySource _notifySource;
private readonly SecurityContext _securityContext;
private readonly FilesLinkUtility _filesLinkUtility;
private readonly FileUtility _fileUtility;
private readonly BaseCommonLinkUtility _baseCommonLinkUtility;
private readonly IDaoFactory _daoFactory;
private readonly PathProvider _pathProvider;
private readonly UserManager _userManager;
private readonly TenantManager _tenantManager;
private readonly StudioNotifyHelper _studioNotifyHelper;
private readonly IServiceScopeFactory _scope;
private readonly Context _notifyContext;
private readonly NotifyEngineQueue _notifyEngineQueue;
public NotifyClient(
Context notifyContext,
NotifyEngineQueue notifyEngineQueue,
NotifySource notifySource,
SecurityContext securityContext,
FilesLinkUtility filesLinkUtility,
FileUtility fileUtility,
BaseCommonLinkUtility baseCommonLinkUtility,
IDaoFactory daoFactory,
PathProvider pathProvider,
UserManager userManager,
TenantManager tenantManager,
StudioNotifyHelper studioNotifyHelper,
IServiceScopeFactory serviceScope)
{
_serviceProvider = serviceProvider;
NotifyContext = notifyContext;
_notifyContext = notifyContext;
_notifyEngineQueue = notifyEngineQueue;
_notifySource = notifySource;
_securityContext = securityContext;
_filesLinkUtility = filesLinkUtility;
_fileUtility = fileUtility;
_baseCommonLinkUtility = baseCommonLinkUtility;
_daoFactory = daoFactory;
_pathProvider = pathProvider;
_userManager = userManager;
_tenantManager = tenantManager;
_studioNotifyHelper = studioNotifyHelper;
_scope = serviceScope;
}
public void SendDocuSignComplete<T>(File<T> file, string sourceTitle)
{
using var scope = _serviceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<NotifyClientScope>();
var (notifySource, securityContext, filesLinkUtility, fileUtility, baseCommonLinkUtility, _, _, _, _) = scopeClass;
var client = NotifyContext.NotifyService.RegisterClient(notifySource, scope);
var recipient = notifySource.GetRecipientsProvider().GetRecipient(securityContext.CurrentAccount.ID.ToString());
var client = _notifyContext.RegisterClient(_notifyEngineQueue, _notifySource);
var recipient = _notifySource.GetRecipientsProvider().GetRecipient(_securityContext.CurrentAccount.ID.ToString());
client.SendNoticeAsync(
NotifyConstants.EventDocuSignComplete,
file.UniqID,
recipient,
true,
new TagValue(NotifyConstants.TagDocumentUrl, baseCommonLinkUtility.GetFullAbsolutePath(filesLinkUtility.GetFileWebPreviewUrl(fileUtility, file.Title, file.Id))),
new TagValue(NotifyConstants.TagDocumentUrl, _baseCommonLinkUtility.GetFullAbsolutePath(_filesLinkUtility.GetFileWebPreviewUrl(_fileUtility, file.Title, file.Id))),
new TagValue(NotifyConstants.TagDocumentTitle, file.Title),
new TagValue(NotifyConstants.TagMessage, sourceTitle)
);
@ -61,12 +95,9 @@ public class NotifyClient
public void SendDocuSignStatus(string subject, string status)
{
using var scope = _serviceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<NotifyClientScope>();
var (notifySource, securityContext, _, _, _, _, _, _, _) = scopeClass;
var client = NotifyContext.NotifyService.RegisterClient(notifySource, scope);
var client = _notifyContext.RegisterClient(_notifyEngineQueue, _notifySource);
var recipient = notifySource.GetRecipientsProvider().GetRecipient(securityContext.CurrentAccount.ID.ToString());
var recipient = _notifySource.GetRecipientsProvider().GetRecipient(_securityContext.CurrentAccount.ID.ToString());
client.SendNoticeAsync(
NotifyConstants.EventDocuSignStatus,
@ -80,11 +111,9 @@ public class NotifyClient
public void SendMailMergeEnd(Guid userId, int countMails, int countError)
{
using var scope = _serviceProvider.CreateScope();
var notifySource = scope.ServiceProvider.GetService<NotifySource>();
var client = NotifyContext.NotifyService.RegisterClient(notifySource, scope);
var client = _notifyContext.RegisterClient(_notifyEngineQueue, _notifySource);
var recipient = notifySource.GetRecipientsProvider().GetRecipient(userId.ToString());
var recipient = _notifySource.GetRecipientsProvider().GetRecipient(userId.ToString());
client.SendNoticeAsync(
NotifyConstants.EventMailMergeEnd,
@ -102,24 +131,20 @@ public class NotifyClient
{
return;
}
var client = _notifyContext.RegisterClient(_notifyEngineQueue, _notifySource);
using var scope = _serviceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<NotifyClientScope>();
var (notifySource, _, filesLinkUtility, fileUtility, baseCommonLinkUtility, daoFactory, pathProvider, userManager, tenantManager) = scopeClass;
var client = NotifyContext.NotifyService.RegisterClient(notifySource, scope);
var studioNotifyHelper = scope.ServiceProvider.GetService<StudioNotifyHelper>();
var folderDao = daoFactory.GetFolderDao<T>();
var folderDao = _daoFactory.GetFolderDao<T>();
if (fileEntry.FileEntryType == FileEntryType.File && await folderDao.GetFolderAsync(((File<T>)fileEntry).ParentId) == null)
{
return;
}
var url = fileEntry.FileEntryType == FileEntryType.File
? filesLinkUtility.GetFileWebPreviewUrl(fileUtility, fileEntry.Title, fileEntry.Id)
: await pathProvider.GetFolderUrlAsync((Folder<T>)fileEntry);
? _filesLinkUtility.GetFileWebPreviewUrl(_fileUtility, fileEntry.Title, fileEntry.Id)
: await _pathProvider.GetFolderUrlAsync((Folder<T>)fileEntry);
var recipientsProvider = notifySource.GetRecipientsProvider();
var recipientsProvider = _notifySource.GetRecipientsProvider();
var action = fileEntry.FileEntryType == FileEntryType.File
? ((File<T>)fileEntry).Encrypted
@ -130,9 +155,9 @@ public class NotifyClient
foreach (var recipientPair in recipients)
{
var u = userManager.GetUsers(recipientPair.Key);
var u = _userManager.GetUsers(recipientPair.Key);
var culture = string.IsNullOrEmpty(u.CultureName)
? tenantManager.GetCurrentTenant().GetCulture()
? _tenantManager.GetCurrentTenant().GetCulture()
: CultureInfo.GetCultureInfo(u.CultureName);
var aceString = GetAccessString(recipientPair.Value, culture);
@ -144,10 +169,10 @@ public class NotifyClient
recipient,
true,
new TagValue(NotifyConstants.TagDocumentTitle, fileEntry.Title),
new TagValue(NotifyConstants.TagDocumentUrl, baseCommonLinkUtility.GetFullAbsolutePath(url)),
new TagValue(NotifyConstants.TagDocumentUrl, _baseCommonLinkUtility.GetFullAbsolutePath(url)),
new TagValue(NotifyConstants.TagAccessRights, aceString),
new TagValue(NotifyConstants.TagMessage, message.HtmlEncode()),
TagValues.Image(studioNotifyHelper, 0, "privacy.png")
TagValues.Image(_studioNotifyHelper, 0, "privacy.png")
);
}
}
@ -158,17 +183,14 @@ public class NotifyClient
{
return;
}
var client = _notifyContext.RegisterClient(_notifyEngineQueue, _notifySource);
using var scope = _serviceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<NotifyClientScope>();
var (notifySource, _, _, _, baseCommonLinkUtility, _, _, userManager, _) = scopeClass;
var client = NotifyContext.NotifyService.RegisterClient(notifySource, scope);
var recipientsProvider = notifySource.GetRecipientsProvider();
var recipientsProvider = _notifySource.GetRecipientsProvider();
foreach (var recipientId in recipientIds)
{
var u = userManager.GetUsers(recipientId);
var u = _userManager.GetUsers(recipientId);
var recipient = recipientsProvider.GetRecipient(u.Id.ToString());
@ -178,7 +200,7 @@ public class NotifyClient
recipient,
true,
new TagValue(NotifyConstants.TagDocumentTitle, file.Title),
new TagValue(NotifyConstants.TagDocumentUrl, baseCommonLinkUtility.GetFullAbsolutePath(documentUrl)),
new TagValue(NotifyConstants.TagDocumentUrl, _baseCommonLinkUtility.GetFullAbsolutePath(documentUrl)),
new TagValue(NotifyConstants.TagMessage, message.HtmlEncode())
);
}
@ -197,68 +219,4 @@ public class NotifyClient
_ => string.Empty,
};
}
}
[Scope]
public class NotifyClientScope
{
private readonly NotifySource _notifySource;
private readonly SecurityContext _securityContext;
private readonly FilesLinkUtility _filesLinkUtility;
private readonly FileUtility _fileUtility;
private readonly BaseCommonLinkUtility _baseCommonLinkUtility;
private readonly IDaoFactory _daoFactory;
private readonly PathProvider _pathProvider;
private readonly UserManager _userManager;
private readonly TenantManager _tenantManager;
public NotifyClientScope(NotifySource notifySource,
SecurityContext securityContext,
FilesLinkUtility filesLinkUtility,
FileUtility fileUtility,
BaseCommonLinkUtility baseCommonLinkUtility,
IDaoFactory daoFactory,
PathProvider pathProvider,
UserManager userManager,
TenantManager tenantManager)
{
_notifySource = notifySource;
_securityContext = securityContext;
_filesLinkUtility = filesLinkUtility;
_fileUtility = fileUtility;
_baseCommonLinkUtility = baseCommonLinkUtility;
_daoFactory = daoFactory;
_pathProvider = pathProvider;
_userManager = userManager;
_tenantManager = tenantManager;
}
public void Deconstruct(out NotifySource notifySource,
out SecurityContext securityContext,
out FilesLinkUtility filesLinkUtility,
out FileUtility fileUtility,
out BaseCommonLinkUtility baseCommonLinkUtility,
out IDaoFactory daoFactory,
out PathProvider pathProvider,
out UserManager userManager,
out TenantManager tenantManager)
{
notifySource = _notifySource;
securityContext = _securityContext;
filesLinkUtility = _filesLinkUtility;
fileUtility = _fileUtility;
baseCommonLinkUtility = _baseCommonLinkUtility;
daoFactory = _daoFactory;
pathProvider = _pathProvider;
userManager = _userManager;
tenantManager = _tenantManager;
}
}
public static class NotifyClientExtension
{
public static void Register(DIHelper services)
{
services.TryAdd<NotifyClientScope>();
}
}

View File

@ -1,334 +1,329 @@
// (c) Copyright Ascensio System SIA 2010-2022
//
// This program is a free software product.
// You can redistribute it and/or modify it under the terms
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
// any third-party rights.
//
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
//
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// The interactive user interfaces in modified source and object code versions of the Program must
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
//
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
// trademark law for use of our trademarks.
//
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
namespace ASC.Files.Api;
// (c) Copyright Ascensio System SIA 2010-2022
//
// This program is a free software product.
// You can redistribute it and/or modify it under the terms
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
// any third-party rights.
//
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
//
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// The interactive user interfaces in modified source and object code versions of the Program must
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
//
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
// trademark law for use of our trademarks.
//
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
namespace ASC.Files.Api;
[ConstraintRoute("int")]
public class FilesControllerInternal : FilesController<int>
{
public FilesControllerInternal(IServiceProvider serviceProvider, FilesControllerHelper<int> filesControllerHelper) : base(serviceProvider, filesControllerHelper)
{
public FilesControllerInternal(FilesControllerHelper<int> filesControllerHelper) : base(filesControllerHelper)
{
}
}
public class FilesControllerThirdparty : FilesController<string>
{
public FilesControllerThirdparty(IServiceProvider serviceProvider, FilesControllerHelper<string> filesControllerHelper) : base(serviceProvider, filesControllerHelper)
public FilesControllerThirdparty(FilesControllerHelper<string> filesControllerHelper) : base(filesControllerHelper)
{
}
}
public abstract class FilesController<T> : ApiControllerBase
{
private readonly FilesControllerHelper<T> _filesControllerHelper;
public abstract class FilesController<T> : ApiControllerBase
{
private readonly IServiceProvider _serviceProvider;
private readonly FilesControllerHelper<T> _filesControllerHelper;
public FilesController(
IServiceProvider serviceProvider,
FilesControllerHelper<T> filesControllerHelper)
{
_serviceProvider = serviceProvider;
_filesControllerHelper = filesControllerHelper;
}
/// <summary>
/// Change version history
/// </summary>
/// <param name="fileId">File ID</param>
/// <param name="version">Version of history</param>
/// <param name="continueVersion">Mark as version or revision</param>
/// <category>Files</category>
/// <returns></returns>
[Update("file/{fileId}/history")]
public FilesController(FilesControllerHelper<T> filesControllerHelper)
{
_filesControllerHelper = filesControllerHelper;
}
/// <summary>
/// Change version history
/// </summary>
/// <param name="fileId">File ID</param>
/// <param name="version">Version of history</param>
/// <param name="continueVersion">Mark as version or revision</param>
/// <category>Files</category>
/// <returns></returns>
[Update("file/{fileId}/history")]
public Task<IEnumerable<FileDto<T>>> ChangeHistoryFromBodyAsync(T fileId, [FromBody] ChangeHistoryRequestDto inDto)
{
{
return _filesControllerHelper.ChangeHistoryAsync(fileId, inDto.Version, inDto.ContinueVersion);
}
[Update("file/{fileId}/history")]
[Consumes("application/x-www-form-urlencoded")]
}
[Update("file/{fileId}/history")]
[Consumes("application/x-www-form-urlencoded")]
public Task<IEnumerable<FileDto<T>>> ChangeHistoryFromFormAsync(T fileId, [FromForm] ChangeHistoryRequestDto inDto)
{
{
return _filesControllerHelper.ChangeHistoryAsync(fileId, inDto.Version, inDto.ContinueVersion);
}
/// <summary>
/// Check conversion status
/// </summary>
/// <short>Convert</short>
/// <category>File operations</category>
/// <param name="fileId"></param>
/// <param name="start"></param>
/// <returns>Operation result</returns>
[Read("file/{fileId}/checkconversion")]
}
/// <summary>
/// Check conversion status
/// </summary>
/// <short>Convert</short>
/// <category>File operations</category>
/// <param name="fileId"></param>
/// <param name="start"></param>
/// <returns>Operation result</returns>
[Read("file/{fileId}/checkconversion")]
public IAsyncEnumerable<ConversationResultDto<T>> CheckConversionAsync(T fileId, bool start)
{
{
return _filesControllerHelper.CheckConversionAsync(new CheckConversionRequestDto<T>()
{
FileId = fileId,
StartConvert = start
});
}
[Create("file/{fileId}/copyas", order: int.MaxValue)]
{
FileId = fileId,
StartConvert = start
});
}
[Create("file/{fileId}/copyas", order: int.MaxValue)]
public object CopyFileAsFromBody(T fileId, [FromBody] CopyAsRequestDto<JsonElement> inDto)
{
return CopyFile(fileId, inDto);
}
[Create("file/{fileId}/copyas", order: int.MaxValue)]
[Consumes("application/x-www-form-urlencoded")]
{
return CopyFile(fileId, inDto, _filesControllerHelper);
}
[Create("file/{fileId}/copyas", order: int.MaxValue)]
[Consumes("application/x-www-form-urlencoded")]
public object CopyFileAsFromForm(T fileId, [FromForm] CopyAsRequestDto<JsonElement> inDto)
{
return CopyFile(fileId, inDto);
}
/// <summary>
/// Creates a new file in the specified folder with the title sent in the request
/// </summary>
/// <short>Create file</short>
/// <category>File Creation</category>
/// <param name="folderId">Folder ID</param>
/// <param name="title" remark="Allowed values: the file must have one of the following extensions: DOCX, XLSX, PPTX">File title</param>
/// <remarks>In case the extension for the file title differs from DOCX/XLSX/PPTX and belongs to one of the known text, spreadsheet or presentation formats, it will be changed to DOCX/XLSX/PPTX accordingly. If the file extension is not set or is unknown, the DOCX extension will be added to the file title.</remarks>
/// <returns>New file info</returns>
[Create("{folderId}/file")]
{
return CopyFile(fileId, inDto, _filesControllerHelper);
}
/// <summary>
/// Creates a new file in the specified folder with the title sent in the request
/// </summary>
/// <short>Create file</short>
/// <category>File Creation</category>
/// <param name="folderId">Folder ID</param>
/// <param name="title" remark="Allowed values: the file must have one of the following extensions: DOCX, XLSX, PPTX">File title</param>
/// <remarks>In case the extension for the file title differs from DOCX/XLSX/PPTX and belongs to one of the known text, spreadsheet or presentation formats, it will be changed to DOCX/XLSX/PPTX accordingly. If the file extension is not set or is unknown, the DOCX extension will be added to the file title.</remarks>
/// <returns>New file info</returns>
[Create("{folderId}/file")]
public Task<FileDto<T>> CreateFileFromBodyAsync(T folderId, [FromBody] CreateFileRequestDto<JsonElement> inDto)
{
{
return _filesControllerHelper.CreateFileAsync(folderId, inDto.Title, inDto.TemplateId, inDto.EnableExternalExt);
}
[Create("{folderId}/file")]
[Consumes("application/x-www-form-urlencoded")]
}
[Create("{folderId}/file")]
[Consumes("application/x-www-form-urlencoded")]
public Task<FileDto<T>> CreateFileFromFormAsync(T folderId, [FromForm] CreateFileRequestDto<JsonElement> inDto)
{
{
return _filesControllerHelper.CreateFileAsync(folderId, inDto.Title, inDto.TemplateId, inDto.EnableExternalExt);
}
/// <summary>
/// Creates an html (.html) file in the selected folder with the title and contents sent in the request
/// </summary>
/// <short>Create html</short>
/// <category>File Creation</category>
/// <param name="folderId">Folder ID</param>
/// <param name="title">File title</param>
/// <param name="content">File contents</param>
/// <returns>Folder contents</returns>
[Create("{folderId}/html")]
}
/// <summary>
/// Creates an html (.html) file in the selected folder with the title and contents sent in the request
/// </summary>
/// <short>Create html</short>
/// <category>File Creation</category>
/// <param name="folderId">Folder ID</param>
/// <param name="title">File title</param>
/// <param name="content">File contents</param>
/// <returns>Folder contents</returns>
[Create("{folderId}/html")]
public Task<FileDto<T>> CreateHtmlFileFromBodyAsync(T folderId, [FromBody] CreateTextOrHtmlFileRequestDto inDto)
{
{
return _filesControllerHelper.CreateHtmlFileAsync(folderId, inDto.Title, inDto.Content);
}
[Create("{folderId}/html")]
[Consumes("application/x-www-form-urlencoded")]
}
[Create("{folderId}/html")]
[Consumes("application/x-www-form-urlencoded")]
public Task<FileDto<T>> CreateHtmlFileFromFormAsync(T folderId, [FromForm] CreateTextOrHtmlFileRequestDto inDto)
{
{
return _filesControllerHelper.CreateHtmlFileAsync(folderId, inDto.Title, inDto.Content);
}
/// <summary>
/// Creates a text (.txt) file in the selected folder with the title and contents sent in the request
/// </summary>
/// <short>Create txt</short>
/// <category>File Creation</category>
/// <param name="folderId">Folder ID</param>
/// <param name="title">File title</param>
/// <param name="content">File contents</param>
/// <returns>Folder contents</returns>
[Create("{folderId}/text")]
}
/// <summary>
/// Creates a text (.txt) file in the selected folder with the title and contents sent in the request
/// </summary>
/// <short>Create txt</short>
/// <category>File Creation</category>
/// <param name="folderId">Folder ID</param>
/// <param name="title">File title</param>
/// <param name="content">File contents</param>
/// <returns>Folder contents</returns>
[Create("{folderId}/text")]
public Task<FileDto<T>> CreateTextFileFromBodyAsync(T folderId, [FromBody] CreateTextOrHtmlFileRequestDto inDto)
{
{
return _filesControllerHelper.CreateTextFileAsync(folderId, inDto.Title, inDto.Content);
}
[Create("{folderId}/text")]
[Consumes("application/x-www-form-urlencoded")]
}
[Create("{folderId}/text")]
[Consumes("application/x-www-form-urlencoded")]
public Task<FileDto<T>> CreateTextFileFromFormAsync(T folderId, [FromForm] CreateTextOrHtmlFileRequestDto inDto)
{
{
return _filesControllerHelper.CreateTextFileAsync(folderId, inDto.Title, inDto.Content);
}
/// <summary>
/// Deletes the file with the ID specified in the request
/// </summary>
/// <short>Delete file</short>
/// <category>Files</category>
/// <param name="fileId">File ID</param>
/// <param name="deleteAfter">Delete after finished</param>
/// <param name="immediately">Don't move to the Recycle Bin</param>
/// <returns>Operation result</returns>
[Delete("file/{fileId}", order: int.MaxValue, DisableFormat = true)]
}
/// <summary>
/// Deletes the file with the ID specified in the request
/// </summary>
/// <short>Delete file</short>
/// <category>Files</category>
/// <param name="fileId">File ID</param>
/// <param name="deleteAfter">Delete after finished</param>
/// <param name="immediately">Don't move to the Recycle Bin</param>
/// <returns>Operation result</returns>
[Delete("file/{fileId}", order: int.MaxValue, DisableFormat = true)]
public Task<IEnumerable<FileOperationDto>> DeleteFile(T fileId, [FromBody] DeleteRequestDto inDto)
{
{
return _filesControllerHelper.DeleteFileAsync(fileId, inDto.DeleteAfter, inDto.Immediately);
}
[AllowAnonymous]
[Read("file/{fileId}/edit/diff")]
}
[AllowAnonymous]
[Read("file/{fileId}/edit/diff")]
public Task<EditHistoryDataDto> GetEditDiffUrlAsync(T fileId, int version = 0, string doc = null)
{
{
return _filesControllerHelper.GetEditDiffUrlAsync(fileId, version, doc);
}
[AllowAnonymous]
[Read("file/{fileId}/edit/history")]
}
[AllowAnonymous]
[Read("file/{fileId}/edit/history")]
public Task<List<EditHistoryDto>> GetEditHistoryAsync(T fileId, string doc = null)
{
{
return _filesControllerHelper.GetEditHistoryAsync(fileId, doc);
}
/// <summary>
/// Returns a detailed information about the file with the ID specified in the request
/// </summary>
/// <short>File information</short>
/// <category>Files</category>
/// <returns>File info</returns>
[Read("file/{fileId}", order: int.MaxValue, DisableFormat = true)]
}
/// <summary>
/// Returns a detailed information about the file with the ID specified in the request
/// </summary>
/// <short>File information</short>
/// <category>Files</category>
/// <returns>File info</returns>
[Read("file/{fileId}", order: int.MaxValue, DisableFormat = true)]
public Task<FileDto<T>> GetFileInfoAsync(T fileId, int version = -1)
{
{
return _filesControllerHelper.GetFileInfoAsync(fileId, version);
}
/// <summary>
/// Returns the detailed information about all the available file versions with the ID specified in the request
/// </summary>
/// <short>File versions</short>
/// <category>Files</category>
/// <param name="fileId">File ID</param>
/// <returns>File information</returns>
[Read("file/{fileId}/history")]
}
/// <summary>
/// Returns the detailed information about all the available file versions with the ID specified in the request
/// </summary>
/// <short>File versions</short>
/// <category>Files</category>
/// <param name="fileId">File ID</param>
/// <returns>File information</returns>
[Read("file/{fileId}/history")]
public Task<IEnumerable<FileDto<T>>> GetFileVersionInfoAsync(T fileId)
{
{
return _filesControllerHelper.GetFileVersionInfoAsync(fileId);
}
[Update("file/{fileId}/lock")]
}
[Update("file/{fileId}/lock")]
public Task<FileDto<T>> LockFileFromBodyAsync(T fileId, [FromBody] LockFileRequestDto inDto)
{
{
return _filesControllerHelper.LockFileAsync(fileId, inDto.LockFile);
}
[Update("file/{fileId}/lock")]
[Consumes("application/x-www-form-urlencoded")]
}
[Update("file/{fileId}/lock")]
[Consumes("application/x-www-form-urlencoded")]
public Task<FileDto<T>> LockFileFromFormAsync(T fileId, [FromForm] LockFileRequestDto inDto)
{
{
return _filesControllerHelper.LockFileAsync(fileId, inDto.LockFile);
}
[AllowAnonymous]
[Read("file/{fileId}/restoreversion")]
}
[AllowAnonymous]
[Read("file/{fileId}/restoreversion")]
public Task<List<EditHistoryDto>> RestoreVersionAsync(T fileId, int version = 0, string url = null, string doc = null)
{
{
return _filesControllerHelper.RestoreVersionAsync(fileId, version, url, doc);
}
/// <summary>
/// Start conversion
/// </summary>
/// <short>Convert</short>
/// <category>File operations</category>
/// <param name="fileId"></param>
/// <returns>Operation result</returns>
[Update("file/{fileId}/checkconversion")]
}
/// <summary>
/// Start conversion
/// </summary>
/// <short>Convert</short>
/// <category>File operations</category>
/// <param name="fileId"></param>
/// <returns>Operation result</returns>
[Update("file/{fileId}/checkconversion")]
public IAsyncEnumerable<ConversationResultDto<T>> StartConversion(T fileId, [FromBody(EmptyBodyBehavior = Microsoft.AspNetCore.Mvc.ModelBinding.EmptyBodyBehavior.Allow)] CheckConversionRequestDto<T> inDto)
{
if (inDto == null)
{
{
if (inDto == null)
{
inDto = new CheckConversionRequestDto<T>();
}
inDto.FileId = fileId;
}
inDto.FileId = fileId;
return _filesControllerHelper.StartConversionAsync(inDto);
}
[Update("file/{fileId}/comment")]
}
[Update("file/{fileId}/comment")]
public async Task<object> UpdateCommentFromBodyAsync(T fileId, [FromBody] UpdateCommentRequestDto inDto)
{
{
return await _filesControllerHelper.UpdateCommentAsync(fileId, inDto.Version, inDto.Comment);
}
[Update("file/{fileId}/comment")]
[Consumes("application/x-www-form-urlencoded")]
}
[Update("file/{fileId}/comment")]
[Consumes("application/x-www-form-urlencoded")]
public async Task<object> UpdateCommentFromFormAsync(T fileId, [FromForm] UpdateCommentRequestDto inDto)
{
{
return await _filesControllerHelper.UpdateCommentAsync(fileId, inDto.Version, inDto.Comment);
}
/// <summary>
/// Updates the information of the selected file with the parameters specified in the request
/// </summary>
/// <short>Update file info</short>
/// <category>Files</category>
/// <param name="fileId">File ID</param>
/// <param name="title">New title</param>
/// <param name="lastVersion">File last version number</param>
/// <returns>File info</returns>
[Update("file/{fileId}", order: int.MaxValue, DisableFormat = true)]
}
/// <summary>
/// Updates the information of the selected file with the parameters specified in the request
/// </summary>
/// <short>Update file info</short>
/// <category>Files</category>
/// <param name="fileId">File ID</param>
/// <param name="title">New title</param>
/// <param name="lastVersion">File last version number</param>
/// <returns>File info</returns>
[Update("file/{fileId}", order: int.MaxValue, DisableFormat = true)]
public Task<FileDto<T>> UpdateFileFromBodyAsync(T fileId, [FromBody] UpdateFileRequestDto inDto)
{
{
return _filesControllerHelper.UpdateFileAsync(fileId, inDto.Title, inDto.LastVersion);
}
[Update("file/{fileId}", order: int.MaxValue, DisableFormat = true)]
[Consumes("application/x-www-form-urlencoded")]
}
[Update("file/{fileId}", order: int.MaxValue, DisableFormat = true)]
[Consumes("application/x-www-form-urlencoded")]
public Task<FileDto<T>> UpdateFileFromFormAsync(T fileId, [FromForm] UpdateFileRequestDto inDto)
{
{
return _filesControllerHelper.UpdateFileAsync(fileId, inDto.Title, inDto.LastVersion);
}
/// <summary>
///
/// </summary>
/// <param name="file"></param>
/// <param name="fileId"></param>
/// <param name="encrypted"></param>
/// <returns></returns>
/// <visible>false</visible>
[Update("{fileId}/update")]
}
/// <summary>
///
/// </summary>
/// <param name="file"></param>
/// <param name="fileId"></param>
/// <param name="encrypted"></param>
/// <returns></returns>
/// <visible>false</visible>
[Update("{fileId}/update")]
public Task<FileDto<T>> UpdateFileStreamFromFormAsync(T fileId, [FromForm] FileStreamRequestDto inDto)
{
{
return _filesControllerHelper.UpdateFileStreamAsync(_filesControllerHelper.GetFileFromRequest(inDto).OpenReadStream(), fileId, inDto.FileExtension, inDto.Encrypted, inDto.Forcesave);
}
private object CopyFile(T fileId, CopyAsRequestDto<JsonElement> inDto)
{
var helper = _serviceProvider.GetService<FilesControllerHelper<T>>();
if (inDto.DestFolderId.ValueKind == JsonValueKind.Number)
{
return helper.CopyFileAsAsync(fileId, inDto.DestFolderId.GetInt32(), inDto.DestTitle, inDto.Password);
}
else if (inDto.DestFolderId.ValueKind == JsonValueKind.String)
{
return helper.CopyFileAsAsync(fileId, inDto.DestFolderId.GetString(), inDto.DestTitle, inDto.Password);
}
return null;
}
}
private object CopyFile(T fileId, CopyAsRequestDto<JsonElement> inDto, FilesControllerHelper<T> helper)
{
if (inDto.DestFolderId.ValueKind == JsonValueKind.Number)
{
return helper.CopyFileAsAsync(fileId, inDto.DestFolderId.GetInt32(), inDto.DestTitle, inDto.Password);
}
else if (inDto.DestFolderId.ValueKind == JsonValueKind.String)
{
return helper.CopyFileAsAsync(fileId, inDto.DestFolderId.GetString(), inDto.DestTitle, inDto.Password);
}
return null;
}
}
public class FilesControllerCommon : ApiControllerBase

View File

@ -1,297 +1,297 @@
// (c) Copyright Ascensio System SIA 2010-2022
//
// This program is a free software product.
// You can redistribute it and/or modify it under the terms
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
// any third-party rights.
//
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
//
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// The interactive user interfaces in modified source and object code versions of the Program must
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
//
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
// trademark law for use of our trademarks.
//
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
namespace ASC.Files.Helpers;
public class FilesControllerHelper<T> : FilesHelperBase<T>
// (c) Copyright Ascensio System SIA 2010-2022
//
// This program is a free software product.
// You can redistribute it and/or modify it under the terms
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
// any third-party rights.
//
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
//
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// The interactive user interfaces in modified source and object code versions of the Program must
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
//
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
// trademark law for use of our trademarks.
//
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
namespace ASC.Files.Helpers;
public class FilesControllerHelper<T> : FilesHelperBase<T>
{
private readonly ILog _logger;
private readonly ApiDateTimeHelper _apiDateTimeHelper;
private readonly UserManager _userManager;
private readonly DisplayUserSettingsHelper _displayUserSettingsHelper;
private readonly IServiceProvider _serviceProvider;
private readonly FileConverter _fileConverter;
private readonly FileOperationDtoHelper _fileOperationDtoHelper;
private readonly ILog _logger;
private readonly ApiDateTimeHelper _apiDateTimeHelper;
private readonly UserManager _userManager;
private readonly DisplayUserSettingsHelper _displayUserSettingsHelper;
private readonly FileConverter _fileConverter;
private readonly FileOperationDtoHelper _fileOperationDtoHelper;
public FilesControllerHelper(
FilesSettingsHelper filesSettingsHelper,
FileUploader fileUploader,
SocketManager socketManager,
FileDtoHelper fileDtoHelper,
ApiContext apiContext,
FileStorageService<T> fileStorageService,
FolderContentDtoHelper folderContentDtoHelper,
IHttpContextAccessor httpContextAccessor,
FolderDtoHelper folderDtoHelper,
ILog logger,
ApiDateTimeHelper apiDateTimeHelper,
UserManager userManager,
DisplayUserSettingsHelper displayUserSettingsHelper,
IServiceProvider serviceProvider,
FileConverter fileConverter,
FileOperationDtoHelper fileOperationDtoHelper)
: base(
filesSettingsHelper,
fileUploader,
socketManager,
fileDtoHelper,
apiContext,
fileStorageService,
folderContentDtoHelper,
httpContextAccessor,
folderDtoHelper)
IServiceProvider serviceProvider,
FilesSettingsHelper filesSettingsHelper,
FileUploader fileUploader,
SocketManager socketManager,
FileDtoHelper fileDtoHelper,
ApiContext apiContext,
FileStorageService<T> fileStorageService,
FolderContentDtoHelper folderContentDtoHelper,
IHttpContextAccessor httpContextAccessor,
FolderDtoHelper folderDtoHelper,
ILog logger,
ApiDateTimeHelper apiDateTimeHelper,
UserManager userManager,
DisplayUserSettingsHelper displayUserSettingsHelper,
FileConverter fileConverter,
FileOperationDtoHelper fileOperationDtoHelper)
: base(
filesSettingsHelper,
fileUploader,
socketManager,
fileDtoHelper,
apiContext,
fileStorageService,
folderContentDtoHelper,
httpContextAccessor,
folderDtoHelper)
{
_logger = logger;
_apiDateTimeHelper = apiDateTimeHelper;
_fileConverter = fileConverter;
_userManager = userManager;
_serviceProvider = serviceProvider;
_displayUserSettingsHelper = displayUserSettingsHelper;
_fileOperationDtoHelper = fileOperationDtoHelper;
}
public async Task<IEnumerable<FileDto<T>>> ChangeHistoryAsync(T fileId, int version, bool continueVersion)
_logger = logger;
_apiDateTimeHelper = apiDateTimeHelper;
_fileConverter = fileConverter;
_userManager = userManager;
_displayUserSettingsHelper = displayUserSettingsHelper;
_fileOperationDtoHelper = fileOperationDtoHelper;
}
public async Task<IEnumerable<FileDto<T>>> ChangeHistoryAsync(T fileId, int version, bool continueVersion)
{
var pair = await _fileStorageService.CompleteVersionAsync(fileId, version, continueVersion);
var history = pair.Value;
var result = new List<FileDto<T>>();
foreach (var e in history)
{
result.Add(await _fileDtoHelper.GetAsync(e));
}
return result;
}
public async IAsyncEnumerable<ConversationResultDto<T>> CheckConversionAsync(CheckConversionRequestDto<T> cheqConversionRequestDto)
{
var checkConversaion = _fileStorageService.CheckConversionAsync(new List<CheckConversionRequestDto<T>>() { cheqConversionRequestDto }, cheqConversionRequestDto.Sync);
await foreach (var r in checkConversaion)
{
var o = new ConversationResultDto<T>
{
Id = r.Id,
Error = r.Error,
OperationType = r.OperationType,
Processed = r.Processed,
Progress = r.Progress,
Source = r.Source,
};
if (!string.IsNullOrEmpty(r.Result))
{
try
{
var options = new JsonSerializerOptions
{
AllowTrailingCommas = true,
PropertyNameCaseInsensitive = true
};
var jResult = JsonSerializer.Deserialize<FileJsonSerializerData<T>>(r.Result, options);
o.File = await GetFileInfoAsync(jResult.Id, jResult.Version);
}
catch (Exception e)
{
o.File = r.Result;
_logger.Error(e);
}
}
yield return o;
}
}
public async Task<FileDto<T>> CreateFileAsync(T folderId, string title, JsonElement templateId, bool enableExternalExt = false)
{
File<T> file;
if (templateId.ValueKind == JsonValueKind.Number)
{
file = await _fileStorageService.CreateNewFileAsync(new FileModel<T, int> { ParentId = folderId, Title = title, TemplateId = templateId.GetInt32() }, enableExternalExt);
}
else if (templateId.ValueKind == JsonValueKind.String)
{
file = await _fileStorageService.CreateNewFileAsync(new FileModel<T, string> { ParentId = folderId, Title = title, TemplateId = templateId.GetString() }, enableExternalExt);
}
else
{
file = await _fileStorageService.CreateNewFileAsync(new FileModel<T, int> { ParentId = folderId, Title = title, TemplateId = 0 }, enableExternalExt);
}
return await _fileDtoHelper.GetAsync(file);
}
public Task<FileDto<T>> CreateHtmlFileAsync(T folderId, string title, string content)
{
ArgumentNullException.ThrowIfNull(title);
return CreateFileAsync(folderId, title, content, ".html");
}
public Task<FileDto<T>> CreateTextFileAsync(T folderId, string title, string content)
{
ArgumentNullException.ThrowIfNull(title);
//Try detect content
var extension = ".txt";
if (!string.IsNullOrEmpty(content))
{
if (Regex.IsMatch(content, @"<([^\s>]*)(\s[^<]*)>"))
{
extension = ".html";
}
}
return CreateFileAsync(folderId, title, content, extension);
}
private async Task<FileDto<T>> CreateFileAsync(T folderId, string title, string content, string extension)
{
using var memStream = new MemoryStream(Encoding.UTF8.GetBytes(content));
var file = await _fileUploader.ExecAsync(folderId,
title.EndsWith(extension, StringComparison.OrdinalIgnoreCase) ? title : (title + extension),
memStream.Length, memStream);
return await _fileDtoHelper.GetAsync(file);
}
public Task<EditHistoryDataDto> GetEditDiffUrlAsync(T fileId, int version = 0, string doc = null)
{
return _fileStorageService.GetEditDiffUrlAsync(fileId, version, doc);
}
public async Task<List<EditHistoryDto>> GetEditHistoryAsync(T fileId, string doc = null)
{
var result = await _fileStorageService.GetEditHistoryAsync(fileId, doc);
return result.Select(r => new EditHistoryDto(r, _apiDateTimeHelper, _userManager, _displayUserSettingsHelper)).ToList();
}
public async Task<IEnumerable<FileDto<T>>> GetFileVersionInfoAsync(T fileId)
{
var files = await _fileStorageService.GetFileHistoryAsync(fileId);
var result = new List<FileDto<T>>();
foreach (var e in files)
{
result.Add(await _fileDtoHelper.GetAsync(e));
}
return result;
}
public async Task<FileDto<T>> LockFileAsync(T fileId, bool lockFile)
{
var result = await _fileStorageService.LockFileAsync(fileId, lockFile);
return await _fileDtoHelper.GetAsync(result);
}
public async Task<List<EditHistoryDto>> RestoreVersionAsync(T fileId, int version = 0, string url = null, string doc = null)
{
var result = await _fileStorageService.RestoreVersionAsync(fileId, version, url, doc);
return result.Select(r => new EditHistoryDto(r, _apiDateTimeHelper, _userManager, _displayUserSettingsHelper)).ToList();
}
public IAsyncEnumerable<ConversationResultDto<T>> StartConversionAsync(CheckConversionRequestDto<T> cheqConversionRequestDto)
{
cheqConversionRequestDto.StartConvert = true;
return CheckConversionAsync(cheqConversionRequestDto);
}
public Task<string> UpdateCommentAsync(T fileId, int version, string comment)
{
return _fileStorageService.UpdateCommentAsync(fileId, version, comment);
}
public async Task<FileDto<T>> UpdateFileAsync(T fileId, string title, int lastVersion)
{
if (!string.IsNullOrEmpty(title))
{
await _fileStorageService.FileRenameAsync(fileId, title);
}
if (lastVersion > 0)
{
await _fileStorageService.UpdateToVersionAsync(fileId, lastVersion);
}
return await GetFileInfoAsync(fileId);
}
public async Task<FileDto<T>> UpdateFileStreamAsync(Stream file, T fileId, string fileExtension, bool encrypted = false, bool forcesave = false)
{
try
{
var resultFile = await _fileStorageService.UpdateFileStreamAsync(fileId, file, fileExtension, encrypted, forcesave);
return await _fileDtoHelper.GetAsync(resultFile);
}
catch (FileNotFoundException e)
{
throw new ItemNotFoundException("File not found", e);
}
}
public async Task<FileDto<TTemplate>> CopyFileAsAsync<TTemplate>(T fileId, TTemplate destFolderId, string destTitle, string password = null)
{
var pair = await _fileStorageService.CompleteVersionAsync(fileId, version, continueVersion);
var history = pair.Value;
var result = new List<FileDto<T>>();
foreach (var e in history)
{
result.Add(await _fileDtoHelper.GetAsync(e));
}
return result;
}
public async IAsyncEnumerable<ConversationResultDto<T>> CheckConversionAsync(CheckConversionRequestDto<T> cheqConversionRequestDto)
{
var checkConversaion = _fileStorageService.CheckConversionAsync(new List<CheckConversionRequestDto<T>>() { cheqConversionRequestDto }, cheqConversionRequestDto.Sync);
await foreach (var r in checkConversaion)
{
var o = new ConversationResultDto<T>
{
Id = r.Id,
Error = r.Error,
OperationType = r.OperationType,
Processed = r.Processed,
Progress = r.Progress,
Source = r.Source,
};
if (!string.IsNullOrEmpty(r.Result))
{
try
{
var options = new JsonSerializerOptions
{
AllowTrailingCommas = true,
PropertyNameCaseInsensitive = true
};
var jResult = JsonSerializer.Deserialize<FileJsonSerializerData<T>>(r.Result, options);
o.File = await GetFileInfoAsync(jResult.Id, jResult.Version);
}
catch (Exception e)
{
o.File = r.Result;
_logger.Error(e);
}
}
yield return o;
}
}
public async Task<FileDto<T>> CreateFileAsync(T folderId, string title, JsonElement templateId, bool enableExternalExt = false)
{
File<T> file;
if (templateId.ValueKind == JsonValueKind.Number)
{
file = await _fileStorageService.CreateNewFileAsync(new FileModel<T, int> { ParentId = folderId, Title = title, TemplateId = templateId.GetInt32() }, enableExternalExt);
}
else if (templateId.ValueKind == JsonValueKind.String)
{
file = await _fileStorageService.CreateNewFileAsync(new FileModel<T, string> { ParentId = folderId, Title = title, TemplateId = templateId.GetString() }, enableExternalExt);
}
else
{
file = await _fileStorageService.CreateNewFileAsync(new FileModel<T, int> { ParentId = folderId, Title = title, TemplateId = 0 }, enableExternalExt);
}
return await _fileDtoHelper.GetAsync(file);
}
public Task<FileDto<T>> CreateHtmlFileAsync(T folderId, string title, string content)
{
ArgumentNullException.ThrowIfNull(title);
return CreateFileAsync(folderId, title, content, ".html");
}
public Task<FileDto<T>> CreateTextFileAsync(T folderId, string title, string content)
{
ArgumentNullException.ThrowIfNull(title);
//Try detect content
var extension = ".txt";
if (!string.IsNullOrEmpty(content))
{
if (Regex.IsMatch(content, @"<([^\s>]*)(\s[^<]*)>"))
{
extension = ".html";
}
}
return CreateFileAsync(folderId, title, content, extension);
}
private async Task<FileDto<T>> CreateFileAsync(T folderId, string title, string content, string extension)
{
using var memStream = new MemoryStream(Encoding.UTF8.GetBytes(content));
var file = await _fileUploader.ExecAsync(folderId,
title.EndsWith(extension, StringComparison.OrdinalIgnoreCase) ? title : (title + extension),
memStream.Length, memStream);
return await _fileDtoHelper.GetAsync(file);
}
public Task<EditHistoryDataDto> GetEditDiffUrlAsync(T fileId, int version = 0, string doc = null)
{
return _fileStorageService.GetEditDiffUrlAsync(fileId, version, doc);
}
public async Task<List<EditHistoryDto>> GetEditHistoryAsync(T fileId, string doc = null)
{
var result = await _fileStorageService.GetEditHistoryAsync(fileId, doc);
return result.Select(r => new EditHistoryDto(r, _apiDateTimeHelper, _userManager, _displayUserSettingsHelper)).ToList();
}
public async Task<IEnumerable<FileDto<T>>> GetFileVersionInfoAsync(T fileId)
{
var files = await _fileStorageService.GetFileHistoryAsync(fileId);
var result = new List<FileDto<T>>();
foreach (var e in files)
{
result.Add(await _fileDtoHelper.GetAsync(e));
}
return result;
}
public async Task<FileDto<T>> LockFileAsync(T fileId, bool lockFile)
{
var result = await _fileStorageService.LockFileAsync(fileId, lockFile);
return await _fileDtoHelper.GetAsync(result);
}
public async Task<List<EditHistoryDto>> RestoreVersionAsync(T fileId, int version = 0, string url = null, string doc = null)
{
var result = await _fileStorageService.RestoreVersionAsync(fileId, version, url, doc);
return result.Select(r => new EditHistoryDto(r, _apiDateTimeHelper, _userManager, _displayUserSettingsHelper)).ToList();
}
public IAsyncEnumerable<ConversationResultDto<T>> StartConversionAsync(CheckConversionRequestDto<T> cheqConversionRequestDto)
{
cheqConversionRequestDto.StartConvert = true;
return CheckConversionAsync(cheqConversionRequestDto);
}
public Task<string> UpdateCommentAsync(T fileId, int version, string comment)
{
return _fileStorageService.UpdateCommentAsync(fileId, version, comment);
}
public async Task<FileDto<T>> UpdateFileAsync(T fileId, string title, int lastVersion)
{
if (!string.IsNullOrEmpty(title))
{
await _fileStorageService.FileRenameAsync(fileId, title);
}
if (lastVersion > 0)
{
await _fileStorageService.UpdateToVersionAsync(fileId, lastVersion);
}
return await GetFileInfoAsync(fileId);
}
public async Task<FileDto<T>> UpdateFileStreamAsync(Stream file, T fileId, string fileExtension, bool encrypted = false, bool forcesave = false)
{
try
{
var resultFile = await _fileStorageService.UpdateFileStreamAsync(fileId, file, fileExtension, encrypted, forcesave);
return await _fileDtoHelper.GetAsync(resultFile);
}
catch (FileNotFoundException e)
{
throw new ItemNotFoundException("File not found", e);
}
}
public async Task<FileDto<TTemplate>> CopyFileAsAsync<TTemplate>(T fileId, TTemplate destFolderId, string destTitle, string password = null)
{
var service = _serviceProvider.GetService<FileStorageService<TTemplate>>();
var controller = _serviceProvider.GetService<FilesControllerHelper<TTemplate>>();
var file = await _fileStorageService.GetFileAsync(fileId, -1);
var ext = FileUtility.GetFileExtension(file.Title);
var destExt = FileUtility.GetFileExtension(destTitle);
if (ext == destExt)
{
var newFile = await service.CreateNewFileAsync(new FileModel<TTemplate, T> { ParentId = destFolderId, Title = destTitle, TemplateId = fileId }, false);
return await _fileDtoHelper.GetAsync(newFile);
}
using (var fileStream = await _fileConverter.ExecAsync(file, destExt, password))
{
return await controller.InsertFileAsync(destFolderId, fileStream, destTitle, true);
}
}
public async Task<IEnumerable<FileOperationDto>> DeleteFileAsync(T fileId, bool deleteAfter, bool immediately)
{
var result = new List<FileOperationDto>();
foreach (var e in _fileStorageService.DeleteFile("delete", fileId, false, deleteAfter, immediately))
{
result.Add(await _fileOperationDtoHelper.GetAsync(e));
}
return result;
}
}
var service = _serviceProvider.GetService<FileStorageService<TTemplate>>();
var controller = _serviceProvider.GetService<FilesControllerHelper<TTemplate>>();
var file = await _fileStorageService.GetFileAsync(fileId, -1);
var ext = FileUtility.GetFileExtension(file.Title);
var destExt = FileUtility.GetFileExtension(destTitle);
if (ext == destExt)
{
var newFile = await service.CreateNewFileAsync(new FileModel<TTemplate, T> { ParentId = destFolderId, Title = destTitle, TemplateId = fileId }, false);
return await _fileDtoHelper.GetAsync(newFile);
}
using (var fileStream = await _fileConverter.ExecAsync(file, destExt, password))
{
return await controller.InsertFileAsync(destFolderId, fileStream, destTitle, true);
}
}
public async Task<IEnumerable<FileOperationDto>> DeleteFileAsync(T fileId, bool deleteAfter, bool immediately)
{
var result = new List<FileOperationDto>();
foreach (var e in _fileStorageService.DeleteFile("delete", fileId, false, deleteAfter, immediately))
{
result.Add(await _fileOperationDtoHelper.GetAsync(e));
}
return result;
}
}

View File

@ -38,9 +38,10 @@ public class ApiProductEntryPoint : ProductEntryPoint
//FilesSpaceUsageStatManager filesSpaceUsageStatManager,
CoreBaseSettings coreBaseSettings,
AuthContext authContext,
UserManager userManager
UserManager userManager,
NotifyConfiguration notifyConfiguration
//SubscriptionManager subscriptionManager
) : base(coreBaseSettings, authContext, userManager, null)
) : base(coreBaseSettings, authContext, userManager, notifyConfiguration)
{
}

View File

@ -29,7 +29,6 @@ namespace ASC.Web.Api.Controllers.Settings;
public class SecurityController : BaseSettingsController
{
private readonly MessageService _messageService;
private readonly IServiceProvider _serviceProvider;
private readonly EmployeeDtoHelper _employeeHelperDto;
private readonly UserManager _userManager;
private readonly AuthContext _authContext;
@ -51,12 +50,10 @@ public class SecurityController : BaseSettingsController
WebItemManager webItemManager,
WebItemManagerSecurity webItemManagerSecurity,
DisplayUserSettingsHelper displayUserSettingsHelper,
IServiceProvider serviceProvider,
EmployeeDtoHelper employeeWraperHelper,
MessageTarget messageTarget,
IMemoryCache memoryCache) : base(apiContext, memoryCache, webItemManager)
{
_serviceProvider = serviceProvider;
_employeeHelperDto = employeeWraperHelper;
_messageService = messageService;
_userManager = userManager;
@ -215,7 +212,7 @@ public class SecurityController : BaseSettingsController
}
else if (productId == defaultPageSettings.DefaultProductID)
{
_settingsManager.Save((StudioDefaultPageSettings)defaultPageSettings.GetDefault(_serviceProvider));
_settingsManager.Save(_settingsManager.GetDefault<StudioDefaultPageSettings>());
}
_webItemSecurity.SetSecurity(item.Key, item.Value, subjects);

View File

@ -32,7 +32,6 @@ public class TfaappController : BaseSettingsController
{
private readonly MessageService _messageService;
private readonly StudioNotifyService _studioNotifyService;
private readonly IServiceProvider _serviceProvider;
private readonly SmsProviderManager _smsProviderManager;
private readonly UserManager _userManager;
private readonly AuthContext _authContext;
@ -62,13 +61,11 @@ public class TfaappController : BaseSettingsController
DisplayUserSettingsHelper displayUserSettingsHelper,
MessageTarget messageTarget,
StudioSmsNotificationSettingsHelper studioSmsNotificationSettingsHelper,
IServiceProvider serviceProvider,
SmsProviderManager smsProviderManager,
IMemoryCache memoryCache,
InstanceCrypto instanceCrypto,
Signature signature) : base(apiContext, memoryCache, webItemManager)
{
_serviceProvider = serviceProvider;
_smsProviderManager = smsProviderManager;
_messageService = messageService;
_studioNotifyService = studioNotifyService;
@ -321,7 +318,7 @@ public class TfaappController : BaseSettingsController
if (user.IsVisitor(_userManager) || user.IsOutsider(_userManager))
throw new NotSupportedException("Not available.");
TfaAppUserSettings.DisableForUser(_serviceProvider, _settingsManager, user.Id);
TfaAppUserSettings.DisableForUser(_settingsManager, user.Id);
_messageService.Send(MessageAction.UserDisconnectedTfaApp, _messageTarget.Create(user.Id), user.DisplayUserName(false, _displayUserSettingsHelper));
if (isMe)

View File

@ -26,11 +26,10 @@
namespace ASC.Web.Api.Controllers.Settings;
public class WhitelabelController: BaseSettingsController
public class WhitelabelController : BaseSettingsController
{
private Tenant Tenant { get { return _apiContext.Tenant; } }
private readonly IServiceProvider _serviceProvider;
private readonly TenantManager _tenantManager;
private readonly TenantExtra _tenantExtra;
private readonly PermissionContext _permissionContext;
@ -40,8 +39,6 @@ public class WhitelabelController: BaseSettingsController
private readonly TenantLogoManager _tenantLogoManager;
private readonly CoreBaseSettings _coreBaseSettings;
private readonly CommonLinkUtility _commonLinkUtility;
private readonly IConfiguration _configuration;
private readonly CoreSettings _coreSettings;
private readonly StorageFactory _storageFactory;
public WhitelabelController(
@ -56,13 +53,9 @@ public class WhitelabelController: BaseSettingsController
TenantLogoManager tenantLogoManager,
CoreBaseSettings coreBaseSettings,
CommonLinkUtility commonLinkUtility,
IConfiguration configuration,
CoreSettings coreSettings,
IServiceProvider serviceProvider,
IMemoryCache memoryCache,
StorageFactory storageFactory) : base(apiContext, memoryCache, webItemManager)
{
_serviceProvider = serviceProvider;
_tenantManager = tenantManager;
_tenantExtra = tenantExtra;
_permissionContext = permissionContext;
@ -72,8 +65,6 @@ public class WhitelabelController: BaseSettingsController
_tenantLogoManager = tenantLogoManager;
_coreBaseSettings = coreBaseSettings;
_commonLinkUtility = commonLinkUtility;
_configuration = configuration;
_coreSettings = coreSettings;
_storageFactory = storageFactory;
}
@ -340,9 +331,9 @@ public class WhitelabelController: BaseSettingsController
result.Add(instance);
if (!instance.IsDefault(_coreSettings) && !instance.IsLicensor)
if (!instance.IsDefault() && !instance.IsLicensor)
{
result.Add(instance.GetDefault(_serviceProvider) as CompanyWhiteLabelSettings);
result.Add(_settingsManager.GetDefault<CompanyWhiteLabelSettings>());
}
return result;
@ -387,12 +378,13 @@ public class WhitelabelController: BaseSettingsController
{
DemandRebrandingPermission();
var defaultSettings = (CompanyWhiteLabelSettings)_settingsManager.LoadForDefaultTenant<CompanyWhiteLabelSettings>().GetDefault(_coreSettings);
var defaultSettings = _settingsManager.GetDefault<CompanyWhiteLabelSettings>();
_settingsManager.SaveForDefaultTenant(defaultSettings);
return defaultSettings;
}
}
///<visible>false</visible>
[Create("rebranding/additional")]
public bool SaveAdditionalWhiteLabelSettingsFromBody([FromBody] AdditionalWhiteLabelSettingsWrapper wrapper)
@ -430,7 +422,7 @@ public class WhitelabelController: BaseSettingsController
{
DemandRebrandingPermission();
var defaultSettings = (AdditionalWhiteLabelSettings)_settingsManager.LoadForDefaultTenant<AdditionalWhiteLabelSettings>().GetDefault(_configuration);
var defaultSettings = _settingsManager.GetDefault<AdditionalWhiteLabelSettings>();
_settingsManager.SaveForDefaultTenant(defaultSettings);
@ -501,7 +493,7 @@ public class WhitelabelController: BaseSettingsController
{
DemandRebrandingPermission();
var defaultSettings = (MailWhiteLabelSettings)_settingsManager.LoadForDefaultTenant<MailWhiteLabelSettings>().GetDefault(_configuration);
var defaultSettings = _settingsManager.GetDefault<MailWhiteLabelSettings>();
_settingsManager.SaveForDefaultTenant(defaultSettings);

View File

@ -44,7 +44,7 @@ public class StorageDto
StorageWrapperInit(consumer, current);
}
private void StorageWrapperInit<T>(DataStoreConsumer consumer, BaseStorageSettings<T> current) where T : class, ISettings, new()
private void StorageWrapperInit<T>(DataStoreConsumer consumer, BaseStorageSettings<T> current) where T : class, ISettings<T>, new()
{
Id = consumer.Name;
Title = ConsumerExtension.GetResourceString(consumer.Name) ?? consumer.Name;

View File

@ -26,7 +26,7 @@
namespace ASC.Web.Studio.Core;
public class OpensourceGiftSettings : ISettings
public class OpensourceGiftSettings : ISettings<OpensourceGiftSettings>
{
public bool Readed { get; set; }
@ -37,7 +37,7 @@ public class OpensourceGiftSettings : ISettings
get { return new Guid("{1F4FEA2C-2D9F-47A6-ADEF-CEC4D1E1E243}"); }
}
public ISettings GetDefault(IServiceProvider serviceProvider)
public OpensourceGiftSettings GetDefault()
{
return new OpensourceGiftSettings { Readed = false };
}

View File

@ -27,7 +27,7 @@
namespace ASC.Web.Studio.Core
{
[Serializable]
public class CollaboratorSettings : ISettings
public class CollaboratorSettings : ISettings<CollaboratorSettings>
{
public bool FirstVisit { get; set; }
@ -36,7 +36,7 @@ namespace ASC.Web.Studio.Core
get { return new Guid("{73537E08-17F6-4706-BFDA-1414108AA7D2}"); }
}
public ISettings GetDefault(IServiceProvider serviceProvider)
public CollaboratorSettings GetDefault()
{
return new CollaboratorSettings()
{

View File

@ -27,7 +27,7 @@
namespace ASC.Web.Studio.Core
{
[Serializable]
public class CustomNavigationSettings : ISettings
public class CustomNavigationSettings : ISettings<CustomNavigationSettings>
{
public List<CustomNavigationItem> Items { get; set; }
@ -36,7 +36,7 @@ namespace ASC.Web.Studio.Core
get { return new Guid("{32E02E4C-925D-4391-BAA4-3B5D223A2104}"); }
}
public ISettings GetDefault(IServiceProvider serviceProvider)
public CustomNavigationSettings GetDefault()
{
return new CustomNavigationSettings { Items = new List<CustomNavigationItem>() };
}

View File

@ -27,7 +27,7 @@
namespace ASC.Web.Studio.Core
{
[Serializable]
public class EmailActivationSettings : ISettings
public class EmailActivationSettings : ISettings<EmailActivationSettings>
{
public bool Show { get; set; }
@ -36,7 +36,7 @@ namespace ASC.Web.Studio.Core
get { return new Guid("{85987929-1339-48EB-B06D-B9D097BDACF6}"); }
}
public ISettings GetDefault(IServiceProvider serviceProvider)
public EmailActivationSettings GetDefault()
{
return new EmailActivationSettings { Show = true };
}

View File

@ -35,12 +35,13 @@ namespace ASC.Web.Studio.Core.Notify
private static readonly object locker = new object();
private static readonly Regex urlReplacer = new Regex(@"(<a [^>]*href=(('(?<url>[^>']*)')|(""(?<url>[^>""]*)""))[^>]*>)|(<img [^>]*src=(('(?<url>(?![data:|cid:])[^>']*)')|(""(?<url>(?![data:|cid:])[^>""]*)""))[^/>]*/?>)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex textileLinkReplacer = new Regex(@"""(?<text>[\w\W]+?)"":""(?<link>[^""]+)""", RegexOptions.Singleline | RegexOptions.Compiled);
private readonly NotifyEngine _notifyEngine;
private readonly WorkContext _workContext;
private IServiceProvider ServiceProvider { get; }
public NotifyConfiguration(IServiceProvider serviceProvider)
public NotifyConfiguration(NotifyEngine notifyEngine, WorkContext workContext)
{
ServiceProvider = serviceProvider;
_notifyEngine = notifyEngine;
_workContext = workContext;
}
public void Configure()
@ -50,9 +51,9 @@ namespace ASC.Web.Studio.Core.Notify
if (!configured)
{
configured = true;
WorkContext.NotifyStartUp(ServiceProvider);
WorkContext.NotifyContext.NotifyClientRegistration += NotifyClientRegisterCallback;
WorkContext.NotifyContext.NotifyEngine.BeforeTransferRequest += BeforeTransferRequest;
_workContext.NotifyStartUp();
_workContext.NotifyContext.NotifyClientRegistration += NotifyClientRegisterCallback;
_notifyEngine.AddAction<NotifyTransferRequest>();
}
}
}
@ -107,81 +108,8 @@ namespace ASC.Web.Studio.Core.Notify
InterceptorLifetime.Global,
(r, p, scope) =>
{
var scopeClass = scope.ServiceProvider.GetService<NotifyConfigurationScope>();
var coreBaseSettings = scope.ServiceProvider.GetService<CoreBaseSettings>();
var (tenantManager, webItemSecurity, userManager, options, _, _, _, _, _, _, _, _, _, _, _) = scopeClass;
try
{
// culture
var u = Constants.LostUser;
if (!(coreBaseSettings.Personal && r.NotifyAction.ID == Actions.PersonalConfirmation.ID))
{
var tenant = tenantManager.GetCurrentTenant();
if (32 <= r.Recipient.ID.Length)
{
var guid = default(Guid);
try
{
guid = new Guid(r.Recipient.ID);
}
catch (FormatException) { }
catch (OverflowException) { }
if (guid != default)
{
u = userManager.GetUsers(guid);
}
}
if (Constants.LostUser.Equals(u))
{
u = userManager.GetUserByEmail(r.Recipient.ID);
}
if (Constants.LostUser.Equals(u))
{
u = userManager.GetUserByUserName(r.Recipient.ID);
}
if (!Constants.LostUser.Equals(u))
{
var culture = !string.IsNullOrEmpty(u.CultureName) ? u.GetCulture() : tenant.GetCulture();
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
// security
var tag = r.Arguments.Find(a => a.Tag == CommonTags.ModuleID);
var productId = tag != null ? (Guid)tag.Value : Guid.Empty;
if (productId == Guid.Empty)
{
tag = r.Arguments.Find(a => a.Tag == CommonTags.ProductID);
productId = tag != null ? (Guid)tag.Value : Guid.Empty;
}
if (productId == Guid.Empty)
{
productId = (Guid)(CallContext.GetData("asc.web.product_id") ?? Guid.Empty);
}
if (productId != Guid.Empty && productId != new Guid("f4d98afdd336433287783c6945c81ea0") /* ignore people product */)
{
return !webItemSecurity.IsAvailableForUser(productId, u.Id);
}
}
}
var tagCulture = r.Arguments.FirstOrDefault(a => a.Tag == CommonTags.Culture);
if (tagCulture != null)
{
var culture = CultureInfo.GetCultureInfo((string)tagCulture.Value);
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
}
}
catch (Exception error)
{
options.CurrentValue.Error(error);
}
return false;
var scopeClass = scope.ServiceProvider.GetRequiredService<ProductSecurityInterceptor>();
return scopeClass.Intercept(r, p);
});
client.AddInterceptor(securityAndCulture);
@ -205,7 +133,7 @@ namespace ASC.Web.Studio.Core.Notify
if (!string.IsNullOrEmpty(logoText))
{
r.CurrentMessage.Body = r.CurrentMessage.Body
.Replace("${{"+ CommonTags.LetterLogoText + "}}", logoText);
.Replace("${{" + CommonTags.LetterLogoText + "}}", logoText);
}
}
catch (Exception error)
@ -218,78 +146,242 @@ namespace ASC.Web.Studio.Core.Notify
#endregion
}
}
private void BeforeTransferRequest(NotifyEngine sender, NotifyRequest request, IServiceScope scope)
[Scope]
public class ProductSecurityInterceptor
{
private readonly TenantManager _tenantManager;
private readonly WebItemSecurity _webItemSecurity;
private readonly UserManager _userManager;
private readonly CoreBaseSettings _coreBaseSettings;
private readonly ILog _log;
public ProductSecurityInterceptor(
TenantManager tenantManager,
WebItemSecurity webItemSecurity,
UserManager userManager,
CoreBaseSettings coreBaseSettings,
IOptionsMonitor<ILog> options
)
{
_tenantManager = tenantManager;
_webItemSecurity = webItemSecurity;
_userManager = userManager;
_coreBaseSettings = coreBaseSettings;
_log = options.CurrentValue;
}
public bool Intercept(NotifyRequest r, InterceptorPlace p)
{
try
{
// culture
var u = Constants.LostUser;
if (!(_coreBaseSettings.Personal && r.NotifyAction.ID == Actions.PersonalConfirmation.ID))
{
var tenant = _tenantManager.GetCurrentTenant();
if (32 <= r.Recipient.ID.Length)
{
var guid = default(Guid);
try
{
guid = new Guid(r.Recipient.ID);
}
catch (FormatException) { }
catch (OverflowException) { }
if (guid != default)
{
u = _userManager.GetUsers(guid);
}
}
if (Constants.LostUser.Equals(u))
{
u = _userManager.GetUserByEmail(r.Recipient.ID);
}
if (Constants.LostUser.Equals(u))
{
u = _userManager.GetUserByUserName(r.Recipient.ID);
}
if (!Constants.LostUser.Equals(u))
{
var culture = !string.IsNullOrEmpty(u.CultureName) ? u.GetCulture() : tenant.GetCulture();
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
// security
var tag = r.Arguments.Find(a => a.Tag == CommonTags.ModuleID);
var productId = tag != null ? (Guid)tag.Value : Guid.Empty;
if (productId == Guid.Empty)
{
tag = r.Arguments.Find(a => a.Tag == CommonTags.ProductID);
productId = tag != null ? (Guid)tag.Value : Guid.Empty;
}
if (productId == Guid.Empty)
{
productId = (Guid)(CallContext.GetData("asc.web.product_id") ?? Guid.Empty);
}
if (productId != Guid.Empty && productId != new Guid("f4d98afdd336433287783c6945c81ea0") /* ignore people product */)
{
return !_webItemSecurity.IsAvailableForUser(productId, u.Id);
}
}
}
var tagCulture = r.Arguments.FirstOrDefault(a => a.Tag == CommonTags.Culture);
if (tagCulture != null)
{
var culture = CultureInfo.GetCultureInfo((string)tagCulture.Value);
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
}
}
catch (Exception error)
{
_log.Error(error);
}
return false;
}
}
public static class NotifyConfigurationExtension
{
public static void Register(DIHelper services)
{
services.TryAdd<NotifyTransferRequest>();
services.TryAdd<ProductSecurityInterceptor>();
services.TryAdd<TextileStyler>();
services.TryAdd<JabberStyler>();
services.TryAdd<PushStyler>();
}
}
[Scope]
public class NotifyTransferRequest : INotifyEngineAction
{
private readonly TenantManager _tenantManager;
private readonly AuthContext _authContext;
private readonly UserManager _userManager;
private readonly DisplayUserSettingsHelper _displayUserSettingsHelper;
private readonly TenantExtra _tenantExtra;
private readonly WebItemManager _webItemManager;
private readonly TenantLogoManager _tenantLogoManager;
private readonly AdditionalWhiteLabelSettingsHelper _additionalWhiteLabelSettingsHelper;
private readonly TenantUtil _tenantUtil;
private readonly CoreBaseSettings _coreBaseSettings;
private readonly CommonLinkUtility _commonLinkUtility;
private readonly SettingsManager _settingsManager;
private readonly StudioNotifyHelper _studioNotifyHelper;
private readonly ILog _log;
public NotifyTransferRequest(
TenantManager tenantManager,
AuthContext authContext,
UserManager userManager,
DisplayUserSettingsHelper displayUserSettingsHelper,
IOptionsMonitor<ILog> options,
TenantExtra tenantExtra,
WebItemManager webItemManager,
TenantLogoManager tenantLogoManager,
AdditionalWhiteLabelSettingsHelper additionalWhiteLabelSettingsHelper,
TenantUtil tenantUtil,
CoreBaseSettings coreBaseSettings,
CommonLinkUtility commonLinkUtility,
SettingsManager settingsManager,
StudioNotifyHelper studioNotifyHelper)
{
_tenantManager = tenantManager;
_authContext = authContext;
_userManager = userManager;
_displayUserSettingsHelper = displayUserSettingsHelper;
_tenantExtra = tenantExtra;
_webItemManager = webItemManager;
_tenantLogoManager = tenantLogoManager;
_additionalWhiteLabelSettingsHelper = additionalWhiteLabelSettingsHelper;
_tenantUtil = tenantUtil;
_coreBaseSettings = coreBaseSettings;
_commonLinkUtility = commonLinkUtility;
_settingsManager = settingsManager;
_studioNotifyHelper = studioNotifyHelper;
_log = options.CurrentValue;
}
public void BeforeTransferRequest(NotifyRequest request)
{
var aid = Guid.Empty;
var aname = string.Empty;
var tenant = scope.ServiceProvider.GetService<TenantManager>().GetCurrentTenant();
var authContext = scope.ServiceProvider.GetService<AuthContext>();
var userManager = scope.ServiceProvider.GetService<UserManager>();
var displayUserSettingsHelper = scope.ServiceProvider.GetService<DisplayUserSettingsHelper>();
var tenant = _tenantManager.GetCurrentTenant();
if (authContext.IsAuthenticated)
if (_authContext.IsAuthenticated)
{
aid = authContext.CurrentAccount.ID;
var user = userManager.GetUsers(aid);
if (userManager.UserExists(user))
aid = _authContext.CurrentAccount.ID;
var user = _userManager.GetUsers(aid);
if (_userManager.UserExists(user))
{
aname = user.DisplayUserName(false, displayUserSettingsHelper)
aname = user.DisplayUserName(false, _displayUserSettingsHelper)
.Replace(">", "&#62")
.Replace("<", "&#60");
}
}
var scopeClass = scope.ServiceProvider.GetService<NotifyConfigurationScope>();
var (_, _, _, options, tenantExtra, _, webItemManager, configuration, tenantLogoManager, additionalWhiteLabelSettingsHelper, tenantUtil, coreBaseSettings, commonLinkUtility, settingsManager, studioNotifyHelper) = scopeClass;
var log = options.CurrentValue;
commonLinkUtility.GetLocationByRequest(out var product, out var module);
_commonLinkUtility.GetLocationByRequest(out var product, out var module);
if (product == null && CallContext.GetData("asc.web.product_id") != null)
{
product = webItemManager[(Guid)CallContext.GetData("asc.web.product_id")] as IProduct;
product = _webItemManager[(Guid)CallContext.GetData("asc.web.product_id")] as IProduct;
}
var logoText = TenantWhiteLabelSettings.DefaultLogoText;
if ((tenantExtra.Enterprise || coreBaseSettings.CustomMode) && !MailWhiteLabelSettings.IsDefault(settingsManager, configuration))
if ((_tenantExtra.Enterprise || _coreBaseSettings.CustomMode) && !MailWhiteLabelSettings.IsDefault(_settingsManager))
{
logoText = tenantLogoManager.GetLogoText();
logoText = _tenantLogoManager.GetLogoText();
}
request.Arguments.Add(new TagValue(CommonTags.AuthorID, aid));
request.Arguments.Add(new TagValue(CommonTags.AuthorName, aname));
request.Arguments.Add(new TagValue(CommonTags.AuthorUrl, commonLinkUtility.GetFullAbsolutePath(commonLinkUtility.GetUserProfile(aid))));
request.Arguments.Add(new TagValue(CommonTags.VirtualRootPath, commonLinkUtility.GetFullAbsolutePath("~").TrimEnd('/')));
request.Arguments.Add(new TagValue(CommonTags.AuthorUrl, _commonLinkUtility.GetFullAbsolutePath(_commonLinkUtility.GetUserProfile(aid))));
request.Arguments.Add(new TagValue(CommonTags.VirtualRootPath, _commonLinkUtility.GetFullAbsolutePath("~").TrimEnd('/')));
request.Arguments.Add(new TagValue(CommonTags.ProductID, product != null ? product.ID : Guid.Empty));
request.Arguments.Add(new TagValue(CommonTags.ModuleID, module != null ? module.ID : Guid.Empty));
request.Arguments.Add(new TagValue(CommonTags.ProductUrl, commonLinkUtility.GetFullAbsolutePath(product != null ? product.StartURL : "~")));
request.Arguments.Add(new TagValue(CommonTags.DateTime, tenantUtil.DateTimeNow()));
request.Arguments.Add(new TagValue(CommonTags.ProductUrl, _commonLinkUtility.GetFullAbsolutePath(product != null ? product.StartURL : "~")));
request.Arguments.Add(new TagValue(CommonTags.DateTime, _tenantUtil.DateTimeNow()));
request.Arguments.Add(new TagValue(CommonTags.RecipientID, Context.SysRecipient));
request.Arguments.Add(new TagValue(CommonTags.ProfileUrl, commonLinkUtility.GetFullAbsolutePath(commonLinkUtility.GetMyStaff())));
request.Arguments.Add(new TagValue(CommonTags.RecipientSubscriptionConfigURL, commonLinkUtility.GetUnsubscribe()));
request.Arguments.Add(new TagValue(CommonTags.HelpLink, commonLinkUtility.GetHelpLink(settingsManager, additionalWhiteLabelSettingsHelper, false)));
request.Arguments.Add(new TagValue(CommonTags.ProfileUrl, _commonLinkUtility.GetFullAbsolutePath(_commonLinkUtility.GetMyStaff())));
request.Arguments.Add(new TagValue(CommonTags.RecipientSubscriptionConfigURL, _commonLinkUtility.GetUnsubscribe()));
request.Arguments.Add(new TagValue(CommonTags.HelpLink, _commonLinkUtility.GetHelpLink(_settingsManager, _additionalWhiteLabelSettingsHelper, false)));
request.Arguments.Add(new TagValue(CommonTags.LetterLogoText, logoText));
request.Arguments.Add(new TagValue(CommonTags.MailWhiteLabelSettings, MailWhiteLabelSettings.Instance(settingsManager)));
request.Arguments.Add(new TagValue(CommonTags.MailWhiteLabelSettings, MailWhiteLabelSettings.Instance(_settingsManager)));
request.Arguments.Add(new TagValue(CommonTags.SendFrom, tenant.Name));
request.Arguments.Add(new TagValue(CommonTags.ImagePath, studioNotifyHelper.GetNotificationImageUrl("").TrimEnd('/')));
request.Arguments.Add(new TagValue(CommonTags.ImagePath, _studioNotifyHelper.GetNotificationImageUrl("").TrimEnd('/')));
AddLetterLogo(request, tenantExtra, tenantLogoManager, coreBaseSettings, commonLinkUtility, log);
AddLetterLogo(request);
}
public void AfterTransferRequest(NotifyRequest request)
{
}
private static void AddLetterLogo(NotifyRequest request, TenantExtra tenantExtra, TenantLogoManager tenantLogoManager, CoreBaseSettings coreBaseSettings, CommonLinkUtility commonLinkUtility, ILog Log)
private void AddLetterLogo(NotifyRequest request)
{
if (tenantExtra.Enterprise || coreBaseSettings.CustomMode)
if (_tenantExtra.Enterprise || _coreBaseSettings.CustomMode)
{
try
{
var logoData = tenantLogoManager.GetMailLogoDataFromCache();
var logoData = _tenantLogoManager.GetMailLogoDataFromCache();
if (logoData == null)
{
var logoStream = tenantLogoManager.GetWhitelabelMailLogo();
var logoStream = _tenantLogoManager.GetWhitelabelMailLogo();
logoData = ReadStreamToByteArray(logoStream) ?? GetDefaultMailLogo();
if (logoData != null)
tenantLogoManager.InsertMailLogoDataToCache(logoData);
{
_tenantLogoManager.InsertMailLogoDataToCache(logoData);
}
}
if (logoData != null)
@ -308,11 +400,11 @@ namespace ASC.Web.Studio.Core.Notify
}
catch (Exception error)
{
Log.Error(error);
_log.Error(error);
}
}
var logoUrl = commonLinkUtility.GetFullAbsolutePath(tenantLogoManager.GetLogoDark(true));
var logoUrl = _commonLinkUtility.GetFullAbsolutePath(_tenantLogoManager.GetLogoDark(true));
request.Arguments.Add(new TagValue(CommonTags.LetterLogo, logoUrl));
}
@ -329,109 +421,11 @@ namespace ASC.Web.Studio.Core.Notify
}
}
public static byte[] GetDefaultMailLogo()
private static byte[] GetDefaultMailLogo()
{
var filePath = CrossPlatform.PathCombine(AppDomain.CurrentDomain.BaseDirectory, "skins", "default", "images", "logo", "dark_general.png");
return File.Exists(filePath) ? File.ReadAllBytes(filePath) : null;
}
}
[Scope]
public class NotifyConfigurationScope
{
private TenantManager TenantManager { get; }
private WebItemSecurity WebItemSecurity { get; }
private UserManager UserManager { get; }
private IOptionsMonitor<ILog> Options { get; }
private TenantExtra TenantExtra { get; }
private WebItemManagerSecurity WebItemManagerSecurity { get; }
private WebItemManager WebItemManager { get; }
private IConfiguration Configuration { get; }
private TenantLogoManager TenantLogoManager { get; }
private AdditionalWhiteLabelSettingsHelper AdditionalWhiteLabelSettingsHelper { get; }
private TenantUtil TenantUtil { get; }
private CoreBaseSettings CoreBaseSettings { get; }
private CommonLinkUtility CommonLinkUtility { get; }
private SettingsManager SettingsManager { get; }
private StudioNotifyHelper StudioNotifyHelper { get; }
public NotifyConfigurationScope(TenantManager tenantManager,
WebItemSecurity webItemSecurity,
UserManager userManager,
IOptionsMonitor<ILog> options,
TenantExtra tenantExtra,
WebItemManagerSecurity webItemManagerSecurity,
WebItemManager webItemManager,
IConfiguration configuration,
TenantLogoManager tenantLogoManager,
AdditionalWhiteLabelSettingsHelper additionalWhiteLabelSettingsHelper,
TenantUtil tenantUtil,
CoreBaseSettings coreBaseSettings,
CommonLinkUtility commonLinkUtility,
SettingsManager settingsManager,
StudioNotifyHelper studioNotifyHelper
)
{
TenantManager = tenantManager;
WebItemSecurity = webItemSecurity;
UserManager = userManager;
Options = options;
TenantExtra = tenantExtra;
WebItemManagerSecurity = webItemManagerSecurity;
WebItemManager = webItemManager;
Configuration = configuration;
TenantLogoManager = tenantLogoManager;
AdditionalWhiteLabelSettingsHelper = additionalWhiteLabelSettingsHelper;
TenantUtil = tenantUtil;
CoreBaseSettings = coreBaseSettings;
CommonLinkUtility = commonLinkUtility;
SettingsManager = settingsManager;
StudioNotifyHelper = studioNotifyHelper;
}
public void Deconstruct(out TenantManager tenantManager,
out WebItemSecurity webItemSecurity,
out UserManager userManager,
out IOptionsMonitor<ILog> optionsMonitor,
out TenantExtra tenantExtra,
out WebItemManagerSecurity webItemManagerSecurity,
out WebItemManager webItemManager,
out IConfiguration configuration,
out TenantLogoManager tenantLogoManager,
out AdditionalWhiteLabelSettingsHelper additionalWhiteLabelSettingsHelper,
out TenantUtil tenantUtil,
out CoreBaseSettings coreBaseSettings,
out CommonLinkUtility commonLinkUtility,
out SettingsManager settingsManager,
out StudioNotifyHelper studioNotifyHelper)
{
tenantManager = TenantManager;
webItemSecurity = WebItemSecurity;
userManager = UserManager;
optionsMonitor = Options;
tenantExtra = TenantExtra;
webItemManagerSecurity = WebItemManagerSecurity;
webItemManager = WebItemManager;
configuration = Configuration;
tenantLogoManager = TenantLogoManager;
additionalWhiteLabelSettingsHelper = AdditionalWhiteLabelSettingsHelper;
tenantUtil = TenantUtil;
coreBaseSettings = CoreBaseSettings;
commonLinkUtility = CommonLinkUtility;
settingsManager = SettingsManager;
studioNotifyHelper = StudioNotifyHelper;
}
}
public static class NotifyConfigurationExtension
{
public static void Register(DIHelper services)
{
services.TryAdd<NotifyConfigurationScope>();
services.TryAdd<TextileStyler>();
services.TryAdd<JabberStyler>();
services.TryAdd<PushStyler>();
}
}
}

View File

@ -27,7 +27,7 @@
namespace ASC.Web.Studio.Core.Notify
{
[Serializable]
public class SpamEmailSettings : ISettings
public class SpamEmailSettings : ISettings<SpamEmailSettings>
{
public int MailsSendedCount { get; set; }
@ -38,7 +38,7 @@ namespace ASC.Web.Studio.Core.Notify
get { return new Guid("{A9819A62-60AF-48E3-989C-08259772FA57}"); }
}
public ISettings GetDefault(IServiceProvider serviceProvider)
public SpamEmailSettings GetDefault()
{
return new SpamEmailSettings
{

View File

@ -28,28 +28,26 @@ using Constants = ASC.Core.Users.Constants;
namespace ASC.Web.Studio.Core.Notify
{
[Scope(Additional = typeof(StudioNotifyServiceExtension))]
[Scope]
public class StudioNotifyService
{
private readonly StudioNotifyServiceHelper client;
private readonly StudioNotifyServiceHelper _client;
public static string EMailSenderName { get { return ASC.Core.Configuration.Constants.NotifyEMailSenderSysName; } }
private UserManager UserManager { get; }
private StudioNotifyHelper StudioNotifyHelper { get; }
private TenantExtra TenantExtra { get; }
private AuthManager Authentication { get; }
private AuthContext AuthContext { get; }
private IConfiguration Configuration { get; }
private TenantManager TenantManager { get; }
private CoreBaseSettings CoreBaseSettings { get; }
private CommonLinkUtility CommonLinkUtility { get; }
private SetupInfo SetupInfo { get; }
private IServiceProvider ServiceProvider { get; }
private DisplayUserSettingsHelper DisplayUserSettingsHelper { get; }
private SettingsManager SettingsManager { get; }
private WebItemSecurity WebItemSecurity { get; }
private ILog Log { get; }
private readonly UserManager _userManager;
private readonly StudioNotifyHelper _studioNotifyHelper;
private readonly TenantExtra _tenantExtra;
private readonly AuthManager _authentication;
private readonly AuthContext _authContext;
private readonly TenantManager _tenantManager;
private readonly CoreBaseSettings _coreBaseSettings;
private readonly CommonLinkUtility _commonLinkUtility;
private readonly SetupInfo _setupInfo;
private readonly DisplayUserSettingsHelper _displayUserSettingsHelper;
private readonly SettingsManager _settingsManager;
private readonly WebItemSecurity _webItemSecurity;
private readonly ILog _log;
public StudioNotifyService(
UserManager userManager,
@ -58,43 +56,39 @@ namespace ASC.Web.Studio.Core.Notify
TenantExtra tenantExtra,
AuthManager authentication,
AuthContext authContext,
IConfiguration configuration,
TenantManager tenantManager,
CoreBaseSettings coreBaseSettings,
CommonLinkUtility commonLinkUtility,
SetupInfo setupInfo,
IServiceProvider serviceProvider,
DisplayUserSettingsHelper displayUserSettingsHelper,
SettingsManager settingsManager,
WebItemSecurity webItemSecurity,
IOptionsMonitor<ILog> option)
{
Log = option.Get("ASC.Notify");
client = studioNotifyServiceHelper;
TenantExtra = tenantExtra;
Authentication = authentication;
AuthContext = authContext;
Configuration = configuration;
TenantManager = tenantManager;
CoreBaseSettings = coreBaseSettings;
CommonLinkUtility = commonLinkUtility;
SetupInfo = setupInfo;
ServiceProvider = serviceProvider;
DisplayUserSettingsHelper = displayUserSettingsHelper;
SettingsManager = settingsManager;
WebItemSecurity = webItemSecurity;
UserManager = userManager;
StudioNotifyHelper = studioNotifyHelper;
_log = option.Get("ASC.Notify");
_client = studioNotifyServiceHelper;
_tenantExtra = tenantExtra;
_authentication = authentication;
_authContext = authContext;
_tenantManager = tenantManager;
_coreBaseSettings = coreBaseSettings;
_commonLinkUtility = commonLinkUtility;
_setupInfo = setupInfo;
_displayUserSettingsHelper = displayUserSettingsHelper;
_settingsManager = settingsManager;
_webItemSecurity = webItemSecurity;
_userManager = userManager;
_studioNotifyHelper = studioNotifyHelper;
}
public void SendMsgToAdminAboutProfileUpdated()
{
client.SendNoticeAsync(Actions.SelfProfileUpdated, null);
_client.SendNoticeAsync(Actions.SelfProfileUpdated, null);
}
public void SendMsgToAdminFromNotAuthUser(string email, string message)
{
client.SendNoticeAsync(Actions.UserMessageToAdmin, null, new TagValue(Tags.Body, message), new TagValue(Tags.UserEmail, email));
_client.SendNoticeAsync(Actions.UserMessageToAdmin, null, new TagValue(Tags.Body, message), new TagValue(Tags.UserEmail, email));
}
public void SendRequestTariff(bool license, string fname, string lname, string title, string email, string phone, string ctitle, string csize, string site, string message)
@ -118,15 +112,15 @@ namespace ASC.Web.Studio.Core.Notify
csize = (csize ?? "").Trim();
ArgumentNullOrEmptyException.ThrowIfNullOrEmpty(csize);
site = (site ?? "").Trim();
if (string.IsNullOrEmpty(site) && !CoreBaseSettings.CustomMode) throw new ArgumentNullException(nameof(site));
if (string.IsNullOrEmpty(site) && !_coreBaseSettings.CustomMode) throw new ArgumentNullException(nameof(site));
message = (message ?? "").Trim();
if (string.IsNullOrEmpty(message) && !CoreBaseSettings.CustomMode) throw new ArgumentNullException(nameof(message));
if (string.IsNullOrEmpty(message) && !_coreBaseSettings.CustomMode) throw new ArgumentNullException(nameof(message));
var salesEmail = SettingsManager.LoadForDefaultTenant<AdditionalWhiteLabelSettings>().SalesEmail ?? SetupInfo.SalesEmail;
var salesEmail = _settingsManager.LoadForDefaultTenant<AdditionalWhiteLabelSettings>().SalesEmail ?? _setupInfo.SalesEmail;
var recipient = (IRecipient)new DirectRecipient(AuthContext.CurrentAccount.ID.ToString(), string.Empty, new[] { salesEmail }, false);
var recipient = (IRecipient)new DirectRecipient(_authContext.CurrentAccount.ID.ToString(), string.Empty, new[] { salesEmail }, false);
client.SendNoticeToAsync(license ? Actions.RequestLicense : Actions.RequestTariff,
_client.SendNoticeToAsync(license ? Actions.RequestLicense : Actions.RequestTariff,
new[] { recipient },
new[] { "email.sender" },
new TagValue(Tags.UserName, fname),
@ -144,12 +138,12 @@ namespace ASC.Web.Studio.Core.Notify
public void SendToAdminVoipWarning(double balance)
{
client.SendNoticeAsync(Actions.VoipWarning, null, new TagValue(Tags.Body, balance));
_client.SendNoticeAsync(Actions.VoipWarning, null, new TagValue(Tags.Body, balance));
}
public void SendToAdminVoipBlocked()
{
client.SendNoticeAsync(Actions.VoipBlocked, null);
_client.SendNoticeAsync(Actions.VoipBlocked, null);
}
#endregion
@ -158,18 +152,18 @@ namespace ASC.Web.Studio.Core.Notify
public void UserPasswordChange(UserInfo userInfo)
{
var hash = Authentication.GetUserPasswordStamp(userInfo.Id).ToString("s");
var confirmationUrl = CommonLinkUtility.GetConfirmationUrl(userInfo.Email, ConfirmType.PasswordChange, hash, userInfo.Id);
var hash = _authentication.GetUserPasswordStamp(userInfo.Id).ToString("s");
var confirmationUrl = _commonLinkUtility.GetConfirmationUrl(userInfo.Email, ConfirmType.PasswordChange, hash, userInfo.Id);
string greenButtonText() => WebstudioNotifyPatternResource.ButtonChangePassword;
var action = CoreBaseSettings.Personal
? (CoreBaseSettings.CustomMode ? Actions.PersonalCustomModePasswordChange : Actions.PersonalPasswordChange)
var action = _coreBaseSettings.Personal
? (_coreBaseSettings.CustomMode ? Actions.PersonalCustomModePasswordChange : Actions.PersonalPasswordChange)
: Actions.PasswordChange;
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
action,
StudioNotifyHelper.RecipientFromEmail(userInfo.Email, false),
_studioNotifyHelper.RecipientFromEmail(userInfo.Email, false),
new[] { EMailSenderName },
TagValues.GreenButton(greenButtonText, confirmationUrl));
}
@ -180,17 +174,17 @@ namespace ASC.Web.Studio.Core.Notify
public void SendEmailChangeInstructions(UserInfo user, string email)
{
var confirmationUrl = CommonLinkUtility.GetConfirmationUrl(email, ConfirmType.EmailChange, AuthContext.CurrentAccount.ID);
var confirmationUrl = _commonLinkUtility.GetConfirmationUrl(email, ConfirmType.EmailChange, _authContext.CurrentAccount.ID);
string greenButtonText() => WebstudioNotifyPatternResource.ButtonChangeEmail;
var action = CoreBaseSettings.Personal
? (CoreBaseSettings.CustomMode ? Actions.PersonalCustomModeEmailChangeV115 : Actions.PersonalEmailChangeV115)
var action = _coreBaseSettings.Personal
? (_coreBaseSettings.CustomMode ? Actions.PersonalCustomModeEmailChangeV115 : Actions.PersonalEmailChangeV115)
: Actions.EmailChangeV115;
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
action,
StudioNotifyHelper.RecipientFromEmail(email, false),
_studioNotifyHelper.RecipientFromEmail(email, false),
new[] { EMailSenderName },
TagValues.GreenButton(greenButtonText, confirmationUrl),
new TagValue(CommonTags.Culture, user.GetCulture().Name));
@ -198,17 +192,17 @@ namespace ASC.Web.Studio.Core.Notify
public void SendEmailActivationInstructions(UserInfo user, string email)
{
var confirmationUrl = CommonLinkUtility.GetConfirmationUrl(email, ConfirmType.EmailActivation, null, user.Id);
var confirmationUrl = _commonLinkUtility.GetConfirmationUrl(email, ConfirmType.EmailActivation, null, user.Id);
string greenButtonText() => WebstudioNotifyPatternResource.ButtonActivateEmail;
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
Actions.ActivateEmail,
StudioNotifyHelper.RecipientFromEmail(email, false),
_studioNotifyHelper.RecipientFromEmail(email, false),
new[] { EMailSenderName },
new TagValue(Tags.InviteLink, confirmationUrl),
TagValues.GreenButton(greenButtonText, confirmationUrl),
new TagValue(Tags.UserDisplayName, (user.DisplayUserName(DisplayUserSettingsHelper) ?? string.Empty).Trim()));
new TagValue(Tags.UserDisplayName, (user.DisplayUserName(_displayUserSettingsHelper) ?? string.Empty).Trim()));
}
#endregion
@ -231,7 +225,7 @@ namespace ASC.Web.Studio.Core.Notify
if (!skipSettings)
{
var link = $"{CommonLinkUtility.GetFullAbsolutePath("~").TrimEnd('/')}/addons/mail/#accounts/changepwd={address}";
var link = $"{_commonLinkUtility.GetFullAbsolutePath("~").TrimEnd('/')}/addons/mail/#accounts/changepwd={address}";
tags.Add(new TagValue(Tags.MyStaffLink, link));
tags.Add(new TagValue(Tags.Server, server));
@ -241,21 +235,21 @@ namespace ASC.Web.Studio.Core.Notify
tags.Add(new TagValue(Tags.Login, login));
}
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
skipSettings
? Actions.MailboxWithoutSettingsCreated
: Actions.MailboxCreated,
null,
StudioNotifyHelper.RecipientFromEmail(toEmails, false),
_studioNotifyHelper.RecipientFromEmail(toEmails, false),
new[] { EMailSenderName });
}
public void SendMailboxPasswordChanged(List<string> toEmails, string username, string address)
{
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
Actions.MailboxPasswordChanged,
null,
StudioNotifyHelper.RecipientFromEmail(toEmails, false),
_studioNotifyHelper.RecipientFromEmail(toEmails, false),
new[] { EMailSenderName },
new TagValue(Tags.UserName, username ?? string.Empty),
new TagValue(Tags.Address, address ?? string.Empty));
@ -265,26 +259,26 @@ namespace ASC.Web.Studio.Core.Notify
public void SendMsgMobilePhoneChange(UserInfo userInfo)
{
var confirmationUrl = CommonLinkUtility.GetConfirmationUrl(userInfo.Email.ToLower(), ConfirmType.PhoneActivation);
var confirmationUrl = _commonLinkUtility.GetConfirmationUrl(userInfo.Email.ToLower(), ConfirmType.PhoneActivation);
string greenButtonText() => WebstudioNotifyPatternResource.ButtonChangePhone;
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
Actions.PhoneChange,
StudioNotifyHelper.RecipientFromEmail(userInfo.Email, false),
_studioNotifyHelper.RecipientFromEmail(userInfo.Email, false),
new[] { EMailSenderName },
TagValues.GreenButton(greenButtonText, confirmationUrl));
}
public void SendMsgTfaReset(UserInfo userInfo)
{
var confirmationUrl = CommonLinkUtility.GetConfirmationUrl(userInfo.Email.ToLower(), ConfirmType.TfaActivation);
var confirmationUrl = _commonLinkUtility.GetConfirmationUrl(userInfo.Email.ToLower(), ConfirmType.TfaActivation);
string greenButtonText() => WebstudioNotifyPatternResource.ButtonChangeTfa;
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
Actions.TfaChange,
StudioNotifyHelper.RecipientFromEmail(userInfo.Email, false),
_studioNotifyHelper.RecipientFromEmail(userInfo.Email, false),
new[] { EMailSenderName },
TagValues.GreenButton(greenButtonText, confirmationUrl));
}
@ -292,22 +286,22 @@ namespace ASC.Web.Studio.Core.Notify
public void UserHasJoin()
{
if (!CoreBaseSettings.Personal)
if (!_coreBaseSettings.Personal)
{
client.SendNoticeAsync(Actions.UserHasJoin, null);
_client.SendNoticeAsync(Actions.UserHasJoin, null);
}
}
public void SendJoinMsg(string email, EmployeeType emplType)
{
var inviteUrl = CommonLinkUtility.GetConfirmationUrl(email, ConfirmType.EmpInvite, (int)emplType)
var inviteUrl = _commonLinkUtility.GetConfirmationUrl(email, ConfirmType.EmpInvite, (int)emplType)
+ string.Format("&emplType={0}", (int)emplType);
string greenButtonText() => WebstudioNotifyPatternResource.ButtonJoin;
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
Actions.JoinUsers,
StudioNotifyHelper.RecipientFromEmail(email, true),
_studioNotifyHelper.RecipientFromEmail(email, true),
new[] { EMailSenderName },
new TagValue(Tags.InviteLink, inviteUrl),
TagValues.GreenButton(greenButtonText, inviteUrl));
@ -315,14 +309,14 @@ namespace ASC.Web.Studio.Core.Notify
public void UserInfoAddedAfterInvite(UserInfo newUserInfo)
{
if (!UserManager.UserExists(newUserInfo)) return;
if (!_userManager.UserExists(newUserInfo)) return;
INotifyAction notifyAction;
var footer = "social";
if (CoreBaseSettings.Personal)
if (_coreBaseSettings.Personal)
{
if (CoreBaseSettings.CustomMode)
if (_coreBaseSettings.CustomMode)
{
notifyAction = Actions.PersonalCustomModeAfterRegistration1;
footer = "personalCustomMode";
@ -333,17 +327,17 @@ namespace ASC.Web.Studio.Core.Notify
footer = "personal";
}
}
else if (TenantExtra.Enterprise)
else if (_tenantExtra.Enterprise)
{
var defaultRebranding = MailWhiteLabelSettings.IsDefault(SettingsManager, Configuration);
var defaultRebranding = MailWhiteLabelSettings.IsDefault(_settingsManager);
notifyAction = defaultRebranding
? Actions.EnterpriseUserWelcomeV10
: CoreBaseSettings.CustomMode
: _coreBaseSettings.CustomMode
? Actions.EnterpriseWhitelabelUserWelcomeCustomMode
: Actions.EnterpriseWhitelabelUserWelcomeV10;
footer = null;
}
else if (TenantExtra.Opensource)
else if (_tenantExtra.Opensource)
{
notifyAction = Actions.OpensourceUserWelcomeV11;
footer = "opensource";
@ -353,35 +347,35 @@ namespace ASC.Web.Studio.Core.Notify
notifyAction = Actions.SaasUserWelcomeV115;
}
string greenButtonText() => TenantExtra.Enterprise
string greenButtonText() => _tenantExtra.Enterprise
? WebstudioNotifyPatternResource.ButtonAccessYourPortal
: WebstudioNotifyPatternResource.ButtonAccessYouWebOffice;
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
notifyAction,
StudioNotifyHelper.RecipientFromEmail(newUserInfo.Email, false),
_studioNotifyHelper.RecipientFromEmail(newUserInfo.Email, false),
new[] { EMailSenderName },
new TagValue(Tags.UserName, newUserInfo.FirstName.HtmlEncode()),
new TagValue(Tags.MyStaffLink, GetMyStaffLink()),
TagValues.GreenButton(greenButtonText, CommonLinkUtility.GetFullAbsolutePath("~").TrimEnd('/')),
TagValues.GreenButton(greenButtonText, _commonLinkUtility.GetFullAbsolutePath("~").TrimEnd('/')),
new TagValue(CommonTags.Footer, footer),
new TagValue(CommonTags.MasterTemplate, CoreBaseSettings.Personal ? "HtmlMasterPersonal" : "HtmlMaster"));
new TagValue(CommonTags.MasterTemplate, _coreBaseSettings.Personal ? "HtmlMasterPersonal" : "HtmlMaster"));
}
public void GuestInfoAddedAfterInvite(UserInfo newUserInfo)
{
if (!UserManager.UserExists(newUserInfo)) return;
if (!_userManager.UserExists(newUserInfo)) return;
INotifyAction notifyAction;
var footer = "social";
if (TenantExtra.Enterprise)
if (_tenantExtra.Enterprise)
{
var defaultRebranding = MailWhiteLabelSettings.IsDefault(SettingsManager, Configuration);
var defaultRebranding = MailWhiteLabelSettings.IsDefault(_settingsManager);
notifyAction = defaultRebranding ? Actions.EnterpriseGuestWelcomeV10 : Actions.EnterpriseWhitelabelGuestWelcomeV10;
footer = null;
}
else if (TenantExtra.Opensource)
else if (_tenantExtra.Opensource)
{
notifyAction = Actions.OpensourceGuestWelcomeV11;
footer = "opensource";
@ -391,17 +385,17 @@ namespace ASC.Web.Studio.Core.Notify
notifyAction = Actions.SaasGuestWelcomeV115;
}
string greenButtonText() => TenantExtra.Enterprise
string greenButtonText() => _tenantExtra.Enterprise
? WebstudioNotifyPatternResource.ButtonAccessYourPortal
: WebstudioNotifyPatternResource.ButtonAccessYouWebOffice;
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
notifyAction,
StudioNotifyHelper.RecipientFromEmail(newUserInfo.Email, false),
_studioNotifyHelper.RecipientFromEmail(newUserInfo.Email, false),
new[] { EMailSenderName },
new TagValue(Tags.UserName, newUserInfo.FirstName.HtmlEncode()),
new TagValue(Tags.MyStaffLink, GetMyStaffLink()),
TagValues.GreenButton(greenButtonText, CommonLinkUtility.GetFullAbsolutePath("~").TrimEnd('/')),
TagValues.GreenButton(greenButtonText, _commonLinkUtility.GetFullAbsolutePath("~").TrimEnd('/')),
new TagValue(CommonTags.Footer, footer));
}
@ -413,13 +407,13 @@ namespace ASC.Web.Studio.Core.Notify
INotifyAction notifyAction;
var footer = "social";
if (TenantExtra.Enterprise)
if (_tenantExtra.Enterprise)
{
var defaultRebranding = MailWhiteLabelSettings.IsDefault(SettingsManager, Configuration);
var defaultRebranding = MailWhiteLabelSettings.IsDefault(_settingsManager);
notifyAction = defaultRebranding ? Actions.EnterpriseUserActivationV10 : Actions.EnterpriseWhitelabelUserActivationV10;
footer = null;
}
else if (TenantExtra.Opensource)
else if (_tenantExtra.Opensource)
{
notifyAction = Actions.OpensourceUserActivationV11;
footer = "opensource";
@ -433,9 +427,9 @@ namespace ASC.Web.Studio.Core.Notify
string greenButtonText() => WebstudioNotifyPatternResource.ButtonAccept;
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
notifyAction,
StudioNotifyHelper.RecipientFromEmail(newUserInfo.Email, false),
_studioNotifyHelper.RecipientFromEmail(newUserInfo.Email, false),
new[] { EMailSenderName },
new TagValue(Tags.ActivateUrl, confirmationUrl),
TagValues.GreenButton(greenButtonText, confirmationUrl),
@ -451,13 +445,13 @@ namespace ASC.Web.Studio.Core.Notify
INotifyAction notifyAction;
var footer = "social";
if (TenantExtra.Enterprise)
if (_tenantExtra.Enterprise)
{
var defaultRebranding = MailWhiteLabelSettings.IsDefault(SettingsManager, Configuration);
var defaultRebranding = MailWhiteLabelSettings.IsDefault(_settingsManager);
notifyAction = defaultRebranding ? Actions.EnterpriseGuestActivationV10 : Actions.EnterpriseWhitelabelGuestActivationV10;
footer = null;
}
else if (TenantExtra.Opensource)
else if (_tenantExtra.Opensource)
{
notifyAction = Actions.OpensourceGuestActivationV11;
footer = "opensource";
@ -471,9 +465,9 @@ namespace ASC.Web.Studio.Core.Notify
string greenButtonText() => WebstudioNotifyPatternResource.ButtonAccept;
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
notifyAction,
StudioNotifyHelper.RecipientFromEmail(newUserInfo.Email, false),
_studioNotifyHelper.RecipientFromEmail(newUserInfo.Email, false),
new[] { EMailSenderName },
new TagValue(Tags.ActivateUrl, confirmationUrl),
TagValues.GreenButton(greenButtonText, confirmationUrl),
@ -483,17 +477,17 @@ namespace ASC.Web.Studio.Core.Notify
public void SendMsgProfileDeletion(UserInfo user)
{
var confirmationUrl = CommonLinkUtility.GetConfirmationUrl(user.Email, ConfirmType.ProfileRemove, AuthContext.CurrentAccount.ID, AuthContext.CurrentAccount.ID);
var confirmationUrl = _commonLinkUtility.GetConfirmationUrl(user.Email, ConfirmType.ProfileRemove, _authContext.CurrentAccount.ID, _authContext.CurrentAccount.ID);
string greenButtonText() => CoreBaseSettings.Personal ? WebstudioNotifyPatternResource.ButtonConfirmTermination : WebstudioNotifyPatternResource.ButtonRemoveProfile;
string greenButtonText() => _coreBaseSettings.Personal ? WebstudioNotifyPatternResource.ButtonConfirmTermination : WebstudioNotifyPatternResource.ButtonRemoveProfile;
var action = CoreBaseSettings.Personal
? (CoreBaseSettings.CustomMode ? Actions.PersonalCustomModeProfileDelete : Actions.PersonalProfileDelete)
var action = _coreBaseSettings.Personal
? (_coreBaseSettings.CustomMode ? Actions.PersonalCustomModeProfileDelete : Actions.PersonalProfileDelete)
: Actions.ProfileDelete;
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
action,
StudioNotifyHelper.RecipientFromEmail(user.Email, false),
_studioNotifyHelper.RecipientFromEmail(user.Email, false),
new[] { EMailSenderName },
TagValues.GreenButton(greenButtonText, confirmationUrl),
new TagValue(CommonTags.Culture, user.GetCulture().Name));
@ -501,15 +495,15 @@ namespace ASC.Web.Studio.Core.Notify
public void SendMsgProfileHasDeletedItself(UserInfo user)
{
var tenant = TenantManager.GetCurrentTenant();
var admins = UserManager.GetUsers()
.Where(u => WebItemSecurity.IsProductAdministrator(WebItemManager.PeopleProductID, u.Id));
var tenant = _tenantManager.GetCurrentTenant();
var admins = _userManager.GetUsers()
.Where(u => _webItemSecurity.IsProductAdministrator(WebItemManager.PeopleProductID, u.Id));
ThreadPool.QueueUserWorkItem(_ =>
{
try
{
TenantManager.SetCurrentTenant(tenant);
_tenantManager.SetCurrentTenant(tenant);
foreach (var admin in admins)
{
@ -517,18 +511,18 @@ namespace ASC.Web.Studio.Core.Notify
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
Actions.ProfileHasDeletedItself,
null,
new IRecipient[] { admin },
new[] { EMailSenderName },
new TagValue(Tags.FromUserName, user.DisplayUserName(DisplayUserSettingsHelper)),
new TagValue(Tags.FromUserName, user.DisplayUserName(_displayUserSettingsHelper)),
new TagValue(Tags.FromUserLink, GetUserProfileLink(user)));
}
}
catch (Exception ex)
{
Log.Error(ex);
_log.Error(ex);
}
});
@ -536,38 +530,38 @@ namespace ASC.Web.Studio.Core.Notify
public void SendMsgReassignsCompleted(Guid recipientId, UserInfo fromUser, UserInfo toUser)
{
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
Actions.ReassignsCompleted,
new[] { StudioNotifyHelper.ToRecipient(recipientId) },
new[] { _studioNotifyHelper.ToRecipient(recipientId) },
new[] { EMailSenderName },
new TagValue(Tags.UserName, DisplayUserSettingsHelper.GetFullUserName(recipientId)),
new TagValue(Tags.FromUserName, fromUser.DisplayUserName(DisplayUserSettingsHelper)),
new TagValue(Tags.UserName, _displayUserSettingsHelper.GetFullUserName(recipientId)),
new TagValue(Tags.FromUserName, fromUser.DisplayUserName(_displayUserSettingsHelper)),
new TagValue(Tags.FromUserLink, GetUserProfileLink(fromUser)),
new TagValue(Tags.ToUserName, toUser.DisplayUserName(DisplayUserSettingsHelper)),
new TagValue(Tags.ToUserName, toUser.DisplayUserName(_displayUserSettingsHelper)),
new TagValue(Tags.ToUserLink, GetUserProfileLink(toUser)));
}
public void SendMsgReassignsFailed(Guid recipientId, UserInfo fromUser, UserInfo toUser, string message)
{
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
Actions.ReassignsFailed,
new[] { StudioNotifyHelper.ToRecipient(recipientId) },
new[] { _studioNotifyHelper.ToRecipient(recipientId) },
new[] { EMailSenderName },
new TagValue(Tags.UserName, DisplayUserSettingsHelper.GetFullUserName(recipientId)),
new TagValue(Tags.FromUserName, fromUser.DisplayUserName(DisplayUserSettingsHelper)),
new TagValue(Tags.UserName, _displayUserSettingsHelper.GetFullUserName(recipientId)),
new TagValue(Tags.FromUserName, fromUser.DisplayUserName(_displayUserSettingsHelper)),
new TagValue(Tags.FromUserLink, GetUserProfileLink(fromUser)),
new TagValue(Tags.ToUserName, toUser.DisplayUserName(DisplayUserSettingsHelper)),
new TagValue(Tags.ToUserName, toUser.DisplayUserName(_displayUserSettingsHelper)),
new TagValue(Tags.ToUserLink, GetUserProfileLink(toUser)),
new TagValue(Tags.Message, message));
}
public void SendMsgRemoveUserDataCompleted(Guid recipientId, UserInfo user, string fromUserName, long docsSpace, long crmSpace, long mailSpace, long talkSpace)
{
client.SendNoticeToAsync(
CoreBaseSettings.CustomMode ? Actions.RemoveUserDataCompletedCustomMode : Actions.RemoveUserDataCompleted,
new[] { StudioNotifyHelper.ToRecipient(recipientId) },
_client.SendNoticeToAsync(
_coreBaseSettings.CustomMode ? Actions.RemoveUserDataCompletedCustomMode : Actions.RemoveUserDataCompleted,
new[] { _studioNotifyHelper.ToRecipient(recipientId) },
new[] { EMailSenderName },
new TagValue(Tags.UserName, DisplayUserSettingsHelper.GetFullUserName(recipientId)),
new TagValue(Tags.UserName, _displayUserSettingsHelper.GetFullUserName(recipientId)),
new TagValue(Tags.FromUserName, fromUserName.HtmlEncode()),
new TagValue(Tags.FromUserLink, GetUserProfileLink(user)),
new TagValue("DocsSpace", FileSizeComment.FilesSizeToString(docsSpace)),
@ -578,11 +572,11 @@ namespace ASC.Web.Studio.Core.Notify
public void SendMsgRemoveUserDataFailed(Guid recipientId, UserInfo user, string fromUserName, string message)
{
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
Actions.RemoveUserDataFailed,
new[] { StudioNotifyHelper.ToRecipient(recipientId) },
new[] { _studioNotifyHelper.ToRecipient(recipientId) },
new[] { EMailSenderName },
new TagValue(Tags.UserName, DisplayUserSettingsHelper.GetFullUserName(recipientId)),
new TagValue(Tags.UserName, _displayUserSettingsHelper.GetFullUserName(recipientId)),
new TagValue(Tags.FromUserName, fromUserName.HtmlEncode()),
new TagValue(Tags.FromUserLink, GetUserProfileLink(user)),
new TagValue(Tags.Message, message));
@ -590,7 +584,7 @@ namespace ASC.Web.Studio.Core.Notify
public void SendAdminWelcome(UserInfo newUserInfo)
{
if (!UserManager.UserExists(newUserInfo)) return;
if (!_userManager.UserExists(newUserInfo)) return;
if (!newUserInfo.IsActive)
throw new ArgumentException("User is not activated yet!");
@ -598,18 +592,18 @@ namespace ASC.Web.Studio.Core.Notify
INotifyAction notifyAction;
var tagValues = new List<ITagValue>();
if (TenantExtra.Enterprise)
if (_tenantExtra.Enterprise)
{
var defaultRebranding = MailWhiteLabelSettings.IsDefault(SettingsManager, Configuration);
var defaultRebranding = MailWhiteLabelSettings.IsDefault(_settingsManager);
notifyAction = defaultRebranding ? Actions.EnterpriseAdminWelcomeV10 : Actions.EnterpriseWhitelabelAdminWelcomeV10;
tagValues.Add(TagValues.GreenButton(() => WebstudioNotifyPatternResource.ButtonAccessControlPanel, CommonLinkUtility.GetFullAbsolutePath(SetupInfo.ControlPanelUrl)));
tagValues.Add(TagValues.GreenButton(() => WebstudioNotifyPatternResource.ButtonAccessControlPanel, _commonLinkUtility.GetFullAbsolutePath(_setupInfo.ControlPanelUrl)));
}
else if (TenantExtra.Opensource)
else if (_tenantExtra.Opensource)
{
notifyAction = Actions.OpensourceAdminWelcomeV11;
tagValues.Add(new TagValue(CommonTags.Footer, "opensource"));
tagValues.Add(new TagValue(Tags.ControlPanelUrl, CommonLinkUtility.GetFullAbsolutePath(SetupInfo.ControlPanelUrl).TrimEnd('/')));
tagValues.Add(new TagValue(Tags.ControlPanelUrl, _commonLinkUtility.GetFullAbsolutePath(_setupInfo.ControlPanelUrl).TrimEnd('/')));
}
else
{
@ -621,9 +615,9 @@ namespace ASC.Web.Studio.Core.Notify
tagValues.Add(new TagValue(Tags.UserName, newUserInfo.FirstName.HtmlEncode()));
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
notifyAction,
StudioNotifyHelper.RecipientFromEmail(newUserInfo.Email, false),
_studioNotifyHelper.RecipientFromEmail(newUserInfo.Email, false),
new[] { EMailSenderName },
tagValues.ToArray());
}
@ -632,55 +626,55 @@ namespace ASC.Web.Studio.Core.Notify
public void SendMsgPortalDeactivation(Tenant t, string deactivateUrl, string activateUrl)
{
var u = UserManager.GetUsers(t.OwnerId);
var u = _userManager.GetUsers(t.OwnerId);
string greenButtonText() => WebstudioNotifyPatternResource.ButtonDeactivatePortal;
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
Actions.PortalDeactivate,
new IRecipient[] { u },
new[] { EMailSenderName },
new TagValue(Tags.ActivateUrl, activateUrl),
TagValues.GreenButton(greenButtonText, deactivateUrl),
new TagValue(Tags.OwnerName, u.DisplayUserName(DisplayUserSettingsHelper)));
new TagValue(Tags.OwnerName, u.DisplayUserName(_displayUserSettingsHelper)));
}
public void SendMsgPortalDeletion(Tenant t, string url, bool showAutoRenewText)
{
var u = UserManager.GetUsers(t.OwnerId);
var u = _userManager.GetUsers(t.OwnerId);
string greenButtonText() => WebstudioNotifyPatternResource.ButtonDeletePortal;
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
Actions.PortalDelete,
new IRecipient[] { u },
new[] { EMailSenderName },
TagValues.GreenButton(greenButtonText, url),
new TagValue(Tags.AutoRenew, showAutoRenewText.ToString()),
new TagValue(Tags.OwnerName, u.DisplayUserName(DisplayUserSettingsHelper)));
new TagValue(Tags.OwnerName, u.DisplayUserName(_displayUserSettingsHelper)));
}
public void SendMsgPortalDeletionSuccess(UserInfo owner, string url)
{
string greenButtonText() => WebstudioNotifyPatternResource.ButtonLeaveFeedback;
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
Actions.PortalDeleteSuccessV115,
new IRecipient[] { owner },
new[] { EMailSenderName },
TagValues.GreenButton(greenButtonText, url),
new TagValue(Tags.OwnerName, owner.DisplayUserName(DisplayUserSettingsHelper)));
new TagValue(Tags.OwnerName, owner.DisplayUserName(_displayUserSettingsHelper)));
}
#endregion
public void SendMsgDnsChange(Tenant t, string confirmDnsUpdateUrl, string portalAddress, string portalDns)
{
var u = UserManager.GetUsers(t.OwnerId);
var u = _userManager.GetUsers(t.OwnerId);
string greenButtonText() => WebstudioNotifyPatternResource.ButtonConfirmPortalAddressChange;
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
Actions.DnsChange,
new IRecipient[] { u },
new[] { EMailSenderName },
@ -688,21 +682,21 @@ namespace ASC.Web.Studio.Core.Notify
TagValues.GreenButton(greenButtonText, confirmDnsUpdateUrl),
new TagValue("PortalAddress", AddHttpToUrl(portalAddress)),
new TagValue("PortalDns", AddHttpToUrl(portalDns ?? string.Empty)),
new TagValue(Tags.OwnerName, u.DisplayUserName(DisplayUserSettingsHelper)));
new TagValue(Tags.OwnerName, u.DisplayUserName(_displayUserSettingsHelper)));
}
public void SendMsgConfirmChangeOwner(UserInfo owner, UserInfo newOwner, string confirmOwnerUpdateUrl)
{
string greenButtonText() => WebstudioNotifyPatternResource.ButtonConfirmPortalOwnerUpdate;
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
Actions.ConfirmOwnerChange,
null,
new IRecipient[] { owner },
new[] { EMailSenderName },
TagValues.GreenButton(greenButtonText, confirmOwnerUpdateUrl),
new TagValue(Tags.UserName, newOwner.DisplayUserName(DisplayUserSettingsHelper)),
new TagValue(Tags.OwnerName, owner.DisplayUserName(DisplayUserSettingsHelper)));
new TagValue(Tags.UserName, newOwner.DisplayUserName(_displayUserSettingsHelper)),
new TagValue(Tags.OwnerName, owner.DisplayUserName(_displayUserSettingsHelper)));
}
public void SendCongratulations(UserInfo u)
@ -712,13 +706,13 @@ namespace ASC.Web.Studio.Core.Notify
INotifyAction notifyAction;
var footer = "common";
if (TenantExtra.Enterprise)
if (_tenantExtra.Enterprise)
{
var defaultRebranding = MailWhiteLabelSettings.IsDefault(SettingsManager, Configuration);
var defaultRebranding = MailWhiteLabelSettings.IsDefault(_settingsManager);
notifyAction = defaultRebranding ? Actions.EnterpriseAdminActivationV10 : Actions.EnterpriseWhitelabelAdminActivationV10;
footer = null;
}
else if (TenantExtra.Opensource)
else if (_tenantExtra.Opensource)
{
notifyAction = Actions.OpensourceAdminActivationV11;
footer = "opensource";
@ -728,14 +722,14 @@ namespace ASC.Web.Studio.Core.Notify
notifyAction = Actions.SaasAdminActivationV115;
}
var confirmationUrl = CommonLinkUtility.GetConfirmationUrl(u.Email, ConfirmType.EmailActivation);
var confirmationUrl = _commonLinkUtility.GetConfirmationUrl(u.Email, ConfirmType.EmailActivation);
confirmationUrl += "&first=true";
string greenButtonText() => WebstudioNotifyPatternResource.ButtonConfirm;
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
notifyAction,
StudioNotifyHelper.RecipientFromEmail(u.Email, false),
_studioNotifyHelper.RecipientFromEmail(u.Email, false),
new[] { EMailSenderName },
new TagValue(Tags.UserName, u.FirstName.HtmlEncode()),
new TagValue(Tags.MyStaffLink, GetMyStaffLink()),
@ -745,7 +739,7 @@ namespace ASC.Web.Studio.Core.Notify
}
catch (Exception error)
{
Log.Error(error);
_log.Error(error);
}
}
@ -753,57 +747,57 @@ namespace ASC.Web.Studio.Core.Notify
public void SendInvitePersonal(string email, string additionalMember = "")
{
var newUserInfo = UserManager.GetUserByEmail(email);
if (UserManager.UserExists(newUserInfo)) return;
var newUserInfo = _userManager.GetUserByEmail(email);
if (_userManager.UserExists(newUserInfo)) return;
var lang = CoreBaseSettings.CustomMode
var lang = _coreBaseSettings.CustomMode
? "ru-RU"
: Thread.CurrentThread.CurrentUICulture.Name;
var culture = SetupInfo.GetPersonalCulture(lang);
var culture = _setupInfo.GetPersonalCulture(lang);
var confirmUrl = CommonLinkUtility.GetConfirmationUrl(email, ConfirmType.EmpInvite, (int)EmployeeType.User)
var confirmUrl = _commonLinkUtility.GetConfirmationUrl(email, ConfirmType.EmpInvite, (int)EmployeeType.User)
+ "&emplType=" + (int)EmployeeType.User
+ "&lang=" + culture.Key
+ additionalMember;
client.SendNoticeToAsync(
CoreBaseSettings.CustomMode ? Actions.PersonalCustomModeConfirmation : Actions.PersonalConfirmation,
StudioNotifyHelper.RecipientFromEmail(email, false),
_client.SendNoticeToAsync(
_coreBaseSettings.CustomMode ? Actions.PersonalCustomModeConfirmation : Actions.PersonalConfirmation,
_studioNotifyHelper.RecipientFromEmail(email, false),
new[] { EMailSenderName },
new TagValue(Tags.InviteLink, confirmUrl),
new TagValue(CommonTags.Footer, CoreBaseSettings.CustomMode ? "personalCustomMode" : "personal"),
new TagValue(CommonTags.Footer, _coreBaseSettings.CustomMode ? "personalCustomMode" : "personal"),
new TagValue(CommonTags.Culture, Thread.CurrentThread.CurrentUICulture.Name));
}
public void SendAlreadyExist(string email)
{
var userInfo = UserManager.GetUserByEmail(email);
if (!UserManager.UserExists(userInfo)) return;
var userInfo = _userManager.GetUserByEmail(email);
if (!_userManager.UserExists(userInfo)) return;
var portalUrl = CommonLinkUtility.GetFullAbsolutePath("~").TrimEnd('/');
var portalUrl = _commonLinkUtility.GetFullAbsolutePath("~").TrimEnd('/');
var hash = Authentication.GetUserPasswordStamp(userInfo.Id).ToString("s");
var hash = _authentication.GetUserPasswordStamp(userInfo.Id).ToString("s");
var linkToRecovery = CommonLinkUtility.GetConfirmationUrl(userInfo.Email, ConfirmType.PasswordChange, hash, userInfo.Id);
var linkToRecovery = _commonLinkUtility.GetConfirmationUrl(userInfo.Email, ConfirmType.PasswordChange, hash, userInfo.Id);
client.SendNoticeToAsync(
CoreBaseSettings.CustomMode ? Actions.PersonalCustomModeAlreadyExist : Actions.PersonalAlreadyExist,
StudioNotifyHelper.RecipientFromEmail(email, false),
_client.SendNoticeToAsync(
_coreBaseSettings.CustomMode ? Actions.PersonalCustomModeAlreadyExist : Actions.PersonalAlreadyExist,
_studioNotifyHelper.RecipientFromEmail(email, false),
new[] { EMailSenderName },
new TagValue(Tags.PortalUrl, portalUrl),
new TagValue(Tags.LinkToRecovery, linkToRecovery),
new TagValue(CommonTags.Footer, CoreBaseSettings.CustomMode ? "personalCustomMode" : "personal"),
new TagValue(CommonTags.Footer, _coreBaseSettings.CustomMode ? "personalCustomMode" : "personal"),
new TagValue(CommonTags.Culture, Thread.CurrentThread.CurrentUICulture.Name));
}
public void SendUserWelcomePersonal(UserInfo newUserInfo)
{
client.SendNoticeToAsync(
CoreBaseSettings.CustomMode ? Actions.PersonalCustomModeAfterRegistration1 : Actions.PersonalAfterRegistration1,
StudioNotifyHelper.RecipientFromEmail(newUserInfo.Email, true),
_client.SendNoticeToAsync(
_coreBaseSettings.CustomMode ? Actions.PersonalCustomModeAfterRegistration1 : Actions.PersonalAfterRegistration1,
_studioNotifyHelper.RecipientFromEmail(newUserInfo.Email, true),
new[] { EMailSenderName },
new TagValue(CommonTags.Footer, CoreBaseSettings.CustomMode ? "personalCustomMode" : "personal"),
new TagValue(CommonTags.Footer, _coreBaseSettings.CustomMode ? "personalCustomMode" : "personal"),
new TagValue(CommonTags.MasterTemplate, "HtmlMasterPersonal"));
}
@ -813,37 +807,31 @@ namespace ASC.Web.Studio.Core.Notify
public void PortalRenameNotify(Tenant tenant, string oldVirtualRootPath)
{
var users = UserManager.GetUsers()
var users = _userManager.GetUsers()
.Where(u => u.ActivationStatus.HasFlag(EmployeeActivationStatus.Activated));
ThreadPool.QueueUserWorkItem(_ =>
try
{
try
{
var scope = ServiceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<StudioNotifyServiceScope>();
var (tenantManager, studioNotifyServiceHelper) = scopeClass;
tenantManager.SetCurrentTenant(tenant);
_tenantManager.SetCurrentTenant(tenant);
foreach (var u in users)
{
var culture = string.IsNullOrEmpty(u.CultureName) ? tenant.GetCulture() : u.GetCulture();
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
studioNotifyServiceHelper.SendNoticeToAsync(
Actions.PortalRename,
new[] { StudioNotifyHelper.ToRecipient(u.Id) },
new[] { EMailSenderName },
new TagValue(Tags.PortalUrl, oldVirtualRootPath),
new TagValue(Tags.UserDisplayName, u.DisplayUserName(DisplayUserSettingsHelper)));
}
}
catch (Exception ex)
foreach (var u in users)
{
Log.Error(ex);
var culture = string.IsNullOrEmpty(u.CultureName) ? tenant.GetCulture() : u.GetCulture();
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
_client.SendNoticeToAsync(
Actions.PortalRename,
new[] { _studioNotifyHelper.ToRecipient(u.Id) },
new[] { EMailSenderName },
new TagValue(Tags.PortalUrl, oldVirtualRootPath),
new TagValue(Tags.UserDisplayName, u.DisplayUserName(_displayUserSettingsHelper)));
}
});
}
catch (Exception ex)
{
_log.Error(ex);
}
}
#endregion
@ -852,12 +840,12 @@ namespace ASC.Web.Studio.Core.Notify
private string GetMyStaffLink()
{
return CommonLinkUtility.GetFullAbsolutePath(CommonLinkUtility.GetMyStaff());
return _commonLinkUtility.GetFullAbsolutePath(_commonLinkUtility.GetMyStaff());
}
private string GetUserProfileLink(UserInfo userInfo)
{
return CommonLinkUtility.GetFullAbsolutePath(CommonLinkUtility.GetUserProfile(userInfo));
return _commonLinkUtility.GetFullAbsolutePath(_commonLinkUtility.GetUserProfile(userInfo));
}
private static string AddHttpToUrl(string url)
@ -868,7 +856,7 @@ namespace ASC.Web.Studio.Core.Notify
private string GenerateActivationConfirmUrl(UserInfo user)
{
var confirmUrl = CommonLinkUtility.GetConfirmationUrl(user.Email, ConfirmType.Activation, user.Id, user.Id);
var confirmUrl = _commonLinkUtility.GetConfirmationUrl(user.Email, ConfirmType.Activation, user.Id, user.Id);
return confirmUrl + $"&firstname={HttpUtility.UrlEncode(user.FirstName)}&lastname={HttpUtility.UrlEncode(user.LastName)}";
}
@ -878,16 +866,16 @@ namespace ASC.Web.Studio.Core.Notify
{
try
{
if (!TenantExtra.Saas || !CoreBaseSettings.CustomMode) return;
if (!_tenantExtra.Saas || !_coreBaseSettings.CustomMode) return;
var settings = SettingsManager.LoadForDefaultTenant<AdditionalWhiteLabelSettings>();
var salesEmail = settings.SalesEmail ?? SetupInfo.SalesEmail;
var settings = _settingsManager.LoadForDefaultTenant<AdditionalWhiteLabelSettings>();
var salesEmail = settings.SalesEmail ?? _setupInfo.SalesEmail;
if (string.IsNullOrEmpty(salesEmail)) return;
var recipient = new DirectRecipient(salesEmail, null, new[] { salesEmail }, false);
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
Actions.SaasCustomModeRegData,
null,
new IRecipient[] { recipient },
@ -902,7 +890,7 @@ namespace ASC.Web.Studio.Core.Notify
}
catch (Exception error)
{
Log.Error(error);
_log.Error(error);
}
}
@ -943,15 +931,15 @@ namespace ASC.Web.Studio.Core.Notify
private void SendStorageEncryptionNotify(INotifyAction action, bool notifyAdminsOnly, string serverRootPath)
{
var users = notifyAdminsOnly
? UserManager.GetUsersByGroup(Constants.GroupAdmin.ID)
: UserManager.GetUsers().Where(u => u.ActivationStatus.HasFlag(EmployeeActivationStatus.Activated));
? _userManager.GetUsersByGroup(Constants.GroupAdmin.ID)
: _userManager.GetUsers().Where(u => u.ActivationStatus.HasFlag(EmployeeActivationStatus.Activated));
foreach (var u in users)
{
client.SendNoticeToAsync(
_client.SendNoticeToAsync(
action,
null,
new[] { StudioNotifyHelper.ToRecipient(u.Id) },
new[] { _studioNotifyHelper.ToRecipient(u.Id) },
new[] { EMailSenderName },
new TagValue(Tags.UserName, u.FirstName.HtmlEncode()),
new TagValue(Tags.PortalUrl, serverRootPath),
@ -961,7 +949,7 @@ namespace ASC.Web.Studio.Core.Notify
private string GetControlPanelUrl(string serverRootPath)
{
var controlPanelUrl = SetupInfo.ControlPanelUrl;
var controlPanelUrl = _setupInfo.ControlPanelUrl;
if (string.IsNullOrEmpty(controlPanelUrl))
return string.Empty;
@ -975,31 +963,4 @@ namespace ASC.Web.Studio.Core.Notify
#endregion
}
[Scope]
public class StudioNotifyServiceScope
{
private TenantManager TenantManager { get; }
private StudioNotifyServiceHelper StudioNotifyServiceHelper { get; }
public StudioNotifyServiceScope(TenantManager tenantManager, StudioNotifyServiceHelper studioNotifyServiceHelper)
{
TenantManager = tenantManager;
StudioNotifyServiceHelper = studioNotifyServiceHelper;
}
public void Deconstruct(out TenantManager tenantManager, out StudioNotifyServiceHelper studioNotifyServiceHelper)
{
tenantManager = TenantManager;
studioNotifyServiceHelper = StudioNotifyServiceHelper;
}
}
public static class StudioNotifyServiceExtension
{
public static void Register(DIHelper services)
{
services.TryAdd<StudioNotifyServiceScope>();
}
}
}

View File

@ -33,29 +33,141 @@ namespace ASC.Web.Studio.Core.Notify
{
private static string EMailSenderName { get { return Constants.NotifyEMailSenderSysName; } }
private IServiceProvider ServiceProvider { get; }
private IConfiguration Configuration { get; }
private readonly IServiceScopeFactory _serviceProvider;
private readonly IConfiguration _configuration;
private readonly WorkContext _workContext;
private readonly TenantExtraConfig _tenantExtraConfig;
private readonly CoreBaseSettings _coreBaseSettings;
public StudioNotifyServiceSender(IServiceProvider serviceProvider, IConfiguration configuration, ICacheNotify<NotifyItem> cache)
public StudioNotifyServiceSender(
IServiceScopeFactory serviceProvider,
IConfiguration configuration,
ICacheNotify<NotifyItem> cache,
WorkContext workContext,
TenantExtraConfig tenantExtraConfig,
CoreBaseSettings coreBaseSettings)
{
cache.Subscribe(this.OnMessage, Common.Caching.CacheNotifyAction.Any);
ServiceProvider = serviceProvider;
Configuration = configuration;
cache.Subscribe(OnMessage, CacheNotifyAction.Any);
_serviceProvider = serviceProvider;
_configuration = configuration;
_workContext = workContext;
_tenantExtraConfig = tenantExtraConfig;
_coreBaseSettings = coreBaseSettings;
}
public void OnMessage(NotifyItem item)
{
using var scope = ServiceProvider.CreateScope();
var commonLinkUtilitySettings = scope.ServiceProvider.GetService<CommonLinkUtilitySettings>();
commonLinkUtilitySettings.ServerUri = item.BaseUrl;
var scopeClass = scope.ServiceProvider.GetService<StudioNotifyServiceSenderScope>();
var (tenantManager, userManager, securityContext, studioNotifyHelper, _, _) = scopeClass;
tenantManager.SetCurrentTenant(item.TenantId);
using var scope = _serviceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetRequiredService<StudioNotifyWorker>();
scopeClass.OnMessage(item);
}
public void RegisterSendMethod()
{
var cron = _configuration["core:notify:cron"] ?? "0 0 5 ? * *"; // 5am every day
if (_configuration["core:notify:tariff"] != "false")
{
if (_tenantExtraConfig.Enterprise)
{
_workContext.RegisterSendMethod(SendEnterpriseTariffLetters, cron);
}
else if (_tenantExtraConfig.Opensource)
{
_workContext.RegisterSendMethod(SendOpensourceTariffLetters, cron);
}
else if (_tenantExtraConfig.Saas)
{
if (_coreBaseSettings.Personal)
{
if (!_coreBaseSettings.CustomMode)
{
_workContext.RegisterSendMethod(SendLettersPersonal, cron);
}
}
else
{
_workContext.RegisterSendMethod(SendSaasTariffLetters, cron);
}
}
}
if (!_coreBaseSettings.Personal)
{
_workContext.RegisterSendMethod(SendMsgWhatsNew, "0 0 * ? * *"); // every hour
}
}
public void SendSaasTariffLetters(DateTime scheduleDate)
{
using var scope = _serviceProvider.CreateScope();
scope.ServiceProvider.GetService<StudioPeriodicNotify>().SendSaasLettersAsync(EMailSenderName, scheduleDate).Wait();
}
public void SendEnterpriseTariffLetters(DateTime scheduleDate)
{
using var scope = _serviceProvider.CreateScope();
scope.ServiceProvider.GetService<StudioPeriodicNotify>().SendEnterpriseLetters(EMailSenderName, scheduleDate);
}
public void SendOpensourceTariffLetters(DateTime scheduleDate)
{
using var scope = _serviceProvider.CreateScope();
scope.ServiceProvider.GetService<StudioPeriodicNotify>().SendOpensourceLetters(EMailSenderName, scheduleDate);
}
public void SendLettersPersonal(DateTime scheduleDate)
{
using var scope = _serviceProvider.CreateScope();
scope.ServiceProvider.GetService<StudioPeriodicNotify>().SendPersonalLetters(EMailSenderName, scheduleDate);
}
public void SendMsgWhatsNew(DateTime scheduleDate)
{
using var scope = _serviceProvider.CreateScope();
scope.ServiceProvider.GetRequiredService<StudioWhatsNewNotify>().SendMsgWhatsNew(scheduleDate);
}
}
[Scope]
public class StudioNotifyWorker
{
private readonly CommonLinkUtilitySettings _commonLinkUtilitySettings;
private readonly NotifyEngineQueue _notifyEngineQueue;
private readonly WorkContext _workContext;
private readonly TenantManager _tenantManager;
private readonly UserManager _userManager;
private readonly SecurityContext _securityContext;
private readonly StudioNotifyHelper _studioNotifyHelper;
public StudioNotifyWorker(
TenantManager tenantManager,
UserManager userManager,
SecurityContext securityContext,
StudioNotifyHelper studioNotifyHelper,
CommonLinkUtilitySettings commonLinkUtilitySettings,
NotifyEngineQueue notifyEngineQueue,
WorkContext workContext)
{
_tenantManager = tenantManager;
_userManager = userManager;
_securityContext = securityContext;
_studioNotifyHelper = studioNotifyHelper;
_commonLinkUtilitySettings = commonLinkUtilitySettings;
_notifyEngineQueue = notifyEngineQueue;
_workContext = workContext;
}
public void OnMessage(NotifyItem item)
{
_commonLinkUtilitySettings.ServerUri = item.BaseUrl;
_tenantManager.SetCurrentTenant(item.TenantId);
CultureInfo culture = null;
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifyHelper.NotifySource, scope);
var client = _workContext.NotifyContext.RegisterClient(_notifyEngineQueue, _studioNotifyHelper.NotifySource);
var tenant = tenantManager.GetCurrentTenant(false);
var tenant = _tenantManager.GetCurrentTenant(false);
if (tenant != null)
{
@ -64,8 +176,8 @@ namespace ASC.Web.Studio.Core.Notify
if (Guid.TryParse(item.UserId, out var userId) && !userId.Equals(Constants.Guest.ID) && !userId.Equals(Guid.Empty))
{
securityContext.AuthenticateMeWithoutCookie(Guid.Parse(item.UserId));
var user = userManager.GetUsers(userId);
_securityContext.AuthenticateMeWithoutCookie(Guid.Parse(item.UserId));
var user = _userManager.GetUsers(userId);
if (!string.IsNullOrEmpty(user.CultureName))
{
culture = CultureInfo.GetCultureInfo(user.CultureName);
@ -89,124 +201,13 @@ namespace ASC.Web.Studio.Core.Notify
item.CheckSubsciption,
item.Tags.Select(r => new TagValue(r.Tag_, r.Value)).ToArray());
}
public void RegisterSendMethod()
{
var cron = Configuration["core:notify:cron"] ?? "0 0 5 ? * *"; // 5am every day
using var scope = ServiceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<StudioNotifyServiceSenderScope>();
var (_, _, _, _, tenantExtra, coreBaseSettings) = scopeClass;
if (Configuration["core:notify:tariff"] != "false")
{
if (tenantExtra.Enterprise)
{
WorkContext.RegisterSendMethod(SendEnterpriseTariffLetters, cron);
}
else if (tenantExtra.Opensource)
{
WorkContext.RegisterSendMethod(SendOpensourceTariffLetters, cron);
}
else if (tenantExtra.Saas)
{
if (coreBaseSettings.Personal)
{
if (!coreBaseSettings.CustomMode)
{
WorkContext.RegisterSendMethod(SendLettersPersonal, cron);
}
}
else
{
WorkContext.RegisterSendMethod(SendSaasTariffLetters, cron);
}
}
}
if (!coreBaseSettings.Personal)
{
WorkContext.RegisterSendMethod(SendMsgWhatsNew, "0 0 * ? * *"); // every hour
}
}
public void SendSaasTariffLetters(DateTime scheduleDate)
{
//remove client
using var scope = ServiceProvider.CreateScope();
scope.ServiceProvider.GetService<StudioPeriodicNotify>().SendSaasLettersAsync(EMailSenderName, scheduleDate).Wait();
}
public void SendEnterpriseTariffLetters(DateTime scheduleDate)
{
using var scope = ServiceProvider.CreateScope();
scope.ServiceProvider.GetService<StudioPeriodicNotify>().SendEnterpriseLetters(EMailSenderName, scheduleDate);
}
public void SendOpensourceTariffLetters(DateTime scheduleDate)
{
using var scope = ServiceProvider.CreateScope();
scope.ServiceProvider.GetService<StudioPeriodicNotify>().SendOpensourceLetters(EMailSenderName, scheduleDate);
}
public void SendLettersPersonal(DateTime scheduleDate)
{
using var scope = ServiceProvider.CreateScope();
scope.ServiceProvider.GetService<StudioPeriodicNotify>().SendPersonalLetters(EMailSenderName, scheduleDate);
}
public void SendMsgWhatsNew(DateTime scheduleDate)
{
using var scope = ServiceProvider.CreateScope();
scope.ServiceProvider.GetService<StudioWhatsNewNotify>().SendMsgWhatsNew(scheduleDate);
}
}
[Scope]
public class StudioNotifyServiceSenderScope
{
private TenantManager TenantManager { get; }
private UserManager UserManager { get; }
private SecurityContext SecurityContext { get; }
private StudioNotifyHelper StudioNotifyHelper { get; }
private TenantExtra TenantExtra { get; }
private CoreBaseSettings CoreBaseSettings { get; }
public StudioNotifyServiceSenderScope(TenantManager tenantManager,
UserManager userManager,
SecurityContext securityContext,
StudioNotifyHelper studioNotifyHelper,
TenantExtra tenantExtra,
CoreBaseSettings coreBaseSettings)
{
TenantManager = tenantManager;
UserManager = userManager;
SecurityContext = securityContext;
StudioNotifyHelper = studioNotifyHelper;
TenantExtra = tenantExtra;
CoreBaseSettings = coreBaseSettings;
}
public void Deconstruct(out TenantManager tenantManager,
out UserManager userManager,
out SecurityContext securityContext,
out StudioNotifyHelper studioNotifyHelper,
out TenantExtra tenantExtra,
out CoreBaseSettings coreBaseSettings)
{
tenantManager = TenantManager;
userManager = UserManager;
securityContext = SecurityContext;
studioNotifyHelper = StudioNotifyHelper;
tenantExtra = TenantExtra;
coreBaseSettings = CoreBaseSettings;
}
}
public static class ServiceLauncherExtension
{
public static void Register(DIHelper services)
{
services.TryAdd<StudioNotifyServiceSenderScope>();
services.TryAdd<StudioNotifyWorker>();
services.TryAdd<StudioPeriodicNotify>();
services.TryAdd<StudioWhatsNewNotify>();
}

View File

@ -26,35 +26,84 @@
namespace ASC.Web.Studio.Core.Notify
{
[Singletone(Additional = typeof(StudioPeriodicNotifyExtension))]
[Scope]
public class StudioPeriodicNotify
{
private IServiceProvider ServiceProvider { get; }
public ILog Log { get; }
{
private readonly NotifyEngineQueue _notifyEngineQueue;
private readonly WorkContext _workContext;
private readonly TenantManager _tenantManager;
private readonly UserManager _userManager;
private readonly StudioNotifyHelper _studioNotifyHelper;
private readonly PaymentManager _paymentManager;
private readonly TenantExtra _tenantExtra;
private readonly AuthContext _authContext;
private readonly CommonLinkUtility _commonLinkUtility;
private readonly ApiSystemHelper _apiSystemHelper;
private readonly SetupInfo _setupInfo;
private readonly DbContextManager<FeedDbContext> _dbContextManager;
private readonly CouponManager _couponManager;
private readonly IConfiguration _configuration;
private readonly SettingsManager _settingsManager;
private readonly CoreBaseSettings _coreBaseSettings;
private readonly DisplayUserSettingsHelper _displayUserSettingsHelper;
private readonly AuthManager _authManager;
private readonly SecurityContext _securityContext;
private readonly ILog _log;
public StudioPeriodicNotify(IServiceProvider serviceProvider, IOptionsMonitor<ILog> log)
{
ServiceProvider = serviceProvider;
Log = log.Get("ASC.Notify");
public StudioPeriodicNotify(
IOptionsMonitor<ILog> log,
NotifyEngineQueue notifyEngineQueue,
WorkContext workContext,
TenantManager tenantManager,
UserManager userManager,
StudioNotifyHelper studioNotifyHelper,
PaymentManager paymentManager,
TenantExtra tenantExtra,
AuthContext authContext,
CommonLinkUtility commonLinkUtility,
ApiSystemHelper apiSystemHelper,
SetupInfo setupInfo,
DbContextManager<FeedDbContext> dbContextManager,
CouponManager couponManager,
IConfiguration configuration,
SettingsManager settingsManager,
CoreBaseSettings coreBaseSettings,
DisplayUserSettingsHelper displayUserSettingsHelper,
AuthManager authManager,
SecurityContext securityContext)
{
_notifyEngineQueue = notifyEngineQueue;
_workContext = workContext;
_tenantManager = tenantManager;
_userManager = userManager;
_studioNotifyHelper = studioNotifyHelper;
_paymentManager = paymentManager;
_tenantExtra = tenantExtra;
_authContext = authContext;
_commonLinkUtility = commonLinkUtility;
_apiSystemHelper = apiSystemHelper;
_setupInfo = setupInfo;
_dbContextManager = dbContextManager;
_couponManager = couponManager;
_configuration = configuration;
_settingsManager = settingsManager;
_coreBaseSettings = coreBaseSettings;
_displayUserSettingsHelper = displayUserSettingsHelper;
_authManager = authManager;
_securityContext = securityContext;
_log = log.Get("ASC.Notify");
}
public Task SendSaasLettersAsync(string senderName, DateTime scheduleDate)
{
Log.Info("Start SendSaasTariffLetters");
_log.Info("Start SendSaasTariffLetters");
List<Tenant> activeTenants;
using (var scope = ServiceProvider.CreateScope())
{
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
activeTenants = tenantManager.GetTenants().ToList();
if (activeTenants.Count <= 0)
{
Log.Info("End SendSaasTariffLetters");
return Task.CompletedTask;
}
var activeTenants = _tenantManager.GetTenants().ToList();
if (activeTenants.Count <= 0)
{
_log.Info("End SendSaasTariffLetters");
return Task.CompletedTask;
}
return InternalSendSaasLettersAsync(senderName, scheduleDate, activeTenants);
@ -68,14 +117,11 @@ namespace ASC.Web.Studio.Core.Notify
{
try
{
using var scope = ServiceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<StudioPeriodicNotifyScope>();
var (tenantManager, userManager, studioNotifyHelper, paymentManager, tenantExtra, authContext, commonLinkUtility, apiSystemHelper, setupInfo, dbContextManager, couponManager, _, _, coreBaseSettings, _, _, _) = scopeClass;
tenantManager.SetCurrentTenant(tenant.Id);
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifyHelper.NotifySource, scope);
_tenantManager.SetCurrentTenant(tenant.Id);
var client = _workContext.NotifyContext.RegisterClient(_notifyEngineQueue, _studioNotifyHelper.NotifySource);
var tariff = paymentManager.GetTariff(tenant.Id);
var quota = tenantManager.GetTenantQuota(tenant.Id);
var tariff = _paymentManager.GetTariff(tenant.Id);
var quota = _tenantManager.GetTenantQuota(tenant.Id);
var createdDate = tenant.CreationDateTime.Date;
var dueDateIsNotMax = tariff.DueDate != DateTime.MaxValue;
@ -163,7 +209,7 @@ namespace ASC.Web.Studio.Core.Notify
toadmins = true;
greenButtonText = () => WebstudioNotifyPatternResource.ButtonUseDiscount;
greenButtonUrl = commonLinkUtility.GetFullAbsolutePath("~/Tariffs.aspx");
greenButtonUrl = _commonLinkUtility.GetFullAbsolutePath("~/Tariffs.aspx");
}
#endregion
@ -181,7 +227,7 @@ namespace ASC.Web.Studio.Core.Notify
toadmins = true;
greenButtonText = () => WebstudioNotifyPatternResource.ButtonAccessYouWebOffice;
greenButtonUrl = $"{commonLinkUtility.GetFullAbsolutePath("~").TrimEnd('/')}/";
greenButtonUrl = $"{_commonLinkUtility.GetFullAbsolutePath("~").TrimEnd('/')}/";
}
#endregion
@ -195,7 +241,7 @@ namespace ASC.Web.Studio.Core.Notify
toadmins = true;
greenButtonText = () => WebstudioNotifyPatternResource.ButtonUseDiscount;
greenButtonUrl = commonLinkUtility.GetFullAbsolutePath("~/Tariffs.aspx");
greenButtonUrl = _commonLinkUtility.GetFullAbsolutePath("~/Tariffs.aspx");
}
#endregion
@ -209,42 +255,42 @@ namespace ASC.Web.Studio.Core.Notify
toadmins = true;
tousers = true;
tableItemImg1 = studioNotifyHelper.GetNotificationImageUrl("tips-documents-formatting-100.png");
tableItemImg1 = _studioNotifyHelper.GetNotificationImageUrl("tips-documents-formatting-100.png");
tableItemText1 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_formatting_hdr;
tableItemComment1 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_formatting;
if (!coreBaseSettings.CustomMode)
if (!_coreBaseSettings.CustomMode)
{
tableItemLearnMoreUrl1 = studioNotifyHelper.Helplink + "/onlyoffice-editors/index.aspx";
tableItemLearnMoreUrl1 = _studioNotifyHelper.Helplink + "/onlyoffice-editors/index.aspx";
tableItemLearnMoreText1 = () => WebstudioNotifyPatternResource.LinkLearnMore;
}
tableItemImg2 = studioNotifyHelper.GetNotificationImageUrl("tips-documents-share-100.png");
tableItemImg2 = _studioNotifyHelper.GetNotificationImageUrl("tips-documents-share-100.png");
tableItemText2 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_share_hdr;
tableItemComment2 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_share;
tableItemImg3 = studioNotifyHelper.GetNotificationImageUrl("tips-documents-coediting-100.png");
tableItemImg3 = _studioNotifyHelper.GetNotificationImageUrl("tips-documents-coediting-100.png");
tableItemText3 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_coediting_hdr;
tableItemComment3 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_coediting;
tableItemImg4 = studioNotifyHelper.GetNotificationImageUrl("tips-documents-review-100.png");
tableItemImg4 = _studioNotifyHelper.GetNotificationImageUrl("tips-documents-review-100.png");
tableItemText4 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_review_hdr;
tableItemComment4 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_review;
tableItemImg5 = studioNotifyHelper.GetNotificationImageUrl("tips-customize-modules-100.png");
tableItemImg5 = _studioNotifyHelper.GetNotificationImageUrl("tips-customize-modules-100.png");
tableItemText5 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_contentcontrols_hdr;
tableItemComment5 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_contentcontrols;
tableItemImg6 = studioNotifyHelper.GetNotificationImageUrl("tips-customize-customize-100.png");
tableItemImg6 = _studioNotifyHelper.GetNotificationImageUrl("tips-customize-customize-100.png");
tableItemText6 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_spreadsheets_hdr;
tableItemComment6 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_spreadsheets;
tableItemImg7 = studioNotifyHelper.GetNotificationImageUrl("tips-documents-attach-100.png");
tableItemImg7 = _studioNotifyHelper.GetNotificationImageUrl("tips-documents-attach-100.png");
tableItemText7 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_differences_hdr;
tableItemComment7 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_differences;
greenButtonText = () => WebstudioNotifyPatternResource.ButtonAccessYouWebOffice;
greenButtonUrl = $"{commonLinkUtility.GetFullAbsolutePath("~").TrimEnd('/')}/products/files/";
greenButtonUrl = $"{_commonLinkUtility.GetFullAbsolutePath("~").TrimEnd('/')}/products/files/";
}
#endregion
@ -267,7 +313,7 @@ namespace ASC.Web.Studio.Core.Notify
#region 5 days before SAAS TRIAL ends to admins
else if (!coreBaseSettings.CustomMode && dueDateIsNotMax && dueDate.AddDays(-5) == nowDate)
else if (!_coreBaseSettings.CustomMode && dueDateIsNotMax && dueDate.AddDays(-5) == nowDate)
{
toadmins = true;
action = Actions.SaasAdminTrialWarningBefore5V115;
@ -277,27 +323,27 @@ namespace ASC.Web.Studio.Core.Notify
{
try
{
Log.InfoFormat("start CreateCoupon to {0}", tenant.Alias);
_log.InfoFormat("start CreateCoupon to {0}", tenant.Alias);
coupon = SetupInfo.IsSecretEmail(userManager.GetUsers(tenant.OwnerId).Email)
coupon = SetupInfo.IsSecretEmail(_userManager.GetUsers(tenant.OwnerId).Email)
? tenant.Alias
: couponManager.CreateCoupon(tenantManager);
: _couponManager.CreateCoupon(_tenantManager);
Log.InfoFormat("end CreateCoupon to {0} coupon = {1}", tenant.Alias, coupon);
_log.InfoFormat("end CreateCoupon to {0} coupon = {1}", tenant.Alias, coupon);
}
catch (AggregateException ae)
{
foreach (var ex in ae.InnerExceptions)
Log.Error(ex);
_log.Error(ex);
}
catch (Exception ex)
{
Log.Error(ex);
_log.Error(ex);
}
}
greenButtonText = () => WebstudioNotifyPatternResource.ButtonUseDiscount;
greenButtonUrl = commonLinkUtility.GetFullAbsolutePath("~/tariffs.aspx");
greenButtonUrl = _commonLinkUtility.GetFullAbsolutePath("~/tariffs.aspx");
}
#endregion
@ -320,7 +366,7 @@ namespace ASC.Web.Studio.Core.Notify
toadmins = true;
greenButtonText = () => WebstudioNotifyPatternResource.ButtonRenewNow;
greenButtonUrl = commonLinkUtility.GetFullAbsolutePath("~/Tariffs.aspx");
greenButtonUrl = _commonLinkUtility.GetFullAbsolutePath("~/Tariffs.aspx");
}
#region 6 months after SAAS TRIAL expired
@ -332,8 +378,8 @@ namespace ASC.Web.Studio.Core.Notify
greenButtonText = () => WebstudioNotifyPatternResource.ButtonLeaveFeedback;
var owner = userManager.GetUsers(tenant.OwnerId);
greenButtonUrl = setupInfo.TeamlabSiteRedirect + "/remove-portal-feedback-form.aspx#" +
var owner = _userManager.GetUsers(tenant.OwnerId);
greenButtonUrl = _setupInfo.TeamlabSiteRedirect + "/remove-portal-feedback-form.aspx#" +
System.Web.HttpUtility.UrlEncode(Convert.ToBase64String(
System.Text.Encoding.UTF8.GetBytes("{\"firstname\":\"" + owner.FirstName +
"\",\"lastname\":\"" + owner.LastName +
@ -342,11 +388,11 @@ namespace ASC.Web.Studio.Core.Notify
}
else if (dueDateIsNotMax && dueDate.AddMonths(6).AddDays(7) <= nowDate)
{
tenantManager.RemoveTenant(tenant.Id, true);
_tenantManager.RemoveTenant(tenant.Id, true);
if (!string.IsNullOrEmpty(apiSystemHelper.ApiCacheUrl))
if (!string.IsNullOrEmpty(_apiSystemHelper.ApiCacheUrl))
{
await apiSystemHelper.RemoveTenantFromCacheAsync(tenant.Alias, authContext.CurrentAccount.ID);
await _apiSystemHelper.RemoveTenantFromCacheAsync(tenant.Alias, _authContext.CurrentAccount.ID);
}
}
@ -370,8 +416,8 @@ namespace ASC.Web.Studio.Core.Notify
greenButtonText = () => WebstudioNotifyPatternResource.ButtonLeaveFeedback;
var owner = userManager.GetUsers(tenant.OwnerId);
greenButtonUrl = setupInfo.TeamlabSiteRedirect + "/remove-portal-feedback-form.aspx#" +
var owner = _userManager.GetUsers(tenant.OwnerId);
greenButtonUrl = _setupInfo.TeamlabSiteRedirect + "/remove-portal-feedback-form.aspx#" +
System.Web.HttpUtility.UrlEncode(Convert.ToBase64String(
System.Text.Encoding.UTF8.GetBytes("{\"firstname\":\"" + owner.FirstName +
"\",\"lastname\":\"" + owner.LastName +
@ -380,11 +426,11 @@ namespace ASC.Web.Studio.Core.Notify
}
else if (tariff.State == TariffState.NotPaid && dueDateIsNotMax && dueDate.AddMonths(6).AddDays(7) <= nowDate)
{
tenantManager.RemoveTenant(tenant.Id, true);
_tenantManager.RemoveTenant(tenant.Id, true);
if (!string.IsNullOrEmpty(apiSystemHelper.ApiCacheUrl))
if (!string.IsNullOrEmpty(_apiSystemHelper.ApiCacheUrl))
{
await apiSystemHelper.RemoveTenantFromCacheAsync(tenant.Alias, authContext.CurrentAccount.ID);
await _apiSystemHelper.RemoveTenantFromCacheAsync(tenant.Alias, _authContext.CurrentAccount.ID);
}
}
@ -397,23 +443,23 @@ namespace ASC.Web.Studio.Core.Notify
if (action == null) continue;
var users = toowner
? new List<UserInfo> { userManager.GetUsers(tenant.OwnerId) }
: studioNotifyHelper.GetRecipients(toadmins, tousers, false);
? new List<UserInfo> { _userManager.GetUsers(tenant.OwnerId) }
: _studioNotifyHelper.GetRecipients(toadmins, tousers, false);
foreach (var u in users.Where(u => paymentMessage || studioNotifyHelper.IsSubscribedToNotify(u, Actions.PeriodicNotify)))
foreach (var u in users.Where(u => paymentMessage || _studioNotifyHelper.IsSubscribedToNotify(u, Actions.PeriodicNotify)))
{
var culture = string.IsNullOrEmpty(u.CultureName) ? tenant.GetCulture() : u.GetCulture();
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
var rquota = tenantExtra.GetRightQuota() ?? TenantQuota.Default;
var rquota = _tenantExtra.GetRightQuota() ?? TenantQuota.Default;
client.SendNoticeToAsync(
action,
new[] { studioNotifyHelper.ToRecipient(u.Id) },
new[] { _studioNotifyHelper.ToRecipient(u.Id) },
new[] { senderName },
new TagValue(Tags.UserName, u.FirstName.HtmlEncode()),
new TagValue(Tags.PricingPage, commonLinkUtility.GetFullAbsolutePath("~/tariffs.aspx")),
new TagValue(Tags.ActiveUsers, userManager.GetUsers().Length),
new TagValue(Tags.PricingPage, _commonLinkUtility.GetFullAbsolutePath("~/tariffs.aspx")),
new TagValue(Tags.ActiveUsers, _userManager.GetUsers().Length),
new TagValue(Tags.Price, rquota.Price),
new TagValue(Tags.PricePeriod, rquota.Year3 ? UserControlsCommonResource.TariffPerYear3 : rquota.Year ? UserControlsCommonResource.TariffPerYear : UserControlsCommonResource.TariffPerMonth),
new TagValue(Tags.DueDate, dueDate.ToLongDateString()),
@ -429,17 +475,17 @@ namespace ASC.Web.Studio.Core.Notify
TagValues.TableItem(6, tableItemText6, tableItemUrl6, tableItemImg6, tableItemComment6, tableItemLearnMoreText6, tableItemLearnMoreUrl6),
TagValues.TableItem(7, tableItemText7, tableItemUrl7, tableItemImg7, tableItemComment7, tableItemLearnMoreText7, tableItemLearnMoreUrl7),
TagValues.TableBottom(),
new TagValue(CommonTags.Footer, u.IsAdmin(userManager) ? "common" : "social"),
new TagValue(CommonTags.Footer, u.IsAdmin(_userManager) ? "common" : "social"),
new TagValue(Tags.Coupon, coupon));
}
}
catch (Exception err)
{
Log.Error(err);
_log.Error(err);
}
}
Log.Info("End SendSaasTariffLetters");
_log.Info("End SendSaasTariffLetters");
}
public void SendEnterpriseLetters(string senderName, DateTime scheduleDate)
@ -447,36 +493,26 @@ namespace ASC.Web.Studio.Core.Notify
var nowDate = scheduleDate.Date;
const string dbid = "webstudio";
Log.Info("Start SendTariffEnterpriseLetters");
_log.Info("Start SendTariffEnterpriseLetters");
List<Tenant> activeTenants;
using (var scope = ServiceProvider.CreateScope())
{
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
activeTenants = tenantManager.GetTenants().ToList();
if (activeTenants.Count <= 0)
{
Log.Info("End SendTariffEnterpriseLetters");
return;
}
var activeTenants = _tenantManager.GetTenants().ToList();
if (activeTenants.Count <= 0)
{
_log.Info("End SendTariffEnterpriseLetters");
return;
}
foreach (var tenant in activeTenants)
{
try
{
using var scope = ServiceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<StudioPeriodicNotifyScope>();
var (tenantManager, userManager, studioNotifyHelper, paymentManager, tenantExtra, _, commonLinkUtility, _, _, dbContextManager, _, configuration, settingsManager, coreBaseSettings, _, _, _) = scopeClass;
var defaultRebranding = MailWhiteLabelSettings.IsDefault(settingsManager, configuration);
tenantManager.SetCurrentTenant(tenant.Id);
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifyHelper.NotifySource, scope);
var defaultRebranding = MailWhiteLabelSettings.IsDefault(_settingsManager);
_tenantManager.SetCurrentTenant(tenant.Id);
var client = _workContext.NotifyContext.RegisterClient(_notifyEngineQueue, _studioNotifyHelper.NotifySource);
var tariff = paymentManager.GetTariff(tenant.Id);
var quota = tenantManager.GetTenantQuota(tenant.Id);
var tariff = _paymentManager.GetTariff(tenant.Id);
var quota = _tenantManager.GetTenantQuota(tenant.Id);
var createdDate = tenant.CreationDateTime.Date;
var actualEndDate = tariff.DueDate != DateTime.MaxValue ? tariff.DueDate : tariff.LicenseDate;
@ -564,42 +600,42 @@ namespace ASC.Web.Studio.Core.Notify
paymentMessage = false;
toadmins = true;
tableItemImg1 = studioNotifyHelper.GetNotificationImageUrl("tips-customize-brand-100.png");
tableItemImg1 = _studioNotifyHelper.GetNotificationImageUrl("tips-customize-brand-100.png");
tableItemText1 = () => WebstudioNotifyPatternResource.pattern_enterprise_admin_customize_portal_v10_item_brand_hdr;
tableItemComment1 = () => WebstudioNotifyPatternResource.pattern_enterprise_admin_customize_portal_v10_item_brand;
tableItemImg2 = studioNotifyHelper.GetNotificationImageUrl("tips-customize-regional-100.png");
tableItemImg2 = _studioNotifyHelper.GetNotificationImageUrl("tips-customize-regional-100.png");
tableItemText2 = () => WebstudioNotifyPatternResource.pattern_enterprise_admin_customize_portal_v10_item_regional_hdr;
tableItemComment2 = () => WebstudioNotifyPatternResource.pattern_enterprise_admin_customize_portal_v10_item_regional;
tableItemImg3 = studioNotifyHelper.GetNotificationImageUrl("tips-customize-customize-100.png");
tableItemImg3 = _studioNotifyHelper.GetNotificationImageUrl("tips-customize-customize-100.png");
tableItemText3 = () => WebstudioNotifyPatternResource.pattern_enterprise_admin_customize_portal_v10_item_customize_hdr;
tableItemComment3 = () => WebstudioNotifyPatternResource.pattern_enterprise_admin_customize_portal_v10_item_customize;
tableItemImg4 = studioNotifyHelper.GetNotificationImageUrl("tips-customize-modules-100.png");
tableItemImg4 = _studioNotifyHelper.GetNotificationImageUrl("tips-customize-modules-100.png");
tableItemText4 = () => WebstudioNotifyPatternResource.pattern_enterprise_admin_customize_portal_v10_item_modules_hdr;
tableItemComment4 = () => WebstudioNotifyPatternResource.pattern_enterprise_admin_customize_portal_v10_item_modules;
tableItemImg5 = studioNotifyHelper.GetNotificationImageUrl("tips-customize-3rdparty-100.png");
tableItemImg5 = _studioNotifyHelper.GetNotificationImageUrl("tips-customize-3rdparty-100.png");
tableItemText5 = () => WebstudioNotifyPatternResource.pattern_enterprise_admin_customize_portal_v10_item_3rdparty_hdr;
tableItemComment5 = () => WebstudioNotifyPatternResource.pattern_enterprise_admin_customize_portal_v10_item_3rdparty;
greenButtonText = () => WebstudioNotifyPatternResource.ButtonConfigureRightNow;
greenButtonUrl = commonLinkUtility.GetFullAbsolutePath(commonLinkUtility.GetAdministration(ManagementType.General));
greenButtonUrl = _commonLinkUtility.GetFullAbsolutePath(_commonLinkUtility.GetAdministration(ManagementType.General));
}
#endregion
#region 4 days after registration to admins ENTERPRISE TRIAL + only 1 user + defaultRebranding
else if (createdDate.AddDays(4) == nowDate && userManager.GetUsers().Length == 1)
else if (createdDate.AddDays(4) == nowDate && _userManager.GetUsers().Length == 1)
{
action = Actions.EnterpriseAdminInviteTeammatesV10;
paymentMessage = false;
toadmins = true;
greenButtonText = () => WebstudioNotifyPatternResource.ButtonInviteRightNow;
greenButtonUrl = $"{commonLinkUtility.GetFullAbsolutePath("~").TrimEnd('/')}/products/people/";
greenButtonUrl = $"{_commonLinkUtility.GetFullAbsolutePath("~").TrimEnd('/')}/products/people/";
}
#endregion
@ -611,8 +647,8 @@ namespace ASC.Web.Studio.Core.Notify
List<DateTime> datesWithActivity;
datesWithActivity =
dbContextManager.Get(dbid).FeedAggregates
.Where(r => r.Tenant == tenantManager.GetCurrentTenant().Id)
_dbContextManager.Get(dbid).FeedAggregates
.Where(r => r.Tenant == _tenantManager.GetCurrentTenant().Id)
.Where(r => r.CreatedDate <= nowDate.AddDays(-1))
.GroupBy(r => r.CreatedDate.Date)
.Select(r => r.Key)
@ -637,42 +673,42 @@ namespace ASC.Web.Studio.Core.Notify
toadmins = true;
tousers = true;
tableItemImg1 = studioNotifyHelper.GetNotificationImageUrl("tips-documents-formatting-100.png");
tableItemImg1 = _studioNotifyHelper.GetNotificationImageUrl("tips-documents-formatting-100.png");
tableItemText1 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_formatting_hdr;
tableItemComment1 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_formatting;
if (!coreBaseSettings.CustomMode)
if (!_coreBaseSettings.CustomMode)
{
tableItemLearnMoreUrl1 = studioNotifyHelper.Helplink + "/onlyoffice-editors/index.aspx";
tableItemLearnMoreUrl1 = _studioNotifyHelper.Helplink + "/onlyoffice-editors/index.aspx";
tableItemLearnMoreText1 = () => WebstudioNotifyPatternResource.LinkLearnMore;
}
tableItemImg2 = studioNotifyHelper.GetNotificationImageUrl("tips-documents-share-100.png");
tableItemImg2 = _studioNotifyHelper.GetNotificationImageUrl("tips-documents-share-100.png");
tableItemText2 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_share_hdr;
tableItemComment2 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_share;
tableItemImg3 = studioNotifyHelper.GetNotificationImageUrl("tips-documents-coediting-100.png");
tableItemImg3 = _studioNotifyHelper.GetNotificationImageUrl("tips-documents-coediting-100.png");
tableItemText3 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_coediting_hdr;
tableItemComment3 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_coediting;
tableItemImg4 = studioNotifyHelper.GetNotificationImageUrl("tips-documents-review-100.png");
tableItemImg4 = _studioNotifyHelper.GetNotificationImageUrl("tips-documents-review-100.png");
tableItemText4 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_review_hdr;
tableItemComment4 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_review;
tableItemImg5 = studioNotifyHelper.GetNotificationImageUrl("tips-documents-3rdparty-100.png");
tableItemImg5 = _studioNotifyHelper.GetNotificationImageUrl("tips-documents-3rdparty-100.png");
tableItemText5 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_3rdparty_hdr;
tableItemComment5 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_3rdparty;
tableItemImg6 = studioNotifyHelper.GetNotificationImageUrl("tips-documents-attach-100.png");
tableItemImg6 = _studioNotifyHelper.GetNotificationImageUrl("tips-documents-attach-100.png");
tableItemText6 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_attach_hdr;
tableItemComment6 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_attach;
tableItemImg7 = studioNotifyHelper.GetNotificationImageUrl("tips-documents-apps-100.png");
tableItemImg7 = _studioNotifyHelper.GetNotificationImageUrl("tips-documents-apps-100.png");
tableItemText7 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_apps_hdr;
tableItemComment7 = () => WebstudioNotifyPatternResource.pattern_saas_admin_user_docs_tips_v115_item_apps;
greenButtonText = () => WebstudioNotifyPatternResource.ButtonAccessYouWebOffice;
greenButtonUrl = $"{commonLinkUtility.GetFullAbsolutePath("~").TrimEnd('/')}/products/files/";
greenButtonUrl = $"{_commonLinkUtility.GetFullAbsolutePath("~").TrimEnd('/')}/products/files/";
}
#endregion
@ -730,31 +766,31 @@ namespace ASC.Web.Studio.Core.Notify
paymentMessage = false;
toadmins = true;
tableItemImg1 = studioNotifyHelper.GetNotificationImageUrl("tips-customize-brand-100.png");
tableItemImg1 = _studioNotifyHelper.GetNotificationImageUrl("tips-customize-brand-100.png");
tableItemText1 = () => WebstudioNotifyPatternResource.pattern_enterprise_admin_customize_portal_v10_item_brand_hdr;
tableItemComment1 = () => WebstudioNotifyPatternResource.pattern_enterprise_admin_customize_portal_v10_item_brand;
tableItemImg2 = studioNotifyHelper.GetNotificationImageUrl("tips-customize-regional-100.png");
tableItemImg2 = _studioNotifyHelper.GetNotificationImageUrl("tips-customize-regional-100.png");
tableItemText2 = () => WebstudioNotifyPatternResource.pattern_enterprise_admin_customize_portal_v10_item_regional_hdr;
tableItemComment2 = () => WebstudioNotifyPatternResource.pattern_enterprise_admin_customize_portal_v10_item_regional;
tableItemImg3 = studioNotifyHelper.GetNotificationImageUrl("tips-customize-customize-100.png");
tableItemImg3 = _studioNotifyHelper.GetNotificationImageUrl("tips-customize-customize-100.png");
tableItemText3 = () => WebstudioNotifyPatternResource.pattern_enterprise_admin_customize_portal_v10_item_customize_hdr;
tableItemComment3 = () => WebstudioNotifyPatternResource.pattern_enterprise_admin_customize_portal_v10_item_customize;
tableItemImg4 = studioNotifyHelper.GetNotificationImageUrl("tips-customize-modules-100.png");
tableItemImg4 = _studioNotifyHelper.GetNotificationImageUrl("tips-customize-modules-100.png");
tableItemText4 = () => WebstudioNotifyPatternResource.pattern_enterprise_admin_customize_portal_v10_item_modules_hdr;
tableItemComment4 = () => WebstudioNotifyPatternResource.pattern_enterprise_admin_customize_portal_v10_item_modules;
if (!coreBaseSettings.CustomMode)
if (!_coreBaseSettings.CustomMode)
{
tableItemImg5 = studioNotifyHelper.GetNotificationImageUrl("tips-customize-3rdparty-100.png");
tableItemImg5 = _studioNotifyHelper.GetNotificationImageUrl("tips-customize-3rdparty-100.png");
tableItemText5 = () => WebstudioNotifyPatternResource.pattern_enterprise_admin_customize_portal_v10_item_3rdparty_hdr;
tableItemComment5 = () => WebstudioNotifyPatternResource.pattern_enterprise_admin_customize_portal_v10_item_3rdparty;
}
greenButtonText = () => WebstudioNotifyPatternResource.ButtonConfigureRightNow;
greenButtonUrl = commonLinkUtility.GetFullAbsolutePath(commonLinkUtility.GetAdministration(ManagementType.General));
greenButtonUrl = _commonLinkUtility.GetFullAbsolutePath(_commonLinkUtility.GetAdministration(ManagementType.General));
}
#endregion
@ -774,7 +810,7 @@ namespace ASC.Web.Studio.Core.Notify
: Actions.EnterpriseWhitelabelAdminPaymentWarningBefore7V10;
toadmins = true;
greenButtonText = () => WebstudioNotifyPatternResource.ButtonSelectPricingPlans;
greenButtonUrl = commonLinkUtility.GetFullAbsolutePath("~/tariffs.aspx");
greenButtonUrl = _commonLinkUtility.GetFullAbsolutePath("~/tariffs.aspx");
}
#endregion
@ -788,7 +824,7 @@ namespace ASC.Web.Studio.Core.Notify
: Actions.EnterpriseWhitelabelAdminPaymentWarningV10;
toadmins = true;
greenButtonText = () => WebstudioNotifyPatternResource.ButtonSelectPricingPlans;
greenButtonUrl = commonLinkUtility.GetFullAbsolutePath("~/tariffs.aspx");
greenButtonUrl = _commonLinkUtility.GetFullAbsolutePath("~/tariffs.aspx");
}
#endregion
@ -799,23 +835,23 @@ namespace ASC.Web.Studio.Core.Notify
if (action == null) continue;
var users = studioNotifyHelper.GetRecipients(toadmins, tousers, false);
var users = _studioNotifyHelper.GetRecipients(toadmins, tousers, false);
foreach (var u in users.Where(u => paymentMessage || studioNotifyHelper.IsSubscribedToNotify(u, Actions.PeriodicNotify)))
foreach (var u in users.Where(u => paymentMessage || _studioNotifyHelper.IsSubscribedToNotify(u, Actions.PeriodicNotify)))
{
var culture = string.IsNullOrEmpty(u.CultureName) ? tenant.GetCulture() : u.GetCulture();
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
var rquota = tenantExtra.GetRightQuota() ?? TenantQuota.Default;
var rquota = _tenantExtra.GetRightQuota() ?? TenantQuota.Default;
client.SendNoticeToAsync(
action,
new[] { studioNotifyHelper.ToRecipient(u.Id) },
new[] { _studioNotifyHelper.ToRecipient(u.Id) },
new[] { senderName },
new TagValue(Tags.UserName, u.FirstName.HtmlEncode()),
new TagValue(Tags.PricingPage, commonLinkUtility.GetFullAbsolutePath("~/tariffs.aspx")),
new TagValue(Tags.ActiveUsers, userManager.GetUsers().Length),
new TagValue(Tags.PricingPage, _commonLinkUtility.GetFullAbsolutePath("~/tariffs.aspx")),
new TagValue(Tags.ActiveUsers, _userManager.GetUsers().Length),
new TagValue(Tags.Price, rquota.Price),
new TagValue(Tags.PricePeriod, rquota.Year3 ? UserControlsCommonResource.TariffPerYear3 : rquota.Year ? UserControlsCommonResource.TariffPerYear : UserControlsCommonResource.TariffPerMonth),
new TagValue(Tags.DueDate, dueDate.ToLongDateString()),
@ -835,43 +871,33 @@ namespace ASC.Web.Studio.Core.Notify
}
catch (Exception err)
{
Log.Error(err);
_log.Error(err);
}
}
Log.Info("End SendTariffEnterpriseLetters");
_log.Info("End SendTariffEnterpriseLetters");
}
public void SendOpensourceLetters(string senderName, DateTime scheduleDate)
{
var nowDate = scheduleDate.Date;
Log.Info("Start SendOpensourceTariffLetters");
_log.Info("Start SendOpensourceTariffLetters");
List<Tenant> activeTenants;
using (var scope = ServiceProvider.CreateScope())
{
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
activeTenants = tenantManager.GetTenants().ToList();
if (activeTenants.Count <= 0)
{
Log.Info("End SendOpensourceTariffLetters");
return;
}
var activeTenants = _tenantManager.GetTenants().ToList();
if (activeTenants.Count <= 0)
{
_log.Info("End SendOpensourceTariffLetters");
return;
}
foreach (var tenant in activeTenants)
{
try
{
using var scope = ServiceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<StudioPeriodicNotifyScope>();
var (tenantManager, userManager, studioNotifyHelper, _, _, _, _, _, _, _, _, _, _, _, displayUserSettingsHelper, _, _) = scopeClass;
tenantManager.SetCurrentTenant(tenant.Id);
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifyHelper.NotifySource, scope);
_tenantManager.SetCurrentTenant(tenant.Id);
var client = _workContext.NotifyContext.RegisterClient(_notifyEngineQueue, _studioNotifyHelper.NotifySource);
var createdDate = tenant.CreationDateTime.Date;
@ -882,20 +908,20 @@ namespace ASC.Web.Studio.Core.Notify
if (createdDate.AddDays(5) == nowDate)
{
var users = studioNotifyHelper.GetRecipients(true, true, false);
var users = _studioNotifyHelper.GetRecipients(true, true, false);
foreach (var u in users.Where(u => studioNotifyHelper.IsSubscribedToNotify(u, Actions.PeriodicNotify)))
foreach (var u in users.Where(u => _studioNotifyHelper.IsSubscribedToNotify(u, Actions.PeriodicNotify)))
{
var culture = string.IsNullOrEmpty(u.CultureName) ? tenant.GetCulture() : u.GetCulture();
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
client.SendNoticeToAsync(
u.IsAdmin(userManager) ? Actions.OpensourceAdminDocsTipsV11 : Actions.OpensourceUserDocsTipsV11,
new[] { studioNotifyHelper.ToRecipient(u.Id) },
u.IsAdmin(_userManager) ? Actions.OpensourceAdminDocsTipsV11 : Actions.OpensourceUserDocsTipsV11,
new[] { _studioNotifyHelper.ToRecipient(u.Id) },
new[] { senderName },
new TagValue(Tags.UserName, u.DisplayUserName(displayUserSettingsHelper)),
new TagValue(Tags.UserName, u.DisplayUserName(_displayUserSettingsHelper)),
new TagValue(CommonTags.Footer, "opensource"));
}
}
@ -905,26 +931,18 @@ namespace ASC.Web.Studio.Core.Notify
}
catch (Exception err)
{
Log.Error(err);
_log.Error(err);
}
}
Log.Info("End SendOpensourceTariffLetters");
_log.Info("End SendOpensourceTariffLetters");
}
public void SendPersonalLetters(string senderName, DateTime scheduleDate)
{
Log.Info("Start SendLettersPersonal...");
_log.Info("Start SendLettersPersonal...");
List<Tenant> activeTenants;
using (var scope = ServiceProvider.CreateScope())
{
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
activeTenants = tenantManager.GetTenants().ToList();
}
var activeTenants = _tenantManager.GetTenants().ToList();
foreach (var tenant in activeTenants)
{
@ -935,22 +953,18 @@ namespace ASC.Web.Studio.Core.Notify
var sendCount = 0;
using var scope = ServiceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<StudioPeriodicNotifyScope>();
var (tenantManager, userManager, studioNotifyHelper, _, _, _, _, _, _, _, _, _, _, coreBaseSettings, _, authManager, securityContext) = scopeClass;
_tenantManager.SetCurrentTenant(tenant.Id);
var client = _workContext.NotifyContext.RegisterClient(_notifyEngineQueue, _studioNotifyHelper.NotifySource);
tenantManager.SetCurrentTenant(tenant.Id);
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifyHelper.NotifySource, scope);
_log.InfoFormat("Current tenant: {0}", tenant.Id);
Log.InfoFormat("Current tenant: {0}", tenant.Id);
var users = _userManager.GetUsers(EmployeeStatus.Active);
var users = userManager.GetUsers(EmployeeStatus.Active);
foreach (var user in users.Where(u => studioNotifyHelper.IsSubscribedToNotify(u, Actions.PeriodicNotify)))
foreach (var user in users.Where(u => _studioNotifyHelper.IsSubscribedToNotify(u, Actions.PeriodicNotify)))
{
INotifyAction action;
securityContext.AuthenticateMeWithoutCookie(authManager.GetAccountByID(tenant.Id, user.Id));
_securityContext.AuthenticateMeWithoutCookie(_authManager.GetAccountByID(tenant.Id, user.Id));
var culture = tenant.GetCulture();
if (!string.IsNullOrEmpty(user.CultureName))
@ -962,7 +976,7 @@ namespace ASC.Web.Studio.Core.Notify
catch (CultureNotFoundException exception)
{
Log.Error(exception);
_log.Error(exception);
}
}
@ -971,7 +985,7 @@ namespace ASC.Web.Studio.Core.Notify
var dayAfterRegister = (int)scheduleDate.Date.Subtract(user.CreateDate.Date).TotalDays;
if (coreBaseSettings.CustomMode)
if (_coreBaseSettings.CustomMode)
{
switch (dayAfterRegister)
{
@ -1008,7 +1022,7 @@ namespace ASC.Web.Studio.Core.Notify
if (action == null) continue;
Log.InfoFormat(@"Send letter personal '{1}' to {0} culture {2}. tenant id: {3} user culture {4} create on {5} now date {6}",
_log.InfoFormat(@"Send letter personal '{1}' to {0} culture {2}. tenant id: {3} user culture {4} create on {5} now date {6}",
user.Email, action.ID, culture, tenant.Id, user.GetCulture(), user.CreateDate, scheduleDate.Date);
sendCount++;
@ -1016,23 +1030,23 @@ namespace ASC.Web.Studio.Core.Notify
client.SendNoticeToAsync(
action,
null,
studioNotifyHelper.RecipientFromEmail(user.Email, true),
_studioNotifyHelper.RecipientFromEmail(user.Email, true),
new[] { senderName },
TagValues.PersonalHeaderStart(),
TagValues.PersonalHeaderEnd(),
TagValues.GreenButton(greenButtonText, greenButtonUrl),
new TagValue(CommonTags.Footer, coreBaseSettings.CustomMode ? "personalCustomMode" : "personal"));
new TagValue(CommonTags.Footer, _coreBaseSettings.CustomMode ? "personalCustomMode" : "personal"));
}
Log.InfoFormat("Total send count: {0}", sendCount);
_log.InfoFormat("Total send count: {0}", sendCount);
}
catch (Exception err)
{
Log.Error(err);
_log.Error(err);
}
}
Log.Info("End SendLettersPersonal.");
_log.Info("End SendLettersPersonal.");
}
public static bool ChangeSubscription(Guid userId, StudioNotifyHelper studioNotifyHelper)
@ -1046,108 +1060,4 @@ namespace ASC.Web.Studio.Core.Notify
return !isSubscribe;
}
}
[Scope]
public class StudioPeriodicNotifyScope
{
private TenantManager TenantManager { get; }
private UserManager UserManager { get; }
private StudioNotifyHelper StudioNotifyHelper { get; }
private PaymentManager PaymentManager { get; }
private TenantExtra TenantExtra { get; }
private AuthContext AuthContext { get; }
private CommonLinkUtility CommonLinkUtility { get; }
private ApiSystemHelper ApiSystemHelper { get; }
private SetupInfo SetupInfo { get; }
private DbContextManager<FeedDbContext> DbContextManager { get; }
private CouponManager CouponManager { get; }
private IConfiguration Configuration { get; }
private SettingsManager SettingsManager { get; }
private CoreBaseSettings CoreBaseSettings { get; }
private DisplayUserSettingsHelper DisplayUserSettingsHelper { get; }
private AuthManager AuthManager { get; }
private SecurityContext SecurityContext { get; }
public StudioPeriodicNotifyScope(TenantManager tenantManager,
UserManager userManager,
StudioNotifyHelper studioNotifyHelper,
PaymentManager paymentManager,
TenantExtra tenantExtra,
AuthContext authContext,
CommonLinkUtility commonLinkUtility,
ApiSystemHelper apiSystemHelper,
SetupInfo setupInfo,
DbContextManager<FeedDbContext> dbContextManager,
CouponManager couponManager,
IConfiguration configuration,
SettingsManager settingsManager,
CoreBaseSettings coreBaseSettings,
DisplayUserSettingsHelper displayUserSettingsHelper,
AuthManager authManager,
SecurityContext securityContext)
{
TenantManager = tenantManager;
UserManager = userManager;
StudioNotifyHelper = studioNotifyHelper;
PaymentManager = paymentManager;
TenantExtra = tenantExtra;
AuthContext = authContext;
CommonLinkUtility = commonLinkUtility;
ApiSystemHelper = apiSystemHelper;
SetupInfo = setupInfo;
DbContextManager = dbContextManager;
CouponManager = couponManager;
Configuration = configuration;
SettingsManager = settingsManager;
CoreBaseSettings = coreBaseSettings;
DisplayUserSettingsHelper = displayUserSettingsHelper;
AuthManager = authManager;
SecurityContext = securityContext;
}
public void Deconstruct(out TenantManager tenantManager,
out UserManager userManager,
out StudioNotifyHelper studioNotifyHelper,
out PaymentManager paymentManager,
out TenantExtra tenantExtra,
out AuthContext authContext,
out CommonLinkUtility commonLinkUtility,
out ApiSystemHelper apiSystemHelper,
out SetupInfo setupInfo,
out DbContextManager<FeedDbContext> dbContextManager,
out CouponManager couponManager,
out IConfiguration configuration,
out SettingsManager settingsManager,
out CoreBaseSettings coreBaseSettings,
out DisplayUserSettingsHelper displayUserSettingsHelper,
out AuthManager authManager,
out SecurityContext securityContext)
{
tenantManager = TenantManager;
userManager = UserManager;
studioNotifyHelper = StudioNotifyHelper;
paymentManager = PaymentManager;
tenantExtra = TenantExtra;
authContext = AuthContext;
commonLinkUtility = CommonLinkUtility;
apiSystemHelper = ApiSystemHelper;
setupInfo = SetupInfo;
dbContextManager = DbContextManager;
couponManager = CouponManager;
configuration = Configuration;
settingsManager = SettingsManager;
coreBaseSettings = CoreBaseSettings;
displayUserSettingsHelper = DisplayUserSettingsHelper;
authManager = AuthManager;
securityContext = SecurityContext;
}
}
public static class StudioPeriodicNotifyExtension
{
public static void Register(DIHelper services)
{
services.TryAdd<StudioPeriodicNotifyScope>();
}
}
}

View File

@ -26,174 +26,222 @@
namespace ASC.Web.Studio.Core.Notify
{
[Singletone(Additional = typeof(StudioWhatsNewNotifyExtension))]
[Scope]
public class StudioWhatsNewNotify
{
private IServiceProvider ServiceProvider { get; }
public IConfiguration Confuguration { get; }
private readonly IMapper _mapper;
{
private readonly ILog _log;
private readonly WebItemManager _webItemManager;
private readonly TenantManager _tenantManager;
private readonly PaymentManager _paymentManager;
private readonly TenantUtil _tenantUtil;
private readonly StudioNotifyHelper _studioNotifyHelper;
private readonly UserManager _userManager;
private readonly SecurityContext _securityContext;
private readonly AuthManager _authManager;
private readonly CommonLinkUtility _commonLinkUtility;
private readonly DisplayUserSettingsHelper _displayUserSettingsHelper;
private readonly FeedAggregateDataProvider _feedAggregateDataProvider;
private readonly CoreSettings _coreSettings;
private readonly NotifyEngineQueue _notifyEngineQueue;
private readonly IConfiguration _confuguration;
private readonly WorkContext _workContext;
private readonly IMapper _mapper;
public StudioWhatsNewNotify(IServiceProvider serviceProvider, IConfiguration confuguration,
IMapper mapper)
{
ServiceProvider = serviceProvider;
Confuguration = confuguration;
_mapper = mapper;
public StudioWhatsNewNotify(
TenantManager tenantManager,
PaymentManager paymentManager,
TenantUtil tenantUtil,
StudioNotifyHelper studioNotifyHelper,
UserManager userManager,
SecurityContext securityContext,
AuthManager authManager,
CommonLinkUtility commonLinkUtility,
DisplayUserSettingsHelper displayUserSettingsHelper,
FeedAggregateDataProvider feedAggregateDataProvider,
CoreSettings coreSettings,
NotifyEngineQueue notifyEngineQueue,
IConfiguration confuguration,
WorkContext workContext,
IOptionsMonitor<ILog> optionsMonitor,
IMapper mapper,
WebItemManager webItemManager)
{
_webItemManager = webItemManager;
_tenantManager = tenantManager;
_paymentManager = paymentManager;
_tenantUtil = tenantUtil;
_studioNotifyHelper = studioNotifyHelper;
_userManager = userManager;
_securityContext = securityContext;
_authManager = authManager;
_commonLinkUtility = commonLinkUtility;
_displayUserSettingsHelper = displayUserSettingsHelper;
_feedAggregateDataProvider = feedAggregateDataProvider;
_coreSettings = coreSettings;
_notifyEngineQueue = notifyEngineQueue;
_confuguration = confuguration;
_workContext = workContext;
_mapper = mapper;
_log = optionsMonitor.Get("ASC.Notify");
}
public void SendMsgWhatsNew(DateTime scheduleDate)
{
var log = ServiceProvider.GetService<IOptionsMonitor<ILog>>().Get("ASC.Notify");
var WebItemManager = ServiceProvider.GetService<WebItemManager>();
if (WebItemManager.GetItemsAll<IProduct>().Count == 0)
if (_webItemManager.GetItemsAll<IProduct>().Count == 0)
{
log.Info("No products. Return from function");
_log.Info("No products. Return from function");
return;
}
log.Info("Start send whats new.");
_log.Info("Start send whats new.");
var products = WebItemManager.GetItemsAll().ToDictionary(p => p.GetSysName());
foreach (var tenantid in GetChangedTenants(ServiceProvider.GetService<FeedAggregateDataProvider>(), scheduleDate))
{
try
{
using var scope = ServiceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<StudioWhatsNewNotifyScope>();
var (tenantManager, paymentManager, tenantUtil, studioNotifyHelper, userManager, securityContext, authContext, authManager, commonLinkUtility, displayUserSettingsHelper, feedAggregateDataProvider, coreSettings) = scopeClass;
var tenant = tenantManager.GetTenant(tenantid);
if (tenant == null ||
tenant.Status != TenantStatus.Active ||
!TimeToSendWhatsNew(tenantUtil.DateTimeFromUtc(tenant.TimeZone, scheduleDate)) ||
TariffState.NotPaid <= paymentManager.GetTariff(tenantid).State)
{
continue;
}
tenantManager.SetCurrentTenant(tenant);
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifyHelper.NotifySource, scope);
log.InfoFormat("Start send whats new in {0} ({1}).", tenant.GetTenantDomain(coreSettings), tenantid);
foreach (var user in userManager.GetUsers())
{
if (!studioNotifyHelper.IsSubscribedToNotify(user, Actions.SendWhatsNew))
{
continue;
}
securityContext.AuthenticateMeWithoutCookie(authManager.GetAccountByID(tenant.Id, user.Id));
var culture = string.IsNullOrEmpty(user.CultureName) ? tenant.GetCulture() : user.GetCulture();
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
var feeds = feedAggregateDataProvider.GetFeeds(new FeedApiFilter
{
From = scheduleDate.Date.AddDays(-1),
To = scheduleDate.Date.AddSeconds(-1),
Max = 100,
});
var feedMinWrappers = _mapper.Map<List<FeedResultItem>, List<FeedMin>>(feeds);
var feedMinGroupedWrappers = feedMinWrappers
.Where(f =>
(f.CreatedDate == DateTime.MaxValue || f.CreatedDate >= scheduleDate.Date.AddDays(-1)) && //'cause here may be old posts with new comments
products.ContainsKey(f.Product) &&
!f.Id.StartsWith("participant")
)
.GroupBy(f => products[f.Product]);
var ProjectsProductName = products["projects"]?.Name; //from ASC.Feed.Aggregator.Modules.ModulesHelper.ProjectsProductName
var activities = feedMinGroupedWrappers
.Where(f => f.Key.Name != ProjectsProductName) //not for project product
.ToDictionary(
g => g.Key.Name,
g => g.Select(f => new WhatsNewUserActivity
{
Date = f.CreatedDate,
UserName = f.Author != null && f.Author.UserInfo != null ? f.Author.UserInfo.DisplayUserName(displayUserSettingsHelper) : string.Empty,
UserAbsoluteURL = f.Author != null && f.Author.UserInfo != null ? commonLinkUtility.GetFullAbsolutePath(f.Author.UserInfo.GetUserProfilePageURL(commonLinkUtility)) : string.Empty,
Title = HtmlUtil.GetText(f.Title, 512),
URL = commonLinkUtility.GetFullAbsolutePath(f.ItemUrl),
BreadCrumbs = Array.Empty<string>(),
Action = GetWhatsNewActionText(f)
}).ToList());
var projectActivities = feedMinGroupedWrappers
.Where(f => f.Key.Name == ProjectsProductName) // for project product
.SelectMany(f => f);
var projectActivitiesWithoutBreadCrumbs = projectActivities.Where(p => string.IsNullOrEmpty(p.ExtraLocation));
var whatsNewUserActivityGroupByPrjs = new List<WhatsNewUserActivity>();
foreach (var prawbc in projectActivitiesWithoutBreadCrumbs)
{
whatsNewUserActivityGroupByPrjs.Add(
new WhatsNewUserActivity
{
Date = prawbc.CreatedDate,
UserName = prawbc.Author != null && prawbc.Author.UserInfo != null ? prawbc.Author.UserInfo.DisplayUserName(displayUserSettingsHelper) : string.Empty,
UserAbsoluteURL = prawbc.Author != null && prawbc.Author.UserInfo != null ? commonLinkUtility.GetFullAbsolutePath(prawbc.Author.UserInfo.GetUserProfilePageURL(commonLinkUtility)) : string.Empty,
Title = HtmlUtil.GetText(prawbc.Title, 512),
URL = commonLinkUtility.GetFullAbsolutePath(prawbc.ItemUrl),
BreadCrumbs = Array.Empty<string>(),
Action = GetWhatsNewActionText(prawbc)
});
}
var groupByPrjs = projectActivities.Where(p => !string.IsNullOrEmpty(p.ExtraLocation)).GroupBy(f => f.ExtraLocation);
foreach (var gr in groupByPrjs)
{
var grlist = gr.ToList();
for (var i = 0; i < grlist.Count; i++)
{
var ls = grlist[i];
whatsNewUserActivityGroupByPrjs.Add(
new WhatsNewUserActivity
{
Date = ls.CreatedDate,
UserName = ls.Author != null && ls.Author.UserInfo != null ? ls.Author.UserInfo.DisplayUserName(displayUserSettingsHelper) : string.Empty,
UserAbsoluteURL = ls.Author != null && ls.Author.UserInfo != null ? commonLinkUtility.GetFullAbsolutePath(ls.Author.UserInfo.GetUserProfilePageURL(commonLinkUtility)) : string.Empty,
Title = HtmlUtil.GetText(ls.Title, 512),
URL = commonLinkUtility.GetFullAbsolutePath(ls.ItemUrl),
BreadCrumbs = i == 0 ? new string[1] { gr.Key } : Array.Empty<string>(),
Action = GetWhatsNewActionText(ls)
});
}
}
if (whatsNewUserActivityGroupByPrjs.Count > 0)
{
activities.Add(ProjectsProductName, whatsNewUserActivityGroupByPrjs);
}
if (activities.Count > 0)
{
log.InfoFormat("Send whats new to {0}", user.Email);
client.SendNoticeAsync(
Actions.SendWhatsNew, null, user,
new TagValue(Tags.Activities, activities),
new TagValue(Tags.Date, DateToString(scheduleDate.AddDays(-1), culture)),
new TagValue(CommonTags.Priority, 1)
);
}
}
}
catch (Exception error)
{
log.Error(error);
}
var products = _webItemManager.GetItemsAll().ToDictionary(p => p.GetSysName());
var tenants = GetChangedTenants(scheduleDate);
foreach (var tenantid in tenants)
{
SendMsgWhatsNew(tenantid, scheduleDate, products);
}
}
}
private IEnumerable<int> GetChangedTenants(DateTime date)
{
return _feedAggregateDataProvider.GetTenants(new TimeInterval(date.Date.AddDays(-1), date.Date.AddSeconds(-1)));
}
private void SendMsgWhatsNew(int tenantid, DateTime scheduleDate, Dictionary<string, IWebItem> products)
{
try
{
var tenant = _tenantManager.GetTenant(tenantid);
if (tenant == null ||
tenant.Status != TenantStatus.Active ||
!TimeToSendWhatsNew(_tenantUtil.DateTimeFromUtc(tenant.TimeZone, scheduleDate)) ||
TariffState.NotPaid <= _paymentManager.GetTariff(tenantid).State)
{
return;
}
_tenantManager.SetCurrentTenant(tenant);
var client = _workContext.NotifyContext.RegisterClient(_notifyEngineQueue, _studioNotifyHelper.NotifySource);
_log.InfoFormat("Start send whats new in {0} ({1}).", tenant.GetTenantDomain(_coreSettings), tenantid);
foreach (var user in _userManager.GetUsers())
{
if (!_studioNotifyHelper.IsSubscribedToNotify(user, Actions.SendWhatsNew))
{
continue;
}
_securityContext.AuthenticateMeWithoutCookie(_authManager.GetAccountByID(tenant.Id, user.Id));
var culture = string.IsNullOrEmpty(user.CultureName) ? tenant.GetCulture() : user.GetCulture();
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
var feeds = _feedAggregateDataProvider.GetFeeds(new FeedApiFilter
{
From = scheduleDate.Date.AddDays(-1),
To = scheduleDate.Date.AddSeconds(-1),
Max = 100,
});
var feedMinWrappers = _mapper.Map<List<FeedResultItem>, List<FeedMin>>(feeds);
var feedMinGroupedWrappers = feedMinWrappers
.Where(f =>
(f.CreatedDate == DateTime.MaxValue || f.CreatedDate >= scheduleDate.Date.AddDays(-1)) && //'cause here may be old posts with new comments
products.ContainsKey(f.Product) &&
!f.Id.StartsWith("participant")
)
.GroupBy(f => products[f.Product]);
var ProjectsProductName = products["projects"]?.Name; //from ASC.Feed.Aggregator.Modules.ModulesHelper.ProjectsProductName
var activities = feedMinGroupedWrappers
.Where(f => f.Key.Name != ProjectsProductName) //not for project product
.ToDictionary(
g => g.Key.Name,
g => g.Select(f => new WhatsNewUserActivity
{
Date = f.CreatedDate,
UserName = f.Author != null && f.Author.UserInfo != null ? f.Author.UserInfo.DisplayUserName(_displayUserSettingsHelper) : string.Empty,
UserAbsoluteURL = f.Author != null && f.Author.UserInfo != null ? _commonLinkUtility.GetFullAbsolutePath(f.Author.UserInfo.GetUserProfilePageURL(_commonLinkUtility)) : string.Empty,
Title = HtmlUtil.GetText(f.Title, 512),
URL = _commonLinkUtility.GetFullAbsolutePath(f.ItemUrl),
BreadCrumbs = Array.Empty<string>(),
Action = GetWhatsNewActionText(f)
}).ToList());
var projectActivities = feedMinGroupedWrappers
.Where(f => f.Key.Name == ProjectsProductName) // for project product
.SelectMany(f => f);
var projectActivitiesWithoutBreadCrumbs = projectActivities.Where(p => string.IsNullOrEmpty(p.ExtraLocation));
var whatsNewUserActivityGroupByPrjs = new List<WhatsNewUserActivity>();
foreach (var prawbc in projectActivitiesWithoutBreadCrumbs)
{
whatsNewUserActivityGroupByPrjs.Add(
new WhatsNewUserActivity
{
Date = prawbc.CreatedDate,
UserName = prawbc.Author != null && prawbc.Author.UserInfo != null ? prawbc.Author.UserInfo.DisplayUserName(_displayUserSettingsHelper) : string.Empty,
UserAbsoluteURL = prawbc.Author != null && prawbc.Author.UserInfo != null ? _commonLinkUtility.GetFullAbsolutePath(prawbc.Author.UserInfo.GetUserProfilePageURL(_commonLinkUtility)) : string.Empty,
Title = HtmlUtil.GetText(prawbc.Title, 512),
URL = _commonLinkUtility.GetFullAbsolutePath(prawbc.ItemUrl),
BreadCrumbs = Array.Empty<string>(),
Action = GetWhatsNewActionText(prawbc)
});
}
var groupByPrjs = projectActivities.Where(p => !string.IsNullOrEmpty(p.ExtraLocation)).GroupBy(f => f.ExtraLocation);
foreach (var gr in groupByPrjs)
{
var grlist = gr.ToList();
for (var i = 0; i < grlist.Count; i++)
{
var ls = grlist[i];
whatsNewUserActivityGroupByPrjs.Add(
new WhatsNewUserActivity
{
Date = ls.CreatedDate,
UserName = ls.Author != null && ls.Author.UserInfo != null ? ls.Author.UserInfo.DisplayUserName(_displayUserSettingsHelper) : string.Empty,
UserAbsoluteURL = ls.Author != null && ls.Author.UserInfo != null ? _commonLinkUtility.GetFullAbsolutePath(ls.Author.UserInfo.GetUserProfilePageURL(_commonLinkUtility)) : string.Empty,
Title = HtmlUtil.GetText(ls.Title, 512),
URL = _commonLinkUtility.GetFullAbsolutePath(ls.ItemUrl),
BreadCrumbs = i == 0 ? new string[1] { gr.Key } : Array.Empty<string>(),
Action = GetWhatsNewActionText(ls)
});
}
}
if (whatsNewUserActivityGroupByPrjs.Count > 0)
{
activities.Add(ProjectsProductName, whatsNewUserActivityGroupByPrjs);
}
if (activities.Count > 0)
{
_log.InfoFormat("Send whats new to {0}", user.Email);
client.SendNoticeAsync(
Actions.SendWhatsNew, null, user,
new TagValue(Tags.Activities, activities),
new TagValue(Tags.Date, DateToString(scheduleDate.AddDays(-1), culture)),
new TagValue(CommonTags.Priority, 1)
);
}
}
}
catch (Exception error)
{
_log.Error(error);
}
}
private static string GetWhatsNewActionText(FeedMin feed)
{
@ -238,17 +286,12 @@ namespace ASC.Web.Studio.Core.Notify
return "";
}
private static IEnumerable<int> GetChangedTenants(FeedAggregateDataProvider feedAggregateDataProvider, DateTime date)
{
return feedAggregateDataProvider.GetTenants(new TimeInterval(date.Date.AddDays(-1), date.Date.AddSeconds(-1)));
}
private bool TimeToSendWhatsNew(DateTime currentTime)
{
var hourToSend = 7;
if (!string.IsNullOrEmpty(Confuguration["web:whatsnew-time"]))
if (!string.IsNullOrEmpty(_confuguration["web:whatsnew-time"]))
{
if (int.TryParse(Confuguration["web:whatsnew-time"], out var hour))
if (int.TryParse(_confuguration["web:whatsnew-time"], out var hour))
{
hourToSend = hour;
}
@ -259,8 +302,9 @@ namespace ASC.Web.Studio.Core.Notify
private static string DateToString(DateTime d, CultureInfo c)
{
return d.ToString(c.TwoLetterISOLanguageName == "ru" ? "d MMMM" : "M", c);
}
}
class WhatsNewUserActivity
{
public IList<string> BreadCrumbs { get; set; }
@ -272,85 +316,4 @@ namespace ASC.Web.Studio.Core.Notify
public string Action { get; set; }
}
}
[Scope]
public class StudioWhatsNewNotifyScope
{
private TenantManager TenantManager { get; }
private PaymentManager PaymentManager { get; }
private TenantUtil TenantUtil { get; }
private StudioNotifyHelper StudioNotifyHelper { get; }
private UserManager UserManager { get; }
private SecurityContext SecurityContext { get; }
private AuthContext AuthContext { get; }
private AuthManager AuthManager { get; }
private CommonLinkUtility CommonLinkUtility { get; }
private DisplayUserSettingsHelper DisplayUserSettingsHelper { get; }
private FeedAggregateDataProvider FeedAggregateDataProvider { get; }
private CoreSettings CoreSettings { get; }
public StudioWhatsNewNotifyScope(TenantManager tenantManager,
PaymentManager paymentManager,
TenantUtil tenantUtil,
StudioNotifyHelper studioNotifyHelper,
UserManager userManager,
SecurityContext securityContext,
AuthContext authContext,
AuthManager authManager,
CommonLinkUtility commonLinkUtility,
DisplayUserSettingsHelper displayUserSettingsHelper,
FeedAggregateDataProvider feedAggregateDataProvider,
CoreSettings coreSettings)
{
TenantManager = tenantManager;
PaymentManager = paymentManager;
TenantUtil = tenantUtil;
StudioNotifyHelper = studioNotifyHelper;
UserManager = userManager;
SecurityContext = securityContext;
AuthContext = authContext;
AuthManager = authManager;
CommonLinkUtility = commonLinkUtility;
DisplayUserSettingsHelper = displayUserSettingsHelper;
FeedAggregateDataProvider = feedAggregateDataProvider;
CoreSettings = coreSettings;
}
public void Deconstruct(out TenantManager tenantManager,
out PaymentManager paymentManager,
out TenantUtil tenantUtil,
out StudioNotifyHelper studioNotifyHelper,
out UserManager userManager,
out SecurityContext securityContext,
out AuthContext authContext,
out AuthManager authManager,
out CommonLinkUtility commonLinkUtility,
out DisplayUserSettingsHelper displayUserSettingsHelper,
out FeedAggregateDataProvider feedAggregateDataProvider,
out CoreSettings coreSettings)
{
tenantManager = TenantManager;
paymentManager = PaymentManager;
tenantUtil = TenantUtil;
studioNotifyHelper = StudioNotifyHelper;
userManager = UserManager;
securityContext = SecurityContext;
authContext = AuthContext;
authManager = AuthManager;
commonLinkUtility = CommonLinkUtility;
displayUserSettingsHelper = DisplayUserSettingsHelper;
feedAggregateDataProvider = FeedAggregateDataProvider;
coreSettings = CoreSettings;
}
}
public static class StudioWhatsNewNotifyExtension
{
public static void Register(DIHelper services)
{
services.TryAdd<WebItemManager>();
services.TryAdd<FeedAggregateDataProvider>();
services.TryAdd<StudioWhatsNewNotifyScope>();
}
}
}

View File

@ -27,7 +27,7 @@
namespace ASC.Web.Studio.Core
{
[Serializable]
public class PersonalSettings : ISettings
public class PersonalSettings : ISettings<PersonalSettings>
{
[JsonPropertyName("IsNewUser")]
@ -41,7 +41,7 @@ namespace ASC.Web.Studio.Core
get { return new Guid("{B3427865-8E32-4E66-B6F3-91C61922239F}"); }
}
public ISettings GetDefault(IServiceProvider serviceProvider)
public PersonalSettings GetDefault()
{
return new PersonalSettings
{

View File

@ -26,7 +26,7 @@
namespace ASC.Web.Studio.Core
{
public class PrivacyRoomSettings : ISettings
public class PrivacyRoomSettings : ISettings<PrivacyRoomSettings>
{
[JsonPropertyName("enbaled")]
public bool EnabledSetting { get; set; }
@ -36,7 +36,7 @@ namespace ASC.Web.Studio.Core
get { return new Guid("{FCF002BC-EC4B-4DAB-A6CE-BDE0ABDA44D3}"); }
}
public ISettings GetDefault(IServiceProvider serviceProvider)
public PrivacyRoomSettings GetDefault()
{
return new PrivacyRoomSettings
{

View File

@ -27,7 +27,7 @@
namespace ASC.Web.Studio.Core
{
[Serializable]
public class PromotionsSettings : ISettings
public class PromotionsSettings : ISettings<PromotionsSettings>
{
public bool Show { get; set; }
@ -36,7 +36,7 @@ namespace ASC.Web.Studio.Core
get { return new Guid("{D291A4C1-179D-4ced-895A-E094E809C859}"); }
}
public ISettings GetDefault(IServiceProvider serviceProvider)
public PromotionsSettings GetDefault()
{
return new PromotionsSettings { Show = true };
}

View File

@ -43,24 +43,8 @@ namespace ASC.Web.Studio.Core.Quota
public void RunJob()//DistributedTask distributedTask, CancellationToken cancellationToken)
{
using var scope = ServiceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<QuotaSyncScope>();
var (tenantManager, storageFactoryConfig, storageFactory) = scopeClass;
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();
}
}
var scopeClass = scope.ServiceProvider.GetService<QuotaSyncJob>();
scopeClass.RunJob(TenantId);
}
public virtual DistributedTask GetDistributedTask()
@ -70,24 +54,37 @@ namespace ASC.Web.Studio.Core.Quota
}
}
class QuotaSyncScope
class QuotaSyncJob
{
private TenantManager TenantManager { get; }
private StorageFactoryConfig StorageFactoryConfig { get; }
private StorageFactory StorageFactory { get; }
private readonly TenantManager _tenantManager;
private readonly StorageFactoryConfig _storageFactoryConfig;
private readonly StorageFactory _storageFactory;
public QuotaSyncScope(TenantManager tenantManager, StorageFactoryConfig storageFactoryConfig, StorageFactory storageFactory)
public QuotaSyncJob(TenantManager tenantManager, StorageFactoryConfig storageFactoryConfig, StorageFactory storageFactory)
{
TenantManager = tenantManager;
StorageFactoryConfig = storageFactoryConfig;
StorageFactory = storageFactory;
_tenantManager = tenantManager;
_storageFactoryConfig = storageFactoryConfig;
_storageFactory = storageFactory;
}
public void Deconstruct(out TenantManager tenantManager, out StorageFactoryConfig storageFactoryConfig, out StorageFactory storageFactory)
public void RunJob(int tenantId)
{
tenantManager = TenantManager;
storageFactoryConfig = StorageFactoryConfig;
storageFactory = 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();
}
}
}
}
}

View File

@ -27,14 +27,14 @@
namespace ASC.Web.Studio.Core.SMS
{
[Serializable]
public class StudioSmsNotificationSettings : ISettings
public class StudioSmsNotificationSettings : ISettings<StudioSmsNotificationSettings>
{
public Guid ID
{
get { return new Guid("{2802df61-af0d-40d4-abc5-a8506a5352ff}"); }
}
public ISettings GetDefault(IServiceProvider serviceProvider)
public StudioSmsNotificationSettings GetDefault()
{
return new StudioSmsNotificationSettings { EnableSetting = false, };
}

View File

@ -26,7 +26,7 @@
namespace ASC.Web.Studio.Core
{
public class StudioAdminMessageSettings : ISettings
public class StudioAdminMessageSettings : ISettings<StudioAdminMessageSettings>
{
public bool Enable { get; set; }
@ -35,7 +35,7 @@ namespace ASC.Web.Studio.Core
get { return new Guid("{28902650-58A9-11E1-B6A9-0F194924019B}"); }
}
public ISettings GetDefault(IServiceProvider serviceProvider)
public StudioAdminMessageSettings GetDefault()
{
return new StudioAdminMessageSettings { Enable = false };
}

View File

@ -27,7 +27,7 @@
namespace ASC.Web.Studio.Core
{
[Serializable]
public class StudioDefaultPageSettings : ISettings
public class StudioDefaultPageSettings : ISettings<StudioDefaultPageSettings>
{
public Guid DefaultProductID { get; set; }
@ -41,7 +41,7 @@ namespace ASC.Web.Studio.Core
get { return new Guid("{48328C27-4C85-4987-BA0E-D6BB17356B10}"); }
}
public ISettings GetDefault(IServiceProvider serviceProvider)
public StudioDefaultPageSettings GetDefault()
{
return new StudioDefaultPageSettings { DefaultProductID = Guid.Empty };
}

View File

@ -26,7 +26,7 @@
namespace ASC.Web.Studio.Core
{
public class StudioTrustedDomainSettings : ISettings
public class StudioTrustedDomainSettings : ISettings<StudioTrustedDomainSettings>
{
public bool InviteUsersAsVisitors { get; set; }
@ -35,7 +35,7 @@ namespace ASC.Web.Studio.Core
get { return new Guid("{00A2DB01-BAE3-48aa-BE32-CE768D7C874E}"); }
}
public ISettings GetDefault(IServiceProvider serviceProvider)
public StudioTrustedDomainSettings GetDefault()
{
return new StudioTrustedDomainSettings { InviteUsersAsVisitors = false };
}

View File

@ -27,7 +27,7 @@
namespace ASC.Web.Studio.UserControls.Management
{
[Serializable]
public class TariffSettings : ISettings
public class TariffSettings : ISettings<TariffSettings>
{
private static readonly CultureInfo CultureInfo = CultureInfo.CreateSpecificCulture("en-US");
@ -40,7 +40,7 @@ namespace ASC.Web.Studio.UserControls.Management
[JsonPropertyName("LicenseAccept")]
public string LicenseAcceptSetting { get; set; }
public ISettings GetDefault(IServiceProvider serviceProvider)
public TariffSettings GetDefault()
{
return new TariffSettings
{

View File

@ -27,14 +27,14 @@
namespace ASC.Web.Studio.Core.TFA
{
[Serializable]
public class TfaAppAuthSettings : ISettings
public class TfaAppAuthSettings : ISettings<TfaAppAuthSettings>
{
public Guid ID
{
get { return new Guid("{822CA059-AA8F-4588-BEE3-6CD2AA920CDB}"); }
}
public ISettings GetDefault(IServiceProvider serviceProvider)
public TfaAppAuthSettings GetDefault()
{
return new TfaAppAuthSettings { EnableSetting = false, };
}

View File

@ -27,7 +27,7 @@
namespace ASC.Web.Studio.Core.TFA
{
[Serializable]
public class TfaAppUserSettings : ISettings
public class TfaAppUserSettings : ISettings<TfaAppUserSettings>
{
[JsonPropertyName("BackupCodes")]
public IEnumerable<BackupCode> CodesSetting { get; set; }
@ -40,7 +40,7 @@ namespace ASC.Web.Studio.Core.TFA
get { return new Guid("{EAF10611-BE1E-4634-B7A1-57F913042F78}"); }
}
public ISettings GetDefault(IServiceProvider serviceProvider)
public TfaAppUserSettings GetDefault()
{
return new TfaAppUserSettings
{
@ -84,14 +84,10 @@ namespace ASC.Web.Studio.Core.TFA
return settingsManager.LoadForUser<TfaAppUserSettings>(guid).CodesSetting.Any();
}
public static void DisableForUser(IServiceProvider serviceProvider, SettingsManager settingsManager, Guid guid)
public static void DisableForUser(SettingsManager settingsManager, Guid guid)
{
if (new TfaAppUserSettings().GetDefault(serviceProvider) is TfaAppUserSettings defaultSettings)
{
settingsManager.SaveForUser(defaultSettings, guid);
}
var defaultSettings = settingsManager.GetDefault<TfaAppUserSettings>();
settingsManager.SaveForUser(defaultSettings, guid);
}
}
}

View File

@ -27,7 +27,7 @@
namespace ASC.Web.Studio.Core
{
[Serializable]
public class TipsSettings : ISettings
public class TipsSettings : ISettings<TipsSettings>
{
[DataMember(Name = "Show")]
public bool Show { get; set; }
@ -37,7 +37,7 @@ namespace ASC.Web.Studio.Core
get { return new Guid("{27909339-B4D4-466F-8F40-A64C9D2FC041}"); }
}
public ISettings GetDefault(IServiceProvider serviceProvider)
public TipsSettings GetDefault()
{
return new TipsSettings { Show = true };
}

View File

@ -27,7 +27,7 @@
namespace ASC.Web.Core.Users
{
[Serializable]
public class PeopleNamesSettings : ISettings
public class PeopleNamesSettings : ISettings<PeopleNamesSettings>
{
public Guid ID
{
@ -38,7 +38,7 @@ namespace ASC.Web.Core.Users
public string ItemId { get; set; }
public ISettings GetDefault(IServiceProvider serviceProvider)
public PeopleNamesSettings GetDefault()
{
return new PeopleNamesSettings { ItemId = PeopleNamesItem.DefaultID };
}
@ -218,7 +218,7 @@ namespace ASC.Web.Core.Users
GuestsCaption = string.Empty
};
}
result.SchemaName = Resource.CustomNamingPeopleSchema;
return result;

View File

@ -27,7 +27,7 @@
namespace ASC.Web.Core.Users
{
[Serializable]
public class UserHelpTourSettings : ISettings
public class UserHelpTourSettings : ISettings<UserHelpTourSettings>
{
public Guid ID
{
@ -38,7 +38,7 @@ namespace ASC.Web.Core.Users
public bool IsNewUser { get; set; }
public ISettings GetDefault(IServiceProvider serviceProvider)
public UserHelpTourSettings GetDefault()
{
return new UserHelpTourSettings
{

View File

@ -74,8 +74,8 @@ namespace ASC.Web.Core.Users
public override int GetHashCode()
{
return HashCode.Combine(UserId, MaxFileSize, Size);
}
}
}
[Singletone]
public class UserPhotoManagerCache
@ -181,7 +181,6 @@ namespace ASC.Web.Core.Users
private StorageFactory StorageFactory { get; }
private UserPhotoManagerCache UserPhotoManagerCache { get; }
private SettingsManager SettingsManager { get; }
private IServiceProvider ServiceProvider { get; }
public ILog Log { get; }
private Tenant tenant;
@ -198,8 +197,7 @@ namespace ASC.Web.Core.Users
UserPhotoManagerCache userPhotoManagerCache,
ILog<UserPhotoManager> logger,
IDistributedTaskQueueFactory queueFactory,
SettingsManager settingsManager,
IServiceProvider serviceProvider)
SettingsManager settingsManager)
{
ResizeQueue = queueFactory.CreateQueue(CUSTOM_DISTRIBUTED_TASK_QUEUE_NAME);
UserManager = userManager;
@ -208,7 +206,6 @@ namespace ASC.Web.Core.Users
StorageFactory = storageFactory;
UserPhotoManagerCache = userPhotoManagerCache;
SettingsManager = settingsManager;
ServiceProvider = serviceProvider;
Log = logger;
}
@ -414,7 +411,7 @@ namespace ASC.Web.Core.Users
}
private string GetDefaultPhotoAbsoluteWebPath(Size size)
{
{
return size switch
{
Size(var w, var h) when w == RetinaFotoSize.Width && h == RetinaFotoSize.Height => WebImageSupplier.GetAbsoluteWebPath(_defaultRetinaAvatar),
@ -493,7 +490,7 @@ namespace ASC.Web.Core.Users
}
public void ResetThumbnailSettings(Guid userId)
{
var thumbSettings = new UserPhotoThumbnailSettings().GetDefault(ServiceProvider) as UserPhotoThumbnailSettings;
var thumbSettings = SettingsManager.GetDefault<UserPhotoThumbnailSettings>();
SettingsManager.SaveForUser(thumbSettings, userId);
}
@ -509,8 +506,8 @@ namespace ASC.Web.Core.Users
{
var storage = GetDataStore();
storage.DeleteFilesAsync("", idUser + "*.*", false).Wait();
}
catch(DirectoryNotFoundException e)
}
catch (DirectoryNotFoundException e)
{
Log.Error(e);
}
@ -589,7 +586,7 @@ namespace ASC.Web.Core.Users
try
{
using var img = Image.Load(data ,out var format);
using var img = Image.Load(data, out var format);
imgFormat = format;
width = img.Width;
height = img.Height;
@ -860,7 +857,7 @@ namespace ASC.Web.Core.Users
}
public static CacheSize ToCache(Size size)
{
{
return size switch
{
Size(var w, var h) when w == RetinaFotoSize.Width && h == RetinaFotoSize.Height => CacheSize.Retina,
@ -870,7 +867,7 @@ namespace ASC.Web.Core.Users
Size(var w, var h) when w == MediumFotoSize.Width && h == MediumFotoSize.Height => CacheSize.Medium,
_ => CacheSize.Original
};
}
}
}
#region Exception Classes
@ -999,7 +996,7 @@ namespace ASC.Web.Core.Users
public static void Deconstruct(this Size size, out int w, out int h)
{
(w, h) = (size.Width, size.Height);
}
}
}
public static class ResizeWorkerItemExtension

View File

@ -27,7 +27,7 @@
namespace ASC.Web.Core.Users
{
[Serializable]
public class UserPhotoThumbnailSettings : ISettings
public class UserPhotoThumbnailSettings : ISettings<UserPhotoThumbnailSettings>
{
public Guid ID
{
@ -56,7 +56,7 @@ namespace ASC.Web.Core.Users
public bool IsDefault { get; private set; }
public ISettings GetDefault(IServiceProvider serviceProvider)
public UserPhotoThumbnailSettings GetDefault()
{
return new UserPhotoThumbnailSettings
{

View File

@ -27,7 +27,7 @@
namespace ASC.Web.Core.Utility
{
[Serializable]
public class ColorThemesSettings : ISettings
public class ColorThemesSettings : ISettings<ColorThemesSettings>
{
public const string ThemeFolderTemplate = "<theme_folder>";
private const string DefaultName = "pure-orange";
@ -37,7 +37,7 @@ namespace ASC.Web.Core.Utility
public bool FirstRequest { get; set; }
public ISettings GetDefault(IServiceProvider serviceProvider)
public ColorThemesSettings GetDefault()
{
return new ColorThemesSettings
{

View File

@ -27,7 +27,7 @@
namespace ASC.Web.Core.Utility
{
[Serializable]
public sealed class PasswordSettings : ISettings
public sealed class PasswordSettings : ISettings<PasswordSettings>
{
public Guid ID
{
@ -35,6 +35,7 @@ namespace ASC.Web.Core.Utility
}
public const int MaxLength = 30;
private readonly IConfiguration _configuration;
/// <summary>
/// Minimal length password has
@ -56,21 +57,25 @@ namespace ASC.Web.Core.Utility
/// </summary>
public bool SpecSymbols { get; set; }
public ISettings GetDefault(IConfiguration configuration)
public PasswordSettings(IConfiguration configuration)
{
var def = new PasswordSettings { MinLength = 8, UpperCase = false, Digits = false, SpecSymbols = false };
_configuration = configuration;
}
if (int.TryParse(configuration["web.password.min"], out var defaultMinLength))
public PasswordSettings()
{
}
public PasswordSettings GetDefault()
{
var def = new PasswordSettings(_configuration) { MinLength = 8, UpperCase = false, Digits = false, SpecSymbols = false };
if (_configuration != null && int.TryParse(_configuration["web:password:min"], out var defaultMinLength))
{
def.MinLength = Math.Max(1, Math.Min(MaxLength, defaultMinLength));
}
return def;
}
public ISettings GetDefault(IServiceProvider serviceProvider)
{
return GetDefault(serviceProvider.GetService<IConfiguration>());
}
}
}

View File

@ -27,7 +27,7 @@
namespace ASC.Web.Core.Utility.Settings
{
[Serializable]
public class TenantAccessSettings : ISettings
public class TenantAccessSettings : ISettings<TenantAccessSettings>
{
public bool Anyone { get; set; }
@ -38,7 +38,7 @@ namespace ASC.Web.Core.Utility.Settings
get { return new Guid("{0CB4C871-0040-45AB-AE79-4CC292B91EF1}"); }
}
public ISettings GetDefault(IServiceProvider serviceProvider)
public TenantAccessSettings GetDefault()
{
return new TenantAccessSettings { Anyone = false, RegisterUsersImmediately = false };
}

View File

@ -26,30 +26,36 @@
namespace ASC.Web.Core.Utility.Settings
{
public class WebItemSettings : ISettings
public class WebItemSettings : ISettings<WebItemSettings>
{
private readonly WebItemManager _webItemManager;
public Guid ID
{
get { return new Guid("{C888CF56-585B-4c78-9E64-FE1093649A62}"); }
}
[JsonPropertyName("Settings")]
public List<WebItemOption> SettingsCollection { get; set; }
public WebItemSettings(WebItemManager webItemManager) : this()
{
_webItemManager = webItemManager;
}
public WebItemSettings()
{
SettingsCollection = new List<WebItemOption>();
}
public ISettings GetDefault(IServiceProvider serviceProvider)
public WebItemSettings GetDefault()
{
var settings = new WebItemSettings();
var webItemManager = serviceProvider.GetService<WebItemManager>();
webItemManager.GetItemsAll().ForEach(w =>
var settings = new WebItemSettings(_webItemManager);
_webItemManager.GetItemsAll().ForEach(w =>
{
var opt = new WebItemOption
{
ItemID = w.ID,
SortOrder = webItemManager.GetSortOrder(w),
SortOrder = _webItemManager.GetSortOrder(w),
Disabled = false,
};
settings.SettingsCollection.Add(opt);

View File

@ -27,7 +27,7 @@
namespace ASC.Web.Core.Utility.Settings
{
[Serializable]
public class WizardSettings : ISettings
public class WizardSettings : ISettings<WizardSettings>
{
public bool Completed { get; set; }
@ -37,7 +37,7 @@ namespace ASC.Web.Core.Utility.Settings
}
public ISettings GetDefault(IServiceProvider serviceProvider)
public WizardSettings GetDefault()
{
return new WizardSettings
{

View File

@ -24,219 +24,249 @@
// 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.Studio.Utility
namespace ASC.Web.Studio.Utility;
[Singletone]
public class TenantExtraConfig
{
[Scope]
public class TenantExtra
private readonly CoreBaseSettings _coreBaseSettings;
private readonly LicenseReaderConfig _licenseReaderConfig;
public TenantExtraConfig(CoreBaseSettings coreBaseSettings, LicenseReaderConfig licenseReaderConfig)
{
private UserManager UserManager { get; }
private TenantStatisticsProvider TenantStatisticsProvider { get; }
private AuthContext AuthContext { get; }
private TenantManager TenantManager { get; }
private PaymentManager PaymentManager { get; }
private CoreBaseSettings CoreBaseSettings { get; }
private LicenseReader LicenseReader { get; }
private SetupInfo SetupInfo { get; }
private SettingsManager SettingsManager { get; }
_coreBaseSettings = coreBaseSettings;
_licenseReaderConfig = licenseReaderConfig;
}
public TenantExtra(
UserManager userManager,
TenantStatisticsProvider tenantStatisticsProvider,
AuthContext authContext,
TenantManager tenantManager,
PaymentManager paymentManager,
CoreBaseSettings coreBaseSettings,
LicenseReader licenseReader,
SetupInfo setupInfo,
SettingsManager settingsManager)
public bool Saas
{
get { return !_coreBaseSettings.Standalone; }
}
public bool Enterprise
{
get { return _coreBaseSettings.Standalone && !string.IsNullOrEmpty(_licenseReaderConfig.LicensePath); }
}
public bool Opensource
{
get { return _coreBaseSettings.Standalone && string.IsNullOrEmpty(_licenseReaderConfig.LicensePath); }
}
}
[Scope]
public class TenantExtra
{
private readonly TenantExtraConfig _tenantExtraConfig;
private readonly UserManager _userManager;
private readonly TenantStatisticsProvider _tenantStatisticsProvider;
private readonly AuthContext _authContext;
private readonly TenantManager _tenantManager;
private readonly PaymentManager _paymentManager;
private readonly CoreBaseSettings _coreBaseSettings;
private readonly LicenseReader _licenseReader;
private readonly SetupInfo _setupInfo;
private readonly SettingsManager _settingsManager;
public TenantExtra(
UserManager userManager,
TenantStatisticsProvider tenantStatisticsProvider,
AuthContext authContext,
TenantManager tenantManager,
PaymentManager paymentManager,
CoreBaseSettings coreBaseSettings,
LicenseReader licenseReader,
SetupInfo setupInfo,
SettingsManager settingsManager,
TenantExtraConfig tenantExtraConfig)
{
_userManager = userManager;
_tenantStatisticsProvider = tenantStatisticsProvider;
_authContext = authContext;
_tenantManager = tenantManager;
_paymentManager = paymentManager;
_coreBaseSettings = coreBaseSettings;
_licenseReader = licenseReader;
_setupInfo = setupInfo;
_settingsManager = settingsManager;
_tenantExtraConfig = tenantExtraConfig;
}
public bool EnableTariffSettings
{
get
{
UserManager = userManager;
TenantStatisticsProvider = tenantStatisticsProvider;
AuthContext = authContext;
TenantManager = tenantManager;
PaymentManager = paymentManager;
CoreBaseSettings = coreBaseSettings;
LicenseReader = licenseReader;
SetupInfo = setupInfo;
SettingsManager = settingsManager;
}
public bool EnableTariffSettings
{
get
{
return
SetupInfo.IsVisibleSettings<TariffSettings>()
&& !SettingsManager.Load<TenantAccessSettings>().Anyone
&& (!CoreBaseSettings.Standalone || !string.IsNullOrEmpty(LicenseReader.LicensePath))
&& string.IsNullOrEmpty(SetupInfo.AmiMetaUrl);
}
}
public bool Saas
{
get { return !CoreBaseSettings.Standalone; }
}
public bool Enterprise
{
get { return CoreBaseSettings.Standalone && !string.IsNullOrEmpty(LicenseReader.LicensePath); }
}
public bool Opensource
{
get { return CoreBaseSettings.Standalone && string.IsNullOrEmpty(LicenseReader.LicensePath); }
}
public bool EnterprisePaid
{
get { return Enterprise && GetCurrentTariff().State < TariffState.NotPaid; }
}
public bool EnableControlPanel
{
get
{
return CoreBaseSettings.Standalone &&
!string.IsNullOrEmpty(SetupInfo.ControlPanelUrl) &&
GetTenantQuota().ControlPanel &&
GetCurrentTariff().State < TariffState.NotPaid &&
UserManager.GetUsers(AuthContext.CurrentAccount.ID).IsAdmin(UserManager);
}
}
public bool EnableDocbuilder
{
get { return !Opensource; }
}
public string GetAppsPageLink()
{
return VirtualPathUtility.ToAbsolute("~/AppInstall.aspx");
}
public string GetTariffPageLink()
{
return VirtualPathUtility.ToAbsolute("~/Tariffs.aspx");
}
public Tariff GetCurrentTariff()
{
return PaymentManager.GetTariff(TenantManager.GetCurrentTenant().Id);
}
public TenantQuota GetTenantQuota()
{
return GetTenantQuota(TenantManager.GetCurrentTenant().Id);
}
public TenantQuota GetTenantQuota(int tenant)
{
return TenantManager.GetTenantQuota(tenant);
}
public IEnumerable<TenantQuota> GetTenantQuotas()
{
return TenantManager.GetTenantQuotas();
}
private TenantQuota GetPrevQuota(TenantQuota curQuota)
{
TenantQuota prev = null;
foreach (var quota in GetTenantQuotas().OrderBy(r => r.ActiveUsers).Where(r => r.Year == curQuota.Year && r.Year3 == curQuota.Year3))
{
if (quota.Tenant == curQuota.Tenant)
return prev;
prev = quota;
}
return null;
}
public int GetPrevUsersCount(TenantQuota quota)
{
var prevQuota = GetPrevQuota(quota);
if (prevQuota == null || prevQuota.Trial)
return 1;
return prevQuota.ActiveUsers + 1;
}
public int GetRightQuotaId()
{
var q = GetRightQuota();
return q != null ? q.Tenant : 0;
}
public TenantQuota GetRightQuota()
{
var usedSpace = TenantStatisticsProvider.GetUsedSize();
var needUsersCount = TenantStatisticsProvider.GetUsersCount();
var quotas = GetTenantQuotas();
return quotas.OrderBy(q => q.ActiveUsers)
.ThenBy(q => q.Year)
.FirstOrDefault(q =>
q.ActiveUsers > needUsersCount
&& q.MaxTotalSize > usedSpace
&& !q.Free
&& !q.Trial);
}
public int GetRemainingCountUsers()
{
return GetTenantQuota().ActiveUsers - TenantStatisticsProvider.GetUsersCount();
}
public bool UpdatedWithoutLicense
{
get
{
DateTime licenseDay;
return CoreBaseSettings.Standalone
&& (licenseDay = GetCurrentTariff().LicenseDate.Date) < DateTime.Today
&& licenseDay < LicenseReader.VersionReleaseDate;
}
}
public void DemandControlPanelPermission()
{
if (!CoreBaseSettings.Standalone || SettingsManager.Load<TenantControlPanelSettings>().LimitedAccess)
{
throw new System.Security.SecurityException(Resource.ErrorAccessDenied);
}
}
public bool IsNotPaid()
{
Tariff tariff;
return EnableTariffSettings
&& ((tariff = GetCurrentTariff()).State >= TariffState.NotPaid
|| Enterprise && !EnterprisePaid && tariff.LicenseDate == DateTime.MaxValue);
}
/// <summary>
/// Max possible file size for not chunked upload. Less or equal than 100 mb.
/// </summary>
public long MaxUploadSize
{
get { return Math.Min(SetupInfo.AvailableFileSize, MaxChunkedUploadSize); }
}
/// <summary>
/// Max possible file size for chunked upload.
/// </summary>
public long MaxChunkedUploadSize
{
get
{
var diskQuota = GetTenantQuota();
if (diskQuota != null)
{
var usedSize = TenantStatisticsProvider.GetUsedSize();
var freeSize = Math.Max(diskQuota.MaxTotalSize - usedSize, 0);
return Math.Min(freeSize, diskQuota.MaxFileSize);
}
return SetupInfo.ChunkUploadSize;
}
return
SetupInfo.IsVisibleSettings<TariffSettings>()
&& !_settingsManager.Load<TenantAccessSettings>().Anyone
&& (!_coreBaseSettings.Standalone || !string.IsNullOrEmpty(_licenseReader.LicensePath))
&& string.IsNullOrEmpty(_setupInfo.AmiMetaUrl);
}
}
}
public bool Saas
{
get => _tenantExtraConfig.Saas;
}
public bool Enterprise
{
get => _tenantExtraConfig.Enterprise;
}
public bool Opensource
{
get => _tenantExtraConfig.Opensource;
}
public bool EnterprisePaid
{
get { return Enterprise && GetCurrentTariff().State < TariffState.NotPaid; }
}
public bool EnableControlPanel
{
get
{
return _coreBaseSettings.Standalone &&
!string.IsNullOrEmpty(_setupInfo.ControlPanelUrl) &&
GetTenantQuota().ControlPanel &&
GetCurrentTariff().State < TariffState.NotPaid &&
_userManager.GetUsers(_authContext.CurrentAccount.ID).IsAdmin(_userManager);
}
}
public bool EnableDocbuilder
{
get { return !Opensource; }
}
public string GetAppsPageLink()
{
return VirtualPathUtility.ToAbsolute("~/AppInstall.aspx");
}
public string GetTariffPageLink()
{
return VirtualPathUtility.ToAbsolute("~/Tariffs.aspx");
}
public Tariff GetCurrentTariff()
{
return _paymentManager.GetTariff(_tenantManager.GetCurrentTenant().Id);
}
public TenantQuota GetTenantQuota()
{
return GetTenantQuota(_tenantManager.GetCurrentTenant().Id);
}
public TenantQuota GetTenantQuota(int tenant)
{
return _tenantManager.GetTenantQuota(tenant);
}
public IEnumerable<TenantQuota> GetTenantQuotas()
{
return _tenantManager.GetTenantQuotas();
}
private TenantQuota GetPrevQuota(TenantQuota curQuota)
{
TenantQuota prev = null;
foreach (var quota in GetTenantQuotas().OrderBy(r => r.ActiveUsers).Where(r => r.Year == curQuota.Year && r.Year3 == curQuota.Year3))
{
if (quota.Tenant == curQuota.Tenant)
return prev;
prev = quota;
}
return null;
}
public int GetPrevUsersCount(TenantQuota quota)
{
var prevQuota = GetPrevQuota(quota);
if (prevQuota == null || prevQuota.Trial)
return 1;
return prevQuota.ActiveUsers + 1;
}
public int GetRightQuotaId()
{
var q = GetRightQuota();
return q != null ? q.Tenant : 0;
}
public TenantQuota GetRightQuota()
{
var usedSpace = _tenantStatisticsProvider.GetUsedSize();
var needUsersCount = _tenantStatisticsProvider.GetUsersCount();
var quotas = GetTenantQuotas();
return quotas.OrderBy(q => q.ActiveUsers)
.ThenBy(q => q.Year)
.FirstOrDefault(q =>
q.ActiveUsers > needUsersCount
&& q.MaxTotalSize > usedSpace
&& !q.Free
&& !q.Trial);
}
public int GetRemainingCountUsers()
{
return GetTenantQuota().ActiveUsers - _tenantStatisticsProvider.GetUsersCount();
}
public bool UpdatedWithoutLicense
{
get
{
DateTime licenseDay;
return _coreBaseSettings.Standalone
&& (licenseDay = GetCurrentTariff().LicenseDate.Date) < DateTime.Today
&& licenseDay < _licenseReader.VersionReleaseDate;
}
}
public void DemandControlPanelPermission()
{
if (!_coreBaseSettings.Standalone || _settingsManager.Load<TenantControlPanelSettings>().LimitedAccess)
{
throw new System.Security.SecurityException(Resource.ErrorAccessDenied);
}
}
public bool IsNotPaid()
{
Tariff tariff;
return EnableTariffSettings
&& ((tariff = GetCurrentTariff()).State >= TariffState.NotPaid
|| Enterprise && !EnterprisePaid && tariff.LicenseDate == DateTime.MaxValue);
}
/// <summary>
/// Max possible file size for not chunked upload. Less or equal than 100 mb.
/// </summary>
public long MaxUploadSize
{
get { return Math.Min(_setupInfo.AvailableFileSize, MaxChunkedUploadSize); }
}
/// <summary>
/// Max possible file size for chunked upload.
/// </summary>
public long MaxChunkedUploadSize
{
get
{
var diskQuota = GetTenantQuota();
if (diskQuota != null)
{
var usedSize = _tenantStatisticsProvider.GetUsedSize();
var freeSize = Math.Max(diskQuota.MaxTotalSize - usedSize, 0);
return Math.Min(freeSize, diskQuota.MaxFileSize);
}
return _setupInfo.ChunkUploadSize;
}
}
}

View File

@ -32,8 +32,10 @@ namespace ASC.Web.Core.WhiteLabel
}
[Serializable]
public class AdditionalWhiteLabelSettings : ISettings
{
public class AdditionalWhiteLabelSettings : ISettings<AdditionalWhiteLabelSettings>
{
private readonly AdditionalWhiteLabelSettingsHelper _additionalWhiteLabelSettingsHelper;
public bool StartDocsEnabled { get; set; }
public bool HelpCenterEnabled { get; set; }
@ -58,9 +60,9 @@ namespace ASC.Web.Core.WhiteLabel
public string LicenseAgreementsUrl { get; set; }
public bool IsDefault(IConfiguration configuration)
{
if (!(GetDefault(configuration) is AdditionalWhiteLabelSettings defaultSettings)) return false;
public bool IsDefault()
{
var defaultSettings = GetDefault();
return StartDocsEnabled == defaultSettings.StartDocsEnabled &&
HelpCenterEnabled == defaultSettings.HelpCenterEnabled &&
@ -80,32 +82,28 @@ namespace ASC.Web.Core.WhiteLabel
{
get { return new Guid("{0108422F-C05D-488E-B271-30C4032494DA}"); }
}
public AdditionalWhiteLabelSettings(AdditionalWhiteLabelSettingsHelper additionalWhiteLabelSettingsHelper)
{
_additionalWhiteLabelSettingsHelper = additionalWhiteLabelSettingsHelper;
}
public AdditionalWhiteLabelSettings() { }
public ISettings GetDefault()
public AdditionalWhiteLabelSettings GetDefault()
{
return new AdditionalWhiteLabelSettings
return new AdditionalWhiteLabelSettings(_additionalWhiteLabelSettingsHelper)
{
StartDocsEnabled = true,
LicenseAgreementsEnabled = true,
LicenseAgreementsUrl = DefaultLicenseAgreements
};
}
public ISettings GetDefault(IConfiguration configuration)
{
var additionalWhiteLabelSettingsHelper = new AdditionalWhiteLabelSettingsHelper(configuration);
return new AdditionalWhiteLabelSettings
{
StartDocsEnabled = true,
HelpCenterEnabled = additionalWhiteLabelSettingsHelper.DefaultHelpCenterUrl != null,
FeedbackAndSupportEnabled = additionalWhiteLabelSettingsHelper.DefaultFeedbackAndSupportUrl != null,
FeedbackAndSupportUrl = additionalWhiteLabelSettingsHelper.DefaultFeedbackAndSupportUrl,
UserForumEnabled = additionalWhiteLabelSettingsHelper.DefaultUserForumUrl != null,
UserForumUrl = additionalWhiteLabelSettingsHelper.DefaultUserForumUrl,
VideoGuidesEnabled = additionalWhiteLabelSettingsHelper.DefaultVideoGuidesUrl != null,
VideoGuidesUrl = additionalWhiteLabelSettingsHelper.DefaultVideoGuidesUrl,
SalesEmail = additionalWhiteLabelSettingsHelper.DefaultMailSalesEmail,
BuyUrl = additionalWhiteLabelSettingsHelper.DefaultBuyUrl,
HelpCenterEnabled = _additionalWhiteLabelSettingsHelper?.DefaultHelpCenterUrl != null,
FeedbackAndSupportEnabled = _additionalWhiteLabelSettingsHelper?.DefaultFeedbackAndSupportUrl != null,
FeedbackAndSupportUrl = _additionalWhiteLabelSettingsHelper?.DefaultFeedbackAndSupportUrl,
UserForumEnabled = _additionalWhiteLabelSettingsHelper?.DefaultUserForumUrl != null,
UserForumUrl = _additionalWhiteLabelSettingsHelper?.DefaultUserForumUrl,
VideoGuidesEnabled = _additionalWhiteLabelSettingsHelper?.DefaultVideoGuidesUrl != null,
VideoGuidesUrl = _additionalWhiteLabelSettingsHelper?.DefaultVideoGuidesUrl,
SalesEmail = _additionalWhiteLabelSettingsHelper?.DefaultMailSalesEmail,
BuyUrl = _additionalWhiteLabelSettingsHelper?.DefaultBuyUrl,
LicenseAgreementsEnabled = true,
LicenseAgreementsUrl = DefaultLicenseAgreements
};
@ -118,11 +116,6 @@ namespace ASC.Web.Core.WhiteLabel
return "https://help.onlyoffice.com/Products/Files/doceditor.aspx?fileid=6795868&doc=RG5GaVN6azdUQW5kLzZQNzBXbHZ4Rm9QWVZuNjZKUmgya0prWnpCd2dGcz0_IjY3OTU4Njgi0";
}
}
public ISettings GetDefault(IServiceProvider serviceProvider)
{
return GetDefault(serviceProvider.GetService<IConfiguration>());
}
}
[Singletone]

View File

@ -32,8 +32,10 @@ namespace ASC.Web.Core.WhiteLabel
}
[Serializable]
public class CompanyWhiteLabelSettings : ISettings
{
public class CompanyWhiteLabelSettings : ISettings<CompanyWhiteLabelSettings>
{
private readonly CoreSettings _coreSettings;
public string CompanyName { get; set; }
public string Site { get; set; }
@ -47,10 +49,19 @@ namespace ASC.Web.Core.WhiteLabel
[JsonPropertyName("IsLicensor")]
public bool IsLicensor { get; set; }
public CompanyWhiteLabelSettings(CoreSettings coreSettings)
{
_coreSettings = coreSettings;
}
public CompanyWhiteLabelSettings()
{
}
public bool IsDefault(CoreSettings coreSettings)
public bool IsDefault()
{
if (!(GetDefault(coreSettings) is CompanyWhiteLabelSettings defaultSettings)) return false;
var defaultSettings = GetDefault();
return CompanyName == defaultSettings.CompanyName &&
Site == defaultSettings.Site &&
@ -66,25 +77,13 @@ namespace ASC.Web.Core.WhiteLabel
{
get { return new Guid("{C3C5A846-01A3-476D-A962-1CFD78C04ADB}"); }
}
private static CompanyWhiteLabelSettings _default;
public ISettings GetDefault(IServiceProvider serviceProvider)
public CompanyWhiteLabelSettings GetDefault()
{
if (_default != null) return _default;
var settings = _coreSettings.GetSetting("CompanyWhiteLabelSettings");
return GetDefault(serviceProvider.GetService<CoreSettings>());
}
public ISettings GetDefault(CoreSettings coreSettings)
{
if (_default != null) return _default;
var settings = coreSettings.GetSetting("CompanyWhiteLabelSettings");
_default = string.IsNullOrEmpty(settings) ? new CompanyWhiteLabelSettings() : Newtonsoft.Json.JsonConvert.DeserializeObject<CompanyWhiteLabelSettings>(settings);
return _default;
return string.IsNullOrEmpty(settings) ? new CompanyWhiteLabelSettings(_coreSettings) : JsonConvert.DeserializeObject<CompanyWhiteLabelSettings>(settings);
}
#endregion

View File

@ -27,7 +27,7 @@
namespace ASC.Web.Core.WhiteLabel
{
[Serializable]
public class TenantInfoSettings : ISettings
public class TenantInfoSettings : ISettings<TenantInfoSettings>
{
[JsonPropertyName("LogoSize")]
public Size CompanyLogoSize { get; internal set; }
@ -38,7 +38,7 @@ namespace ASC.Web.Core.WhiteLabel
[JsonPropertyName("Default")]
internal bool IsDefault { get; set; }
public ISettings GetDefault(IServiceProvider serviceProvider)
public TenantInfoSettings GetDefault()
{
return new TenantInfoSettings()
{

View File

@ -29,7 +29,7 @@ using UnknownImageFormatException = SixLabors.ImageSharp.UnknownImageFormatExcep
namespace ASC.Web.Core.WhiteLabel
{
[Serializable]
public class TenantWhiteLabelSettings : ISettings
public class TenantWhiteLabelSettings : ISettings<TenantWhiteLabelSettings>
{
public const string DefaultLogoText = BaseWhiteLabelSettings.DefaultLogoText;
@ -90,7 +90,7 @@ namespace ASC.Web.Core.WhiteLabel
#region ISettings Members
public ISettings GetDefault(IServiceProvider serviceProvider)
public TenantWhiteLabelSettings GetDefault()
{
return new TenantWhiteLabelSettings
{
@ -201,8 +201,7 @@ namespace ASC.Web.Core.WhiteLabel
private StorageFactory StorageFactory { get; }
private WhiteLabelHelper WhiteLabelHelper { get; }
private TenantManager TenantManager { get; }
private SettingsManager SettingsManager { get; }
public IServiceProvider ServiceProvider { get; }
private SettingsManager SettingsManager { get; }
private ILog Log { get; set; }
public TenantWhiteLabelSettingsHelper(
@ -211,8 +210,7 @@ namespace ASC.Web.Core.WhiteLabel
StorageFactory storageFactory,
WhiteLabelHelper whiteLabelHelper,
TenantManager tenantManager,
SettingsManager settingsManager,
IServiceProvider serviceProvider,
SettingsManager settingsManager,
ILog logger)
{
WebImageSupplier = webImageSupplier;
@ -221,7 +219,6 @@ namespace ASC.Web.Core.WhiteLabel
WhiteLabelHelper = whiteLabelHelper;
TenantManager = tenantManager;
SettingsManager = settingsManager;
ServiceProvider = serviceProvider;
Log = logger;
}
@ -229,9 +226,7 @@ namespace ASC.Web.Core.WhiteLabel
public bool IsDefault(TenantWhiteLabelSettings tenantWhiteLabelSettings)
{
var defaultSettings = tenantWhiteLabelSettings.GetDefault(ServiceProvider) as TenantWhiteLabelSettings;
if (defaultSettings == null) return false;
var defaultSettings = SettingsManager.GetDefault<TenantWhiteLabelSettings>();
return tenantWhiteLabelSettings.LogoLightSmallExt == defaultSettings.LogoLightSmallExt &&
tenantWhiteLabelSettings.LogoDarkExt == defaultSettings.LogoDarkExt &&

View File

@ -72,7 +72,7 @@ public class Startup : BaseStartup
services.AddMemoryCache();
DIHelper.TryAdd<Login>();
DIHelper.TryAdd<PathUtils>();
DIHelper.TryAdd<StorageHandlerScope>();
DIHelper.TryAdd<StorageFactory>();
DIHelper.TryAdd<GoogleLoginProvider>();
DIHelper.TryAdd<FacebookLoginProvider>();
DIHelper.TryAdd<LinkedInLoginProvider>();