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

346 lines
15 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;
using ASC.Common.Logging;
using ASC.Core;
using ASC.Core.Tenants;
using ASC.Core.Users;
using ASC.Notify;
using ASC.Notify.Engine;
using ASC.Notify.Messages;
using ASC.Notify.Patterns;
using ASC.Web.Core;
using ASC.Web.Studio.Utility;
using MimeKit.Utils;
using ASC.Web.Core.WhiteLabel;
using ASC.Common.Notify.Engine;
namespace ASC.Web.Studio.Core.Notify
{
public static 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);
public static void Configure()
{
lock (locker)
{
if (!configured)
{
configured = true;
WorkContext.NotifyContext.NotifyClientRegistration += NotifyClientRegisterCallback;
WorkContext.NotifyContext.NotifyEngine.BeforeTransferRequest += BeforeTransferRequest;
}
}
}
public static void RegisterSendMethods()
{
StudioNotifyService.Instance.RegisterSendMethod();
}
private static void NotifyClientRegisterCallback(Context context, INotifyClient client)
{
#region url correction
var absoluteUrl = new SendInterceptorSkeleton(
"Web.UrlAbsoluter",
InterceptorPlace.MessageSend,
InterceptorLifetime.Global,
(r, p) =>
{
if (r != null && r.CurrentMessage != null && r.CurrentMessage.ContentType == Pattern.HTMLContentType)
{
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 ?
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 ?
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,
(r, p) =>
{
try
{
// culture
var u = Constants.LostUser;
if (32 <= r.Recipient.ID.Length)
{
var guid = default(Guid);
try
{
guid = new Guid(r.Recipient.ID);
}
catch (FormatException) { }
catch (OverflowException) { }
if (guid != default(Guid))
{
u = CoreContext.UserManager.GetUsers(guid);
}
}
if (Constants.LostUser.Equals(u))
{
u = CoreContext.UserManager.GetUserByEmail(r.Recipient.ID);
}
if (Constants.LostUser.Equals(u))
{
u = CoreContext.UserManager.GetUserByUserName(r.Recipient.ID);
}
if (!Constants.LostUser.Equals(u))
{
var culture = !string.IsNullOrEmpty(u.CultureName) ? u.GetCulture() : CoreContext.TenantManager.GetCurrentTenant().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)
{
LogManager.GetLogger("ASC").Error(error);
}
return false;
});
client.AddInterceptor(securityAndCulture);
#endregion
#region white label correction
var whiteLabel = new SendInterceptorSkeleton(
"WhiteLabelInterceptor",
InterceptorPlace.MessageSend,
InterceptorLifetime.Global,
(r, p) =>
{
try
{
var tags = r.Arguments;
var logoTextTag = tags.FirstOrDefault(a => a.Tag == CommonTags.LetterLogoText);
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)
{
LogManager.GetLogger("ASC").Error(error);
}
return false;
});
client.AddInterceptor(whiteLabel);
#endregion
}
private static void BeforeTransferRequest(NotifyEngine sender, NotifyRequest request)
{
var aid = Guid.Empty;
var aname = string.Empty;
if (SecurityContext.IsAuthenticated)
{
aid = SecurityContext.CurrentAccount.ID;
if (CoreContext.UserManager.UserExists(aid))
{
aname = CoreContext.UserManager.GetUsers(aid).DisplayUserName(false)
.Replace(">", "&#62")
.Replace("<", "&#60");
}
}
IProduct product;
IModule module;
2019-07-02 15:30:31 +00:00
//TODOL httpContext
CommonLinkUtility.GetLocationByRequest(out product, out module, null);
if (product == null && CallContext.GetData("asc.web.product_id") != null)
{
product = WebItemManager.Instance[(Guid)CallContext.GetData("asc.web.product_id")] as IProduct;
}
var logoText = TenantWhiteLabelSettings.DefaultLogoText;
if ((TenantExtra.Enterprise || CoreContext.Configuration.CustomMode) && !MailWhiteLabelSettings.Instance.IsDefault)
{
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.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.RecipientID, Context.SYS_RECIPIENT_ID));
request.Arguments.Add(new TagValue(CommonTags.ProfileUrl, CommonLinkUtility.GetFullAbsolutePath(CommonLinkUtility.GetMyStaff())));
request.Arguments.Add(new TagValue(CommonTags.HelpLink, CommonLinkUtility.GetHelpLink(false)));
request.Arguments.Add(new TagValue(CommonTags.LetterLogoText, logoText));
request.Arguments.Add(new TagValue(CommonTags.MailWhiteLabelSettings, MailWhiteLabelSettings.Instance));
if (!request.Arguments.Any(x => CommonTags.SendFrom.Equals(x.Tag)))
{
request.Arguments.Add(new TagValue(CommonTags.SendFrom, CoreContext.TenantManager.GetCurrentTenant().Name));
}
AddLetterLogo(request);
}
private static void AddLetterLogo(NotifyRequest request)
{
if (TenantExtra.Enterprise || CoreContext.Configuration.CustomMode)
{
try
{
var logoData = TenantLogoManager.GetMailLogoDataFromCache();
if (logoData == null)
{
var logoStream = TenantLogoManager.GetWhitelabelMailLogo();
logoData = ReadStreamToByteArray(logoStream) ?? GetDefaultMailLogo();
if (logoData != null)
TenantLogoManager.InsertMailLogoDataToCache(logoData);
}
if (logoData != null)
{
var attachment = new NotifyMessageAttachment
{
FileName = "logo.png",
Content = 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)
{
LogManager.GetLogger("ASC").Error(error);
}
}
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)
{
using (var memoryStream = new MemoryStream())
{
inputStream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
}
}
public static byte[] GetDefaultMailLogo()
{
var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "skins", "default", "images", "onlyoffice_logo", "dark_general.png");
return File.Exists(filePath) ? File.ReadAllBytes(filePath) : null;
}
}
}