Example #1
0
        // Private methods

        async Task <IdeaComment> EntityReplyCreated(IdeaComment reply)
        {
            // If the created reply is hidden, no need to send notifications
            // Replies can be hidden automatically, for example if they are detected as SPAM
            if (reply.IsHidden())
            {
                return(reply);;
            }

            // We need an entity to build the url
            if (reply.EntityId <= 0)
            {
                return(reply);
            }

            // Get entity
            var entity = await _entityStore.GetByIdAsync(reply.EntityId);

            // Ensure the entity exists
            if (entity == null)
            {
                return(reply);
            }

            // Build url to entity reply
            var baseUri = await _capturedRouterUrlHelper.GetBaseUrlAsync();

            var url = _capturedRouterUrlHelper.GetRouteUrl(baseUri, new RouteValueDictionary()
            {
                ["area"]         = "Plato.Ideas",
                ["controller"]   = "Home",
                ["action"]       = "Reply",
                ["opts.id"]      = entity.Id,
                ["opts.alias"]   = entity.Alias,
                ["opts.replyId"] = reply.Id
            });

            // Build the message to post to Slack
            var sb = new StringBuilder();

            sb
            .Append("RE: ")
            .Append(entity.Title)
            .Append(" - ")
            .Append(baseUri)
            .Append(url);

            // Finally post our message to Slack
            var response = await _slackService.PostAsync(sb.ToString());

            // Log any errors that may have occurred
            if (!response.Success)
            {
                if (_logger.IsEnabled(LogLevel.Error))
                {
                    _logger.LogError($"An error occurred whilst attempting to post a reply to Slack. Response from POST request to Slack Webhook Url: {response.Error}");
                }
            }

            // Continue processing the broker pipeline
            return(reply);
        }
Example #2
0
        public async Task <ICommandResult <Comment> > SendAsync(INotificationContext <Comment> context)
        {
            // Validate
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (context.Notification == null)
            {
                throw new ArgumentNullException(nameof(context.Notification));
            }

            if (context.Notification.Type == null)
            {
                throw new ArgumentNullException(nameof(context.Notification.Type));
            }

            if (context.Notification.To == null)
            {
                throw new ArgumentNullException(nameof(context.Notification.To));
            }

            // Ensure correct notification provider
            if (!context.Notification.Type.Name.Equals(WebNotifications.CommentSpam.Name, StringComparison.Ordinal))
            {
                return(null);
            }

            // Create result
            var result = new CommandResult <Comment>();

            // Get entity for reply
            var entity = await _entityStore.GetByIdAsync(context.Model.EntityId);

            // Ensure we found the entity
            if (entity == null)
            {
                return(result.Failed(
                           $"No entity with id '{context.Model.EntityId}' exists. Failed to send reply spam web notification."));
            }

            var baseUri = await _urlHelper.GetBaseUrlAsync();

            var url = _urlHelper.GetRouteUrl(baseUri, new RouteValueDictionary()
            {
                ["area"]         = "Plato.Articles",
                ["controller"]   = "Home",
                ["action"]       = "Reply",
                ["opts.id"]      = entity.Id,
                ["opts.alias"]   = entity.Alias,
                ["opts.replyId"] = context.Model.Id
            });

            //// Build notification
            var userNotification = new UserNotification()
            {
                NotificationName = context.Notification.Type.Name,
                UserId           = context.Notification.To.Id,
                Title            = S["Possible SPAM"].Value,
                Message          = S["Am article comment has been detected as SPAM!"],
                Url           = url,
                CreatedUserId = context.Notification.From?.Id ?? 0,
                CreatedDate   = DateTimeOffset.UtcNow
            };

            // Create notification
            var userNotificationResult = await _userNotificationManager.CreateAsync(userNotification);

            if (userNotificationResult.Succeeded)
            {
                return(result.Success(context.Model));
            }

            return(result.Failed(userNotificationResult.Errors?.ToArray()));
        }
Example #3
0
        public async Task <ICommandResult <Issue> > SendAsync(INotificationContext <Issue> context)
        {
            // Ensure correct notification provider
            if (!context.Notification.Type.Name.Equals(EmailNotifications.IssueSpam.Name, StringComparison.Ordinal))
            {
                return(null);
            }

            // Create result
            var result = new CommandResult <Issue>();

            // Get email template
            const string templateId = "NewIssueSpam";

            // Tasks run in a background thread and don't have access to HttpContext
            // Create a dummy principal to represent the user so we can still obtain
            // the current culture for the email
            var principal = await _claimsPrincipalFactory.CreateAsync((User)context.Notification.To);

            var culture = await _contextFacade.GetCurrentCultureAsync(principal.Identity);

            var email = await _localeStore.GetFirstOrDefaultByKeyAsync <LocaleEmail>(culture, templateId);

            if (email == null)
            {
                return(result.Failed(
                           $"No email template with the Id '{templateId}' exists within the 'locales/{culture}/emails.json' file!"));
            }

            // Build topic url
            var baseUri = await _capturedRouterUrlHelper.GetBaseUrlAsync();

            var url = _capturedRouterUrlHelper.GetRouteUrl(baseUri, new RouteValueDictionary()
            {
                ["area"]       = "Plato.Issues",
                ["controller"] = "Home",
                ["action"]     = "Display",
                ["opts.id"]    = context.Model.Id,
                ["opts.alias"] = context.Model.Alias
            });

            // Build message from template
            var message = email.BuildMailMessage();

            message.Body = string.Format(
                email.Message,
                context.Notification.To.DisplayName,
                context.Model.Title,
                baseUri + url);
            ;
            message.IsBodyHtml = true;
            message.To.Add(new MailAddress(context.Notification.To.Email));

            // Send message
            var emailResult = await _emailManager.SaveAsync(message);

            if (emailResult.Succeeded)
            {
                return(result.Success(context.Model));
            }

            return(result.Failed(emailResult.Errors?.ToArray()));
        }
Example #4
0
        public async Task <ICommandResult <ReportSubmission <Comment> > > SendAsync(INotificationContext <ReportSubmission <Comment> > context)
        {
            // Ensure correct notification provider
            if (!context.Notification.Type.Name.Equals(EmailNotifications.CommentReport.Name, StringComparison.Ordinal))
            {
                return(null);
            }

            // Create result
            var result = new CommandResult <ReportSubmission <Comment> >();

            // Get email template
            const string templateId = "NewCommentReport";

            // Tasks run in a background thread and don't have access to HttpContext
            // Create a dummy principal to represent the user so we can still obtain
            // the current culture for the email
            var principal = await _claimsPrincipalFactory.CreateAsync((User)context.Notification.To);

            var culture = await _contextFacade.GetCurrentCultureAsync(principal.Identity);

            var email = await _localeStore.GetFirstOrDefaultByKeyAsync <LocaleEmail>(culture, templateId);

            if (email == null)
            {
                return(result.Failed(
                           $"No email template with the Id '{templateId}' exists within the 'locales/{culture}/emails.json' file!"));
            }

            // Get entity for reply
            var entity = await _articleStore.GetByIdAsync(context.Model.What.EntityId);

            // We need an entity for the reply
            if (entity == null)
            {
                return(result.Failed(
                           $"No entity with id '{context.Model.What.EntityId}' exists. Failed to send reply spam email notification."));
            }

            // Build entity url
            var baseUri = await _capturedRouterUrlHelper.GetBaseUrlAsync();

            var url = _capturedRouterUrlHelper.GetRouteUrl(baseUri, new RouteValueDictionary()
            {
                ["area"]         = "Plato.Articles",
                ["controller"]   = "Home",
                ["action"]       = "Reply",
                ["opts.id"]      = entity.Id,
                ["opts.alias"]   = entity.Alias,
                ["opts.replyId"] = context.Model.What.Id
            });

            // Reason given text
            var reasonText = S["None Provided"];

            if (ReportReasons.Reasons.ContainsKey(context.Model.Why))
            {
                reasonText = S[ReportReasons.Reasons[context.Model.Why]];
            }

            // Build message from template
            var message = email.BuildMailMessage();

            message.Body = string.Format(
                email.Message,
                context.Notification.To.DisplayName,
                entity.Title,
                reasonText.Value,
                context.Model.Who.DisplayName,
                context.Model.Who.UserName,
                baseUri + url);

            message.IsBodyHtml = true;
            message.To.Add(new MailAddress(context.Notification.To.Email));

            // Send message
            var emailResult = await _emailManager.SaveAsync(message);

            if (emailResult.Succeeded)
            {
                return(result.Success(context.Model));
            }

            return(result.Failed(emailResult.Errors?.ToArray()));
        }
Example #5
0
        public async Task <ICommandResult <ReportSubmission <Doc> > > SendAsync(INotificationContext <ReportSubmission <Doc> > context)
        {
            // Validate
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (context.Notification == null)
            {
                throw new ArgumentNullException(nameof(context.Notification));
            }

            if (context.Notification.Type == null)
            {
                throw new ArgumentNullException(nameof(context.Notification.Type));
            }

            if (context.Notification.To == null)
            {
                throw new ArgumentNullException(nameof(context.Notification.To));
            }

            // Ensure correct notification provider
            if (!context.Notification.Type.Name.Equals(WebNotifications.DocReport.Name, StringComparison.Ordinal))
            {
                return(null);
            }

            // Create result
            var result = new CommandResult <ReportSubmission <Doc> >();

            var baseUri = await _urlHelper.GetBaseUrlAsync();

            var url = _urlHelper.GetRouteUrl(baseUri, new RouteValueDictionary()
            {
                ["area"]       = "Plato.Docs",
                ["controller"] = "Home",
                ["action"]     = "Display",
                ["opts.id"]    = context.Model.What.Id,
                ["opts.alias"] = context.Model.What.Alias
            });

            // Get reason given text
            var reasonText = S["Doc Reported"];

            if (ReportReasons.Reasons.ContainsKey(context.Model.Why))
            {
                reasonText = S[ReportReasons.Reasons[context.Model.Why]];
            }

            //// Build notification
            var userNotification = new UserNotification()
            {
                NotificationName = context.Notification.Type.Name,
                UserId           = context.Notification.To.Id,
                Title            = reasonText.Value,
                Message          = S["A doc has been reported!"],
                Url           = url,
                CreatedUserId = context.Notification.From?.Id ?? 0,
                CreatedDate   = DateTimeOffset.UtcNow
            };

            // Create notification
            var userNotificationResult = await _userNotificationManager.CreateAsync(userNotification);

            if (userNotificationResult.Succeeded)
            {
                return(result.Success(context.Model));
            }

            return(result.Failed(userNotificationResult.Errors?.ToArray()));
        }
Example #6
0
        public async Task <ICommandResult <Badge> > SendAsync(INotificationContext <Badge> context)
        {
            // Validate
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (context.Notification == null)
            {
                throw new ArgumentNullException(nameof(context.Notification));
            }

            if (context.Notification.Type == null)
            {
                throw new ArgumentNullException(nameof(context.Notification.Type));
            }

            if (context.Notification.To == null)
            {
                throw new ArgumentNullException(nameof(context.Notification.To));
            }

            // Ensure correct notification provider
            if (!context.Notification.Type.Name.Equals(WebNotifications.NewBadge.Name, StringComparison.Ordinal))
            {
                return(null);
            }

            // Create result
            var result = new CommandResult <Badge>();

            var baseUri = await _urlHelper.GetBaseUrlAsync();

            var url = _urlHelper.GetRouteUrl(baseUri, new RouteValueDictionary()
            {
                ["area"]       = "Plato.Users.Badges",
                ["controller"] = "Profile",
                ["action"]     = "Index",
                ["opts.id"]    = context.Notification.To.Id,
                ["opts.alias"] = context.Notification.To.Alias
            });

            //// Build notification
            var userNotification = new UserNotification()
            {
                NotificationName = context.Notification.Type.Name,
                UserId           = context.Notification.To.Id,
                Title            = context.Model.Title,
                Message          = $"{S["You've earned the"].Value} '{context.Model.Title}' {S["badge"].Value}",
                Url           = url,
                CreatedUserId = context.Notification.From?.Id ?? 0,
                CreatedDate   = DateTimeOffset.UtcNow
            };

            // Create notification
            var userNotificationResult = await _userNotificationManager.CreateAsync(userNotification);

            if (userNotificationResult.Succeeded)
            {
                return(result.Success(context.Model));
            }

            return(result.Failed(userNotificationResult.Errors?.ToArray()));
        }
Example #7
0
        public async Task <ICommandResult <Issue> > SendAsync(INotificationContext <Issue> context)
        {
            // Validate
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (context.Notification == null)
            {
                throw new ArgumentNullException(nameof(context.Notification));
            }

            if (context.Notification.Type == null)
            {
                throw new ArgumentNullException(nameof(context.Notification.Type));
            }

            if (context.Notification.To == null)
            {
                throw new ArgumentNullException(nameof(context.Notification.To));
            }

            // Ensure correct notification provider
            if (!context.Notification.Type.Name.Equals(WebNotifications.IssueSpam.Name, StringComparison.Ordinal))
            {
                return(null);
            }

            // Create result
            var result = new CommandResult <Issue>();

            var baseUri = await _urlHelper.GetBaseUrlAsync();

            var url = _urlHelper.GetRouteUrl(baseUri, new RouteValueDictionary()
            {
                ["area"]       = "Plato.Issues",
                ["controller"] = "Home",
                ["action"]     = "Display",
                ["opts.id"]    = context.Model.Id,
                ["opts.alias"] = context.Model.Alias
            });

            //// Build notification
            var userNotification = new UserNotification()
            {
                NotificationName = context.Notification.Type.Name,
                UserId           = context.Notification.To.Id,
                Title            = S["Possible SPAM"].Value,
                Message          = S["An issue has been detected as SPAM!"],
                Url           = url,
                CreatedUserId = context.Notification.From?.Id ?? 0,
                CreatedDate   = DateTimeOffset.UtcNow
            };

            // Create notification
            var userNotificationResult = await _userNotificationManager.CreateAsync(userNotification);

            if (userNotificationResult.Succeeded)
            {
                return(result.Success(context.Model));
            }

            return(result.Failed(userNotificationResult.Errors?.ToArray()));
        }
Example #8
0
        public async Task <ICommandResult <FileInvite> > SendLinkInviteAsync(FileInvite invite)
        {
            if (invite == null)
            {
                throw new ArgumentException(nameof(invite));
            }

            // Create result
            var result = new CommandResult <FileInvite>();

            if (invite.FileId <= 0)
            {
                return(result.Failed(T["A file is required to share"].Value));
            }

            if (string.IsNullOrEmpty(invite.Email))
            {
                return(result.Failed(T["An email address is required"].Value));
            }

            // Get file
            var file = await _fileStore.GetByIdAsync(invite.FileId);

            // Ensure we found the file
            if (file == null)
            {
                return(result.Failed(T["The file could not be found"].Value));
            }

            // Get email template
            const string templateId = "ShareFileLink";

            // Configured culture
            var culture = await _contextFacade.GetCurrentCultureAsync();

            var email = await _localeStore.GetFirstOrDefaultByKeyAsync <LocaleEmail>(culture, templateId);

            if (email != null)
            {
                // Ensure email is safe for URL
                var token = Convert.ToBase64String(Encoding.UTF8.GetBytes(invite.Email));

                // Build invite URL
                var baseUri = await _capturedRouterUrlHelper.GetBaseUrlAsync();

                var url = _capturedRouterUrlHelper.GetRouteUrl(baseUri, new RouteValueDictionary()
                {
                    ["area"]       = "Plato.Files.Sharing",
                    ["controller"] = "Home",
                    ["action"]     = "Index",
                    ["id"]         = invite.Id,
                    ["token"]      = token,
                    ["alias"]      = file.Alias
                });

                // Build message from template
                var message = email.BuildMailMessage();
                message.Subject = string.Format(
                    email.Subject,
                    invite.CreatedBy.DisplayName);
                message.Body = string.Format(
                    email.Message,
                    invite.CreatedBy.DisplayName,
                    file.Name,
                    file.ContentLength.ToFriendlyFileSize(),
                    baseUri + url);
                message.IsBodyHtml = true;
                message.To.Add(new MailAddress(invite.Email));

                // Send message
                var emailResult = await _emailManager.SaveAsync(message);

                if (emailResult.Succeeded)
                {
                    return(result.Success(invite));
                }

                return(result.Failed(emailResult.Errors?.ToArray()));
            }

            return(result.Failed($"No email template with the Id '{templateId}' exists within the 'locales/{culture}/emails.json' file!"));
        }