using System; using System.Collections.Generic; using System.IO; using System.Reflection; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.OpenApi.Models; using Newtonsoft.Json.Converters; using Serilog; using CRIF.ACTion.Common.Parsers; using CRIF.ACTion.Configuration; using CRIF.ACTion.Decisioning; using CRIF.ACTion.Loan; using CRIF.ACTion.Loan.Individuals; using CRIF.ACTion.Services.Crif; using Landmark.OLA.Application.Common.Domain; using Landmark.OLA.Application.Common.Security; using Landmark.OLA.Application.Configuration; using Landmark.OLA.Application.DataAccess; using Landmark.OLA.Application.DataAccessLayer; using Landmark.OLA.Application.Services; using Landmark.OLA.Models; using Landmark.OLA.Models.Addresses; using Landmark.OLA.Models.Decisioning; using Landmark.OLA.Models.Decisioning.Enums; using Landmark.OLA.Models.Individuals; using Landmark.OLA.Models.Loan; using Landmark.OLA.Models.OnlineBanking; using Landmark.OLA.Models.Vendor; using OnlineBankingAuth.Communication; using OnlineBankingAuth.Parsers; using OnlineBankingAuth.Services; using OnlineBankingAuth.Tokens; using LCU.Library.Internal.Logging; using LCU.Library.Internal.Logging.Middleware; using LCU.Library.Internal.Logging.Models; using LCU.Library.Internal.LcuHttpClient; using Landmark.OLA.Application.Services.MicroApiServices; using Landmark.OLA.Application.Services.Email; namespace Landmark.OLA.Application { public class Startup(IConfiguration configuration) { public IConfiguration Configuration { get; } = configuration; // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { var appConfig = new ApplicationSettings(); Configuration.GetSection("Primary").Bind(appConfig); services.AddSingleton(appConfig); var loggerConfiguration = new LoggingConfiguration(appConfig.AppName, appConfig.SeqKey, appConfig.SeqUrl); var lcuLogging = new LcuLogging(loggerConfiguration); lcuLogging.UseLcuLogging(); Log.Information($"{appConfig.AppName} Starting Up"); services.AddLCUHttpServices(); services.AddCors(options => { options.AddPolicy("DevCors", b => b .SetIsOriginAllowed(_ => true) .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials()); options.AddPolicy("ProdCors", b => b .WithOrigins( "https://applydev.landmarkcu.com", "https://applyqa.landmarkcu.com", "https://apply.landmarkcu.com", "https://qa-online-loan-app.apps.azure.lcu-internal.com", "https://uat-online-loan-app.apps.azure.lcu-internal.com", "https://prd-online-loan-app.apps.azure.lcu-internal.com", "https://qa-apps.landmarkcu.com", "https://uat-apps.landmarkcu.com", "https://apps.landmarkcu.com") .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials()); }); services.AddControllers().AddNewtonsoftJson(o => o.SerializerSettings.Converters.Add(new StringEnumConverter())); services.Configure(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = context => false; options.MinimumSameSitePolicy = SameSiteMode.None; }); //TODO #245: Disable in production? services.AddEndpointsApiExplorer(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "Landmark Loan API", Version = "v1" }); // For this to work, I also had to check the generate xml box in build options. var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); c.IncludeXmlComments(xmlPath, includeControllerXmlComments: true); }); services.AddScoped(); services.AddScoped(); services.Configure(options => Configuration.GetSection("ApplicationStorage").Bind(options)); services.AddSingleton(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped, AddIndividualResponseParser>(); services.AddScoped, LoanApplicationResponseParser>(); services.AddScoped, DecisioningStateResponseParser>(); services.AddScoped, GetApplicationProductsResponseParser>(); services.AddScoped>, ConfigurationRequestResponseParser>(); services.AddScoped>, ProductDetailsResponseParser>(); services.AddScoped, CustomFieldRequestResponseParser>(); services.AddScoped, DealershipResponseParser>(); services.AddSingleton(); // Add USPS scopes services.AddScoped(); services.AddScoped(); services.AddScoped, USPS.Parsers.AddressValidationResponseParser>(); services.Configure(options => Configuration.GetSection("ApplicationControl").Bind(options)); services.Configure(options => Configuration.GetSection("CrifSettings").Bind(options)); services.Configure(options => Configuration.GetSection("BlobStorageSettings").Bind(options)); services.Configure(options => Configuration.GetSection("BlobStorageConnectionSettings").Bind(options)); services.Configure(options => Configuration.GetSection("DealershipEmailSettings").Bind(options)); services.AddSingleton(); // Set up USPS services.Configure(options => Configuration.GetSection("UspsSettings").Bind(options)); // Setup up Email services.Configure(options => Configuration.GetSection("NotificationsApiConfiguration").Bind(options)); services.AddScoped(); services.AddSingleton(); // Setup up Core var coreSettings = new CoreSettings(); Configuration.GetSection("CoreSettings").Bind(coreSettings); services.AddSingleton(coreSettings); services.AddScoped(); services.AddScoped(); // Set up SAML IdP scopes services.AddScoped(); services.AddScoped, SAMLParser>(); // Set up SAML IdP configuration services.Configure(options => { Configuration.GetSection("SecuritySettings").Bind(options); }); // Setup DI service services.AddScoped(); services.AddScoped(); services.AddScoped(); //Set up Authentication services .AddAuthentication(JwtBearerDefaults.AuthenticationScheme) // AzureAD config .AddAzureAdBearer(options => Configuration.Bind("AzureActiveDirectory", options)); services.AddAuthorization(); services.AddDistributedMemoryCache(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ApplicationSettings appSettings) { Log.Information("Configuring..."); var policyCollection = new HeaderPolicyCollection() .AddDefaultSecurityHeaders() .AddCustomHeader("Cache-Control", "no-cache") .AddCustomHeader("Arr-Disable-Session-Affinity", "true"); app.UseCookiePolicy(new CookiePolicyOptions { CheckConsentNeeded = context => false, MinimumSameSitePolicy = SameSiteMode.None }); app.UseSecurityHeaders(policyCollection); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseSwagger(); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Landmark Loan API")); app.UseMiddleware(); app.UseSerilogRequestLogging(options => { options.EnrichDiagnosticContext = RequestResponseLoggingMiddleware.RequestDataParser.EnrichFromRequest; }); } else { app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")?.Equals("Development", StringComparison.OrdinalIgnoreCase) ?? false) app.UseCors("DevCors"); else app.UseCors("ProdCors"); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => endpoints.MapControllers()); } } }