All checks were successful
Build and Publish / Build Yale Access Frontend (pull_request) Successful in 50s
Build and Publish / Push Yale Access Frontend Docker Image (pull_request) Has been skipped
Build and Publish / Build Yale Access Backend (pull_request) Successful in 1m53s
Build and Publish / Push Yale Access Backend Docker Image (pull_request) Has been skipped
150 lines
4.8 KiB
C#
150 lines
4.8 KiB
C#
using Microsoft.AspNetCore.Authentication.Cookies;
|
|
using Microsoft.AspNetCore.HttpOverrides;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using OpenTelemetry.Logs;
|
|
using YaleAccess.Data;
|
|
using YaleAccess.Models.Options;
|
|
using YaleAccess.Services;
|
|
using YaleAccess.Services.Interfaces;
|
|
|
|
var builder = WebApplication.CreateBuilder(args);
|
|
|
|
try
|
|
{
|
|
var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]);
|
|
|
|
builder.Logging.AddOpenTelemetry(logging =>
|
|
{
|
|
logging.IncludeFormattedMessage = true;
|
|
logging.IncludeScopes = true;
|
|
|
|
if (useOtlpExporter)
|
|
{
|
|
logging.AddOtlpExporter();
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("OTEL_EXPORTER_OTLP_ENDPOINT is not set. Skipping OTLP exporter configuration.");
|
|
}
|
|
});
|
|
|
|
// Add services to the container.
|
|
builder.Services.AddControllers();
|
|
|
|
// Add the database context
|
|
builder.Services.AddDbContext<YaleContext>(options =>
|
|
{
|
|
options.UseSqlite(builder.Configuration.GetConnectionString(nameof(YaleContext)));
|
|
});
|
|
|
|
// Configure the options
|
|
builder.Services.Configure<AuthenticationOptions>(builder.Configuration.GetSection(AuthenticationOptions.Authentication));
|
|
builder.Services.Configure<CodesOptions>(builder.Configuration.GetSection(CodesOptions.Codes));
|
|
builder.Services.Configure<DevicesOptions>(builder.Configuration.GetSection(DevicesOptions.Devices));
|
|
builder.Services.Configure<ZWaveOptions>(builder.Configuration.GetSection(ZWaveOptions.ZWave));
|
|
builder.Services.Configure<TwiloOptions>(builder.Configuration.GetSection(TwiloOptions.Twilio));
|
|
|
|
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
|
builder.Services.AddEndpointsApiExplorer();
|
|
builder.Services.AddSwaggerGen();
|
|
|
|
// Get a copy of the configuration
|
|
IConfiguration configuration = builder.Configuration;
|
|
|
|
// Configure the DI services
|
|
builder.Services.AddScoped<SMSService>();
|
|
|
|
// If the environment is development and the mock option is set to true, use the mock service
|
|
if (builder.Environment.IsDevelopment() && configuration.GetValue<bool>("UseMockDevelopmentMode"))
|
|
{
|
|
builder.Services.AddSingleton<MockYaleData>();
|
|
builder.Services.AddSingleton<IYaleAccessor, MockYaleAccessor>();
|
|
}
|
|
else
|
|
{
|
|
builder.Services.AddSingleton<IYaleAccessor, YaleAccessor>();
|
|
}
|
|
|
|
|
|
// Setup CORS
|
|
string[] corsAllowedOrigins = (configuration["CorsAllowedOrigins"] ?? "http://localhost:3000").Split(",") ;
|
|
builder.Services.AddCors(options =>
|
|
{
|
|
options.AddDefaultPolicy(policy =>
|
|
{
|
|
policy.WithOrigins(corsAllowedOrigins)
|
|
.AllowCredentials()
|
|
.AllowAnyMethod()
|
|
.WithHeaders("Content-Type", "Authorization");
|
|
});
|
|
});
|
|
|
|
// Setup cookie authentication scheme
|
|
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
|
|
.AddCookie(options =>
|
|
{
|
|
// Set HTTP only to true to prevent XSS attacks
|
|
options.Cookie.HttpOnly = true;
|
|
|
|
// Set secure policy to always to prevent sending cookies over HTTP for production use, for development set to None
|
|
if (builder.Environment.IsDevelopment())
|
|
options.Cookie.SecurePolicy = CookieSecurePolicy.None;
|
|
else
|
|
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
|
|
|
|
// Ensure that the API will return a 401 Unauthorized instead of redirecting to the login page
|
|
options.AccessDeniedPath = string.Empty;
|
|
options.LoginPath = string.Empty;
|
|
options.Events.OnRedirectToLogin = context =>
|
|
{
|
|
context.Response.StatusCode = 401;
|
|
return Task.CompletedTask;
|
|
};
|
|
});
|
|
|
|
var app = builder.Build();
|
|
|
|
// Create the database if it doesn't exist
|
|
using (var scope = app.Services.CreateScope())
|
|
{
|
|
var services = scope.ServiceProvider;
|
|
var context = services.GetRequiredService<YaleContext>();
|
|
context.Database.Migrate();
|
|
}
|
|
|
|
// Configure the forwarded headers middleware
|
|
app.UseForwardedHeaders(new ForwardedHeadersOptions
|
|
{
|
|
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
|
|
});
|
|
|
|
// Configure the HTTP request pipeline.
|
|
if (app.Environment.IsDevelopment())
|
|
{
|
|
app.UseSwagger();
|
|
app.UseSwaggerUI();
|
|
}
|
|
|
|
app.UseHttpsRedirection();
|
|
|
|
app.UseCors();
|
|
|
|
app.UseAuthentication();
|
|
|
|
app.UseAuthorization();
|
|
|
|
app.MapControllers();
|
|
|
|
app.Run();
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// Ignore host aborted exceptions caused by build checks
|
|
if (ex is not HostAbortedException)
|
|
{
|
|
Console.WriteLine("Host terminated unexpectedly");
|
|
throw;
|
|
}
|
|
}
|