using LiteDB;
namespace LehrerApp.Data;
///
/// Prüft und ändert den Passwortschutz einer LiteDB-Datei.
/// Passwort-Änderungen laufen über eine Kopie (neue Datei mit Zielpasswort, alle
/// Collections umkopiert, dann Austausch) statt über LiteDatabase.Rebuild mit
/// Passwort, das in LiteDB 5.0.21 nachweislich fehlschlägt (per Skript verifiziert).
///
public class DatabaseEncryptionService
{
public bool IsEncrypted(string dbPath)
{
if (!File.Exists(dbPath)) return false;
try
{
using var db = new LiteDatabase(dbPath);
return false;
}
catch (LiteException)
{
return true;
}
}
public bool VerifyPassword(string dbPath, string password)
{
try
{
using var db = new LiteDatabase(new ConnectionString(dbPath) { Password = password });
return true;
}
catch (LiteException)
{
return false;
}
}
/// Setzt (newPassword != null), ändert oder entfernt (newPassword == null) das
/// Passwort der Datenbank. Der Aufrufer muss sicherstellen, dass keine andere
/// Verbindung (z.B. der laufende ) die Datei offen hält.
public void SetPassword(string dbPath, string? currentPassword, string? newPassword)
{
var tempPath = dbPath + ".reencrypt.tmp";
if (File.Exists(tempPath)) File.Delete(tempPath);
var srcConnection = currentPassword is null
? new ConnectionString(dbPath)
: new ConnectionString(dbPath) { Password = currentPassword };
var dstConnection = newPassword is null
? new ConnectionString(tempPath)
: new ConnectionString(tempPath) { Password = newPassword };
using (var src = new LiteDatabase(srcConnection))
using (var dst = new LiteDatabase(dstConnection))
{
foreach (var name in src.GetCollectionNames())
{
var docs = src.GetCollection(name).FindAll().ToList();
if (docs.Count > 0) dst.GetCollection(name).InsertBulk(docs);
}
}
File.Copy(tempPath, dbPath, overwrite: true);
File.Delete(tempPath);
}
}