public async void CanThrottle() { Assert.True(LimitRequestZone.TryParse("zone=mylimit rate=10r/s burst=20", out var limitRequestZone)); var delay = new MockDelay(); var service = new RateLimitService(delay); await Assert.ThrowsAsync <KeyNotFoundException>(async() => await service.Throttle("mylimit")); Assert.Equal(0, service.BucketsCount); service.SetZone(limitRequestZone); var throttling = service.Throttle("mylimit"); // Will execute immediately, slot reserved until +100 Assert.True(throttling.Wait(10)); Assert.Equal(1, service.BucketsCount); var throttling2 = service.Throttle("mylimit"); // Will execute at +100, slot reserved until +200 Assert.False(throttling2.Wait(10)); Assert.Equal(1, service.BucketsCount); delay.AdvanceMilliseconds(100); Assert.True(throttling2.Wait(10)); Assert.True(throttling2.IsCompletedSuccessfully); Assert.Equal(1, service.BucketsCount); // Still bucket 1, because the slot used by throttling2 is still here delay.AdvanceMilliseconds(100); // The bucket should be empty, though but wait one more period before deleting the bucket Thread.Sleep(10); Assert.Equal(1, service.BucketsCount); delay.AdvanceMilliseconds(100); Thread.Sleep(100); Assert.Equal(0, service.BucketsCount); }
public static IServiceCollection AddRateLimits(this IServiceCollection services) { var instance = new RateLimitService(); services.AddSingleton(instance); return(services); }
private async Task InitializeTimers(bool allShardsLoggedIn) { if (!allShardsLoggedIn) { return; } // We need to load the cache on program start. await MemoryCache.Initialize(); await ConsoleLogger.LogAsync("Memory Cache timer initialized", LogLvl.INFO); await KaguyaStatsFactory.Initialize(); await ConsoleLogger.LogAsync("Kaguya stats updater initialized", LogLvl.INFO); await AntiRaidService.Initialize(); await ConsoleLogger.LogAsync("Antiraid service initialized", LogLvl.INFO); await AutoUnmuteHandler.Initialize(); await ConsoleLogger.LogAsync("Unmute handler initialized", LogLvl.INFO); #if !DEBUG await OwnerGiveawayMessageUpdaterService.Initialize(); await ConsoleLogger.LogAsync("Owner giveaway message updater initialized", LogLvl.INFO); await KaguyaPremiumRoleHandler.Initialize(); await ConsoleLogger.LogAsync("Kaguya Premium role handler initialized", LogLvl.INFO); await KaguyaPremiumExpirationHandler.Initialize(); await ConsoleLogger.LogAsync("Kaguya Premium expiration handler initialized", LogLvl.INFO); await RateLimitService.Initialize(); await ConsoleLogger.LogAsync("Ratelimit service initialized", LogLvl.INFO); await StatsUpdater.Initialize(); await ConsoleLogger.LogAsync("Top.gg stats updater initialized", LogLvl.INFO); await RemindService.Initialize(); await ConsoleLogger.LogAsync("Remind service initialized", LogLvl.INFO); await UpvoteExpirationNotifier.Initialize(); await ConsoleLogger.LogAsync("Upvote expiration notification timer initialized", LogLvl.INFO); await GameRotationService.Initialize(); await ConsoleLogger.LogAsync("Game rotation timer initialized", LogLvl.INFO); #endif await ConsoleLogger.LogAsync("All timers initialized.", LogLvl.INFO); }
public static IServiceCollection AddRateLimits(this IServiceCollection services) { var rateLimitService = new RateLimitService(); services.AddSingleton <RateLimitService>(rateLimitService); // for compatibility reasons services.AddSingleton <IRateLimitService>(rateLimitService); return(services); }
public HwiServer(ITransport transport, IPermissionPrompt permissionPrompt, RateLimitService rateLimitService, ILoggerFactory loggerFactory) { Transport = transport; _permissionPrompt = permissionPrompt; _rateLimitService = rateLimitService; _logger = loggerFactory.CreateLogger(LoggerNames.HwiServer); }
public void Configure(IApplicationBuilder app, RateLimitService service) { var forwardingOptions = new ForwardedHeadersOptions(); forwardingOptions.KnownNetworks.Clear(); forwardingOptions.KnownProxies.Clear(); forwardingOptions.ForwardedHeaders = ForwardedHeaders.All; app.UseForwardedHeaders(forwardingOptions); service.SetZone("zone=mylimit rate=10r/s"); app.UseMvc(); }
public void Configure(IApplicationBuilder app, RateLimitService rateLimitService) { rateLimitService.SetZone($"zone={RateLimitZones.Prompt} rate=4r/m burst=3"); app.UseStaticFiles(); app.UseHwiServer(); app.UseRouting(); app.UseEndpoints(e => { e.MapControllers(); }); }
public MessageReceived(IServiceProvider provider) : base(provider) { _provider = provider; _commandService = _provider.GetRequiredService <CommandService>(); _chatService = _provider.GetRequiredService <ChatService>(); _resultService = _provider.GetRequiredService <ResultService>(); _spamService = _provider.GetRequiredService <SpamService>(); _rateLimitService = _provider.GetRequiredService <RateLimitService>(); _logger = _provider.GetRequiredService <LoggingService>(); _client.MessageReceived += OnMessageReceivedAsync; }
public void WorkAsExpected( uint max, ushort slot, ushort block, ushort now, params uint[] timeLine) { IRateLimitCache cache = new RateLimitCacheForCityApi(max, slot, block); foreach (var time in timeLine) { // Threshold not crossed for given time line Assert.False(RateLimitService.IsThresholdCrossed(time, cache)); } // Threshold crossed now Assert.True(RateLimitService.IsThresholdCrossed(now, cache)); }
public UsersController(UserManager <ApplicationUser> userManager, BTCPayServerOptions btcPayServerOptions, RoleManager <IdentityRole> roleManager, SettingsRepository settingsRepository, EventAggregator eventAggregator, IPasswordValidator <ApplicationUser> passwordValidator, NicolasDorier.RateLimits.RateLimitService throttleService, Configuration.BTCPayServerOptions options, IAuthorizationService authorizationService) { _userManager = userManager; _btcPayServerOptions = btcPayServerOptions; _roleManager = roleManager; _settingsRepository = settingsRepository; _eventAggregator = eventAggregator; _passwordValidator = passwordValidator; _throttleService = throttleService; _options = options; _authorizationService = authorizationService; }
public override Task <PreconditionResult> CheckPermissions(ICommandContext context, CommandInfo command, IServiceProvider serviceProvider) { return(Task.Run(() => { _serviceProvider = serviceProvider; _rateLimitService = _serviceProvider.GetService <RateLimitService>(); _statistics = _serviceProvider.GetService <Statistics>(); if (_rateLimitService.TryGet(context.User.Id)) { return Task.FromResult(PreconditionResult.FromError(string.Empty)); } else { _rateLimitService.TryAdd(context.User.Id, new RateLimit(Config.UserRateLimit)); _statistics.CommandUsage.AddOrUpdate(command.Name, 0, (key, value) => value + 1); } if (_rateLimitService.TryGet(context.Channel.Id, out var pair)) { if (pair.Item1.Uses >= Config.MaxChannelRateLimitUses) { return Task.FromResult(PreconditionResult.FromError(string.Empty)); } else { _rateLimitService.Update(context.Channel.Id, (k, v) => { v.Item1.Uses++; return v; }); } } else { _rateLimitService.TryAdd(context.Channel.Id, new RateLimit(Config.ChannelRateLimit)); } (context as Context).Command = command; return Task.FromResult(PreconditionResult.FromSuccess()); })); }
public UsersController(UserManager <ApplicationUser> userManager, RoleManager <IdentityRole> roleManager, SettingsRepository settingsRepository, EventAggregator eventAggregator, IPasswordValidator <ApplicationUser> passwordValidator, RateLimitService throttleService, BTCPayServerOptions options, IAuthorizationService authorizationService, CssThemeManager themeManager) { _userManager = userManager; _roleManager = roleManager; _settingsRepository = settingsRepository; _eventAggregator = eventAggregator; _passwordValidator = passwordValidator; _throttleService = throttleService; _options = options; _authorizationService = authorizationService; _themeManager = themeManager; }
public GreenfieldUsersController(UserManager <ApplicationUser> userManager, RoleManager <IdentityRole> roleManager, SettingsRepository settingsRepository, EventAggregator eventAggregator, IPasswordValidator <ApplicationUser> passwordValidator, RateLimitService throttleService, BTCPayServerOptions options, IAuthorizationService authorizationService, UserService userService, Logs logs) { this.Logs = logs; _userManager = userManager; _roleManager = roleManager; _settingsRepository = settingsRepository; _eventAggregator = eventAggregator; _passwordValidator = passwordValidator; _throttleService = throttleService; _options = options; _authorizationService = authorizationService; _userService = userService; }
public AccountController( UserManager <ApplicationUser> userManager, RoleManager <IdentityRole> roleManager, SignInManager <ApplicationUser> signInManager, SettingsRepository settingsRepository, Configuration.BTCPayServerOptions options, BTCPayServerEnvironment btcPayServerEnvironment, U2FService u2FService, RateLimitService rateLimitService, EventAggregator eventAggregator) { _userManager = userManager; _signInManager = signInManager; _RoleManager = roleManager; _SettingsRepository = settingsRepository; _Options = options; _btcPayServerEnvironment = btcPayServerEnvironment; _u2FService = u2FService; _rateLimitService = rateLimitService; _eventAggregator = eventAggregator; _logger = Logs.PayServer; }
public static IServiceCollection AddBTCPayServer(this IServiceCollection services, IConfiguration configuration) { services.AddSingleton<MvcNewtonsoftJsonOptions>(o => o.GetRequiredService<IOptions<MvcNewtonsoftJsonOptions>>().Value); services.AddDbContext<ApplicationDbContext>((provider, o) => { var factory = provider.GetRequiredService<ApplicationDbContextFactory>(); factory.ConfigureBuilder(o); }); services.AddHttpClient(); services.AddHttpClient(nameof(ExplorerClientProvider), httpClient => { httpClient.Timeout = Timeout.InfiniteTimeSpan; }); services.AddSingleton<BTCPayNetworkJsonSerializerSettings>(); services.RegisterJsonConverter(n => new ClaimDestinationJsonConverter(n)); services.AddPayJoinServices(); #if ALTCOINS services.AddMoneroLike(); services.AddEthereumLike(); #endif services.TryAddSingleton<SettingsRepository>(); services.TryAddSingleton<LabelFactory>(); services.TryAddSingleton<TorServices>(); services.TryAddSingleton<SocketFactory>(); services.TryAddSingleton<LightningClientFactoryService>(); services.TryAddSingleton<InvoicePaymentNotification>(); services.TryAddSingleton<BTCPayServerOptions>(o => o.GetRequiredService<IOptions<BTCPayServerOptions>>().Value); services.AddStartupTask<MigrationStartupTask>(); services.TryAddSingleton<InvoiceRepository>(o => { var opts = o.GetRequiredService<BTCPayServerOptions>(); var dbContext = o.GetRequiredService<ApplicationDbContextFactory>(); var dbpath = Path.Combine(opts.DataDir, "InvoiceDB"); if (!Directory.Exists(dbpath)) Directory.CreateDirectory(dbpath); return new InvoiceRepository(dbContext, dbpath, o.GetRequiredService<BTCPayNetworkProvider>(), o.GetService<EventAggregator>()); }); services.AddSingleton<BTCPayServerEnvironment>(); services.TryAddSingleton<TokenRepository>(); services.TryAddSingleton<WalletRepository>(); services.TryAddSingleton<EventAggregator>(); services.TryAddSingleton<PaymentRequestService>(); services.TryAddSingleton<U2FService>(); services.TryAddSingleton<ApplicationDbContextFactory>(o => { var opts = o.GetRequiredService<BTCPayServerOptions>(); ApplicationDbContextFactory dbContext = null; if (!String.IsNullOrEmpty(opts.PostgresConnectionString)) { Logs.Configuration.LogInformation($"Postgres DB used ({opts.PostgresConnectionString})"); dbContext = new ApplicationDbContextFactory(DatabaseType.Postgres, opts.PostgresConnectionString); } else if (!String.IsNullOrEmpty(opts.MySQLConnectionString)) { Logs.Configuration.LogInformation($"MySQL DB used ({opts.MySQLConnectionString})"); Logs.Configuration.LogWarning("MySQL is not widely tested and should be considered experimental, we advise you to use postgres instead."); dbContext = new ApplicationDbContextFactory(DatabaseType.MySQL, opts.MySQLConnectionString); } else { var connStr = "Data Source=" + Path.Combine(opts.DataDir, "sqllite.db"); Logs.Configuration.LogInformation($"SQLite DB used ({connStr})"); Logs.Configuration.LogWarning("SQLite is not widely tested and should be considered experimental, we advise you to use postgres instead."); dbContext = new ApplicationDbContextFactory(DatabaseType.Sqlite, connStr); } return dbContext; }); services.TryAddSingleton<BTCPayNetworkProvider>(o => { var opts = o.GetRequiredService<BTCPayServerOptions>(); return opts.NetworkProvider; }); services.TryAddSingleton<AppService>(); services.TryAddTransient<Safe>(); services.TryAddSingleton<Ganss.XSS.HtmlSanitizer>(o => { var htmlSanitizer = new Ganss.XSS.HtmlSanitizer(); htmlSanitizer.RemovingAtRule += (sender, args) => { }; htmlSanitizer.RemovingTag += (sender, args) => { if (args.Tag.TagName.Equals("img", StringComparison.InvariantCultureIgnoreCase)) { if (!args.Tag.ClassList.Contains("img-fluid")) { args.Tag.ClassList.Add("img-fluid"); } args.Cancel = true; } }; htmlSanitizer.RemovingAttribute += (sender, args) => { if (args.Tag.TagName.Equals("img", StringComparison.InvariantCultureIgnoreCase) && args.Attribute.Name.Equals("src", StringComparison.InvariantCultureIgnoreCase) && args.Reason == Ganss.XSS.RemoveReason.NotAllowedUrlValue) { args.Cancel = true; } }; htmlSanitizer.RemovingStyle += (sender, args) => { args.Cancel = true; }; htmlSanitizer.AllowedAttributes.Add("class"); htmlSanitizer.AllowedTags.Add("iframe"); htmlSanitizer.AllowedTags.Add("style"); htmlSanitizer.AllowedTags.Remove("img"); htmlSanitizer.AllowedAttributes.Add("webkitallowfullscreen"); htmlSanitizer.AllowedAttributes.Add("allowfullscreen"); return htmlSanitizer; }); services.TryAddSingleton<LightningConfigurationProvider>(); services.TryAddSingleton<LanguageService>(); services.TryAddSingleton<NBXplorerDashboard>(); services.TryAddSingleton<ISyncSummaryProvider, NBXSyncSummaryProvider>(); services.TryAddSingleton<StoreRepository>(); services.TryAddSingleton<PaymentRequestRepository>(); services.TryAddSingleton<BTCPayWalletProvider>(); services.TryAddSingleton<WalletReceiveStateService>(); services.TryAddSingleton<CurrencyNameTable>(CurrencyNameTable.Instance); services.TryAddSingleton<IFeeProviderFactory>(o => new NBXplorerFeeProviderFactory(o.GetRequiredService<ExplorerClientProvider>()) { Fallback = new FeeRate(100L, 1) }); services.AddSingleton<CssThemeManager>(); services.Configure<MvcOptions>((o) => { o.Filters.Add(new ContentSecurityPolicyCssThemeManager()); o.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(WalletId))); o.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(DerivationStrategyBase))); }); services.AddSingleton<IHostedService, CssThemeManagerHostedService>(); services.AddSingleton<HostedServices.CheckConfigurationHostedService>(); services.AddSingleton<IHostedService, HostedServices.CheckConfigurationHostedService>(o => o.GetRequiredService<CheckConfigurationHostedService>()); services.AddSingleton<HostedServices.PullPaymentHostedService>(); services.AddSingleton<IHostedService, HostedServices.PullPaymentHostedService>(o => o.GetRequiredService<PullPaymentHostedService>()); services.AddSingleton<BitcoinLikePaymentHandler>(); services.AddSingleton<IPaymentMethodHandler>(provider => provider.GetService<BitcoinLikePaymentHandler>()); services.AddSingleton<IHostedService, NBXplorerListener>(); services.AddSingleton<LightningLikePaymentHandler>(); services.AddSingleton<IPaymentMethodHandler>(provider => provider.GetService<LightningLikePaymentHandler>()); services.AddSingleton<IHostedService, LightningListener>(); services.AddSingleton<PaymentMethodHandlerDictionary>(); services.AddSingleton<NotificationManager>(); services.AddScoped<NotificationSender>(); services.AddSingleton<IHostedService, NBXplorerWaiters>(); services.AddSingleton<IHostedService, InvoiceNotificationManager>(); services.AddSingleton<IHostedService, InvoiceWatcher>(); services.AddSingleton<IHostedService, RatesHostedService>(); services.AddSingleton<IHostedService, BackgroundJobSchedulerHostedService>(); services.AddSingleton<IHostedService, AppHubStreamer>(); services.AddSingleton<IHostedService, AppInventoryUpdaterHostedService>(); services.AddSingleton<IHostedService, TransactionLabelMarkerHostedService>(); services.AddSingleton<IHostedService, UserEventHostedService>(); services.AddSingleton<IHostedService, DynamicDnsHostedService>(); services.AddSingleton<IHostedService, TorServicesHostedService>(); services.AddSingleton<IHostedService, PaymentRequestStreamer>(); services.AddSingleton<IHostedService, WalletReceiveCacheUpdater>(); services.AddSingleton<IBackgroundJobClient, BackgroundJobClient>(); services.AddScoped<IAuthorizationHandler, CookieAuthorizationHandler>(); services.AddScoped<IAuthorizationHandler, BitpayAuthorizationHandler>(); services.AddSingleton<IVersionFetcher, GithubVersionFetcher>(); services.AddSingleton<IHostedService, NewVersionCheckerHostedService>(); services.AddSingleton<INotificationHandler, NewVersionNotification.Handler>(); services.AddSingleton<INotificationHandler, InvoiceEventNotification.Handler>(); services.AddSingleton<INotificationHandler, PayoutNotification.Handler>(); #if DEBUG services.AddSingleton<INotificationHandler, JunkNotification.Handler>(); #endif services.TryAddSingleton<ExplorerClientProvider>(); services.TryAddSingleton<Bitpay>(o => { if (o.GetRequiredService<BTCPayServerOptions>().NetworkType == NetworkType.Mainnet) return new Bitpay(new Key(), new Uri("https://bitpay.com/")); else return new Bitpay(new Key(), new Uri("https://test.bitpay.com/")); }); services.TryAddSingleton<RateProviderFactory>(); services.TryAddSingleton<RateFetcher>(); services.TryAddScoped<IHttpContextAccessor, HttpContextAccessor>(); services.AddTransient<AccessTokenController>(); services.AddTransient<InvoiceController>(); services.AddTransient<AppsPublicController>(); services.AddTransient<PaymentRequestController>(); // Add application services. services.AddSingleton<EmailSenderFactory>(); services.AddAPIKeyAuthentication(); services.AddBtcPayServerAuthenticationSchemes(); services.AddAuthorization(o => o.AddBTCPayPolicies()); // bundling services.AddSingleton<IBundleProvider, ResourceBundleProvider>(); services.AddTransient<BundleOptions>(provider => { var opts = provider.GetRequiredService<BTCPayServerOptions>(); var bundle = new BundleOptions(); bundle.UseBundles = opts.BundleJsCss; bundle.AppendVersion = true; return bundle; }); services.AddCors(options => { options.AddPolicy(CorsPolicies.All, p => p.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin()); }); services.AddSingleton(provider => { var btcPayEnv = provider.GetService<BTCPayServerEnvironment>(); var rateLimits = new RateLimitService(); if (btcPayEnv.IsDeveloping) { rateLimits.SetZone($"zone={ZoneLimits.Login} rate=1000r/min burst=100 nodelay"); rateLimits.SetZone($"zone={ZoneLimits.Register} rate=1000r/min burst=100 nodelay"); rateLimits.SetZone($"zone={ZoneLimits.PayJoin} rate=1000r/min burst=100 nodelay"); } else { rateLimits.SetZone($"zone={ZoneLimits.Login} rate=5r/min burst=3 nodelay"); rateLimits.SetZone($"zone={ZoneLimits.Register} rate=2r/min burst=2 nodelay"); rateLimits.SetZone($"zone={ZoneLimits.PayJoin} rate=5r/min burst=3 nodelay"); } return rateLimits; }); services.AddLogging(logBuilder => { var debugLogFile = BTCPayServerOptions.GetDebugLog(configuration); if (!string.IsNullOrEmpty(debugLogFile)) { Serilog.Log.Logger = new LoggerConfiguration() .Enrich.FromLogContext() .MinimumLevel.Is(BTCPayServerOptions.GetDebugLogLevel(configuration)) .WriteTo.File(debugLogFile, rollingInterval: RollingInterval.Day, fileSizeLimitBytes: MAX_DEBUG_LOG_FILE_SIZE, rollOnFileSizeLimit: true, retainedFileCountLimit: 1) .CreateLogger(); logBuilder.AddProvider(new Serilog.Extensions.Logging.SerilogLoggerProvider(Log.Logger)); } }); return services; }
public static IServiceCollection AddBTCPayServer(this IServiceCollection services, IConfiguration configuration) { services.AddDbContext <ApplicationDbContext>((provider, o) => { var factory = provider.GetRequiredService <ApplicationDbContextFactory>(); factory.ConfigureBuilder(o); o.UseOpenIddict <BTCPayOpenIdClient, BTCPayOpenIdAuthorization, OpenIddictScope <string>, BTCPayOpenIdToken, string>(); }); services.AddHttpClient(); services.AddHttpClient(nameof(ExplorerClientProvider), httpClient => { httpClient.Timeout = Timeout.InfiniteTimeSpan; }); services.TryAddSingleton <SettingsRepository>(); services.TryAddSingleton <TorServices>(); services.TryAddSingleton <SocketFactory>(); services.TryAddSingleton <LightningClientFactoryService>(); services.TryAddSingleton <InvoicePaymentNotification>(); services.TryAddSingleton <BTCPayServerOptions>(o => o.GetRequiredService <IOptions <BTCPayServerOptions> >().Value); services.AddStartupTask <MigrationStartupTask>(); services.TryAddSingleton <InvoiceRepository>(o => { var opts = o.GetRequiredService <BTCPayServerOptions>(); var dbContext = o.GetRequiredService <ApplicationDbContextFactory>(); var dbpath = Path.Combine(opts.DataDir, "InvoiceDB"); if (!Directory.Exists(dbpath)) { Directory.CreateDirectory(dbpath); } return(new InvoiceRepository(dbContext, dbpath, o.GetRequiredService <BTCPayNetworkProvider>())); }); services.AddSingleton <BTCPayServerEnvironment>(); services.TryAddSingleton <TokenRepository>(); services.TryAddSingleton <WalletRepository>(); services.TryAddSingleton <EventAggregator>(); services.TryAddSingleton <PaymentRequestService>(); services.TryAddSingleton <U2FService>(); services.TryAddSingleton <CoinAverageSettings>(); services.TryAddSingleton <ApplicationDbContextFactory>(o => { var opts = o.GetRequiredService <BTCPayServerOptions>(); ApplicationDbContextFactory dbContext = null; if (!String.IsNullOrEmpty(opts.PostgresConnectionString)) { Logs.Configuration.LogInformation($"Postgres DB used ({opts.PostgresConnectionString})"); dbContext = new ApplicationDbContextFactory(DatabaseType.Postgres, opts.PostgresConnectionString); } else if (!String.IsNullOrEmpty(opts.MySQLConnectionString)) { Logs.Configuration.LogInformation($"MySQL DB used ({opts.MySQLConnectionString})"); dbContext = new ApplicationDbContextFactory(DatabaseType.MySQL, opts.MySQLConnectionString); } else { var connStr = "Data Source=" + Path.Combine(opts.DataDir, "sqllite.db"); Logs.Configuration.LogInformation($"SQLite DB used ({connStr})"); dbContext = new ApplicationDbContextFactory(DatabaseType.Sqlite, connStr); } return(dbContext); }); services.TryAddSingleton <BTCPayNetworkProvider>(o => { var opts = o.GetRequiredService <BTCPayServerOptions>(); return(opts.NetworkProvider); }); services.TryAddSingleton <AppService>(); services.TryAddTransient <Safe>(); services.TryAddSingleton <Ganss.XSS.HtmlSanitizer>(o => { var htmlSanitizer = new Ganss.XSS.HtmlSanitizer(); htmlSanitizer.RemovingAtRule += (sender, args) => { }; htmlSanitizer.RemovingTag += (sender, args) => { if (args.Tag.TagName.Equals("img", StringComparison.InvariantCultureIgnoreCase)) { if (!args.Tag.ClassList.Contains("img-fluid")) { args.Tag.ClassList.Add("img-fluid"); } args.Cancel = true; } }; htmlSanitizer.RemovingAttribute += (sender, args) => { if (args.Tag.TagName.Equals("img", StringComparison.InvariantCultureIgnoreCase) && args.Attribute.Name.Equals("src", StringComparison.InvariantCultureIgnoreCase) && args.Reason == Ganss.XSS.RemoveReason.NotAllowedUrlValue) { args.Cancel = true; } }; htmlSanitizer.RemovingStyle += (sender, args) => { args.Cancel = true; }; htmlSanitizer.AllowedAttributes.Add("class"); htmlSanitizer.AllowedTags.Add("iframe"); htmlSanitizer.AllowedTags.Remove("img"); htmlSanitizer.AllowedAttributes.Add("webkitallowfullscreen"); htmlSanitizer.AllowedAttributes.Add("allowfullscreen"); return(htmlSanitizer); }); services.TryAddSingleton <LightningConfigurationProvider>(); services.TryAddSingleton <LanguageService>(); services.TryAddSingleton <NBXplorerDashboard>(); services.TryAddSingleton <StoreRepository>(); services.TryAddSingleton <PaymentRequestRepository>(); services.TryAddSingleton <BTCPayWalletProvider>(); services.TryAddSingleton <CurrencyNameTable>(); services.TryAddSingleton <IFeeProviderFactory>(o => new NBXplorerFeeProviderFactory(o.GetRequiredService <ExplorerClientProvider>()) { Fallback = new FeeRate(100L, 1), BlockTarget = 20 }); services.AddSingleton <CssThemeManager>(); services.Configure <MvcOptions>((o) => { o.Filters.Add(new ContentSecurityPolicyCssThemeManager()); o.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(WalletId))); o.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(DerivationStrategyBase))); }); services.AddSingleton <IHostedService, CssThemeManagerHostedService>(); services.AddSingleton <HostedServices.CheckConfigurationHostedService>(); services.AddSingleton <IHostedService, HostedServices.CheckConfigurationHostedService>(o => o.GetRequiredService <CheckConfigurationHostedService>()); services.AddSingleton <BitcoinLikePaymentHandler>(); services.AddSingleton <IPaymentMethodHandler>(provider => provider.GetService <BitcoinLikePaymentHandler>()); services.AddSingleton <IHostedService, NBXplorerListener>(); services.AddSingleton <LightningLikePaymentHandler>(); services.AddSingleton <IPaymentMethodHandler>(provider => provider.GetService <LightningLikePaymentHandler>()); services.AddSingleton <IHostedService, LightningListener>(); services.AddSingleton <PaymentMethodHandlerDictionary>(); services.AddSingleton <ChangellyClientProvider>(); services.AddSingleton <IHostedService, NBXplorerWaiters>(); services.AddSingleton <IHostedService, InvoiceNotificationManager>(); services.AddSingleton <IHostedService, InvoiceWatcher>(); services.AddSingleton <IHostedService, RatesHostedService>(); services.AddSingleton <IHostedService, BackgroundJobSchedulerHostedService>(); services.AddSingleton <IHostedService, AppHubStreamer>(); services.AddSingleton <IHostedService, DynamicDnsHostedService>(); services.AddSingleton <IHostedService, TorServicesHostedService>(); services.AddSingleton <IHostedService, PaymentRequestStreamer>(); services.AddSingleton <IBackgroundJobClient, BackgroundJobClient>(); services.AddTransient <IConfigureOptions <MvcOptions>, BTCPayClaimsFilter>(); services.TryAddSingleton <ExplorerClientProvider>(); services.TryAddSingleton <Bitpay>(o => { if (o.GetRequiredService <BTCPayServerOptions>().NetworkType == NetworkType.Mainnet) { return(new Bitpay(new Key(), new Uri("https://bitpay.com/"))); } else { return(new Bitpay(new Key(), new Uri("https://test.bitpay.com/"))); } }); services.TryAddSingleton <RateProviderFactory>(); services.TryAddSingleton <RateFetcher>(); services.TryAddScoped <IHttpContextAccessor, HttpContextAccessor>(); services.AddTransient <AccessTokenController>(); services.AddTransient <InvoiceController>(); services.AddTransient <AppsPublicController>(); services.AddTransient <PaymentRequestController>(); // Add application services. services.AddSingleton <EmailSenderFactory>(); // bundling services.AddAuthorization(o => Policies.AddBTCPayPolicies(o)); services.AddBtcPayServerAuthenticationSchemes(configuration); services.AddSingleton <IBundleProvider, ResourceBundleProvider>(); services.AddTransient <BundleOptions>(provider => { var opts = provider.GetRequiredService <BTCPayServerOptions>(); var bundle = new BundleOptions(); bundle.UseBundles = opts.BundleJsCss; bundle.AppendVersion = true; return(bundle); }); services.AddCors(options => { options.AddPolicy(CorsPolicies.All, p => p.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin()); }); var rateLimits = new RateLimitService(); rateLimits.SetZone($"zone={ZoneLimits.Login} rate=5r/min burst=3 nodelay"); services.AddSingleton(rateLimits); return(services); }
public void Configure(IApplicationBuilder app, RateLimitService service) { service.SetZone("zone=mylimit rate=10r/s"); app.UseMvc(); }
public static IServiceCollection AddBTCPayServer(this IServiceCollection services) { services.AddDbContext <ApplicationDbContext>((provider, o) => { var factory = provider.GetRequiredService <ApplicationDbContextFactory>(); factory.ConfigureBuilder(o); }); services.AddHttpClient(); services.TryAddSingleton <SettingsRepository>(); services.TryAddSingleton <InvoicePaymentNotification>(); services.TryAddSingleton <BTCPayServerOptions>(o => o.GetRequiredService <IOptions <BTCPayServerOptions> >().Value); services.TryAddSingleton <InvoiceRepository>(o => { var opts = o.GetRequiredService <BTCPayServerOptions>(); var dbContext = o.GetRequiredService <ApplicationDbContextFactory>(); var dbpath = Path.Combine(opts.DataDir, "InvoiceDB"); if (!Directory.Exists(dbpath)) { Directory.CreateDirectory(dbpath); } return(new InvoiceRepository(dbContext, dbpath)); }); services.AddSingleton <BTCPayServerEnvironment>(); services.TryAddSingleton <TokenRepository>(); services.TryAddSingleton <EventAggregator>(); services.TryAddSingleton <CoinAverageSettings>(); services.TryAddSingleton <ApplicationDbContextFactory>(o => { var opts = o.GetRequiredService <BTCPayServerOptions>(); ApplicationDbContextFactory dbContext = null; if (!String.IsNullOrEmpty(opts.PostgresConnectionString)) { Logs.Configuration.LogInformation($"Postgres DB used ({opts.PostgresConnectionString})"); dbContext = new ApplicationDbContextFactory(DatabaseType.Postgres, opts.PostgresConnectionString); } else if (!String.IsNullOrEmpty(opts.MySQLConnectionString)) { Logs.Configuration.LogInformation($"MySQL DB used ({opts.MySQLConnectionString})"); dbContext = new ApplicationDbContextFactory(DatabaseType.MySQL, opts.MySQLConnectionString); } else { var connStr = "Data Source=" + Path.Combine(opts.DataDir, "sqllite.db"); Logs.Configuration.LogInformation($"SQLite DB used ({connStr})"); dbContext = new ApplicationDbContextFactory(DatabaseType.Sqlite, connStr); } return(dbContext); }); services.TryAddSingleton <BTCPayNetworkProvider>(o => { var opts = o.GetRequiredService <BTCPayServerOptions>(); return(opts.NetworkProvider); }); services.TryAddSingleton <AppsHelper>(); services.TryAddSingleton <LightningConfigurationProvider>(); services.TryAddSingleton <LanguageService>(); services.TryAddSingleton <NBXplorerDashboard>(); services.TryAddSingleton <StoreRepository>(); services.TryAddSingleton <BTCPayWalletProvider>(); services.TryAddSingleton <CurrencyNameTable>(); services.TryAddSingleton <IFeeProviderFactory>(o => new NBXplorerFeeProviderFactory(o.GetRequiredService <ExplorerClientProvider>()) { Fallback = new FeeRate(100, 1), BlockTarget = 20 }); services.AddSingleton <CssThemeManager>(); services.Configure <MvcOptions>((o) => { o.Filters.Add(new ContentSecurityPolicyCssThemeManager()); o.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(WalletId))); o.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(DerivationStrategyBase))); }); services.AddSingleton <IHostedService, CssThemeManagerHostedService>(); services.AddSingleton <IHostedService, MigratorHostedService>(); services.AddSingleton <Payments.IPaymentMethodHandler <DerivationStrategy>, Payments.Bitcoin.BitcoinLikePaymentHandler>(); services.AddSingleton <IHostedService, Payments.Bitcoin.NBXplorerListener>(); services.AddSingleton <IHostedService, HostedServices.CheckConfigurationHostedService>(); services.AddSingleton <Payments.IPaymentMethodHandler <Payments.Lightning.LightningSupportedPaymentMethod>, Payments.Lightning.LightningLikePaymentHandler>(); services.AddSingleton <LightningLikePaymentHandler>(); services.AddSingleton <IHostedService, Payments.Lightning.LightningListener>(); services.AddSingleton <ChangellyClientProvider>(); services.AddSingleton <IHostedService, NBXplorerWaiters>(); services.AddSingleton <IHostedService, InvoiceNotificationManager>(); services.AddSingleton <IHostedService, InvoiceWatcher>(); services.AddSingleton <IHostedService, RatesHostedService>(); services.AddTransient <IConfigureOptions <MvcOptions>, BTCPayClaimsFilter>(); services.TryAddSingleton <ExplorerClientProvider>(); services.TryAddSingleton <Bitpay>(o => { if (o.GetRequiredService <BTCPayServerOptions>().NetworkType == NetworkType.Mainnet) { return(new Bitpay(new Key(), new Uri("https://bitpay.com/"))); } else { return(new Bitpay(new Key(), new Uri("https://test.bitpay.com/"))); } }); services.TryAddSingleton <RateProviderFactory>(); services.TryAddSingleton <RateFetcher>(); services.TryAddScoped <IHttpContextAccessor, HttpContextAccessor>(); services.AddTransient <AccessTokenController>(); services.AddTransient <InvoiceController>(); // Add application services. services.AddTransient <IEmailSender, EmailSender>(); // bundling services.AddAuthorization(o => Policies.AddBTCPayPolicies(o)); BitpayAuthentication.AddAuthentication(services); services.AddBundles(); services.AddTransient <BundleOptions>(provider => { var opts = provider.GetRequiredService <BTCPayServerOptions>(); var bundle = new BundleOptions(); bundle.UseBundles = opts.BundleJsCss; bundle.AppendVersion = true; return(bundle); }); services.AddCors(options => { options.AddPolicy(CorsPolicies.All, p => p.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin()); }); var rateLimits = new RateLimitService(); rateLimits.SetZone($"zone={ZoneLimits.Login} rate=5r/min burst=3 nodelay"); services.AddSingleton(rateLimits); return(services); }
public void WorkAsExpected() { var rateLimiter = new RateLimitService(10, 10, 5); // 10 requests received at 0 IList <ushort> inputs = new List <ushort>(new ushort[10]); foreach (var i in inputs) { Assert.True(rateLimiter.IsAllowed(i)); } // 11 request should fail Assert.False(rateLimiter.IsAllowed(0)); //=========================== rateLimiter = new RateLimitService(10, 10, 5); // 10 requests received at 0 inputs = new List <ushort>() { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 }; foreach (var i in inputs) { Assert.True(rateLimiter.IsAllowed(i)); } // 11 request should fail Assert.False(rateLimiter.IsAllowed(9)); //=========================== rateLimiter = new RateLimitService(10, 10, 5); // 10 requests received at 0 inputs = new List <ushort>() { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 }; foreach (var i in inputs) { Assert.True(rateLimiter.IsAllowed(i)); } // 11 request should fail Assert.False(rateLimiter.IsAllowed(0)); //=========================== rateLimiter = new RateLimitService(10, 10, 5); // 10 requests received at 0 inputs = new List <ushort>() { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 }; foreach (var i in inputs) { Assert.True(rateLimiter.IsAllowed(i)); } // 11 request should fail Assert.False(rateLimiter.IsAllowed(5)); }