306 lines
10 KiB
C#
306 lines
10 KiB
C#
using InnovEnergy.App.Backend.DataTypes;
|
|
using InnovEnergy.App.Backend.DataTypes.Methods;
|
|
using InnovEnergy.App.Backend.Relations;
|
|
using InnovEnergy.Lib.S3Utils;
|
|
using InnovEnergy.Lib.S3Utils.DataTypes;
|
|
using InnovEnergy.Lib.Utils;
|
|
using SQLite;
|
|
using SQLiteConnection = SQLite.SQLiteConnection;
|
|
|
|
|
|
namespace InnovEnergy.App.Backend.Database;
|
|
|
|
public static partial class Db
|
|
{
|
|
private static SQLiteConnection Connection { get; } = InitConnection();
|
|
|
|
private static SQLiteConnection InitConnection()
|
|
{
|
|
var latestDb = new DirectoryInfo("DbBackups")
|
|
.GetFiles()
|
|
.OrderBy(f => f.LastWriteTime)
|
|
.Last().Name;
|
|
|
|
Console.WriteLine("latestdb is "+latestDb);
|
|
|
|
//This is the file connection from the DbBackups folder
|
|
var fileConnection = new SQLiteConnection("DbBackups/" + latestDb);
|
|
|
|
//Create a table if it does not exist
|
|
fileConnection.CreateTable<User>();
|
|
fileConnection.CreateTable<Installation>();
|
|
fileConnection.CreateTable<Folder>();
|
|
fileConnection.CreateTable<FolderAccess>();
|
|
fileConnection.CreateTable<InstallationAccess>();
|
|
fileConnection.CreateTable<Session>();
|
|
fileConnection.CreateTable<OrderNumber2Installation>();
|
|
fileConnection.CreateTable<Error>();
|
|
fileConnection.CreateTable<Warning>();
|
|
fileConnection.CreateTable<UserAction>();
|
|
fileConnection.CreateTable<CsvTimestamp>();
|
|
|
|
return fileConnection;
|
|
//return CopyDbToMemory(fileConnection);
|
|
}
|
|
|
|
private static SQLiteConnection CopyDbToMemory(SQLiteConnection fileConnection)
|
|
{
|
|
var memoryConnection = new SQLiteConnection(":memory:");
|
|
|
|
//Create a table if it does not exist in main memory
|
|
memoryConnection.CreateTable<User>();
|
|
memoryConnection.CreateTable<Installation>();
|
|
memoryConnection.CreateTable<Folder>();
|
|
memoryConnection.CreateTable<FolderAccess>();
|
|
memoryConnection.CreateTable<InstallationAccess>();
|
|
memoryConnection.CreateTable<Session>();
|
|
memoryConnection.CreateTable<OrderNumber2Installation>();
|
|
memoryConnection.CreateTable<Error>();
|
|
memoryConnection.CreateTable<Warning>();
|
|
fileConnection.CreateTable<UserAction>();
|
|
fileConnection.CreateTable<CsvTimestamp>();
|
|
|
|
//Copy all the existing tables from the disk to main memory
|
|
fileConnection.Table<Session>().ForEach(memoryConnection.Insert);
|
|
fileConnection.Table<Folder>().ForEach(memoryConnection.Insert);
|
|
fileConnection.Table<Installation>().ForEach(memoryConnection.Insert);
|
|
fileConnection.Table<User>().ForEach(memoryConnection.Insert);
|
|
fileConnection.Table<FolderAccess>().ForEach(memoryConnection.Insert);
|
|
fileConnection.Table<InstallationAccess>().ForEach(memoryConnection.Insert);
|
|
fileConnection.Table<OrderNumber2Installation>().ForEach(memoryConnection.Insert);
|
|
fileConnection.Table<Error>().ForEach(memoryConnection.Insert);
|
|
fileConnection.Table<Warning>().ForEach(memoryConnection.Insert);
|
|
fileConnection.Table<UserAction>().ForEach(memoryConnection.Insert);
|
|
fileConnection.Table<CsvTimestamp>().ForEach(memoryConnection.Insert);
|
|
|
|
return memoryConnection;
|
|
}
|
|
|
|
public static void BackupDatabase()
|
|
{
|
|
var filename = "db-" + DateTimeOffset.UtcNow.ToUnixTimeSeconds() + ".sqlite";
|
|
Connection.Backup("DbBackups/" + filename);
|
|
}
|
|
|
|
public static TableQuery<Session> Sessions => Connection.Table<Session>();
|
|
public static TableQuery<Folder> Folders => Connection.Table<Folder>();
|
|
public static TableQuery<Installation> Installations => Connection.Table<Installation>();
|
|
public static TableQuery<User> Users => Connection.Table<User>();
|
|
public static TableQuery<FolderAccess> FolderAccess => Connection.Table<FolderAccess>();
|
|
public static TableQuery<InstallationAccess> InstallationAccess => Connection.Table<InstallationAccess>();
|
|
public static TableQuery<OrderNumber2Installation> OrderNumber2Installation => Connection.Table<OrderNumber2Installation>();
|
|
public static TableQuery<Error> Errors => Connection.Table<Error>();
|
|
public static TableQuery<Warning> Warnings => Connection.Table<Warning>();
|
|
public static TableQuery<UserAction> UserActions => Connection.Table<UserAction>();
|
|
public static TableQuery<CsvTimestamp> CsvTimestamps => Connection.Table<CsvTimestamp>();
|
|
|
|
public static void Init()
|
|
{
|
|
// used to force static constructor
|
|
//Since this class is static, we call Init method from the Program.cs to initialize all the fields of the class
|
|
}
|
|
|
|
//This is the constructor of the class
|
|
static Db()
|
|
{
|
|
Connection.RunInTransaction(() =>
|
|
{
|
|
Connection.CreateTable<User>();
|
|
Connection.CreateTable<Installation>();
|
|
Connection.CreateTable<Folder>();
|
|
Connection.CreateTable<FolderAccess>();
|
|
Connection.CreateTable<InstallationAccess>();
|
|
Connection.CreateTable<Session>();
|
|
Connection.CreateTable<OrderNumber2Installation>();
|
|
Connection.CreateTable<Error>();
|
|
Connection.CreateTable<Warning>();
|
|
Connection.CreateTable<UserAction>();
|
|
Connection.CreateTable<CsvTimestamp>();
|
|
});
|
|
|
|
//UpdateKeys();
|
|
CleanupSessions().SupressAwaitWarning();
|
|
|
|
}
|
|
|
|
private static async Task CleanupSessions()
|
|
{
|
|
while (true)
|
|
{
|
|
try
|
|
{
|
|
DeleteStaleSessions();
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
Console.WriteLine("An error has occured when cleaning stale sessions, exception is:\n"+e);
|
|
}
|
|
|
|
await Task.Delay(TimeSpan.FromHours(0.5));
|
|
}
|
|
}
|
|
|
|
private static async Task RemoveNonExistingKeys()
|
|
{
|
|
while (true)
|
|
{
|
|
try
|
|
{
|
|
var validReadKeys = Installations
|
|
.Select(i => i.S3Key)
|
|
.Distinct()
|
|
.ToList();
|
|
|
|
|
|
|
|
var validWriteKeys = Installations
|
|
.Select(i => i.S3WriteKey)
|
|
.Distinct()
|
|
.ToList();
|
|
|
|
Console.WriteLine("VALID READ KEYS");
|
|
for (int i = 0; i < validReadKeys.Count; i++)
|
|
{
|
|
Console.WriteLine(validReadKeys[i]);
|
|
}
|
|
|
|
Console.WriteLine("VALID WRITE KEYS");
|
|
|
|
for (int i = 0; i < validReadKeys.Count; i++)
|
|
{
|
|
Console.WriteLine(validWriteKeys[i]);
|
|
}
|
|
|
|
|
|
const String provider = "exo.io";
|
|
var S3keys = await ExoCmd.GetAccessKeys();
|
|
|
|
foreach (var keyMetadata in S3keys)
|
|
{
|
|
if (keyMetadata["key"].ToString()!="EXOa0b53cf10517307cec1bf00e" && !validReadKeys.Contains(keyMetadata["key"].ToString()) && !validWriteKeys.Contains(keyMetadata["key"].ToString()))
|
|
{
|
|
//await ExoCmd.RevokeReadKey(keyMetadata["key"].ToString());
|
|
Console.WriteLine("Deleted key "+keyMetadata["key"]);
|
|
}
|
|
|
|
}
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
Console.WriteLine("An error has occured when updating S3 keys, exception is:\n"+e);
|
|
}
|
|
|
|
await Task.Delay(TimeSpan.FromHours(24));
|
|
}
|
|
|
|
}
|
|
|
|
private static async Task UpdateKeys()
|
|
{
|
|
while (true)
|
|
{
|
|
try
|
|
{
|
|
await UpdateS3Urls();
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
Console.WriteLine("An error has occured when updating S3 keys, exception is:\n"+e);
|
|
}
|
|
|
|
await RemoveNonExistingKeys();
|
|
|
|
await Task.Delay(TimeSpan.FromHours(24));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private static Boolean RunTransaction(Func<Boolean> func)
|
|
{
|
|
var savepoint = Connection.SaveTransactionPoint();
|
|
var success = false;
|
|
|
|
try
|
|
{
|
|
success = func();
|
|
}
|
|
finally
|
|
{
|
|
if (success)
|
|
Connection.Release(savepoint);
|
|
else
|
|
Connection.RollbackTo(savepoint);
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
|
|
private static void DeleteStaleSessions()
|
|
{
|
|
var deadline = DateTime.Now.AddDays((-1) * Session.MaxAge.Days);
|
|
Sessions.Delete(s => s.LastSeen < deadline);
|
|
}
|
|
|
|
private static async Task UpdateS3Urls()
|
|
{
|
|
var regions = Installations
|
|
.Select(i => i.S3Region)
|
|
.Distinct()
|
|
.ToList();
|
|
|
|
const String provider = "exo.io";
|
|
Console.WriteLine("-----------------------UPDATED READ KEYS-------------------------------------------------------------------");
|
|
|
|
foreach (var region in regions)
|
|
{
|
|
var s3Region = new S3Region($"https://{region}.{provider}", ExoCmd.S3Credentials!);
|
|
var bucketList = await s3Region.ListAllBuckets();
|
|
|
|
var installations = from bucket in bucketList.Buckets
|
|
from installation in Installations
|
|
where installation.BucketName() == bucket.BucketName
|
|
select installation;
|
|
|
|
foreach (var installation in installations)
|
|
{
|
|
await installation.RenewS3Credentials();
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
public static async Task<Boolean> SendPasswordResetEmail(User user, String sessionToken)
|
|
{
|
|
try
|
|
{
|
|
await user.SendPasswordResetEmail(sessionToken);
|
|
return true;
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static async Task<Boolean> SendNewUserEmail(User user)
|
|
{
|
|
try
|
|
{
|
|
await user.SendNewUserWelcomeMessage();
|
|
return true;
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static Boolean DeleteUserPassword(User user)
|
|
{
|
|
user.Password = "";
|
|
user.MustResetPassword = true;
|
|
return Update(user);
|
|
}
|
|
} |