Browse Source

加强了无效邮箱的检测

懒得勤快 4 years ago
parent
commit
f3cac1ae07

+ 5 - 1
src/Masuit.MyBlogs.Core/Common/Mails/IMailSender.cs

@@ -1,7 +1,11 @@
-namespace Masuit.MyBlogs.Core.Common.Mails
+using System.Collections.Generic;
+
+namespace Masuit.MyBlogs.Core.Common.Mails
 {
 {
     public interface IMailSender
     public interface IMailSender
     {
     {
         void Send(string title, string content, string tos);
         void Send(string title, string content, string tos);
+        List<string> GetBounces();
+        string AddBounces(string email);
     }
     }
 }
 }

+ 38 - 5
src/Masuit.MyBlogs.Core/Common/Mails/MailgunSender.cs

@@ -1,9 +1,13 @@
-using System;
+using CacheManager.Core;
+using Masuit.Tools.Models;
+using Microsoft.Extensions.Configuration;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Linq;
 using System.Net.Http;
 using System.Net.Http;
 using System.Net.Http.Headers;
 using System.Net.Http.Headers;
 using System.Text;
 using System.Text;
-using Masuit.Tools.Models;
-using Microsoft.Extensions.Configuration;
 
 
 namespace Masuit.MyBlogs.Core.Common.Mails
 namespace Masuit.MyBlogs.Core.Common.Mails
 {
 {
@@ -11,16 +15,18 @@ namespace Masuit.MyBlogs.Core.Common.Mails
     {
     {
         private readonly HttpClient _httpClient;
         private readonly HttpClient _httpClient;
         private readonly IConfiguration _configuration;
         private readonly IConfiguration _configuration;
+        private readonly ICacheManager<List<string>> _cacheManager;
 
 
-        public MailgunSender(HttpClient httpClient, IConfiguration configuration)
+        public MailgunSender(HttpClient httpClient, IConfiguration configuration, ICacheManager<List<string>> cacheManager)
         {
         {
             _configuration = configuration;
             _configuration = configuration;
+            _cacheManager = cacheManager;
             _httpClient = httpClient;
             _httpClient = httpClient;
+            _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes($"api:{_configuration["MailgunConfig:apikey"]}")));
         }
         }
 
 
         public void Send(string title, string content, string tos)
         public void Send(string title, string content, string tos)
         {
         {
-            _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes($"api:{_configuration["MailgunConfig:apikey"]}")));
             EmailAddress email = _configuration["MailgunConfig:from"];
             EmailAddress email = _configuration["MailgunConfig:from"];
             var form = new MultipartFormDataContent
             var form = new MultipartFormDataContent
             {
             {
@@ -31,5 +37,32 @@ namespace Masuit.MyBlogs.Core.Common.Mails
             };
             };
             _httpClient.PostAsync($"https://api.mailgun.net/v3/{email.Domain}/messages", form).Wait();
             _httpClient.PostAsync($"https://api.mailgun.net/v3/{email.Domain}/messages", form).Wait();
         }
         }
+
+        public List<string> GetBounces()
+        {
+            EmailAddress email = _configuration["MailgunConfig:from"];
+            return _cacheManager.GetOrAdd("emailbounces", _ => _httpClient.GetStringAsync($"https://api.mailgun.net/v3/{email.Domain}/bounces").ContinueWith(t =>
+             {
+                 return t.IsCompletedSuccessfully ? ((JArray)JObject.Parse(t.Result)["items"])?.Select(x => (string)x["address"]).ToList() : new List<string>();
+             }).Result);
+        }
+
+        public string AddBounces(string email)
+        {
+            EmailAddress mail = _configuration["MailgunConfig:from"];
+            return _httpClient.PostAsync($"https://api.mailgun.net/v3/{mail.Domain}/bounces", new MultipartFormDataContent
+            {
+                { new StringContent(email,Encoding.UTF8), "address" },
+                { new StringContent("黑名单邮箱",Encoding.UTF8), "error" }
+            }).ContinueWith(t =>
+            {
+                var resp = t.Result;
+                if (resp.IsSuccessStatusCode)
+                {
+                    return (string)JObject.Parse(resp.Content.ReadAsStringAsync().Result)["message"];
+                }
+                return "添加失败";
+            }).Result;
+        }
     }
     }
 }
 }

+ 18 - 0
src/Masuit.MyBlogs.Core/Common/Mails/SmtpSender.cs

@@ -1,5 +1,10 @@
 using Masuit.Tools;
 using Masuit.Tools;
 using Masuit.Tools.Models;
 using Masuit.Tools.Models;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
 
 
 namespace Masuit.MyBlogs.Core.Common.Mails
 namespace Masuit.MyBlogs.Core.Common.Mails
 {
 {
@@ -21,5 +26,18 @@ namespace Masuit.MyBlogs.Core.Common.Mails
             }.Send();
             }.Send();
 #endif
 #endif
         }
         }
+
+        public List<string> GetBounces()
+        {
+            return File.ReadAllText(Path.Combine(AppContext.BaseDirectory + "App_Data", "email-bounces.txt"), Encoding.UTF8).Split(',').ToList();
+        }
+
+        public string AddBounces(string email)
+        {
+            var bounces = GetBounces();
+            bounces.Add(email);
+            File.WriteAllText(Path.Combine(AppContext.BaseDirectory + "App_Data", "email-bounces.txt"), bounces.Join(","));
+            return "添加成功";
+        }
     }
     }
 }
 }

+ 7 - 1
src/Masuit.MyBlogs.Core/Controllers/CommentController.cs

@@ -1,6 +1,7 @@
 using CacheManager.Core;
 using CacheManager.Core;
 using Hangfire;
 using Hangfire;
 using Masuit.MyBlogs.Core.Common;
 using Masuit.MyBlogs.Core.Common;
+using Masuit.MyBlogs.Core.Common.Mails;
 using Masuit.MyBlogs.Core.Extensions;
 using Masuit.MyBlogs.Core.Extensions;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
 using Masuit.MyBlogs.Core.Models.Command;
 using Masuit.MyBlogs.Core.Models.Command;
@@ -16,7 +17,6 @@ using Masuit.Tools.Strings;
 using Microsoft.AspNetCore.Hosting;
 using Microsoft.AspNetCore.Hosting;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc;
-using Microsoft.EntityFrameworkCore.Internal;
 using Microsoft.Net.Http.Headers;
 using Microsoft.Net.Http.Headers;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
@@ -38,6 +38,7 @@ namespace Masuit.MyBlogs.Core.Controllers
         public IInternalMessageService MessageService { get; set; }
         public IInternalMessageService MessageService { get; set; }
         public IWebHostEnvironment HostEnvironment { get; set; }
         public IWebHostEnvironment HostEnvironment { get; set; }
         public ICacheManager<int> CommentFeq { get; set; }
         public ICacheManager<int> CommentFeq { get; set; }
+        public IMailSender MailSender { get; set; }
 
 
         /// <summary>
         /// <summary>
         /// 发表评论
         /// 发表评论
@@ -54,6 +55,11 @@ namespace Masuit.MyBlogs.Core.Controllers
                 return ResultData(null, false, "您提交的内容包含敏感词,被禁止发表,请检查您的内容后尝试重新提交!");
                 return ResultData(null, false, "您提交的内容包含敏感词,被禁止发表,请检查您的内容后尝试重新提交!");
             }
             }
 
 
+            if (MailSender.GetBounces().Any(s => s == dto.Email))
+            {
+                return ResultData(null, false, "邮箱地址错误,请使用有效的邮箱地址!");
+            }
+
             Post post = await PostService.GetByIdAsync(dto.PostId) ?? throw new NotFoundException("评论失败,文章未找到");
             Post post = await PostService.GetByIdAsync(dto.PostId) ?? throw new NotFoundException("评论失败,文章未找到");
             if (post.DisableComment)
             if (post.DisableComment)
             {
             {

+ 7 - 0
src/Masuit.MyBlogs.Core/Controllers/MsgController.cs

@@ -1,6 +1,7 @@
 using CacheManager.Core;
 using CacheManager.Core;
 using Hangfire;
 using Hangfire;
 using Masuit.MyBlogs.Core.Common;
 using Masuit.MyBlogs.Core.Common;
+using Masuit.MyBlogs.Core.Common.Mails;
 using Masuit.MyBlogs.Core.Extensions;
 using Masuit.MyBlogs.Core.Extensions;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
 using Masuit.MyBlogs.Core.Models.Command;
 using Masuit.MyBlogs.Core.Models.Command;
@@ -43,6 +44,7 @@ namespace Masuit.MyBlogs.Core.Controllers
         public IWebHostEnvironment HostEnvironment { get; set; }
         public IWebHostEnvironment HostEnvironment { get; set; }
 
 
         public ICacheManager<int> MsgFeq { get; set; }
         public ICacheManager<int> MsgFeq { get; set; }
+        public IMailSender MailSender { get; set; }
 
 
         /// <summary>
         /// <summary>
         /// 留言板
         /// 留言板
@@ -129,6 +131,11 @@ namespace Masuit.MyBlogs.Core.Controllers
                 return ResultData(null, false, "您提交的内容包含敏感词,被禁止发表,请检查您的内容后尝试重新提交!");
                 return ResultData(null, false, "您提交的内容包含敏感词,被禁止发表,请检查您的内容后尝试重新提交!");
             }
             }
 
 
+            if (MailSender.GetBounces().Any(s => s == dto.Email))
+            {
+                return ResultData(null, false, "邮箱地址错误,请使用有效的邮箱地址!");
+            }
+
             dto.Content = dto.Content.Trim().Replace("<p><br></p>", string.Empty);
             dto.Content = dto.Content.Trim().Replace("<p><br></p>", string.Empty);
             if (MsgFeq.GetOrAdd("Comments:" + ClientIP, 1) > 2)
             if (MsgFeq.GetOrAdd("Comments:" + ClientIP, 1) > 2)
             {
             {

+ 8 - 0
src/Masuit.MyBlogs.Core/Controllers/SystemController.cs

@@ -1,4 +1,5 @@
 using Masuit.MyBlogs.Core.Common;
 using Masuit.MyBlogs.Core.Common;
+using Masuit.MyBlogs.Core.Common.Mails;
 using Masuit.MyBlogs.Core.Extensions.Firewall;
 using Masuit.MyBlogs.Core.Extensions.Firewall;
 using Masuit.MyBlogs.Core.Hubs;
 using Masuit.MyBlogs.Core.Hubs;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
@@ -37,6 +38,7 @@ namespace Masuit.MyBlogs.Core.Controllers
         public ISystemSettingService SystemSettingService { get; set; }
         public ISystemSettingService SystemSettingService { get; set; }
 
 
         public IFirewallRepoter FirewallRepoter { get; set; }
         public IFirewallRepoter FirewallRepoter { get; set; }
+        public IMailSender MailSender { get; set; }
 
 
         /// <summary>
         /// <summary>
         /// 获取硬件基本信息
         /// 获取硬件基本信息
@@ -260,6 +262,12 @@ namespace Masuit.MyBlogs.Core.Controllers
             return RedisHelper.SUnion(RedisHelper.Keys("Email:*")).Select(JObject.Parse).OrderByDescending(o => o["time"]).ToList();
             return RedisHelper.SUnion(RedisHelper.Keys("Email:*")).Select(JObject.Parse).OrderByDescending(o => o["time"]).ToList();
         }
         }
 
 
+        public ActionResult BounceEmail(string email)
+        {
+            var msg = MailSender.AddBounces(email);
+            return Ok(new { msg });
+        }
+
         #region 网站防火墙
         #region 网站防火墙
 
 
         /// <summary>
         /// <summary>

+ 21 - 2
src/Masuit.MyBlogs.Core/Views/Msg/Index_Admin.cshtml

@@ -119,7 +119,7 @@
                                             <span class="label label-primary">${rows[i].Location}</span>
                                             <span class="label label-primary">${rows[i].Location}</span>
                                         </div>
                                         </div>
                                         <div class="pull-right">
                                         <div class="pull-right">
-                                            <span class="label label-success">${rows[i].Email}</span>
+                                            <span class="label label-success" onclick="bounceEmail('${rows[i].Email}')">${rows[i].Email}</span>
                                             <span class="label label-primary">${rows[i].QQorWechat}</span>
                                             <span class="label label-primary">${rows[i].QQorWechat}</span>
                                         </div><br/>
                                         </div><br/>
                                         ${loadMsgs(data.rows, Enumerable.From(data.rows).Where(c => c.ParentId === rows[i].Id).OrderBy(c => c.PostDate).ToArray(), startfloor--)}
                                         ${loadMsgs(data.rows, Enumerable.From(data.rows).Where(c => c.ParentId === rows[i].Id).OrderBy(c => c.PostDate).ToArray(), startfloor--)}
@@ -155,7 +155,7 @@
                                 <span class="label label-primary">${item.Location}</span>
                                 <span class="label label-primary">${item.Location}</span>
                             </div>
                             </div>
                             <div class="pull-right">
                             <div class="pull-right">
-                                <span class="label label-success">${item.Email}</span>
+                                <span class="label label-success" onclick="bounceEmail('${item.Email}')">${item.Email}</span>
                                 <span class="label label-primary">${item.QQorWechat}</span>
                                 <span class="label label-primary">${item.QQorWechat}</span>
                             </div><br/>
                             </div><br/>
                             ${loadMsgs(data, Enumerable.From(data).Where(c => c.ParentId === item.Id).OrderBy(c => c.PostDate), root, depth)}
                             ${loadMsgs(data, Enumerable.From(data).Where(c => c.ParentId === item.Id).OrderBy(c => c.PostDate), root, depth)}
@@ -174,6 +174,25 @@
 		});
 		});
     }
     }
 
 
+    function bounceEmail(email) {
+        swal({
+            title: "确定将这个邮箱添加到黑名单吗?",
+            showCancelButton: true,
+            confirmButtonColor: "#DD6B55",
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            showLoaderOnConfirm: true,
+            animation: true,
+            allowOutsideClick: false
+        }).then(function () {
+            window.post("/system/BounceEmail", { email: email }, function () {
+                swal("邮箱添加到黑名单成功", "", "success");
+            }, (e) => {
+                swal("操作失败,请稍候再试", "", "error");
+            });
+        }, function () { });
+    }
+
     function del(id) {
     function del(id) {
 		swal({
 		swal({
             title: "确认删除这条留言吗?",
             title: "确认删除这条留言吗?",

+ 41 - 30
src/Masuit.MyBlogs.Core/Views/Post/Details_Admin.cshtml

@@ -441,7 +441,7 @@
                                             <span class="label label-primary">${rows[i].Location}</span>
                                             <span class="label label-primary">${rows[i].Location}</span>
                                         </div>
                                         </div>
                                         <div class="pull-right">
                                         <div class="pull-right">
-                                            <span class="label label-success">${rows[i].Email}</span>
+                                            <span class="label label-success" onclick="bounceEmail('${rows[i].Email}')">${rows[i].Email}</span>
                                             <span class="label label-warning">${rows[i].QQorWechat}</span>
                                             <span class="label label-warning">${rows[i].QQorWechat}</span>
                                         </div><br/>
                                         </div><br/>
                                         ${loadComments(data.rows, Enumerable.From(data.rows).Where(c => c.ParentId === rows[i].Id).OrderBy(c => c.CommentDate).ToArray(), startfloor--)}
                                         ${loadComments(data.rows, Enumerable.From(data.rows).Where(c => c.ParentId === rows[i].Id).OrderBy(c => c.CommentDate).ToArray(), startfloor--)}
@@ -478,7 +478,7 @@
                                     <span class="label label-primary">${item.Location}</span>
                                     <span class="label label-primary">${item.Location}</span>
                                 </div>
                                 </div>
                                 <div class="pull-right">
                                 <div class="pull-right">
-                                    <span class="label label-success">${item.Email}</span>
+                                    <span class="label label-success" onclick="bounceEmail('${item.Email}')">${item.Email}</span>
                                     <span class="label label-primary">${item.QQorWechat}</span>
                                     <span class="label label-primary">${item.QQorWechat}</span>
                                 </div><br/>
                                 </div><br/>
                                 ${loadComments(data, Enumerable.From(data).Where(c => c.ParentId === item.Id).OrderBy(c => c.CommentDate), root, depth)}
                                 ${loadComments(data, Enumerable.From(data).Where(c => c.ParentId === item.Id).OrderBy(c => c.CommentDate), root, depth)}
@@ -493,35 +493,46 @@
 			swal(res.Message, "", res.Success ? "success" : "error");
 			swal(res.Message, "", res.Success ? "success" : "error");
 			getcomments();
 			getcomments();
 		}, () => {
 		}, () => {
-                    window.notie.alert({
-						type: 3,
-						text: "请求失败,请稍候再试!",
-						time: 4
-					});
-                });
+            swal("操作失败,请稍候再试", "", "error");
+        });
 	}
 	}
+
+	function bounceEmail(email) {
+        swal({
+            title: "确定将这个邮箱添加到黑名单吗?",
+            showCancelButton: true,
+            confirmButtonColor: "#DD6B55",
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            showLoaderOnConfirm: true,
+            animation: true,
+            allowOutsideClick: false
+        }).then(function () {
+            window.post("/system/BounceEmail", { email: email }, function () {
+                swal("邮箱添加到黑名单成功", "", "success");
+            }, (e) => {
+                swal("操作失败,请稍候再试", "", "error");
+            });
+        }, function () { });
+	}
+
 	function del(id) {
 	function del(id) {
-		swal({
-			title: '确定删除这条评论吗?',
-			type: 'warning',
-			showCancelButton: true,
-			confirmButtonColor: '#3085d6',
-			cancelButtonColor: '#d33',
-			confirmButtonText: '确定',
-			cancelButtonText: '取消',
-			preConfirm: function() {
-				return new Promise(function (resolve) {
-					window.post("/comment/delete", {
-						id: id
-					}, function (res) {
-						resolve(res);
-					}, (e) => reject(e));
-				});
-			},
-			allowOutsideClick: false
-		}).then(function(res) {
-			swal(res.Message, "", res.Success ? "success" : "error");
-			getcomments();
-		});
+        swal({
+            title: "确定删除这条评论吗?",
+            showCancelButton: true,
+            confirmButtonColor: "#DD6B55",
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            showLoaderOnConfirm: true,
+            animation: true,
+            allowOutsideClick: false
+        }).then(function () {
+            $.post("/comment/delete", {
+                id: id
+            }, function (res) {
+                swal(res.Message, "", res.Success ? "success" : "error");
+                getcomments();
+            });
+        }, function () { });
 	}
 	}
 </script>
 </script>