Liam Pietralla
f577617b4d
All checks were successful
Build and Publish / Build Yale Access Backend (push) Successful in 28s
Build and Publish / Build Yale Access Frontend (push) Successful in 47s
Build and Publish / Push Yale Access Backend Docker Image (push) Successful in 9s
Build and Publish / Push Yale Access Frontend Docker Image (push) Successful in 10s
154 lines
5.0 KiB
C#
154 lines
5.0 KiB
C#
using Microsoft.AspNetCore.Authentication.Cookies;
|
|
using Microsoft.AspNetCore.HttpOverrides;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Serilog;
|
|
using Serilog.Events;
|
|
using YaleAccess.Data;
|
|
using YaleAccess.Models.Options;
|
|
using YaleAccess.Services;
|
|
using YaleAccess.Services.Interfaces;
|
|
|
|
var builder = WebApplication.CreateBuilder(args);
|
|
|
|
// Create the bootstraper logger
|
|
Log.Logger = new LoggerConfiguration()
|
|
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
|
|
.Enrich.FromLogContext()
|
|
.WriteTo.Console()
|
|
.CreateLogger();
|
|
|
|
try
|
|
{
|
|
// 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;
|
|
string logLocation = configuration["LogLocation"] ?? "Log.txt";
|
|
|
|
// Setup the application logger
|
|
Log.Logger = new LoggerConfiguration()
|
|
.WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Error)
|
|
.WriteTo.File(logLocation, rollingInterval: RollingInterval.Day)
|
|
.CreateLogger();
|
|
|
|
// 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.AddScoped<IYaleAccessor, MockYaleAccessor>();
|
|
}
|
|
else
|
|
{
|
|
builder.Services.AddScoped<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;
|
|
};
|
|
});
|
|
|
|
// Setup logging flow
|
|
builder.Host.UseSerilog();
|
|
|
|
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)
|
|
{
|
|
Log.Fatal(ex, "Host terminated unexpectedly");
|
|
throw;
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
Log.CloseAndFlush();
|
|
} |