201 lines
5.5 KiB
C#
201 lines
5.5 KiB
C#
using Microsoft.AspNetCore.Authentication;
|
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
|
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Sqlite;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using Watcher.Data;
|
|
using Watcher.Models;
|
|
|
|
var builder = WebApplication.CreateBuilder(args);
|
|
|
|
// Add services to the container.
|
|
builder.Services.AddControllersWithViews();
|
|
|
|
// HttpContentAccessor
|
|
builder.Services.AddHttpContextAccessor();
|
|
|
|
// ---------- 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;
|
|
var pocketId = principal.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier")?.Value;
|
|
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=Auth}/{action=Login}/"
|
|
);
|
|
|
|
|
|
app.Run();
|