Files
watcher/Watcher/Program.cs

225 lines
6.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.EntityFrameworkCore;
using Serilog;
using Watcher.Data;
using Watcher.Models;
using Watcher.Services;
//using Watcher.Services;
//using Watcher.Workers;
var builder = WebApplication.CreateBuilder(args);
// Serilog konfigurieren nur Logs, die nicht von Microsoft stammen
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", Serilog.Events.LogEventLevel.Warning)
.Enrich.FromLogContext()
.WriteTo.File(
"logs/watcher-.log",
outputTemplate: "[{Timestamp:yyyy-MM-dd HH:mm:ss}] [{Level:u3}] {Message:lj}{NewLine}{Exception}",
rollingInterval: RollingInterval.Day
)
.CreateLogger();
builder.Host.UseSerilog();
// Add services to the container.
builder.Services.AddControllersWithViews();
// HttpContentAccessor
builder.Services.AddHttpContextAccessor();
// Storage Singleton
builder.Services.AddSingleton<IDashboardStore, DashboardStore>();
// Background Services
builder.Services.AddHostedService<NetworkCheck>();
builder.Services.AddHostedService<DatabaseCheck>();
// ---------- Konfiguration ----------
DotNetEnv.Env.Load();
builder.Configuration
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables();
// Konfiguration laden
var configuration = builder.Configuration;
// ---------- DB-Kontext ----------
var dbProvider = configuration["Database:Provider"] ?? "MySQL";
var connectionString = configuration["Database:ConnectionString"];
builder.Services.AddDbContext<AppDbContext>((serviceProvider, options) =>
{
var config = serviceProvider.GetRequiredService<IConfiguration>();
var provider = dbProvider;
if (provider == "MySql")
{
var connStr = config.GetConnectionString("MySql") ?? config["Database:ConnectionStrings:MySql"];
options.UseMySql(connStr, ServerVersion.AutoDetect(connStr));
}
else if (provider == "Sqlite")
{
var connStr = config.GetConnectionString("Sqlite") ?? config["Database:ConnectionStrings:Sqlite"];
options.UseSqlite(connStr);
}
else
{
throw new Exception("Unsupported database provider configured.");
}
});
// ---------- Authentifizierung konfigurieren ----------
// PocketID nur konfigurieren, wenn aktiviert
var pocketIdSection = builder.Configuration.GetSection("Authentication:PocketID");
var pocketIdEnabled = pocketIdSection.GetValue<bool>("Enabled");
var auth = builder.Services.AddAuthentication("Cookies");
auth.AddCookie("Cookies", options =>
{
options.LoginPath = "/Auth/Login";
options.AccessDeniedPath = "/Auth/AccessDenied";
});
builder.Services.AddAuthentication()
.AddOpenIdConnect("oidc", options =>
{
options.Authority = pocketIdSection["Authority"];
options.ClientId = pocketIdSection["ClientId"];
options.ClientSecret = pocketIdSection["ClientSecret"];
options.ResponseType = "code";
options.CallbackPath = pocketIdSection["CallbackPath"];
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Clear();
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("email");
options.Events = new OpenIdConnectEvents
{
OnTokenValidated = async ctx =>
{
var db = ctx.HttpContext.RequestServices.GetRequiredService<AppDbContext>();
var principal = ctx.Principal;
#pragma warning disable CS8602 // Dereference of a possibly null reference.
var pocketId = principal.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier")?.Value;
#pragma warning restore CS8602 // Dereference of a possibly null reference.
var preferredUsername = principal.FindFirst("preferred_username")?.Value;
var email = principal.FindFirst("email")?.Value;
if (string.IsNullOrEmpty(pocketId))
return;
var user = await db.Users.FirstOrDefaultAsync(u => u.OIDC_Id == pocketId);
if (user == null)
{
user = new User
{
OIDC_Id = pocketId,
Username = preferredUsername ?? "",
Email = email,
LastLogin = DateTime.UtcNow,
IdentityProvider = "oidc",
Password = string.Empty
};
db.Users.Add(user);
}
else
{
user.LastLogin = DateTime.UtcNow;
user.Username = preferredUsername ?? user.Username;
user.Email = email ?? user.Email;
db.Users.Update(user);
}
await db.SaveChangesAsync();
}
};
});
var app = builder.Build();
// Migrationen anwenden (für SQLite oder andere DBs)
using (var scope = app.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
db.Database.Migrate();
}
// Standart-User in Datenbank schreiben
using (var scope = app.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
Console.WriteLine("Checking for users...");
if (!db.Users.Any())
{
Console.WriteLine("No users found, creating default user...");
var defaultUser = new User
{
OIDC_Id = string.Empty,
Username = "admin",
Email = string.Empty,
LastLogin = DateTime.UtcNow,
IdentityProvider = "local",
Password = BCrypt.Net.BCrypt.HashPassword("changeme")
};
db.Users.Add(defaultUser);
db.SaveChanges();
Console.WriteLine("Default user created.");
}
else
{
Console.WriteLine("Users already exist.");
}
}
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseStaticFiles();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}"
);
app.Run();