From f59460405fe931ca4acf339eb931fcb5eab4d8fa Mon Sep 17 00:00:00 2001 From: Nikolay Rechkin Date: Thu, 16 Jun 2022 16:07:49 +0300 Subject: [PATCH] Push: push sender --- common/ASC.Core.Common/Context/WorkContext.cs | 8 +- .../Notify/Push/Dao/NotifyData.cs | 50 +++++++++ .../Notify/Push/Dao/NotifyFileData.cs | 41 +++++++ .../Notify/Push/Dao/NotifyFolderData.cs | 39 +++++++ .../ASC.Core.Common/Notify/PushSenderSink.cs | 102 ++++++++++++------ .../Notify/Senders/PushSender.cs | 64 +++++++++++ 6 files changed, 273 insertions(+), 31 deletions(-) create mode 100644 common/ASC.Core.Common/Notify/Push/Dao/NotifyData.cs create mode 100644 common/ASC.Core.Common/Notify/Push/Dao/NotifyFileData.cs create mode 100644 common/ASC.Core.Common/Notify/Push/Dao/NotifyFolderData.cs create mode 100644 common/ASC.Core.Common/Notify/Senders/PushSender.cs diff --git a/common/ASC.Core.Common/Context/WorkContext.cs b/common/ASC.Core.Common/Context/WorkContext.cs index 8f0c6024db..65d35eb0ae 100644 --- a/common/ASC.Core.Common/Context/WorkContext.cs +++ b/common/ASC.Core.Common/Context/WorkContext.cs @@ -41,6 +41,7 @@ public class WorkContext private readonly SmtpSender _smtpSender; private readonly NotifyServiceSender _notifyServiceSender; private readonly TelegramSender _telegramSender; + private readonly PushSender _pushSender; private static bool _notifyStarted; private static bool? _isMono; private static string _monoVersion; @@ -87,7 +88,8 @@ public class WorkContext AWSSender awsSender, SmtpSender smtpSender, NotifyServiceSender notifyServiceSender, - TelegramSender telegramSender + TelegramSender telegramSender, + PushSender pushSender ) { _serviceProvider = serviceProvider; @@ -100,6 +102,7 @@ public class WorkContext _smtpSender = smtpSender; _notifyServiceSender = notifyServiceSender; _telegramSender = telegramSender; + _pushSender = pushSender; } public void NotifyStartUp() @@ -119,6 +122,8 @@ public class WorkContext INotifySender jabberSender = _notifyServiceSender; INotifySender emailSender = _notifyServiceSender; INotifySender telegramSender = _telegramSender; + INotifySender pushSender = _pushSender; + var postman = _configuration["core:notify:postman"]; @@ -148,6 +153,7 @@ public class WorkContext 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)); + NotifyContext.RegisterSender(_dispatchEngine, Constants.NotifyPushSenderSysName, new PushSenderSink(pushSender, _serviceProvider)); NotifyEngine.AddAction(); diff --git a/common/ASC.Core.Common/Notify/Push/Dao/NotifyData.cs b/common/ASC.Core.Common/Notify/Push/Dao/NotifyData.cs new file mode 100644 index 0000000000..260717e1b7 --- /dev/null +++ b/common/ASC.Core.Common/Notify/Push/Dao/NotifyData.cs @@ -0,0 +1,50 @@ +// (c) Copyright Ascensio System SIA 2010-2022 +// +// This program is a free software product. +// You can redistribute it and/or modify it under the terms +// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software +// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended +// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of +// any third-party rights. +// +// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see +// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html +// +// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021. +// +// The interactive user interfaces in modified source and object code versions of the Program must +// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3. +// +// Pursuant to Section 7(b) of the License you must retain the original Product logo when +// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under +// trademark law for use of our trademarks. +// +// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing +// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0 +// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + +namespace ASC.Core.Common.Notify.Push.Dao; +[Serializable] +public class NotifyData +{ + [JsonProperty("portal")] + [DataMember(Name = "portal")] + public string Portal { get; set; } + + [JsonProperty("email")] + [DataMember(Name = "email")] + public string Email { get; set; } + + [JsonProperty("file")] + [DataMember(Name = "file")] + public NotifyFileData File { get; set; } + + [JsonProperty("folder")] + [DataMember(Name = "folder")] + public NotifyFolderData Folder { get; set; } + + [JsonProperty("originalUrl")] + [DataMember(Name = "originalUrl")] + public string OriginalUrl { get; set; } +} diff --git a/common/ASC.Core.Common/Notify/Push/Dao/NotifyFileData.cs b/common/ASC.Core.Common/Notify/Push/Dao/NotifyFileData.cs new file mode 100644 index 0000000000..76aead5fa0 --- /dev/null +++ b/common/ASC.Core.Common/Notify/Push/Dao/NotifyFileData.cs @@ -0,0 +1,41 @@ +// (c) Copyright Ascensio System SIA 2010-2022 +// +// This program is a free software product. +// You can redistribute it and/or modify it under the terms +// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software +// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended +// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of +// any third-party rights. +// +// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see +// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html +// +// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021. +// +// The interactive user interfaces in modified source and object code versions of the Program must +// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3. +// +// Pursuant to Section 7(b) of the License you must retain the original Product logo when +// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under +// trademark law for use of our trademarks. +// +// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing +// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0 +// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + +namespace ASC.Core.Common.Notify.Push.Dao; +[Serializable] +public class NotifyFileData +{ + [JsonProperty("id")] + [DataMember(Name = "id")] + public string Id { get; set; } + [JsonProperty("title")] + [DataMember(Name = "title")] + public string Title { get; set; } + [JsonProperty("extension")] + [DataMember(Name = "extension")] + public string Extension { get; set; } + +} diff --git a/common/ASC.Core.Common/Notify/Push/Dao/NotifyFolderData.cs b/common/ASC.Core.Common/Notify/Push/Dao/NotifyFolderData.cs new file mode 100644 index 0000000000..b8deddb206 --- /dev/null +++ b/common/ASC.Core.Common/Notify/Push/Dao/NotifyFolderData.cs @@ -0,0 +1,39 @@ +// (c) Copyright Ascensio System SIA 2010-2022 +// +// This program is a free software product. +// You can redistribute it and/or modify it under the terms +// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software +// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended +// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of +// any third-party rights. +// +// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see +// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html +// +// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021. +// +// The interactive user interfaces in modified source and object code versions of the Program must +// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3. +// +// Pursuant to Section 7(b) of the License you must retain the original Product logo when +// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under +// trademark law for use of our trademarks. +// +// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing +// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0 +// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + +namespace ASC.Core.Common.Notify.Push.Dao; +public class NotifyFolderData +{ + [JsonProperty("id")] + [DataMember(Name = "id")] + public string Id { get; set; } + [JsonProperty("parentId")] + [DataMember(Name = "parentId")] + public string ParentId { get; set; } + [JsonProperty("rootFolderType")] + [DataMember(Name = "rootFolderType")] + public int RootFolderType { get; set; } +} diff --git a/common/ASC.Core.Common/Notify/PushSenderSink.cs b/common/ASC.Core.Common/Notify/PushSenderSink.cs index a148958343..eb03c39cef 100644 --- a/common/ASC.Core.Common/Notify/PushSenderSink.cs +++ b/common/ASC.Core.Common/Notify/PushSenderSink.cs @@ -24,19 +24,22 @@ // 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.Core.Common.Notify.Push.Dao; + using Constants = ASC.Core.Configuration.Constants; namespace ASC.Core.Common.Notify; class PushSenderSink : Sink { - private readonly ILogger _logger; + private static readonly string _senderName = Constants.NotifyPushSenderSysName; + private readonly INotifySender _sender; private bool _configured = true; - public PushSenderSink(IServiceProvider serviceProvider, ILogger logger) + public PushSenderSink(INotifySender sender, IServiceProvider serviceProvider) { + _sender = sender ?? throw new ArgumentNullException(nameof(sender)); _serviceProvider = serviceProvider; - _logger = logger; } private readonly IServiceProvider _serviceProvider; @@ -45,42 +48,81 @@ class PushSenderSink : Sink { try { + using var scope = _serviceProvider.CreateScope(); + + var result = SendResult.OK; var tenantManager = scope.ServiceProvider.GetService(); + var userManager = scope.ServiceProvider.GetService(); + var user = userManager.GetUsers(new Guid(message.Recipient.ID)); + var username = user.UserName; - var notification = new PushNotification + if (string.IsNullOrEmpty(username)) { - Module = GetTagValue(message, PushConstants.PushModuleTagName), - Action = GetTagValue(message, PushConstants.PushActionTagName), - Item = GetTagValue(message, PushConstants.PushItemTagName), - ParentItem = GetTagValue(message, PushConstants.PushParentItemTagName), - Message = message.Body, - ShortMessage = message.Subject - }; - - if (_configured) - { - try - { - using var pushClient = new PushServiceClient(); - pushClient.EnqueueNotification( - tenantManager.GetCurrentTenant().Id, - message.Recipient.ID, - notification, - new List()); - } - catch (InvalidOperationException) - { - _configured = false; - _logger.DebugPushSender(); - } + result = SendResult.IncorrectRecipient; } else { - _logger.DebugPushSender(); + var fromTag = message.Arguments.FirstOrDefault(x => x.Tag.Equals("MessageFrom")); + var productID = message.Arguments.FirstOrDefault(x => x.Tag.Equals("__ProductID")); + var originalUrl = message.Arguments.FirstOrDefault(x => x.Tag.Equals("DocumentURL")); + + var folderId = message.Arguments.FirstOrDefault(x => x.Tag.Equals("FolderId")); + var rootFolderId = message.Arguments.FirstOrDefault(x => x.Tag.Equals("FolderParentId")); + var rootFolderType = message.Arguments.FirstOrDefault(x => x.Tag.Equals("FolderRootFolderType")); + + + var notifyData = new NotifyData() + { + Email = user.Email, + Portal = tenantManager.GetCurrentTenant().TrustedDomains.FirstOrDefault(), + OriginalUrl = originalUrl != null && originalUrl.Value != null ? originalUrl.Value.ToString() : "", + Folder = new NotifyFolderData + { + Id = folderId != null && folderId.Value != null ? folderId.Value.ToString() : "", + ParentId = rootFolderId != null && rootFolderId.Value != null ? rootFolderId.Value.ToString() : "", + RootFolderType = rootFolderType != null && rootFolderType.Value != null ? (int)rootFolderType.Value : 0 + }, + }; + + var msg = (NoticeMessage)message; + + if (msg.ObjectID.StartsWith("file_")) + { + var documentTitle = message.Arguments.FirstOrDefault(x => x.Tag.Equals("DocumentTitle")); + var documentExtension = message.Arguments.FirstOrDefault(x => x.Tag.Equals("DocumentExtension")); + + notifyData.File = new NotifyFileData() + { + Id = msg.ObjectID.Substring(5), + Title = documentTitle != null && documentTitle.Value != null ? documentTitle.Value.ToString() : "", + Extension = documentExtension != null && documentExtension.Value != null ? documentExtension.Value.ToString() : "" + + }; + } + + var jsonNotifyData = JsonConvert.SerializeObject(notifyData); + var tenant = tenantManager.GetCurrentTenant(false); + + var m = new NotifyMessage + { + // To = username, + Subject = fromTag != null && fromTag.Value != null ? fromTag.Value.ToString() : message.Subject, + ContentType = message.ContentType, + Content = message.Body, + Sender = Constants.NotifyPushSenderSysName, + CreationDate = DateTime.UtcNow, + ProductID = fromTag != null && fromTag.Value != null ? productID.Value.ToString() : null, + ObjectID = msg.ObjectID, + // Tenant = tenant == null ? Tenant.DefaultTenant : tenant.Id, + Data = jsonNotifyData + }; + + _sender.Send(m); + } - return new SendResponse(message, Constants.NotifyPushSenderSysName, SendResult.OK); + return new SendResponse(message, Constants.NotifyPushSenderSysName, result); } catch (Exception error) { diff --git a/common/ASC.Core.Common/Notify/Senders/PushSender.cs b/common/ASC.Core.Common/Notify/Senders/PushSender.cs new file mode 100644 index 0000000000..f2a99816eb --- /dev/null +++ b/common/ASC.Core.Common/Notify/Senders/PushSender.cs @@ -0,0 +1,64 @@ +// (c) Copyright Ascensio System SIA 2010-2022 +// +// This program is a free software product. +// You can redistribute it and/or modify it under the terms +// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software +// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended +// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of +// any third-party rights. +// +// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see +// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html +// +// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021. +// +// The interactive user interfaces in modified source and object code versions of the Program must +// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3. +// +// Pursuant to Section 7(b) of the License you must retain the original Product logo when +// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under +// trademark law for use of our trademarks. +// +// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing +// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0 +// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + +namespace ASC.Core.Notify.Senders; + +[Singletone] +public class PushSender : INotifySender +{ + private readonly ILogger _logger; + private readonly IServiceProvider _serviceProvider; + + public PushSender(ILoggerProvider options, IServiceProvider serviceProvider) + { + _logger = options.CreateLogger("ASC"); + _serviceProvider = serviceProvider; + } + + + public void Init(IDictionary properties) { } + + public NoticeSendResult Send(NotifyMessage m) + { + if (!string.IsNullOrEmpty(m.Content)) + { + m.Content = m.Content.Replace("\r\n", "\n").Trim('\n', '\r', ' '); + m.Content = Regex.Replace(m.Content, "\n{3,}", "\n\n"); + } + try + { + using var scope = _serviceProvider.CreateScope(); + var TelegramHelper = scope.ServiceProvider.GetService(); + TelegramHelper.SendMessage(m); + } + catch (Exception e) + { + _logger.ErrorUnexpected(e); + } + + return NoticeSendResult.OK; + } +}