Пример #1
0
        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);
        }
Пример #2
0
 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();
     });
 }
Пример #3
0
        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 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;
        }
Пример #5
0
        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 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);
        }
Пример #7
0
 public void Configure(IApplicationBuilder app, RateLimitService service)
 {
     service.SetZone("zone=mylimit rate=10r/s");
     app.UseMvc();
 }