Example #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);
        }
        public static IServiceCollection AddRateLimits(this IServiceCollection services)
        {
            var instance = new RateLimitService();

            services.AddSingleton(instance);
            return(services);
        }
Example #3
0
        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);
        }
Example #5
0
 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();
        }
Example #7
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();
     });
 }
Example #8
0
        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));
        }
Example #10
0
 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;
 }
Example #11
0
        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());
            }));
        }
Example #12
0
 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;
 }
Example #13
0
 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;
        }
Example #16
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);
        }
Example #17
0
 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);
        }
Example #19
0
        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));
        }