DocSpace-buildtools/web/ASC.Web.Core/Notify/NotifyConfiguration.cs

469 lines
22 KiB
C#
Raw Normal View History

/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL 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 more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
2019-08-01 08:47:15 +00:00
2020-02-17 08:58:14 +00:00
using ASC.Common;
using ASC.Common.Logging;
2019-08-01 08:47:15 +00:00
using ASC.Common.Notify.Engine;
using ASC.Common.Utils;
using ASC.Core;
using ASC.Core.Common.Settings;
using ASC.Core.Tenants;
using ASC.Core.Users;
using ASC.Notify;
using ASC.Notify.Engine;
using ASC.Notify.Messages;
using ASC.Notify.Patterns;
2020-10-22 17:57:18 +00:00
using ASC.Notify.Textile;
using ASC.Web.Core;
2019-09-24 10:32:12 +00:00
using ASC.Web.Core.Users;
2019-08-01 08:47:15 +00:00
using ASC.Web.Core.WhiteLabel;
using ASC.Web.Studio.Utility;
2019-08-01 08:47:15 +00:00
using Google.Protobuf;
2020-01-23 08:52:07 +00:00
using Microsoft.Extensions.Configuration;
2019-09-09 12:56:33 +00:00
using Microsoft.Extensions.DependencyInjection;
2019-10-17 15:55:35 +00:00
using Microsoft.Extensions.Options;
2020-01-23 08:52:07 +00:00
using MimeKit.Utils;
namespace ASC.Web.Studio.Core.Notify
{
2020-10-28 12:26:27 +00:00
[Singletone(Additional = typeof(WorkContextExtension))]
public class NotifyConfiguration
{
private static bool configured;
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);
2020-10-28 12:26:27 +00:00
private IServiceProvider ServiceProvider { get; }
public NotifyConfiguration(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
}
public void Configure()
{
lock (locker)
{
if (!configured)
{
configured = true;
2020-10-28 12:26:27 +00:00
WorkContext.NotifyStartUp(ServiceProvider);
WorkContext.NotifyContext.NotifyClientRegistration += NotifyClientRegisterCallback;
WorkContext.NotifyContext.NotifyEngine.BeforeTransferRequest += BeforeTransferRequest;
}
}
}
2019-10-11 08:31:21 +00:00
private static void NotifyClientRegisterCallback(Context context, INotifyClient client)
{
#region url correction
var absoluteUrl = new SendInterceptorSkeleton(
"Web.UrlAbsoluter",
InterceptorPlace.MessageSend,
InterceptorLifetime.Global,
2019-10-11 08:31:21 +00:00
(r, p, scope) =>
{
if (r != null && r.CurrentMessage != null && r.CurrentMessage.ContentType == Pattern.HTMLContentType)
{
2019-10-11 08:31:21 +00:00
var commonLinkUtility = scope.ServiceProvider.GetService<CommonLinkUtility>();
2019-09-19 15:55:44 +00:00
var body = r.CurrentMessage.Body;
body = urlReplacer.Replace(body, m =>
{
var url = m.Groups["url"].Value;
var ind = m.Groups["url"].Index - m.Index;
return string.IsNullOrEmpty(url) && ind > 0 ?
2019-09-19 15:55:44 +00:00
m.Value.Insert(ind, commonLinkUtility.GetFullAbsolutePath(string.Empty)) :
m.Value.Replace(url, commonLinkUtility.GetFullAbsolutePath(url));
});
body = textileLinkReplacer.Replace(body, m =>
{
var url = m.Groups["link"].Value;
var ind = m.Groups["link"].Index - m.Index;
return string.IsNullOrEmpty(url) && ind > 0 ?
2019-09-19 15:55:44 +00:00
m.Value.Insert(ind, commonLinkUtility.GetFullAbsolutePath(string.Empty)) :
m.Value.Replace(url, commonLinkUtility.GetFullAbsolutePath(url));
});
r.CurrentMessage.Body = body;
}
return false;
});
client.AddInterceptor(absoluteUrl);
#endregion
#region security and culture
var securityAndCulture = new SendInterceptorSkeleton(
"ProductSecurityInterceptor",
InterceptorPlace.DirectSend,
InterceptorLifetime.Global,
2019-10-11 08:31:21 +00:00
(r, p, scope) =>
{
2020-08-24 18:41:06 +00:00
var scopeClass = scope.ServiceProvider.GetService<NotifyConfigurationScope>();
2020-12-28 13:22:08 +00:00
var coreBaseSettings = scope.ServiceProvider.GetService<CoreBaseSettings>();
2020-09-07 12:01:15 +00:00
var (tenantManager, webItemSecurity, userManager, options, _, _, _, _, _, _, _, _, _, _, _) = scopeClass;
try
{
// culture
var u = Constants.LostUser;
2020-12-28 13:22:08 +00:00
if (!(coreBaseSettings.Personal && r.NotifyAction.ID == Actions.PersonalConfirmation.ID))
{
2020-12-28 13:22:08 +00:00
var tenant = tenantManager.GetCurrentTenant();
2020-12-28 13:22:08 +00:00
if (32 <= r.Recipient.ID.Length)
{
2020-12-28 13:22:08 +00:00
var guid = default(Guid);
try
{
guid = new Guid(r.Recipient.ID);
}
catch (FormatException) { }
catch (OverflowException) { }
if (guid != default)
{
u = userManager.GetUsers(guid);
}
}
2020-12-28 13:22:08 +00:00
if (Constants.LostUser.Equals(u))
{
2020-12-28 13:22:08 +00:00
u = userManager.GetUserByEmail(r.Recipient.ID);
}
2020-12-28 13:22:08 +00:00
if (Constants.LostUser.Equals(u))
{
2020-12-28 13:22:08 +00:00
u = userManager.GetUserByUserName(r.Recipient.ID);
}
2020-12-28 13:22:08 +00:00
if (!Constants.LostUser.Equals(u))
{
2020-12-28 13:22:08 +00:00
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)
{
2020-08-31 08:18:07 +00:00
options.CurrentValue.Error(error);
}
return false;
});
client.AddInterceptor(securityAndCulture);
#endregion
#region white label correction
var whiteLabel = new SendInterceptorSkeleton(
"WhiteLabelInterceptor",
InterceptorPlace.MessageSend,
InterceptorLifetime.Global,
2019-10-11 08:31:21 +00:00
(r, p, scope) =>
{
try
{
var tags = r.Arguments;
var logoTextTag = tags.FirstOrDefault(a => a.Tag == CommonTags.LetterLogoText);
2019-08-15 13:16:39 +00:00
var logoText = logoTextTag != null ? (string)logoTextTag.Value : string.Empty;
if (!string.IsNullOrEmpty(logoText))
{
r.CurrentMessage.Body = r.CurrentMessage.Body
.Replace(string.Format("${{{0}}}", CommonTags.LetterLogoText), logoText);
}
}
catch (Exception error)
{
2019-11-06 15:03:09 +00:00
scope.ServiceProvider.GetService<IOptionsMonitor<ILog>>().CurrentValue.Error(error);
}
return false;
});
client.AddInterceptor(whiteLabel);
#endregion
}
2020-09-08 08:42:13 +00:00
private static void BeforeTransferRequest(NotifyEngine sender, NotifyRequest request, IServiceScope scope)
{
var aid = Guid.Empty;
var aname = string.Empty;
2020-09-08 08:42:13 +00:00
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>();
2019-08-08 09:26:58 +00:00
2019-09-09 12:56:33 +00:00
if (authContext.IsAuthenticated)
{
2019-09-09 12:56:33 +00:00
aid = authContext.CurrentAccount.ID;
var user = userManager.GetUsers(aid);
2019-09-09 12:56:33 +00:00
if (userManager.UserExists(user))
{
aname = user.DisplayUserName(false, displayUserSettingsHelper)
.Replace(">", "&#62")
.Replace("<", "&#60");
}
}
2020-08-24 18:41:06 +00:00
var scopeClass = scope.ServiceProvider.GetService<NotifyConfigurationScope>();
var (_, _, _, options, tenantExtra, _, webItemManager, configuration, tenantLogoManager, additionalWhiteLabelSettingsHelper, tenantUtil, coreBaseSettings, commonLinkUtility, settingsManager, studioNotifyHelper) = scopeClass;
2020-08-31 08:18:07 +00:00
var log = options.CurrentValue;
2020-07-30 13:33:54 +00:00
2020-08-31 08:18:07 +00:00
commonLinkUtility.GetLocationByRequest(out var product, out var module);
if (product == null && CallContext.GetData("asc.web.product_id") != null)
{
2020-08-31 08:18:07 +00:00
product = webItemManager[(Guid)CallContext.GetData("asc.web.product_id")] as IProduct;
}
var logoText = TenantWhiteLabelSettings.DefaultLogoText;
2020-08-31 08:18:07 +00:00
if ((tenantExtra.Enterprise || coreBaseSettings.CustomMode) && !MailWhiteLabelSettings.IsDefault(settingsManager, configuration))
{
2020-08-31 08:18:07 +00:00
logoText = tenantLogoManager.GetLogoText();
}
request.Arguments.Add(new TagValue(CommonTags.AuthorID, aid));
request.Arguments.Add(new TagValue(CommonTags.AuthorName, aname));
2020-08-31 08:18:07 +00:00
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));
2020-08-31 08:18:07 +00:00
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.SYS_RECIPIENT_ID));
2020-08-31 08:18:07 +00:00
request.Arguments.Add(new TagValue(CommonTags.ProfileUrl, commonLinkUtility.GetFullAbsolutePath(commonLinkUtility.GetMyStaff())));
request.Arguments.Add(new TagValue(CommonTags.RecipientSubscriptionConfigURL, commonLinkUtility.GetMyStaff()));
request.Arguments.Add(new TagValue(CommonTags.HelpLink, commonLinkUtility.GetHelpLink(settingsManager, additionalWhiteLabelSettingsHelper, false)));
request.Arguments.Add(new TagValue(CommonTags.LetterLogoText, logoText));
2020-08-31 08:18:07 +00:00
request.Arguments.Add(new TagValue(CommonTags.MailWhiteLabelSettings, MailWhiteLabelSettings.Instance(settingsManager)));
2020-01-23 08:52:07 +00:00
request.Arguments.Add(new TagValue(CommonTags.SendFrom, tenant.Name));
2020-08-31 08:18:07 +00:00
request.Arguments.Add(new TagValue(CommonTags.ImagePath, studioNotifyHelper.GetNotificationImageUrl("").TrimEnd('/')));
2020-08-31 08:18:07 +00:00
AddLetterLogo(request, tenantExtra, tenantLogoManager, coreBaseSettings, commonLinkUtility, log);
}
2019-10-17 15:55:35 +00:00
private static void AddLetterLogo(NotifyRequest request, TenantExtra tenantExtra, TenantLogoManager tenantLogoManager, CoreBaseSettings coreBaseSettings, CommonLinkUtility commonLinkUtility, ILog Log)
{
2019-09-19 11:34:54 +00:00
if (tenantExtra.Enterprise || coreBaseSettings.CustomMode)
{
try
{
2019-09-16 14:51:39 +00:00
var logoData = tenantLogoManager.GetMailLogoDataFromCache();
if (logoData == null)
{
2019-09-13 11:18:27 +00:00
var logoStream = tenantLogoManager.GetWhitelabelMailLogo();
logoData = ReadStreamToByteArray(logoStream) ?? GetDefaultMailLogo();
if (logoData != null)
2019-09-16 14:51:39 +00:00
tenantLogoManager.InsertMailLogoDataToCache(logoData);
}
if (logoData != null)
{
var attachment = new NotifyMessageAttachment
{
FileName = "logo.png",
2019-08-01 08:47:15 +00:00
Content = ByteString.CopyFrom(logoData),
ContentId = MimeUtils.GenerateMessageId()
};
request.Arguments.Add(new TagValue(CommonTags.LetterLogo, "cid:" + attachment.ContentId));
request.Arguments.Add(new TagValue(CommonTags.EmbeddedAttachments, new[] { attachment }));
return;
}
}
catch (Exception error)
{
2019-10-17 15:55:35 +00:00
Log.Error(error);
}
}
2019-09-19 15:55:44 +00:00
var logoUrl = commonLinkUtility.GetFullAbsolutePath(tenantLogoManager.GetLogoDark(true));
request.Arguments.Add(new TagValue(CommonTags.LetterLogo, logoUrl));
}
private static byte[] ReadStreamToByteArray(Stream inputStream)
{
if (inputStream == null) return null;
using (inputStream)
{
2019-08-15 15:08:40 +00:00
using var memoryStream = new MemoryStream();
inputStream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
}
public static byte[] GetDefaultMailLogo()
{
2021-05-24 17:41:31 +00:00
var filePath = CrossPlatform.PathCombine(AppDomain.CurrentDomain.BaseDirectory, "skins", "default", "images", "logo", "dark_general.png");
return File.Exists(filePath) ? File.ReadAllBytes(filePath) : null;
}
2020-08-24 18:41:06 +00:00
}
2020-07-30 13:33:54 +00:00
2020-10-22 17:57:18 +00:00
[Scope]
2020-08-24 18:41:06 +00:00
public class NotifyConfigurationScope
{
2020-08-31 08:18:07 +00:00
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; }
2020-08-24 18:41:06 +00:00
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
)
2020-07-30 13:33:54 +00:00
{
2020-08-24 18:41:06 +00:00
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;
2020-07-30 13:33:54 +00:00
}
2020-08-31 08:18:07 +00:00
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,
2020-08-31 08:18:07 +00:00
out TenantLogoManager tenantLogoManager,
out AdditionalWhiteLabelSettingsHelper additionalWhiteLabelSettingsHelper,
out TenantUtil tenantUtil,
2020-08-31 08:18:07 +00:00
out CoreBaseSettings coreBaseSettings,
out CommonLinkUtility commonLinkUtility,
out SettingsManager settingsManager,
2020-08-31 08:18:07 +00:00
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;
2020-08-31 08:18:07 +00:00
}
}
2020-10-22 17:57:18 +00:00
public class NotifyConfigurationExtension
{
2020-10-22 17:57:18 +00:00
public static void Register(DIHelper services)
{
2020-10-22 17:57:18 +00:00
services.TryAdd<NotifyConfigurationScope>();
services.TryAdd<TextileStyler>();
services.TryAdd<JabberStyler>();
services.TryAdd<PushStyler>();
}
}
}