Syncshells (#11)
* some groups stuff * further groups rework * fixes for pause changes * adjsut timeout interval * fixes and namespace change to file scoped * more fixes * further implement groups * fix change group ownership * add some more stuff for groups * more fixes and additions * some fixes based on analyzers, add shard info to ui * add discord command, cleanup * fix regex * add group migration and deletion on user deletion * add api method for client to check health of connection * adjust regex for vanity * fixes for server and bot * fixes some string comparison in linq queries * fixes group leave and sets alias to null * fix syntax in changeownership * add better logging, fixes for group leaving * fixes for group leave Co-authored-by: Stanley Dimant <root.darkarchon@outlook.com>
This commit is contained in:
		| @@ -22,169 +22,170 @@ using System.Collections.Generic; | ||||
| using MareSynchronosServer.Services; | ||||
| using MareSynchronosShared.Services; | ||||
| using System.Net.Http; | ||||
| using MareSynchronosServer.Utils; | ||||
|  | ||||
| namespace MareSynchronosServer | ||||
| namespace MareSynchronosServer; | ||||
|  | ||||
| public class Startup | ||||
| { | ||||
|     public class Startup | ||||
|     public Startup(IConfiguration configuration) | ||||
|     { | ||||
|         public Startup(IConfiguration configuration) | ||||
|         Configuration = configuration; | ||||
|     } | ||||
|  | ||||
|     public IConfiguration Configuration { get; } | ||||
|  | ||||
|     public void ConfigureServices(IServiceCollection services) | ||||
|     { | ||||
|         services.AddHttpContextAccessor(); | ||||
|  | ||||
|         services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting")); | ||||
|         services.Configure<IpRateLimitPolicies>(Configuration.GetSection("IpRateLimitPolicies")); | ||||
|  | ||||
|         services.AddMemoryCache(); | ||||
|         services.AddInMemoryRateLimiting(); | ||||
|  | ||||
|         services.AddSingleton<SystemInfoService, SystemInfoService>(); | ||||
|         services.AddSingleton<IUserIdProvider, IdBasedUserIdProvider>(); | ||||
|         services.AddTransient(_ => Configuration); | ||||
|  | ||||
|         var mareConfig = Configuration.GetRequiredSection("MareSynchronos"); | ||||
|  | ||||
|         var defaultMethodConfig = new MethodConfig | ||||
|         { | ||||
|             Configuration = configuration; | ||||
|         } | ||||
|  | ||||
|         public IConfiguration Configuration { get; } | ||||
|  | ||||
|         public void ConfigureServices(IServiceCollection services) | ||||
|         { | ||||
|             services.AddHttpContextAccessor(); | ||||
|  | ||||
|             services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting")); | ||||
|             services.Configure<IpRateLimitPolicies>(Configuration.GetSection("IpRateLimitPolicies")); | ||||
|  | ||||
|             services.AddMemoryCache(); | ||||
|             services.AddInMemoryRateLimiting(); | ||||
|  | ||||
|             services.AddSingleton<SystemInfoService, SystemInfoService>(); | ||||
|             services.AddSingleton<IUserIdProvider, IdBasedUserIdProvider>(); | ||||
|             services.AddTransient(_ => Configuration); | ||||
|  | ||||
|             var mareConfig = Configuration.GetRequiredSection("MareSynchronos"); | ||||
|  | ||||
|             var defaultMethodConfig = new MethodConfig | ||||
|             Names = { MethodName.Default }, | ||||
|             RetryPolicy = new RetryPolicy | ||||
|             { | ||||
|                 Names = { MethodName.Default }, | ||||
|                 RetryPolicy = new RetryPolicy | ||||
|                 { | ||||
|                     MaxAttempts = 100, | ||||
|                     InitialBackoff = TimeSpan.FromSeconds(1), | ||||
|                     MaxBackoff = TimeSpan.FromSeconds(5), | ||||
|                     BackoffMultiplier = 1.5, | ||||
|                     RetryableStatusCodes = { Grpc.Core.StatusCode.Unavailable } | ||||
|                 } | ||||
|                 MaxAttempts = 100, | ||||
|                 InitialBackoff = TimeSpan.FromSeconds(1), | ||||
|                 MaxBackoff = TimeSpan.FromSeconds(5), | ||||
|                 BackoffMultiplier = 1.5, | ||||
|                 RetryableStatusCodes = { Grpc.Core.StatusCode.Unavailable } | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         services.AddSingleton(new MareMetrics(new List<string> | ||||
|         { | ||||
|             MetricsAPI.CounterInitializedConnections, | ||||
|             MetricsAPI.CounterUserPushData, | ||||
|             MetricsAPI.CounterUserPushDataTo, | ||||
|             MetricsAPI.CounterUsersRegisteredDeleted, | ||||
|         }, new List<string> | ||||
|         { | ||||
|             MetricsAPI.GaugeAuthorizedConnections, | ||||
|             MetricsAPI.GaugeConnections, | ||||
|             MetricsAPI.GaugePairs, | ||||
|             MetricsAPI.GaugePairsPaused, | ||||
|             MetricsAPI.GaugeAvailableIOWorkerThreads, | ||||
|             MetricsAPI.GaugeAvailableWorkerThreads | ||||
|         })); | ||||
|  | ||||
|         services.AddGrpcClient<AuthService.AuthServiceClient>(c => | ||||
|         { | ||||
|             c.Address = new Uri(mareConfig.GetValue<string>("ServiceAddress")); | ||||
|         }).ConfigureChannel(c => | ||||
|         { | ||||
|             c.ServiceConfig = new ServiceConfig { MethodConfigs = { defaultMethodConfig } }; | ||||
|             c.HttpHandler = new SocketsHttpHandler() | ||||
|             { | ||||
|                 EnableMultipleHttp2Connections = true | ||||
|             }; | ||||
|  | ||||
|             services.AddSingleton(new MareMetrics(new List<string> | ||||
|             { | ||||
|                 MetricsAPI.CounterInitializedConnections, | ||||
|                 MetricsAPI.CounterUserPushData, | ||||
|                 MetricsAPI.CounterUserPushDataTo, | ||||
|                 MetricsAPI.CounterUsersRegisteredDeleted, | ||||
|             }, new List<string> | ||||
|             { | ||||
|                 MetricsAPI.GaugeAuthorizedConnections, | ||||
|                 MetricsAPI.GaugeConnections, | ||||
|                 MetricsAPI.GaugePairs, | ||||
|                 MetricsAPI.GaugePairsPaused, | ||||
|                 MetricsAPI.GaugeAvailableIOWorkerThreads, | ||||
|                 MetricsAPI.GaugeAvailableWorkerThreads | ||||
|             })); | ||||
|  | ||||
|             services.AddGrpcClient<AuthService.AuthServiceClient>(c => | ||||
|             { | ||||
|                 c.Address = new Uri(mareConfig.GetValue<string>("ServiceAddress")); | ||||
|             }).ConfigureChannel(c => | ||||
|             { | ||||
|                 c.ServiceConfig = new ServiceConfig { MethodConfigs = { defaultMethodConfig } }; | ||||
|                 c.HttpHandler = new SocketsHttpHandler() | ||||
|                 { | ||||
|                     EnableMultipleHttp2Connections = true | ||||
|                 }; | ||||
|             }); | ||||
|             services.AddGrpcClient<FileService.FileServiceClient>(c => | ||||
|             { | ||||
|                 c.Address = new Uri(mareConfig.GetValue<string>("StaticFileServiceAddress")); | ||||
|             }).ConfigureChannel(c => | ||||
|             { | ||||
|                 c.ServiceConfig = new ServiceConfig { MethodConfigs = { defaultMethodConfig } }; | ||||
|             }); | ||||
|  | ||||
|             services.AddDbContextPool<MareDbContext>(options => | ||||
|             { | ||||
|                 options.UseNpgsql(Configuration.GetConnectionString("DefaultConnection"), builder => | ||||
|                 { | ||||
|                     builder.MigrationsHistoryTable("_efmigrationshistory", "public"); | ||||
|                     builder.MigrationsAssembly("MareSynchronosShared"); | ||||
|                 }).UseSnakeCaseNamingConvention(); | ||||
|                 options.EnableThreadSafetyChecks(false); | ||||
|             }, mareConfig.GetValue("DbContextPoolSize", 1024)); | ||||
|  | ||||
|             services.AddAuthentication(options => | ||||
|             { | ||||
|                 options.DefaultScheme = SecretKeyGrpcAuthenticationHandler.AuthScheme; | ||||
|             }).AddScheme<AuthenticationSchemeOptions, SecretKeyGrpcAuthenticationHandler>(SecretKeyGrpcAuthenticationHandler.AuthScheme, _ => { }); | ||||
|             services.AddAuthorization(options => options.FallbackPolicy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build()); | ||||
|  | ||||
|             services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>(); | ||||
|  | ||||
|             var signalRServiceBuilder = services.AddSignalR(hubOptions => | ||||
|             { | ||||
|                 hubOptions.MaximumReceiveMessageSize = long.MaxValue; | ||||
|                 hubOptions.EnableDetailedErrors = true; | ||||
|                 hubOptions.MaximumParallelInvocationsPerClient = 10; | ||||
|                 hubOptions.StreamBufferCapacity = 200; | ||||
|                 hubOptions.AddFilter<SignalRLimitFilter>(); | ||||
|             }); | ||||
|  | ||||
|             // add redis related options | ||||
|             var redis = mareConfig.GetValue("RedisConnectionString", string.Empty); | ||||
|             if (!string.IsNullOrEmpty(redis)) | ||||
|             { | ||||
|                 signalRServiceBuilder.AddStackExchangeRedis(redis, options => | ||||
|                 { | ||||
|                     options.Configuration.ChannelPrefix = "MareSynchronos"; | ||||
|                 }); | ||||
|  | ||||
|                 services.AddStackExchangeRedisCache(opt => | ||||
|                 { | ||||
|                     opt.Configuration = redis; | ||||
|                     opt.InstanceName = "MareSynchronosCache:"; | ||||
|                 }); | ||||
|                 services.AddSingleton<IClientIdentificationService, DistributedClientIdentificationService>(); | ||||
|                 services.AddHostedService(p => p.GetService<IClientIdentificationService>()); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 services.AddSingleton<IClientIdentificationService, LocalClientIdentificationService>(); | ||||
|                 services.AddHostedService(p => p.GetService<IClientIdentificationService>()); | ||||
|             } | ||||
|  | ||||
|             services.AddHostedService(provider => provider.GetService<SystemInfoService>()); | ||||
|         } | ||||
|  | ||||
|         public void Configure(IApplicationBuilder app, IWebHostEnvironment env) | ||||
|         }); | ||||
|         services.AddGrpcClient<FileService.FileServiceClient>(c => | ||||
|         { | ||||
|             if (env.IsDevelopment()) | ||||
|             c.Address = new Uri(mareConfig.GetValue<string>("StaticFileServiceAddress")); | ||||
|         }).ConfigureChannel(c => | ||||
|         { | ||||
|             c.ServiceConfig = new ServiceConfig { MethodConfigs = { defaultMethodConfig } }; | ||||
|         }); | ||||
|  | ||||
|         services.AddDbContextPool<MareDbContext>(options => | ||||
|         { | ||||
|             options.UseNpgsql(Configuration.GetConnectionString("DefaultConnection"), builder => | ||||
|             { | ||||
|                 app.UseDeveloperExceptionPage(); | ||||
|                 app.UseMigrationsEndPoint(); | ||||
|             } | ||||
|             else | ||||
|                 builder.MigrationsHistoryTable("_efmigrationshistory", "public"); | ||||
|                 builder.MigrationsAssembly("MareSynchronosShared"); | ||||
|             }).UseSnakeCaseNamingConvention(); | ||||
|             options.EnableThreadSafetyChecks(false); | ||||
|         }, mareConfig.GetValue("DbContextPoolSize", 1024)); | ||||
|  | ||||
|         services.AddAuthentication(options => | ||||
|         { | ||||
|             options.DefaultScheme = SecretKeyGrpcAuthenticationHandler.AuthScheme; | ||||
|         }).AddScheme<AuthenticationSchemeOptions, SecretKeyGrpcAuthenticationHandler>(SecretKeyGrpcAuthenticationHandler.AuthScheme, _ => { }); | ||||
|         services.AddAuthorization(options => options.FallbackPolicy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build()); | ||||
|  | ||||
|         services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>(); | ||||
|  | ||||
|         var signalRServiceBuilder = services.AddSignalR(hubOptions => | ||||
|         { | ||||
|             hubOptions.MaximumReceiveMessageSize = long.MaxValue; | ||||
|             hubOptions.EnableDetailedErrors = true; | ||||
|             hubOptions.MaximumParallelInvocationsPerClient = 10; | ||||
|             hubOptions.StreamBufferCapacity = 200; | ||||
|  | ||||
|             hubOptions.AddFilter<SignalRLimitFilter>(); | ||||
|         }); | ||||
|  | ||||
|         // add redis related options | ||||
|         var redis = mareConfig.GetValue("RedisConnectionString", string.Empty); | ||||
|         if (!string.IsNullOrEmpty(redis)) | ||||
|         { | ||||
|             signalRServiceBuilder.AddStackExchangeRedis(redis, options => | ||||
|             { | ||||
|                 app.UseExceptionHandler("/Error"); | ||||
|                 app.UseHsts(); | ||||
|             } | ||||
|  | ||||
|             app.UseIpRateLimiting(); | ||||
|  | ||||
|             app.UseRouting(); | ||||
|  | ||||
|             app.UseWebSockets(); | ||||
|  | ||||
|             var metricServer = new KestrelMetricServer(4980); | ||||
|             metricServer.Start(); | ||||
|  | ||||
|             app.UseAuthentication(); | ||||
|             app.UseAuthorization(); | ||||
|  | ||||
|             app.UseEndpoints(endpoints => | ||||
|             { | ||||
|                 endpoints.MapHub<MareHub>(Api.Path, options => | ||||
|                 { | ||||
|                     options.ApplicationMaxBufferSize = 5242880; | ||||
|                     options.TransportMaxBufferSize = 5242880; | ||||
|                     options.Transports = HttpTransportType.WebSockets | HttpTransportType.ServerSentEvents | HttpTransportType.LongPolling; | ||||
|                 }); | ||||
|                 options.Configuration.ChannelPrefix = "MareSynchronos"; | ||||
|             }); | ||||
|  | ||||
|             services.AddStackExchangeRedisCache(opt => | ||||
|             { | ||||
|                 opt.Configuration = redis; | ||||
|                 opt.InstanceName = "MareSynchronosCache:"; | ||||
|             }); | ||||
|             services.AddSingleton<IClientIdentificationService, DistributedClientIdentificationService>(); | ||||
|             services.AddHostedService(p => p.GetService<IClientIdentificationService>()); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             services.AddSingleton<IClientIdentificationService, LocalClientIdentificationService>(); | ||||
|             services.AddHostedService(p => p.GetService<IClientIdentificationService>()); | ||||
|         } | ||||
|  | ||||
|         services.AddHostedService(provider => provider.GetService<SystemInfoService>()); | ||||
|     } | ||||
|  | ||||
|     public void Configure(IApplicationBuilder app, IWebHostEnvironment env) | ||||
|     { | ||||
|         if (env.IsDevelopment()) | ||||
|         { | ||||
|             app.UseDeveloperExceptionPage(); | ||||
|             app.UseMigrationsEndPoint(); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             app.UseExceptionHandler("/Error"); | ||||
|             app.UseHsts(); | ||||
|         } | ||||
|  | ||||
|         app.UseIpRateLimiting(); | ||||
|  | ||||
|         app.UseRouting(); | ||||
|  | ||||
|         app.UseWebSockets(); | ||||
|  | ||||
|         var metricServer = new KestrelMetricServer(4980); | ||||
|         metricServer.Start(); | ||||
|  | ||||
|         app.UseAuthentication(); | ||||
|         app.UseAuthorization(); | ||||
|  | ||||
|         app.UseEndpoints(endpoints => | ||||
|         { | ||||
|             endpoints.MapHub<MareHub>(Api.Path, options => | ||||
|             { | ||||
|                 options.ApplicationMaxBufferSize = 5242880; | ||||
|                 options.TransportMaxBufferSize = 5242880; | ||||
|                 options.Transports = HttpTransportType.WebSockets | HttpTransportType.ServerSentEvents | HttpTransportType.LongPolling; | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 rootdarkarchon
					rootdarkarchon