Esempio n. 1
0
        public void BannedClient_AfterExceeded_CanRequest()
        {
            //Arrange
            throttleOptionConfigurationMock.Setup(x => x.Value)
            .Returns(new ThrottleConfiguration
            {
                MaxRequests  = 5,
                PenaltyTime  = TimeSpan.FromSeconds(5),
                Period       = TimeSpan.FromSeconds(1),
                ErrorMessage = "Too many requests."
            });

            var memoryOptionsMock = new Mock <IOptions <MemoryCacheOptions> >();

            memoryOptionsMock.Setup(x => x.Value)
            .Returns(new MemoryCacheOptions());

            var throttleService = new ThrottleService(new MemoryCache(memoryOptionsMock.Object), throttleOptionConfigurationMock.Object, Mock.Of <ILogger <ThrottleService> >());

            //Act
            var ip = faker.Internet.Ip();

            for (int i = 0; i < 10; i++)
            {
                throttleService.IsAllowed(ip);
            }

            System.Threading.Thread.Sleep(TimeSpan.FromSeconds(6));

            //Assert
            Assert.True(throttleService.IsAllowed(ip));
        }
Esempio n. 2
0
        static void Main(string[] args)
        {
            ThrottleService  throttleService = new ThrottleService();
            List <QueueItem> testList        = new List <QueueItem>();

            TestAddItems(testList, "111", 10, QueueItemTypes.Comment);
            TestAddItems(testList, "333", 5, QueueItemTypes.Idea);
            TestAddItems(testList, "222", 6, QueueItemTypes.Comment);
            TestAddItems(testList, "111", 6, QueueItemTypes.Comment);

            foreach (QueueItem queueItem in testList)
            {
                throttleService.AddItem(queueItem);
            }

            //Tasks
            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();

            while (!cancellationTokenSource.IsCancellationRequested)
            {
                Task.Factory.StartNew(ThrottlerManager.CheckThrottlers, cancellationTokenSource.Token);

                Thread.Sleep(1000);
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Скачать страницу.
        /// </summary>
        /// <param name="chapterFolder">Папка для файлов.</param>
        public async Task Download(string chapterFolder)
        {
            this.IsDownloaded = false;

            if (restartCounter > MaxAttempt)
            {
                throw new DownloadAttemptFailed(restartCounter, this);
            }

            try
            {
                await DownloadManager.CheckPause().ConfigureAwait(false);

                using (await ThrottleService.WaitAsync().ConfigureAwait(false))
                {
                    await DownloadManager.CheckPause().ConfigureAwait(false);

                    if (!DirectoryHelpers.ValidateSettingPath(chapterFolder))
                    {
                        throw new DirectoryNotFoundException($"Попытка скачивания в папку {chapterFolder}, папка не существует.");
                    }

                    if (!Directory.Exists(chapterFolder))
                    {
                        Directory.CreateDirectory(chapterFolder);
                    }

                    var manga  = Chapter?.Volume?.Manga ?? Chapter?.Manga ?? Manga;
                    var plugin = ConfigStorage.Plugins.Single(p => p.MangaType == manga.GetType());
                    var cache  = MangaSettingCache.Get(plugin.GetType());

                    var file = await DownloadManager.DownloadImage(this.ImageLink, cache).ConfigureAwait(false);

                    if (!file.Exist)
                    {
                        OnDownloadFailed();
                    }
                    var fileName = this.Number.ToString(CultureInfo.InvariantCulture).PadLeft(4, '0') + "." + file.Extension;
                    await file.Save(Path.Combine(chapterFolder, fileName)).ConfigureAwait(false);

                    this.IsDownloaded = true;
                }
            }
            catch (System.Exception ex)
            {
                Log.Exception(ex, this.Uri.OriginalString);
                ++restartCounter;
                await Download(chapterFolder).ConfigureAwait(false);
            }
        }
Esempio n. 4
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", "options", Route = null)] HttpRequest req,
            [StorageAccount("StorageConnectionString")] CloudStorageAccount storageAccount,
            TraceWriter log
            )
        {
            var email = req.Query["email"].FirstOrDefault()?.ToLower();

            if (string.IsNullOrWhiteSpace(email))
            {
                return(new BadRequestObjectResult("The query parameter \"email\" is empty or missing"));
            }

            log.Info($"E-mail verification request received for {email}");
            var client          = storageAccount.CreateCloudTableClient();
            var throttleService = new ThrottleService(client, log);
            var throttled       = (await throttleService.ThrottleOrIncrement(email)) || (await throttleService.ThrottleOrIncrement(IpUtility.GetClientIp(req)));

            if (throttled)
            {
                return(new StatusCodeResult(429));
            }

            var code  = $"{new Random().Next(100, 999)}{new Random().Next(100, 999)}{new Random().Next(100, 999)}";
            var token = Guid.NewGuid().ToString().Replace("-", "");
            var auth  = new EmailAuthToken(email, token, code)
            {
                Expiration = DateTimeOffset.UtcNow.AddHours(4),
            };

            var secret = Environment.GetEnvironmentVariable("email-secret", EnvironmentVariableTarget.Process);

            if (Upload(log, "http://grimdawn.dreamcrash.org/ia/backup/auth.php", $"token={secret}&target={email}&code={code}"))
            {
                var table = client.GetTableReference(EmailAuthToken.TableName);
                await table.CreateIfNotExistsAsync();

                await table.ExecuteAsync(TableOperation.Insert(auth));

                log.Info($"Successfully posted email for {email}");
            }

            return(new OkObjectResult(new ResponseDto {
                Token = token
            }));
        }
Esempio n. 5
0
        private static async Task <(HttpResponseMessage, System.Exception)> DoWithRestarts(Uri uri, HttpClient client,
                                                                                           Func <Uri, HttpClient, Task <HttpResponseMessage> > func, int restartCounter = 0)
        {
            try
            {
                if (restartCounter > 3)
                {
                    throw new DownloadAttemptFailed(restartCounter, uri);
                }

                HttpResponseMessage content;
                using (await ThrottleService.WaitAsync().ConfigureAwait(false))
                {
                    content = await func(uri, client).ConfigureAwait(false);
                }

                if (await RequestCanBeRetry(content).ConfigureAwait(false))
                {
                    Log.Error($"{Strings.Page_GetPage_SiteOff}, код {content.StatusCode}, ссылка: {uri}, попытка номер - {restartCounter}");
                    ++restartCounter;
                    return(await DoWithRestarts(uri, client, func, restartCounter).ConfigureAwait(false));
                }

                return(content, null);
            }
            catch (TaskCanceledException ex)
            {
                Log.Exception(ex, $"{Strings.Page_GetPage_SiteOff}, ссылка: {uri}, попытка номер - {restartCounter}");
                ++restartCounter;
                return(await DoWithRestarts(uri, client, func, restartCounter).ConfigureAwait(false));
            }
            catch (HttpRequestException ex) when(ex.InnerException is System.Net.Sockets.SocketException || ex.InnerException is System.IO.IOException)
            {
                Log.Exception(ex, $"{Strings.Page_GetPage_SiteOff}, ссылка: {uri}, попытка номер - {restartCounter}");
                ++restartCounter;
                return(await DoWithRestarts(uri, client, func, restartCounter).ConfigureAwait(false));
            }
            catch (System.Exception ex)
            {
                Log.Exception(ex, $"Не удалось получить страницу: {uri}");
                return(null, ex);
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Скачать страницу.
        /// </summary>
        /// <param name="chapterFolder">Папка для файлов.</param>
        public async Task Download(string chapterFolder)
        {
            this.IsDownloaded = false;

            if (restartCounter > MaxAttempt)
            {
                throw new DownloadAttemptFailed(restartCounter, this);
            }

            try
            {
                await DownloadManager.CheckPause();

                using (await ThrottleService.WaitAsync())
                {
                    await DownloadManager.CheckPause();

                    chapterFolder = DirectoryHelpers.MakeValidPath(chapterFolder);
                    if (!Directory.Exists(chapterFolder))
                    {
                        Directory.CreateDirectory(chapterFolder);
                    }

                    var file = await DownloadManager.DownloadImage(this.ImageLink);

                    if (!file.Exist)
                    {
                        OnDownloadFailed();
                    }
                    var fileName = this.Number.ToString(CultureInfo.InvariantCulture).PadLeft(4, '0') + "." + file.Extension;
                    await file.Save(Path.Combine(chapterFolder, fileName));

                    this.IsDownloaded = true;
                }
            }
            catch (System.Exception ex)
            {
                Log.Exception(ex, this.Uri.OriginalString);
                ++restartCounter;
                await Download(chapterFolder);
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ThrottleActionFilter"/> class.
 /// </summary>
 public ThrottleActionFilter(ThrottleService throttleService, SiteConfig siteConfig, ILicenseManager licenseManager)
 {
     this.siteConfig      = siteConfig;
     this.throttleService = throttleService;
     this.licenseManager  = licenseManager;
 }
Esempio n. 8
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", "options", Route = null)] HttpRequest req,
            [StorageAccount("StorageConnectionString")] CloudStorageAccount storageAccount,
            TraceWriter log
            )
        {
            var token  = req.Query["token"];
            var code   = req.Query["code"];
            var client = storageAccount.CreateCloudTableClient();

            if (string.IsNullOrWhiteSpace(token))
            {
                return(new BadRequestObjectResult("The query parameter \"token\" is empty or missing"));
            }
            else if (string.IsNullOrWhiteSpace(code))
            {
                return(new BadRequestObjectResult("The query parameter \"code\" is empty or missing"));
            }

            log.Info($"E-mail verification request received for {token}");

            // Throttling required for verification as well, to prevent infinite attempts on a token.
            var throttleService = new ThrottleService(storageAccount.CreateCloudTableClient(), log);
            var throttled       = (await throttleService.ThrottleOrIncrement("attempt-" + token)) || (await throttleService.ThrottleOrIncrement("attempt-" + IpUtility.GetClientIp(req)));

            if (throttled)
            {
                return(new StatusCodeResult(429));
            }

            var table = client.GetTableReference(EmailAuthToken.TableName);
            await table.CreateIfNotExistsAsync();

            var query = TableQuery.CombineFilters(
                TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, token),
                TableOperators.And,
                TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, code)
                );
            var exQuery = new TableQuery <EmailAuthToken>().Where(query);

            var entry = await QueryHelper.Get(table, exQuery);

            if (entry != null)
            {
                if (DateTimeOffset.UtcNow < entry.Expiration)
                {
                    log.Info($"Authentication successful for {entry.Email}");

                    var auth = new Authentication {
                        PartitionKey = Authentication.PartitionName,
                        RowKey       = (Guid.NewGuid().ToString() + Guid.NewGuid().ToString()).Replace("-", ""),
                        Identity     = entry.Email
                    };

                    var authTable = client.GetTableReference(Authentication.TableName);
                    await authTable.CreateIfNotExistsAsync();

                    await authTable.ExecuteAsync(TableOperation.Insert(auth));

                    return(new OkObjectResult(new VerifyEmailTokenResponseDto {
                        Success = true,
                        Token = auth.RowKey
                    }));
                }
                else
                {
                    log.Info($"Authentication token {token} for {entry.Email} has already expired, expiration {entry.Expiration}");

                    return(new OkObjectResult(new VerifyEmailTokenResponseDto {
                        Success = false
                    }));
                }
            }
            else
            {
                log.Info("No entry found");
                return(new OkObjectResult(new VerifyEmailTokenResponseDto {
                    Success = false
                }));
            }
        }