SystemController.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. using Masuit.MyBlogs.Core.Common;
  2. using Masuit.MyBlogs.Core.Common.Mails;
  3. using Masuit.MyBlogs.Core.Extensions.Firewall;
  4. using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
  5. using Masuit.MyBlogs.Core.Models.Entity;
  6. using Masuit.MyBlogs.Core.Models.Enum;
  7. using Masuit.Tools;
  8. using Masuit.Tools.DateTimeExt;
  9. using Masuit.Tools.Logging;
  10. using Masuit.Tools.Models;
  11. using Masuit.Tools.Systems;
  12. using Microsoft.AspNetCore.Mvc;
  13. using Newtonsoft.Json;
  14. using Newtonsoft.Json.Linq;
  15. using System;
  16. using System.Collections.Generic;
  17. using System.IO;
  18. using System.Linq;
  19. using System.Net;
  20. using System.Text;
  21. using System.Threading.Tasks;
  22. namespace Masuit.MyBlogs.Core.Controllers
  23. {
  24. /// <summary>
  25. /// 系统设置
  26. /// </summary>
  27. public class SystemController : AdminController
  28. {
  29. /// <summary>
  30. /// 系统设置
  31. /// </summary>
  32. public ISystemSettingService SystemSettingService { get; set; }
  33. /// <summary>
  34. /// 获取历史性能计数器
  35. /// </summary>
  36. /// <returns></returns>
  37. public IActionResult GetCounterHistory()
  38. {
  39. var list = PerfCounter.List.Count < 5000 ? PerfCounter.List : PerfCounter.List.GroupBy(c => c.Time / 60000).Select(g => new PerfCounter.PerformanceCounter()
  40. {
  41. Time = g.Key * 60000,
  42. CpuLoad = g.Average(c => c.CpuLoad),
  43. DiskRead = g.Average(c => c.DiskRead),
  44. DiskWrite = g.Average(c => c.DiskWrite),
  45. Download = g.Average(c => c.Download),
  46. Upload = g.Average(c => c.Upload),
  47. MemoryUsage = g.Average(c => c.MemoryUsage)
  48. }).ToList();
  49. return Ok(new
  50. {
  51. cpu = list.Select(c => new[]
  52. {
  53. c.Time,
  54. c.CpuLoad.ConvertTo<long>()
  55. }),
  56. mem = list.Select(c => new[]
  57. {
  58. c.Time,
  59. c.MemoryUsage.ConvertTo<long>()
  60. }),
  61. read = list.Select(c => new[]
  62. {
  63. c.Time,
  64. c.DiskRead.ConvertTo<long>()
  65. }),
  66. write = list.Select(c => new[]
  67. {
  68. c.Time,
  69. c.DiskWrite.ConvertTo<long>()
  70. }),
  71. down = list.Select(c => new[]
  72. {
  73. c.Time,
  74. c.Download.ConvertTo<long>()
  75. }),
  76. up = list.Select(c => new[]
  77. {
  78. c.Time,
  79. c.Upload.ConvertTo<long>()
  80. })
  81. });
  82. }
  83. /// <summary>
  84. /// 获取设置信息
  85. /// </summary>
  86. /// <returns></returns>
  87. public ActionResult GetSettings()
  88. {
  89. var list = SystemSettingService.GetAll().Select(s => new
  90. {
  91. s.Name,
  92. s.Value
  93. }).ToList();
  94. return ResultData(list);
  95. }
  96. /// <summary>
  97. /// 保存设置
  98. /// </summary>
  99. /// <param name="sets"></param>
  100. /// <returns></returns>
  101. public async Task<ActionResult> Save(string sets)
  102. {
  103. var settings = JsonConvert.DeserializeObject<List<SystemSetting>>(sets).ToArray();
  104. var b = await SystemSettingService.AddOrUpdateSavedAsync(s => s.Name, settings) > 0;
  105. var dic = settings.ToDictionary(s => s.Name, s => s.Value); //同步设置
  106. foreach (var (key, value) in dic)
  107. {
  108. CommonHelper.SystemSettings.AddOrUpdate(key, value);
  109. }
  110. return ResultData(null, b, b ? "设置保存成功!" : "设置保存失败!");
  111. }
  112. /// <summary>
  113. /// 获取状态
  114. /// </summary>
  115. /// <returns></returns>
  116. public ActionResult GetStatus()
  117. {
  118. Array array = Enum.GetValues(typeof(Status));
  119. var list = new List<object>();
  120. foreach (Enum e in array)
  121. {
  122. list.Add(new
  123. {
  124. e,
  125. name = e.GetDisplay()
  126. });
  127. }
  128. return ResultData(list);
  129. }
  130. /// <summary>
  131. /// 邮件测试
  132. /// </summary>
  133. /// <param name="smtp"></param>
  134. /// <param name="user"></param>
  135. /// <param name="pwd"></param>
  136. /// <param name="port"></param>
  137. /// <param name="to"></param>
  138. /// <returns></returns>
  139. public ActionResult MailTest(string smtp, string user, string pwd, int port, string to, bool ssl)
  140. {
  141. try
  142. {
  143. new Email()
  144. {
  145. EnableSsl = ssl,
  146. Body = "发送成功,网站邮件配置正确!",
  147. SmtpServer = smtp,
  148. Username = user,
  149. Password = pwd,
  150. SmtpPort = port,
  151. Subject = "网站测试邮件",
  152. Tos = to
  153. }.Send();
  154. return ResultData(null, true, "测试邮件发送成功,网站邮件配置正确!");
  155. }
  156. catch (Exception e)
  157. {
  158. return ResultData(null, false, "邮件配置测试失败!错误信息:\r\n" + e.Message + "\r\n\r\n详细堆栈跟踪:\r\n" + e.StackTrace);
  159. }
  160. }
  161. /// <summary>
  162. /// 路径测试
  163. /// </summary>
  164. /// <param name="path"></param>
  165. /// <returns></returns>
  166. public ActionResult PathTest(string path)
  167. {
  168. if (!(path.EndsWith("/") || path.EndsWith("\\")))
  169. {
  170. return ResultData(null, false, "路径不存在");
  171. }
  172. if (path.Equals("/") || path.Equals("\\"))
  173. {
  174. return ResultData(null, true, "根路径正确");
  175. }
  176. try
  177. {
  178. bool b = Directory.Exists(path);
  179. return ResultData(null, b, b ? "根路径正确" : "路径不存在");
  180. }
  181. catch (Exception e)
  182. {
  183. LogManager.Error(GetType(), e);
  184. return ResultData(null, false, "路径格式不正确!错误信息:\r\n" + e.Message + "\r\n\r\n详细堆栈跟踪:\r\n" + e.StackTrace);
  185. }
  186. }
  187. /// <summary>
  188. /// 发件箱记录
  189. /// </summary>
  190. /// <returns></returns>
  191. public ActionResult<List<JObject>> SendBox()
  192. {
  193. return RedisHelper.SUnion(RedisHelper.Keys("Email:*")).Select(JObject.Parse).OrderByDescending(o => o["time"]).ToList();
  194. }
  195. public ActionResult BounceEmail([FromServices] IMailSender mailSender, string email)
  196. {
  197. var msg = mailSender.AddRecipient(email);
  198. return Ok(new
  199. {
  200. msg
  201. });
  202. }
  203. #region 网站防火墙
  204. /// <summary>
  205. /// 获取全局IP黑名单
  206. /// </summary>
  207. /// <returns></returns>
  208. public ActionResult IpBlackList()
  209. {
  210. return ResultData(CommonHelper.DenyIP);
  211. }
  212. /// <summary>
  213. /// 获取IP地址段黑名单
  214. /// </summary>
  215. /// <returns></returns>
  216. public ActionResult GetIPRangeBlackList()
  217. {
  218. return ResultData(System.IO.File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data", "DenyIPRange.txt")));
  219. }
  220. /// <summary>
  221. /// 设置IP地址段黑名单
  222. /// </summary>
  223. /// <returns></returns>
  224. public ActionResult SetIPRangeBlackList(string content)
  225. {
  226. System.IO.File.WriteAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data", "DenyIPRange.txt"), content, Encoding.UTF8);
  227. CommonHelper.DenyIPRange.Clear();
  228. var lines = System.IO.File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data", "DenyIPRange.txt")).Where(s => s.Split(' ').Length > 2);
  229. foreach (var line in lines)
  230. {
  231. try
  232. {
  233. var strs = line.Split(' ');
  234. CommonHelper.DenyIPRange[strs[0]] = strs[1];
  235. }
  236. catch (IndexOutOfRangeException)
  237. {
  238. }
  239. }
  240. return ResultData(null);
  241. }
  242. /// <summary>
  243. /// 全局IP白名单
  244. /// </summary>
  245. /// <returns></returns>
  246. public ActionResult IpWhiteList()
  247. {
  248. return ResultData(System.IO.File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data", "whitelist.txt")));
  249. }
  250. /// <summary>
  251. /// 设置IP黑名单
  252. /// </summary>
  253. /// <param name="content"></param>
  254. /// <returns></returns>
  255. public async Task<ActionResult> SetIpBlackList(string content)
  256. {
  257. CommonHelper.DenyIP = content + "";
  258. await System.IO.File.WriteAllTextAsync(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data", "denyip.txt"), CommonHelper.DenyIP, Encoding.UTF8);
  259. return ResultData(null);
  260. }
  261. /// <summary>
  262. /// 设置IP白名单
  263. /// </summary>
  264. /// <param name="content"></param>
  265. /// <returns></returns>
  266. public async Task<ActionResult> SetIpWhiteList(string content)
  267. {
  268. await System.IO.File.WriteAllTextAsync(Path.Combine(AppDomain.CurrentDomain.BaseDirectory!, "App_Data", "whitelist.txt"), content, Encoding.UTF8);
  269. CommonHelper.IPWhiteList.Add(content);
  270. return ResultData(null);
  271. }
  272. /// <summary>
  273. /// 获取拦截日志
  274. /// </summary>
  275. /// <returns></returns>
  276. public ActionResult InterceptLog()
  277. {
  278. var list = RedisHelper.LRange<IpIntercepter>("intercept", 0, -1);
  279. return ResultData(new
  280. {
  281. interceptCount = RedisHelper.Get("interceptCount"),
  282. list,
  283. ranking = list.GroupBy(i => i.IP).Where(g => g.Count() > 1).Select(g =>
  284. {
  285. var start = g.Min(t => t.Time);
  286. var end = g.Max(t => t.Time);
  287. return new
  288. {
  289. g.Key,
  290. g.First().Address,
  291. Start = start,
  292. End = end,
  293. Continue = start.GetDiffTime(end),
  294. Count = g.Count()
  295. };
  296. }).OrderByDescending(a => a.Count).Take(30)
  297. });
  298. }
  299. /// <summary>
  300. /// 清除拦截日志
  301. /// </summary>
  302. /// <returns></returns>
  303. public ActionResult ClearInterceptLog()
  304. {
  305. bool b = RedisHelper.Del("intercept") > 0;
  306. return ResultData(null, b, b ? "拦截日志清除成功!" : "拦截日志清除失败!");
  307. }
  308. /// <summary>
  309. /// 将IP添加到白名单
  310. /// </summary>
  311. /// <param name="ip"></param>
  312. /// <returns></returns>
  313. public async Task<ActionResult> AddToWhiteList(string ip)
  314. {
  315. if (!ip.MatchInetAddress())
  316. {
  317. return ResultData(null, false);
  318. }
  319. var basedir = AppDomain.CurrentDomain.BaseDirectory;
  320. string ips = await System.IO.File.ReadAllTextAsync(Path.Combine(basedir, "App_Data", "whitelist.txt"));
  321. List<string> list = ips.Split(',').Where(s => !string.IsNullOrEmpty(s)).ToList();
  322. list.Add(ip);
  323. await System.IO.File.WriteAllTextAsync(Path.Combine(basedir, "App_Data", "whitelist.txt"), string.Join(",", list.Distinct()), Encoding.UTF8);
  324. CommonHelper.IPWhiteList = list;
  325. return ResultData(null);
  326. }
  327. /// <summary>
  328. /// 将IP添加到黑名单
  329. /// </summary>
  330. /// <param name="firewallRepoter"></param>
  331. /// <param name="ip"></param>
  332. /// <returns></returns>
  333. public async Task<ActionResult> AddToBlackList([FromServices] IFirewallRepoter firewallRepoter, string ip)
  334. {
  335. if (!ip.MatchInetAddress())
  336. {
  337. return ResultData(null, false);
  338. }
  339. CommonHelper.DenyIP += "," + ip;
  340. var basedir = AppDomain.CurrentDomain.BaseDirectory;
  341. await System.IO.File.WriteAllTextAsync(Path.Combine(basedir, "App_Data", "denyip.txt"), CommonHelper.DenyIP, Encoding.UTF8);
  342. CommonHelper.IPWhiteList.Remove(ip);
  343. await System.IO.File.WriteAllTextAsync(Path.Combine(basedir, "App_Data", "whitelist.txt"), string.Join(",", CommonHelper.IPWhiteList.Distinct()), Encoding.UTF8);
  344. await firewallRepoter.ReportAsync(IPAddress.Parse(ip));
  345. return ResultData(null);
  346. }
  347. #endregion
  348. }
  349. }