public bool OpenRateLimit(string url, int threshold, int period, out AuditLogEntity errorLog)
        {
            var zoneTableId = ZoneBusiness.GetZoneByZoneId(_zoneId).TableID;

            errorLog = null;
            var ratelimit = GetRateLimitRule(url, threshold, period);

            if (null != ratelimit)
            {
                ratelimit.Disabled = false;
                var response = UpdateRateLimit(ratelimit);
                if (!response.success)
                {
                    errorLog = new AuditLogEntity(zoneTableId, LogLevel.Error,
                                                  $"Open rate limiting rule of Cloudflare failure,the reason is:[{(null != response.errors && response.errors.Length > 0 ? response.errors[0].message : "No error message from Cloudflare.")}].<br />");
                }
                return(response.success);
            }
            else
            {
                var response = CreateRateLimit(new CloudflareRateLimitRule(url, threshold, period, $"[Auto Prevention] {url}"));
                if (!response.success)
                {
                    errorLog = new AuditLogEntity(zoneTableId, LogLevel.Error,
                                                  $"Create rate limiting rule of Cloudflare failure,the reason is:[{(response.errors !=null && response.errors .Length > 0 ? response.errors[0].message : "No error message from Cloudflare.")}].<br />");
                }
                return(response.success);
            }
        }
        private void TestingEnvironment()
        {
            List <SmtpQueue> smtpQueues = SmtpQueueBusiness.GetList();
            SmtpQueue        lastReport = smtpQueues.OrderBy(a => a.Id).LastOrDefault();
            DateTime         date       = Convert.ToDateTime(DateTime.Now.AddDays(-1).ToString("MM/dd/yyyy 00:00:00"));
            string           title      = date.ToString("MM/dd/yyyy 23");

            if (lastReport != null && lastReport.Title == title)
            {
                //已经生成了报表
            }
            else
            {
                string lastTitle = lastReport?.Title;
                if (string.IsNullOrEmpty(lastTitle))
                {
                    title = date.ToString("MM/dd/yyyy HH");
                }
                else
                {
                    DateTime lastDate = DateTime.Parse(lastTitle.Contains(" ") ? lastTitle + ":00:00" : lastTitle);
                    date  = lastDate.AddHours(1);
                    title = date.ToString("MM/dd/yyyy HH");
                }

                //// 每天9开始统计前一天的数据
                //if (DateTime.Now > Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 09:00:00")))
                //{
                List <ZoneEntity> zoneEntities = ZoneBusiness.GetZoneList().Where(a => a.IfEnable).ToList();
                if (zoneEntities != null && zoneEntities.Count > 0)
                {
                    foreach (ZoneEntity zone in zoneEntities)
                    {
                        CreateActiveReportZoneTesting(zone, date);
                    }
                    //插入邮件发送队列
                    SmtpQueueBusiness.Add(new SmtpQueue
                    {
                        Title       = title,
                        Status      = 0,
                        CreatedTime = DateTime.Now,
                        SendedTime  = DateTime.Now,
                        Remark      = "",
                    });
                }
            }
            //}
        }
        public List <CloudflareLog> GetLogs(DateTime start, DateTime end, double sample, out bool retry)
        {
            var zoneTableId = ZoneBusiness.GetZoneByZoneId(_zoneId).TableID;

            retry = false;
            var cloudflareLogs = new List <CloudflareLog>();

            try
            {
                string fields    = "RayID,ClientIP,ClientRequestHost,ClientRequestMethod,ClientRequestURI,EdgeEndTimestamp,EdgeResponseBytes,EdgeResponseStatus,EdgeStartTimestamp,CacheResponseStatus,ClientRequestBytes,CacheCacheStatus,OriginResponseStatus,OriginResponseTime";
                string startTime = GetUTCTimeString(start);
                string endTime   = GetUTCTimeString(end);
                string url       = "{5}/zones/{0}/logs/received?start={1}&end={2}&fields={3}&sample={4}";
                url = string.Format(url, _zoneId, startTime, endTime, fields, sample, _apiUrlPrefix);
                string content = HttpGet(url, 240);
                if (content.Contains(@"""success"":false"))
                {
                    if (content.Contains("429 Too Many Requests"))
                    {
                        retry = true;
                    }
                    else
                    {
                        var errorResponse = JsonConvert.DeserializeObject <CloudflareLogErrorResponse>(content);
                        AuditLogBusiness.Add(new AuditLogEntity(zoneTableId, LogLevel.Error,
                                                                $"Got logs failure, the reason is:[{ (errorResponse.Errors.Count > 0 ? errorResponse.Errors[0].Message : "No error message from Cloudflare.")}]."));
                    }
                }
                else
                {
                    content        = content.Replace("\"}", "\"},");
                    cloudflareLogs = JsonConvert.DeserializeObject <List <CloudflareLog> >($"[{content}]");
                    cloudflareLogs.RemoveAll(x =>
                                             (null != x.CacheCacheStatus && x.CacheCacheStatus.ToLower().Equals("hit")) ||
                                             0 == x.OriginResponseStatus);
                }

                return(cloudflareLogs);
            }
            catch (Exception ex)
            {
                retry = true;
                AuditLogBusiness.Add(new AuditLogEntity(zoneTableId, LogLevel.Error,
                                                        $"Got logs failure, the reason is:[{ex.Message}]. <br />stack trace:{ex.StackTrace}]."));
                return(cloudflareLogs);
            }
        }
        private string GeneratedMail(string title)
        {
            StringBuilder mail      = new StringBuilder();
            SmtpQueue     smtpQueue = SmtpQueueBusiness.GetByTitle(title);

            if (smtpQueue != null && smtpQueue.Id > 0)
            {
                mail.AppendLine("<div id=\"mail\">");
                List <ActionReport> actionReports = ActionReportBusiness.GetListByTitle(title);

                List <ZoneEntity> zoneEntities = ZoneBusiness.GetZoneList().Where(a => a.IfEnable).ToList();
                foreach (ZoneEntity zone in zoneEntities)
                {
                    List <ActionReport> subActionReports = actionReports.Where(a => a.ZoneId == zone.ZoneId && a.Mode == "Action").ToList();
                    string body = CreateMainZone(zone.ZoneName, subActionReports);
                    mail.Append(body);
                }
                mail.AppendLine("</div>");
            }
            return(mail.ToString());
        }
        private void ProductionEnvironment()
        {
            List <SmtpQueue> smtpQueues = SmtpQueueBusiness.GetList();
            SmtpQueue        lastReport = smtpQueues.OrderBy(a => a.Id).LastOrDefault();
            DateTime         date       = DateTime.Now.AddDays(-1);
            string           title      = date.ToString("MM/dd/yyyy");

            if (lastReport != null && lastReport.Title == title)
            {
                //已经生成了报表
            }
            else
            {
                //// 每天9开始统计前一天的数据
                //if (DateTime.Now > Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 09:00:00")))
                //{

                List <ZoneEntity> zoneEntities = ZoneBusiness.GetZoneList().Where(a => a.IfEnable).ToList();
                if (zoneEntities != null && zoneEntities.Count > 0)
                {
                    foreach (ZoneEntity zone in zoneEntities)
                    {
                        CreateActiveReportZoneProduction(zone, date);
                    }
                    //插入邮件发送队列
                    SmtpQueueBusiness.Add(new SmtpQueue
                    {
                        Title       = title,
                        Status      = 0,
                        CreatedTime = DateTime.Now,
                        SendedTime  = DateTime.Now,
                        Remark      = "",
                    });
                }
            }
            //}
        }
        private void Analyze(AnalyzeResult analyzeResult)
        {
            if (analyzeResult != null && analyzeResult.result != null)
            {
                List <AuditLogEntity> auditLogEntities = new List <AuditLogEntity>();
                string            key      = "AnalyzeRatelimit_GetZoneList_Key";
                List <ZoneEntity> zoneList = Utils.GetMemoryCache(key, () =>
                {
                    return(ZoneBusiness.GetZoneList());
                }, 1440);

                string zoneID = analyzeResult.ZoneId;
                var    zone   = zoneList.FirstOrDefault(a => a.ZoneId == zoneID);

                if (zone != null)
                {
                    string authEmail = zone.AuthEmail;
                    string authKey   = zone.AuthKey;

                    var cloudflare = new CloudFlareApiService(zone.ZoneId, zone.AuthEmail, zone.AuthKey);

                    //发送警报
                    Warn(analyzeResult);

                    //开启RateLimit
                    var logs = OpenRageLimit(zone, cloudflare, analyzeResult);
                    auditLogEntities.AddRange(logs);

                    //Ban IP
                    //logs = BanIp(zone, cloudflare, analyzeResult);
                    //auditLogEntities.AddRange(logs);

                    //记录日志
                    InsertLogs(auditLogEntities);
                }
            }
        }
 private void Warn(AnalyzeResult analyzeResult)
 {
     // 发送警报
     ZoneBusiness.UpdateAttackFlag(true, analyzeResult.ZoneId);
 }