using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.ResponseCompression; using OpenIddict.Validation.AspNetCore; using PrivaPub.ClientModels; using PrivaPub.Extensions; using PrivaPub.Models; using PrivaPub.Services; using PrivaPub.StaticServices; using System.Text.Json.Serialization; using Microsoft.OpenApi; using PrivaPub.Services.ClientToServer.Private; using PrivaPub.Services.ClientToServer.Public; using PrivaPub.Federation.Actors; using PrivaPub.Federation.Outbox; using PrivaPub.Federation.Signing; using PrivaPub.Federation.Inbox; using PrivaPub.Federation.Objects; using PrivaPub.Federation.Moderation; using PrivaPub.Federation.Inbox.Handlers; using PrivaPub.Domain.Content; using PrivaPub.Domain.Relationships; using PrivaPub.Domain.Social; using PrivaPub.Domain.Statuses; using PrivaPub.Domain.Timelines; using PrivaPub.Infrastructure.Http; using PrivaPub.Infrastructure.Jobs; using PrivaPub.Infrastructure.Geo; using PrivaPub.Infrastructure.Statistics; using Microsoft.Extensions.Options; namespace PrivaPub.Middleware { public static class PrivaPubConfigurations { const string SchemeSelector = "PrivaPub"; public static IServiceCollection PrivaPubAppSettingsConfiguration(this IServiceCollection service, IConfiguration configuration) { return service .Configure(configuration.GetSection(nameof(MongoSettings))) .Configure(configuration.GetSection(nameof(AppConfiguration))); } public static IServiceCollection PrivaPubWorkersConfiguration(this IServiceCollection service) { return service; //.AddHostedService() //.AddHostedService() //.AddHostedService(); } public static IServiceCollection PrivaPubFederationConfiguration(this IServiceCollection service, IConfiguration configuration) { service.Configure(configuration.GetSection("Federation")); service.AddHttpClient(FederationHttp.ClientName, (provider, client) => { var baseAddress = provider.GetRequiredService>().CurrentValue.BackendBaseAddress?.TrimEnd('/'); client.Timeout = FederationHttp.RequestTimeout; client.DefaultRequestHeaders.UserAgent.ParseAdd($"PrivaPub/{BuildInfo.Ref} (+{baseAddress}/)"); }) .ConfigurePrimaryHttpMessageHandler(provider => SafeHttpHandlerFactory.Create(provider.GetRequiredService>().Value, provider.GetRequiredService())); return service .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton(services => services.GetRequiredService()) .AddSingleton(services => services.GetRequiredService()) .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddHostedService(); } public static IServiceCollection PrivaPubStatisticsConfiguration(this IServiceCollection service, IConfiguration configuration) => service .Configure(configuration.GetSection("Statistics")) .AddSingleton() .AddSingleton() .AddSingleton(services => services.GetRequiredService()) .AddHostedService(services => services.GetRequiredService()) .AddSingleton() .AddSingleton() .AddHostedService(); public static IServiceCollection PrivaPubAuthServicesConfiguration(this IServiceCollection service, IConfiguration configuration) { return service .AddAuthorization(options => { options.AddPolicy(Policies.IsUser, Extensions.Extensions.IsUserPolicy()); options.AddPolicy(Policies.IsAdmin, Extensions.Extensions.IsAdminPolicy()); options.AddPolicy(Policies.IsModerator, Extensions.Extensions.IsModeratorPolicy()); }) .AddAuthentication(options => { options.DefaultAuthenticateScheme = SchemeSelector; options.DefaultChallengeScheme = SchemeSelector; options.DefaultScheme = SchemeSelector; }) .AddPolicyScheme(SchemeSelector, SchemeSelector, options => options.ForwardDefaultSelector = context => context.Request.Path.StartsWithSegments("/api") ? OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme : JwtBearerDefaults.AuthenticationScheme) .AddPrivaPubAuth(configuration) .Services .AddSingleton() .AddSingleton(); } public static IServiceCollection PrivaPubInternalizationConfiguration(this IServiceCollection service, IConfiguration configuration) { return service .AddLocalization() .AddSingleton(); } public static IServiceCollection PrivaPubOptimizationConfiguration(this IServiceCollection service) { return service.AddResponseCompression(opts => { opts.Providers.Add(); opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(new[] { "application/octet-stream" }); }); } public static IServiceCollection PrivaPubDataBaseConfiguration(this IServiceCollection service) { return service.AddSingleton(); } public static IServiceCollection PrivaPubServicesConfiguration(this IServiceCollection service) { return service .AddTransient() .AddTransient() .AddTransient() .AddTransient() .AddTransient() .AddTransient() .AddTransient() .AddTransient() .AddTransient() .AddTransient() .AddTransient() .AddSingleton() .AddHttpContextAccessor() .AddMemoryCache() .AddSingleton(); } public static IServiceCollection PrivaPubMiddlewareConfiguration(this IServiceCollection service) { return service .AddEndpointsApiExplorer() .AddSwaggerGen(c => { c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { In = ParameterLocation.Header, Description = "Please enter a valid token", Name = "Authorization", Type = SecuritySchemeType.Http, BearerFormat = "JWT", Scheme = "bearer" }); c.AddSecurityRequirement(document => new OpenApiSecurityRequirement { [new OpenApiSecuritySchemeReference("Bearer", document)] = [] }); }) .AddRazorPages(options => options.RootDirectory = "/Web/Pages") .Services .AddControllers(options => { options.Filters.Add(); }) .AddJsonOptions(options => { options.JsonSerializerOptions.IgnoreReadOnlyFields = false; options.JsonSerializerOptions.IgnoreReadOnlyProperties = false; options.JsonSerializerOptions.PropertyNameCaseInsensitive = true; options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull; options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); }).Services; } public static IServiceCollection PrivaPubCORSConfiguration(this IServiceCollection service) { return service.AddCors(options => { options.DefaultPolicyName = "DefaultCORS"; options.AddDefaultPolicy(configure => { configure.AllowAnyMethod() .AllowAnyHeader() .AllowAnyOrigin() .WithExposedHeaders("Link", "X-RateLimit-Remaining", "X-RateLimit-Reset") .DisallowCredentials(); }); }); } } }