using System.IO; using System.Reflection; using System.Security.Cryptography.X509Certificates; using Dough.IdentityServer; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Dough.Models; using Dough.Models.Database; using Dough.Services; using IdentityServer4.Configuration; using IdentityServer4.EntityFramework.DbContexts; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Diagnostics.HealthChecks; namespace Dough { public class Startup { private IConfiguration _configuration { get; } private IWebHostEnvironment _environment { get; } private const string DefaultCorsPolicy = "DefaultCorsPolicy"; public Startup(IConfiguration configuration, IWebHostEnvironment environment) { _configuration = configuration; _environment = environment; } private string GetConnectionStringFromEnvironment(string database) { var host = _configuration.GetValue("DB_HOST"); var port = _configuration.GetValue("DB_PORT"); var user = _configuration.GetValue("DB_USER"); var password = _configuration.GetValue("DB_PASSWORD"); return $"Server={host},{port};Database={database};User={user};Password={password}"; } private static X509Certificate2 GetSigningCredentialFromPfx(string fileName) { var path = Path.Combine(Directory.GetCurrentDirectory(), "AppData", "certs", fileName); return new X509Certificate2(path, string.Empty); } public void ConfigureServices(IServiceCollection services) { services.AddCors(options => { options.AddPolicy(DefaultCorsPolicy, builder => { builder .WithOrigins(Constants.BrowserAppUrls) .AllowAnyHeader() .AllowAnyMethod(); }); }); var dataprotectionkeyPath = Path.Combine(Directory.GetCurrentDirectory(), "AppData", "dpkeys"); services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(dataprotectionkeyPath)); services.AddHealthChecks() .AddDbContextCheck(); services.AddDbContext(options => { options.UseMySql(GetConnectionStringFromEnvironment("dough"), builder => { builder.EnableRetryOnFailure(); } ); if (_environment.IsDevelopment()) { options.EnableSensitiveDataLogging(); } }); var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name; services.AddAuthentication().AddLocalApi(); services.AddIdentityServer(options => { options.UserInteraction = new UserInteractionOptions { LoginUrl = "/login", ErrorUrl = "/error", }; }) .AddOperationalStore(options => { options.ConfigureDbContext = builder => { builder.UseMySql(GetConnectionStringFromEnvironment("dough_tokens"), sql => { sql.MigrationsAssembly(migrationsAssembly); sql.EnableRetryOnFailure(); }); if (_environment.IsDevelopment()) { builder.EnableSensitiveDataLogging(); } }; }) .AddInMemoryIdentityResources(Config.IdentityResources) .AddInMemoryApiScopes(Config.ApiScopes) .AddInMemoryClients(Config.Clients) .AddSigningCredential(GetSigningCredentialFromPfx("example.pfx")) .AddProfileService(); services.AddSingleton(); services.AddControllers(); services.AddRazorPages().AddRazorRuntimeCompilation(); } public void Configure(IApplicationBuilder app) { if (_environment.IsDevelopment()) app.UseDeveloperExceptionPage(); app.UseRouting(); app.UseStaticFiles(); app.UseCors(DefaultCorsPolicy); app.UseStatusCodePages(); app.UseIdentityServer(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health"); endpoints.MapRazorPages(); endpoints.MapControllers() .RequireAuthorization(); }); } } }