222 lines
6.1 KiB
C#
222 lines
6.1 KiB
C#
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();
|
||
|
||
// Background Services
|
||
builder.Services.AddHostedService<NetworkCheck>();
|
||
|
||
|
||
// ---------- 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();
|