using AspNetCoreRateLimit; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using ZR.Admin.WebApi.Filters; using ZR.Model; using ZR.ServiceCore.Model; using ZR.ServiceCore.Services.IService; using IpRateLimitPolicy = ZR.ServiceCore.Model.IpRateLimitPolicy; namespace ZR.Admin.WebApi.Controllers.System.monitor; [Verify] [Route("ip/route/limit")] public class IpRateLimitController : BaseController { private readonly IpRateLimitOptions _options; private readonly IIpPolicyStore _ipPolicyStore; private readonly IIpRateLimitPolicyService _ipRateLimitPolicyService; private readonly IRateLimitRuleService _rateLimitRuleService; private readonly IIpRateLimitLogService _ipRateLimitLogService; public IpRateLimitController(IOptions optionsAccessor, IIpPolicyStore ipPolicyStore, IIpRateLimitPolicyService ipRateLimitPolicyService, IRateLimitRuleService rateLimitRuleService, IIpRateLimitLogService ipRateLimitLogService) { _options = optionsAccessor.Value; _ipPolicyStore = ipPolicyStore; _ipRateLimitPolicyService = ipRateLimitPolicyService; _rateLimitRuleService = rateLimitRuleService; _ipRateLimitLogService = ipRateLimitLogService; } /// /// 获取限制规则 /// /// [HttpGet("getIpRateLimitPolicyPage")] public async Task GetIpRateLimitPolicyPage([FromQuery] IpRateLimitPolicy ipRateLimitPolicy, PagerInfo pager) { var page = await _ipRateLimitPolicyService.SelectIpRateLimitPolicyPageAsync(ipRateLimitPolicy, pager); return SUCCESS(page); } [HttpPost("addIpRateLimitPolicy")] public async Task AddIpRateLimitPolicy([FromBody] IpRateLimitPolicy ipRateLimitPolicy) { var isExist = await _ipRateLimitPolicyService.Queryable() .Where(it => it.Ip == ipRateLimitPolicy.Ip) .AnyAsync(); if (isExist) throw new CustomException("该IP已存在"); var res = await _ipRateLimitPolicyService.InsertNav(ipRateLimitPolicy) .Include(it => it.Rules) .ExecuteCommandAsync(); return SUCCESS(res); } [HttpPut("updateIpRateLimitPolicy")] public async Task UpdateIpRateLimitPolicy( [FromBody] IpRateLimitPolicy ipRateLimitPolicy) { var isEnable = await _ipRateLimitPolicyService .Queryable() .Where(it => it.Id == ipRateLimitPolicy.Id && it.Flag == '1') .AnyAsync(); var res = await _ipRateLimitPolicyService.UpdateNav(ipRateLimitPolicy) .Include(it => it.Rules) .ExecuteCommandAsync(); if (!isEnable) return SUCCESS(res); { await _ipPolicyStore.RemoveAsync(_options.IpPolicyPrefix); var ipRateLimitPolicies = _ipRateLimitPolicyService.Queryable() .Includes(it => it.Rules.Where(r => r.Flag == '1').ToList()) .Where(it => it.Flag == '1') .ToListAsync() .GetAwaiter().GetResult() .Adapt>(); await _ipPolicyStore.SeedAsync(); var pol = await _ipPolicyStore.GetAsync(_options.IpPolicyPrefix); pol.IpRules.AddRange(ipRateLimitPolicies); await _ipPolicyStore.SetAsync(_options.IpPolicyPrefix, pol); } return SUCCESS(res); } [HttpPatch("enableIpRateLimitPolicy/{id}")] public async Task EnableIpRateLimitPolicy([FromRoute] long id) { var isEnable = await _ipRateLimitPolicyService .Queryable() .Where(it => it.Id == id && it.Flag == '1') .AnyAsync(); if (isEnable) { throw new CustomException("已启用,无法再次启用"); } await _ipRateLimitPolicyService.Updateable(new IpRateLimitPolicy { Id = id, Flag = '1' }).UpdateColumns(it => it.Flag) .ExecuteCommandAsync(); var ipRateLimitPolicy = await _ipRateLimitPolicyService.Queryable() .Includes(it => it.Rules.Where(r => r.Flag == '1').ToList()) .Where(it => it.Id == id) .SingleAsync(); var pol = await _ipPolicyStore.GetAsync(_options.IpPolicyPrefix); pol.IpRules.Add(ipRateLimitPolicy.Adapt()); await _ipPolicyStore.SetAsync(_options.IpPolicyPrefix, pol); return SUCCESS('1'); } [HttpPatch("disableIpRateLimitPolicy/{id}")] public async Task DisableIpRateLimitPolicy([FromRoute] long id) { var isEnable = await _ipRateLimitPolicyService .Queryable() .Where(it => it.Id == id && it.Flag == '1') .AnyAsync(); if (!isEnable) { throw new CustomException("已禁用,无法再次禁用"); } await _ipRateLimitPolicyService.Updateable(new IpRateLimitPolicy { Id = id, Flag = '0' }).UpdateColumns(it => it.Flag) .ExecuteCommandAsync(); var ipRateLimitPolicies = _ipRateLimitPolicyService.Queryable() .Includes(it => it.Rules.Where(r => r.Flag == '1').ToList()) .Where(it => it.Flag == '1') .ToListAsync() .GetAwaiter().GetResult() .Adapt>(); await _ipPolicyStore.RemoveAsync(_options.IpPolicyPrefix); await _ipPolicyStore.SeedAsync(); var pol = await _ipPolicyStore.GetAsync(_options.IpPolicyPrefix); pol.IpRules.AddRange(ipRateLimitPolicies); await _ipPolicyStore.SetAsync(_options.IpPolicyPrefix, pol); return SUCCESS('0'); } [HttpDelete("deleteIpRateLimitPolicy/{id}")] public async Task DeleteIpRateLimitPolicyAsync([FromRoute] long id) { var isEnable = await _ipRateLimitPolicyService .Queryable() .Where(it => it.Id == id && it.Flag == '1') .AnyAsync(); await _ipRateLimitPolicyService .DeleteNav(it => it.Id == id) .Include(it => it.Rules) .ExecuteCommandAsync(); if (isEnable) { var ipRateLimitPolicies = _ipRateLimitPolicyService.Queryable() .Includes(it => it.Rules.Where(r => r.Flag == '1').ToList()) .Where(it => it.Flag == '1') .ToListAsync() .GetAwaiter().GetResult() .Adapt>(); await _ipPolicyStore.RemoveAsync(_options.IpPolicyPrefix); await _ipPolicyStore.SeedAsync(); var pol = await _ipPolicyStore.GetAsync(_options.IpPolicyPrefix); pol.IpRules.AddRange(ipRateLimitPolicies); await _ipPolicyStore.SetAsync(_options.IpPolicyPrefix, pol); } } [HttpGet("getIpRateLimitLogPage")] public async Task GetIpRateLimitLogPage([FromQuery] IpRateLimitLog ipRateLimitLog, PagerInfo pager) { return SUCCESS(await _ipRateLimitLogService.SelectIpRateLimitLogPageAsync(ipRateLimitLog, pager)); } [HttpGet("get")] public async Task Get() { return await _ipPolicyStore.GetAsync(_options.IpPolicyPrefix); } [HttpGet("checkIp/{ip}")] public async Task CheckIp(string ip) { var res = await _ipRateLimitPolicyService.Queryable() .Where(it => it.Ip == ip) .AnyAsync(); return SUCCESS(res); } }