using System.Reflection; using DbContextLib; using Entities; using HeartTrackAPI.Services; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc.Versioning; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; using Model.Manager; using Model2Entities; using StubAPI; using StubbedContextLib; using Swashbuckle.AspNetCore.SwaggerGen; namespace HeartTrackAPI.Utils; public class AppBootstrap(IConfiguration configuration) { private IConfiguration Configuration { get; } = configuration; public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddOpenApiDocument(); services.AddEndpointsApiExplorer(); AddSwagger(services); AddHeartTrackContextServices(services); AddModelService(services); AddIdentityServices(services, configuration); AddApiVersioning(services); services.AddHealthChecks(); } private void AddHeartTrackContextServices(IServiceCollection services) { string? connectionString; switch (Environment.GetEnvironmentVariable("TYPE")) { case "BDD": var host = Environment.GetEnvironmentVariable("HOST"); var port = Environment.GetEnvironmentVariable("PORTDB"); var database = Environment.GetEnvironmentVariable("DATABASE"); var username = Environment.GetEnvironmentVariable("USERNAME"); var password = Environment.GetEnvironmentVariable("PASSWORD"); connectionString = $"Server={host};port={port};database={database};user={username};password={password}"; Console.WriteLine("========RUNNING USING THE MYSQL SERVER=============="); Console.WriteLine(connectionString); Console.WriteLine("===================================================="); services.AddDbContext(options => options.UseMySql($"{connectionString}", new MySqlServerVersion(new Version(10, 11, 1))) , ServiceLifetime.Singleton); break; default: Console.WriteLine("====== RUNNING USING THE IN SQLITE DATABASE ======"); connectionString = Configuration.GetConnectionString("HeartTrackAuthConnection"); Console.WriteLine(connectionString); if (!string.IsNullOrWhiteSpace(connectionString)) { services.AddDbContext(options => options.UseSqlite(connectionString), ServiceLifetime.Singleton); } else { services.AddDbContext(); } break; } } private void AddModelService(IServiceCollection services) { switch (Environment.GetEnvironmentVariable("TYPE")) { case "BDD": services.AddSingleton(provider => new DbDataManager(provider.GetRequiredService())); break; case "STUB-MODEL": services.AddSingleton(); break; default: services.AddSingleton(provider => { provider.GetRequiredService().Database.EnsureCreated(); return new DbDataManager(provider.GetRequiredService()); }); // services.AddSingleton(provider => new DbDataManager(provider.GetRequiredService())); break; } // Auth services.AddScoped(); } private void AddIdentityServices(IServiceCollection services, IConfiguration config) { /*services.AddAuthorization(); services.AddIdentityApiEndpoints() .AddEntityFrameworkStores();*/ var identityBuilder = services.AddIdentity>(options => { options.Password.RequireDigit = true; options.Password.RequireLowercase = true; options.Password.RequireUppercase = true; options.Password.RequireNonAlphanumeric = true; options.Password.RequiredLength = 8; }); if (Environment.GetEnvironmentVariable("TYPE") == "BDD") { identityBuilder.AddEntityFrameworkStores(); } else { identityBuilder.AddEntityFrameworkStores(); } services.AddAuthentication(options => { options.DefaultAuthenticateScheme = options.DefaultChallengeScheme = options.DefaultForbidScheme = options.DefaultScheme = options.DefaultSignInScheme = options.DefaultSignOutScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidIssuer =config["JWT:Issuer"], ValidateAudience = true, ValidAudience = config["JWT:Audience"], ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey( System.Text.Encoding.UTF8.GetBytes(config["JWT:SigningKey"]) ) }; }); /* app.UseCors(x => x .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials() //.WithOrigins("https://localhost:44351)) .SetIsOriginAllowed(origin => true));*/ // services.AddTransient, EmailSender>(); // services.AddAuthorization(); // services.AddIdentityApiEndpoints() // .AddEntityFrameworkStores(); // .AddEntityFrameworkStores().AddDefaultTokenProviders(); } private void AddApiVersioning(IServiceCollection services) { services.AddApiVersioning(opt => { opt.ReportApiVersions = true; opt.AssumeDefaultVersionWhenUnspecified = true; opt.DefaultApiVersion = new Microsoft.AspNetCore.Mvc.ApiVersion(1, 0); opt.ApiVersionReader = ApiVersionReader.Combine(new UrlSegmentApiVersionReader(), new HeaderApiVersionReader("x-api-version"), new MediaTypeApiVersionReader("x-api-version")); }); } private void AddSwagger(IServiceCollection services) { services.AddSwaggerGen(options => { var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); options.IncludeXmlComments(xmlPath); options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"", Name = "Authorization", In = ParameterLocation.Header, Type = SecuritySchemeType.Http, Scheme = "Bearer", BearerFormat = "JWT" }); var scheme = new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" }, Scheme = "oauth2", Name = "Bearer", In = ParameterLocation.Header, }, new List() } }; options.AddSecurityRequirement(scheme); options.OperationFilter(); }); services.AddTransient, SwaggerOptions>(); services.AddVersionedApiExplorer(setup => { setup.GroupNameFormat = "'v'VVV"; setup.SubstituteApiVersionInUrl = true; }); } public void Configure(WebApplication app, IWebHostEnvironment env) { app.UseHttpsRedirection(); app.UseAuthentication(); app.UseAuthorization(); // app.MapIdentityApi(); app.MapControllers(); app.MapHealthChecks("/health"); // Configure the HTTP request pipeline. if (true) { app.UseSwagger(options => { options.PreSerializeFilters.Add((swagger, httpReq) => { if (httpReq.Headers.ContainsKey("X-Forwarded-Host")) { string basePath; switch (Environment.GetEnvironmentVariable("TYPE")) // httpReq.Host.Value { case "STUB": basePath = "containers/HeartDev-heart_stub"; break; case "BDD": basePath = "containers/HeartDev-api"; break; default: basePath = httpReq.Host.Value; break; } var serverUrl = $"https://{httpReq.Headers["X-Forwarded-Host"]}/{basePath}"; swagger.Servers = new List { new() { Url = serverUrl } }; } }); }); app.UseOpenApi(); app.UseSwaggerUI(); app.MapSwagger(); } } }