Merge branch 'main' of https://git.innov.energy/Innovenergy/git_trunk
This commit is contained in:
commit
e10c880d01
|
@ -4,7 +4,6 @@ using InnovEnergy.App.Backend.DataTypes.Methods;
|
||||||
using InnovEnergy.App.Backend.Relations;
|
using InnovEnergy.App.Backend.Relations;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using static System.Net.HttpStatusCode;
|
using static System.Net.HttpStatusCode;
|
||||||
using static System.String;
|
|
||||||
using Folder = InnovEnergy.App.Backend.DataTypes.Folder;
|
using Folder = InnovEnergy.App.Backend.DataTypes.Folder;
|
||||||
using Installation = InnovEnergy.App.Backend.DataTypes.Installation;
|
using Installation = InnovEnergy.App.Backend.DataTypes.Installation;
|
||||||
using Object = System.Object;
|
using Object = System.Object;
|
||||||
|
@ -47,58 +46,58 @@ public class Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// [Returns<User>]
|
[Returns<User>]
|
||||||
// [Returns(HttpStatusCode.Unauthorized)]
|
[Returns(Unauthorized)]
|
||||||
// [HttpGet($"{nameof(GetUserById)}")]
|
[HttpGet($"{nameof(GetUserById)}")]
|
||||||
// public Object GetUserById(Int64 id)
|
public Object GetUserById(Int64 id)
|
||||||
// {
|
{
|
||||||
// var caller = GetCaller();
|
var caller = GetSession()?.User;
|
||||||
// if (caller is null)
|
if (caller == null)
|
||||||
// return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
return _Unauthorized;
|
||||||
//
|
|
||||||
// var user = Db.GetUserById(id);
|
var user = Db.GetUserById(id);
|
||||||
//
|
|
||||||
// if (user is null || !caller.HasAccessTo(user))
|
if (user is null || !caller.HasAccessTo(user))
|
||||||
// return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
return _Unauthorized;
|
||||||
//
|
|
||||||
// return user;
|
return user;
|
||||||
// }
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// [Returns<Installation>]
|
|
||||||
// [Returns(HttpStatusCode.Unauthorized)]
|
|
||||||
// [HttpGet($"{nameof(GetInstallationById)}")]
|
|
||||||
// public Object GetInstallationById(Int64 id)
|
|
||||||
// {
|
|
||||||
// var caller = GetCaller();
|
|
||||||
// if (caller == null)
|
|
||||||
// return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
|
||||||
//
|
|
||||||
// var installation = Db.GetInstallationById(id);
|
|
||||||
//
|
|
||||||
// if (installation is null || !caller.HasAccessTo(installation))
|
|
||||||
// return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
|
||||||
//
|
|
||||||
// return installation;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// [Returns<Folder>]
|
[Returns<Installation>]
|
||||||
// [Returns(HttpStatusCode.Unauthorized)]
|
[Returns(Unauthorized)]
|
||||||
// [HttpGet($"{nameof(GetFolderById)}")]
|
[HttpGet($"{nameof(GetInstallationById)}")]
|
||||||
// public Object GetFolderById(Int64 id)
|
public Object GetInstallationById(Int64 id)
|
||||||
// {
|
{
|
||||||
// var caller = GetCaller();
|
var user = GetSession()?.User;
|
||||||
// if (caller == null)
|
if (user == null)
|
||||||
// return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
return _Unauthorized;
|
||||||
//
|
|
||||||
// var folder = Db.GetFolderById(id);
|
var installation = Db.GetInstallationById(id);
|
||||||
//
|
|
||||||
// if (folder is null || !caller.HasAccessTo(folder))
|
if (installation is null || !user.HasAccessTo(installation))
|
||||||
// return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
return _Unauthorized;
|
||||||
//
|
|
||||||
// return folder;
|
return installation;
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Returns<Folder>]
|
||||||
|
[Returns(Unauthorized)]
|
||||||
|
[HttpGet($"{nameof(GetFolderById)}")]
|
||||||
|
public Object GetFolderById(Int64 id)
|
||||||
|
{
|
||||||
|
var user = GetSession()?.User;
|
||||||
|
if (user == null)
|
||||||
|
return _Unauthorized;
|
||||||
|
|
||||||
|
var folder = Db.GetFolderById(id);
|
||||||
|
|
||||||
|
if (folder is null || !user.HasAccessTo(folder))
|
||||||
|
return _Unauthorized;
|
||||||
|
|
||||||
|
return folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[Returns<Installation[]>] // assuming swagger knows about arrays but not lists (JSON)
|
[Returns<Installation[]>] // assuming swagger knows about arrays but not lists (JSON)
|
||||||
|
|
|
@ -14,6 +14,6 @@ public class Installation : TreeNode
|
||||||
public Double Long { get; set; }
|
public Double Long { get; set; }
|
||||||
|
|
||||||
public String S3Bucket { get; set; } = "";
|
public String S3Bucket { get; set; } = "";
|
||||||
public String S3Key { get; set; } = "";
|
public String S3Url { get; set; } = "";
|
||||||
|
|
||||||
}
|
}
|
|
@ -8,7 +8,7 @@ public static class CredentialsMethods
|
||||||
{
|
{
|
||||||
public static Session? Login(this Credentials credentials)
|
public static Session? Login(this Credentials credentials)
|
||||||
{
|
{
|
||||||
if (credentials.Username.IsNull() || credentials.Password.IsNull())
|
if (credentials.Username.IsNullOrEmpty() || credentials.Password.IsNullOrEmpty())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var user = Db.GetUserByEmail(credentials.Username);
|
var user = Db.GetUserByEmail(credentials.Username);
|
||||||
|
|
|
@ -33,7 +33,9 @@ public static class FolderMethods
|
||||||
|
|
||||||
public static IEnumerable<Folder> Ancestors(this Folder folder)
|
public static IEnumerable<Folder> Ancestors(this Folder folder)
|
||||||
{
|
{
|
||||||
return folder.Unfold(Parent);
|
return folder
|
||||||
|
.Unfold(Parent)
|
||||||
|
.Skip(1); // skip self
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Folder? Parent(this Folder folder)
|
public static Folder? Parent(this Folder folder)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
using CliWrap;
|
||||||
|
using CliWrap.Buffered;
|
||||||
using InnovEnergy.App.Backend.Database;
|
using InnovEnergy.App.Backend.Database;
|
||||||
|
|
||||||
namespace InnovEnergy.App.Backend.DataTypes.Methods;
|
namespace InnovEnergy.App.Backend.DataTypes.Methods;
|
||||||
|
@ -5,13 +7,39 @@ namespace InnovEnergy.App.Backend.DataTypes.Methods;
|
||||||
|
|
||||||
public static class InstallationMethods
|
public static class InstallationMethods
|
||||||
{
|
{
|
||||||
|
public static async Task RenewS3BucketUrl(this Installation installation)
|
||||||
|
{
|
||||||
|
await RenewS3BucketUrl(installation, TimeSpan.FromDays(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task RenewS3BucketUrl(this Installation installation, TimeSpan validity)
|
||||||
|
{
|
||||||
|
//secret 55MAqyO_FqUmh7O64VIO0egq50ERn_WIAWuc2QC44QU
|
||||||
|
const String apiKey = "EXO44d2979c8e570eae81ead564";
|
||||||
|
const String salt = "3e5b3069-214a-43ee-8d85-57d72000c19d";
|
||||||
|
|
||||||
|
var cmd = Cli
|
||||||
|
.Wrap("s3cmd")
|
||||||
|
.WithArguments(new[] { "signurl",$"s3://{installation.Id}-{salt}", validity.TotalSeconds.ToString(), "--access_key", apiKey});
|
||||||
|
|
||||||
|
var x = await cmd.ExecuteBufferedAsync();
|
||||||
|
installation.S3Url = x.StandardOutput.Replace("\n", "").Replace(" ", "");
|
||||||
|
|
||||||
|
Console.WriteLine(installation.S3Url);
|
||||||
|
|
||||||
|
Db.Update(installation);
|
||||||
|
}
|
||||||
|
|
||||||
public static IEnumerable<Folder> Ancestors(this Installation installation)
|
public static IEnumerable<Folder> Ancestors(this Installation installation)
|
||||||
{
|
{
|
||||||
var parentFolder = Parent(installation);
|
var parentFolder = Parent(installation);
|
||||||
|
|
||||||
return parentFolder is null
|
if (parentFolder is null)
|
||||||
? Enumerable.Empty<Folder>()
|
return Enumerable.Empty<Folder>();
|
||||||
: parentFolder.Ancestors();
|
|
||||||
|
return parentFolder
|
||||||
|
.Ancestors()
|
||||||
|
.Prepend(parentFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Folder? Parent(this Installation installation)
|
public static Folder? Parent(this Installation installation)
|
||||||
|
|
|
@ -110,6 +110,34 @@ public static class SessionMethods
|
||||||
&& Db.Delete(userToDelete);
|
&& Db.Delete(userToDelete);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Boolean GrantUserAccessTo(this Session? session, User? user, Installation? installation)
|
||||||
|
{
|
||||||
|
var sessionUser = session?.User;
|
||||||
|
|
||||||
|
return sessionUser is not null
|
||||||
|
&& user is not null
|
||||||
|
&& installation is not null
|
||||||
|
&& user.IsDescendantOf(sessionUser)
|
||||||
|
&& sessionUser.HasAccessTo(installation)
|
||||||
|
&& !user.HasAccessTo(installation)
|
||||||
|
&& Db.Create(new InstallationAccess { UserId = user.Id, InstallationId = installation.Id });
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Boolean GrantUserAccessTo(this Session? session, User? user, Folder? folder)
|
||||||
|
{
|
||||||
|
var sessionUser = session?.User;
|
||||||
|
|
||||||
|
return sessionUser is not null
|
||||||
|
&& user is not null
|
||||||
|
&& folder is not null
|
||||||
|
&& user.IsDescendantOf(sessionUser)
|
||||||
|
&& sessionUser.HasAccessTo(folder)
|
||||||
|
&& !user.HasAccessTo(folder)
|
||||||
|
&& Db.Create(new FolderAccess { UserId = user.Id, FolderId = folder.Id });
|
||||||
|
}
|
||||||
|
|
||||||
public static Boolean Logout(this Session? session)
|
public static Boolean Logout(this Session? session)
|
||||||
{
|
{
|
||||||
return session is not null
|
return session is not null
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
using System.Net.Http.Headers;
|
|
||||||
using System.Net.Mail;
|
using System.Net.Mail;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text.Json.Nodes;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using InnovEnergy.App.Backend.Database;
|
using InnovEnergy.App.Backend.Database;
|
||||||
using InnovEnergy.Lib.Utils;
|
using InnovEnergy.Lib.Utils;
|
||||||
using Convert = System.Convert;
|
using Convert = System.Convert;
|
||||||
|
@ -48,7 +45,7 @@ public static class UserMethods
|
||||||
public static IEnumerable<Installation> DirectlyAccessibleInstallations(this User user)
|
public static IEnumerable<Installation> DirectlyAccessibleInstallations(this User user)
|
||||||
{
|
{
|
||||||
return Db
|
return Db
|
||||||
.User2Installation
|
.InstallationAccess
|
||||||
.Where(r => r.UserId == user.Id)
|
.Where(r => r.UserId == user.Id)
|
||||||
.Select(r => r.InstallationId)
|
.Select(r => r.InstallationId)
|
||||||
.Select(Db.GetInstallationById)
|
.Select(Db.GetInstallationById)
|
||||||
|
@ -59,7 +56,7 @@ public static class UserMethods
|
||||||
public static IEnumerable<Folder> DirectlyAccessibleFolders(this User user)
|
public static IEnumerable<Folder> DirectlyAccessibleFolders(this User user)
|
||||||
{
|
{
|
||||||
return Db
|
return Db
|
||||||
.User2Folder
|
.FolderAccess
|
||||||
.Where(r => r.UserId == user.Id)
|
.Where(r => r.UserId == user.Id)
|
||||||
.Select(r => r.FolderId)
|
.Select(r => r.FolderId)
|
||||||
.Select(Db.GetFolderById)
|
.Select(Db.GetFolderById)
|
||||||
|
@ -88,7 +85,9 @@ public static class UserMethods
|
||||||
|
|
||||||
private static IEnumerable<User> Ancestors(this User user)
|
private static IEnumerable<User> Ancestors(this User user)
|
||||||
{
|
{
|
||||||
return user.Unfold(Parent);
|
return user
|
||||||
|
.Unfold(Parent)
|
||||||
|
.Skip(1); // skip self
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean VerifyPassword(this User user, String password)
|
public static Boolean VerifyPassword(this User user, String password)
|
||||||
|
@ -126,7 +125,7 @@ public static class UserMethods
|
||||||
public static Boolean HasDirectAccessTo(this User user, Folder folder)
|
public static Boolean HasDirectAccessTo(this User user, Folder folder)
|
||||||
{
|
{
|
||||||
return Db
|
return Db
|
||||||
.User2Folder
|
.FolderAccess
|
||||||
.Any(r => r.FolderId == folder.Id && r.UserId == user.Id);
|
.Any(r => r.FolderId == folder.Id && r.UserId == user.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +134,8 @@ public static class UserMethods
|
||||||
if (folder is null)
|
if (folder is null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return folder
|
return user.HasDirectAccessTo(folder)
|
||||||
|
|| folder
|
||||||
.Ancestors()
|
.Ancestors()
|
||||||
.Any(user.HasDirectAccessTo);
|
.Any(user.HasDirectAccessTo);
|
||||||
}
|
}
|
||||||
|
@ -143,8 +143,8 @@ public static class UserMethods
|
||||||
public static Boolean HasDirectAccessTo(this User user, Installation installation)
|
public static Boolean HasDirectAccessTo(this User user, Installation installation)
|
||||||
{
|
{
|
||||||
return Db
|
return Db
|
||||||
.User2Installation
|
.InstallationAccess
|
||||||
.Any(r => r.InstallationId == installation.Id && r.UserId == user.Id);
|
.Any(r => r.UserId == user.Id && r.InstallationId == installation.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean HasAccessTo(this User user, Installation? installation)
|
public static Boolean HasAccessTo(this User user, Installation? installation)
|
||||||
|
@ -163,7 +163,6 @@ public static class UserMethods
|
||||||
|
|
||||||
return other
|
return other
|
||||||
.Ancestors()
|
.Ancestors()
|
||||||
.Skip(1) // Important! skip self, user cannot delete or edit himself
|
|
||||||
.Contains(user);
|
.Contains(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,154 +175,7 @@ public static class UserMethods
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static Byte[] HmacSha256Digest(String message, String secret)
|
|
||||||
{
|
|
||||||
// var encoding = new UTF8Encoding();
|
|
||||||
// var keyBytes = encoding.GetBytes(secret);
|
|
||||||
// var messageBytes = encoding.GetBytes(message);
|
|
||||||
// var cryptographer = new HMACSHA256(keyBytes);
|
|
||||||
// return cryptographer.ComputeHash(messageBytes);
|
|
||||||
|
|
||||||
var keyBytes = UTF8.GetBytes(secret);
|
|
||||||
var messageBytes = UTF8.GetBytes(message);
|
|
||||||
|
|
||||||
return HMACSHA256.HashData(keyBytes, messageBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String BuildSignature(String method, String path, String data, Int64 time, String secret)
|
|
||||||
{
|
|
||||||
var messageToSign = "";
|
|
||||||
messageToSign += method + " /v2/" + path + "\n";
|
|
||||||
messageToSign += data + "\n";
|
|
||||||
|
|
||||||
// query strings
|
|
||||||
messageToSign += "\n";
|
|
||||||
// headers
|
|
||||||
messageToSign += "\n";
|
|
||||||
|
|
||||||
messageToSign += time;
|
|
||||||
|
|
||||||
Console.WriteLine("Message to sign:\n" + messageToSign);
|
|
||||||
|
|
||||||
var hmac = HmacSha256Digest(messageToSign, secret);
|
|
||||||
return Convert.ToBase64String(hmac);
|
|
||||||
}
|
|
||||||
|
|
||||||
// public Object CreateAndSaveUserS3ApiKey(User user)
|
|
||||||
// {
|
|
||||||
// //EXOSCALE API URL
|
|
||||||
// const String url = "https://api-ch-dk-2.exoscale.com/v2/";
|
|
||||||
// const String path = "access-key";
|
|
||||||
//
|
|
||||||
// //TODO HIDE ME
|
|
||||||
// const String secret = "S2K1okphiCSNK4mzqr4swguFzngWAMb1OoSlZsJa9F0";
|
|
||||||
// const String apiKey = "EXOb98ec9008e3ec16e19d7b593";
|
|
||||||
//
|
|
||||||
// var installationList = User2Installation
|
|
||||||
// .Where(i => i.UserId == user.Id)
|
|
||||||
// .SelectMany(i => Installations.Where(f => i.InstallationId == f.Id))
|
|
||||||
// .ToList();
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// var instList = new JsonArray();
|
|
||||||
//
|
|
||||||
// foreach (var installation in installationList)
|
|
||||||
// {
|
|
||||||
// instList.Add(new JsonObject {["domain"] = "sos",["resource-name"] = installation.Name,["resource-type"] = "bucket"});
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// var jsonPayload = new JsonObject { ["name"] = user.Email, ["operations"] = new JsonArray{ "list-sos-bucket", "get-sos-object" }, ["content"] = instList};
|
|
||||||
// var stringPayload = jsonPayload.ToJsonString();
|
|
||||||
//
|
|
||||||
// var unixExpiration = DateTimeOffset.UtcNow.ToUnixTimeSeconds()+60;
|
|
||||||
// var signature = BuildSignature("POST", path, stringPayload, unixExpiration , secret);
|
|
||||||
//
|
|
||||||
// var authHeader = "credential="+apiKey+",expires="+unixExpiration+",signature="+signature;
|
|
||||||
//
|
|
||||||
// var client = new HttpClient();
|
|
||||||
// client.DefaultRequestHeaders.Authorization =
|
|
||||||
// new AuthenticationHeaderValue("EXO2-HMAC-SHA256", authHeader);
|
|
||||||
//
|
|
||||||
// var content = new StringContent(stringPayload, Encoding.UTF8, "application/json");
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// var response = client.PostAsync(url+path, content).Result;
|
|
||||||
//
|
|
||||||
// if (response.StatusCode.ToString() != "OK")
|
|
||||||
// {
|
|
||||||
// return response;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// var responseString = response.Content.ReadAsStringAsync().Result;
|
|
||||||
// return Enumerable.Last(Regex.Match(responseString, "key\\\":\\\"([A-Z])\\w+").ToString().Split('"'));
|
|
||||||
// // return SetUserS3ApiKey(user, newKey);
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
|
||||||
public static Object CreateAndSaveInstallationS3ApiKey(Installation installation)
|
|
||||||
{
|
|
||||||
//EXOSCALE API URL
|
|
||||||
const String url = "https://api-ch-dk-2.exoscale.com/v2/";
|
|
||||||
const String path = "access-key";
|
|
||||||
|
|
||||||
//TODO HIDE ME
|
|
||||||
const String secret = "S2K1okphiCSNK4mzqr4swguFzngWAMb1OoSlZsJa9F0";
|
|
||||||
const String apiKey = "EXOb98ec9008e3ec16e19d7b593";
|
|
||||||
|
|
||||||
|
|
||||||
var jsonPayload = new JsonObject
|
|
||||||
{
|
|
||||||
["name"] = installation.Id,
|
|
||||||
["operations"] = new JsonArray
|
|
||||||
{
|
|
||||||
"list-sos-bucket",
|
|
||||||
"get-sos-object"
|
|
||||||
},
|
|
||||||
["content"] = new JsonArray
|
|
||||||
{
|
|
||||||
new JsonObject
|
|
||||||
{
|
|
||||||
["domain"] = "sos",
|
|
||||||
["resource-name"] = installation.Name,
|
|
||||||
["resource-type"] = "bucket"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var stringPayload = jsonPayload.ToJsonString();
|
|
||||||
|
|
||||||
var unixExpiration = DateTimeOffset.UtcNow.ToUnixTimeSeconds() + 60;
|
|
||||||
|
|
||||||
var signature = BuildSignature("POST", path, stringPayload, unixExpiration, secret);
|
|
||||||
|
|
||||||
var authHeader = "credential=" + apiKey + ",expires=" + unixExpiration + ",signature=" + signature;
|
|
||||||
|
|
||||||
var client = new HttpClient();
|
|
||||||
|
|
||||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("EXO2-HMAC-SHA256", authHeader);
|
|
||||||
|
|
||||||
var content = new StringContent(stringPayload, UTF8, "application/json");
|
|
||||||
|
|
||||||
var response = client.PostAsync(url + path, content).Result;
|
|
||||||
|
|
||||||
if (response.StatusCode.ToString() != "OK")
|
|
||||||
{
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
var responseString = response.Content.ReadAsStringAsync().Result;
|
|
||||||
var newKey = Regex
|
|
||||||
.Match(responseString, "key\\\":\\\"([A-Z])\\w+")
|
|
||||||
.ToString()
|
|
||||||
.Split('"')
|
|
||||||
.Last();
|
|
||||||
|
|
||||||
installation.S3Key = newKey;
|
|
||||||
Db.Update(installation);
|
|
||||||
return newKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
private static Boolean IsValidEmail(String email)
|
private static Boolean IsValidEmail(String email)
|
||||||
|
|
|
@ -29,10 +29,18 @@ public static partial class Db
|
||||||
return Connection.Insert(user) > 0;
|
return Connection.Insert(user) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Boolean Create(Session session)
|
public static Boolean Create(Session session)
|
||||||
{
|
{
|
||||||
return Connection.Insert(session) > 0;
|
return Connection.Insert(session) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Boolean Create(InstallationAccess installationAccess)
|
||||||
|
{
|
||||||
|
return Connection.Insert(installationAccess) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Boolean Create(FolderAccess folderAccess)
|
||||||
|
{
|
||||||
|
return Connection.Insert(folderAccess) > 0;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -20,8 +20,8 @@ public static partial class Db
|
||||||
public static TableQuery<Folder> Folders => Connection.Table<Folder>();
|
public static TableQuery<Folder> Folders => Connection.Table<Folder>();
|
||||||
public static TableQuery<Installation> Installations => Connection.Table<Installation>();
|
public static TableQuery<Installation> Installations => Connection.Table<Installation>();
|
||||||
public static TableQuery<User> Users => Connection.Table<User>();
|
public static TableQuery<User> Users => Connection.Table<User>();
|
||||||
public static TableQuery<User2Folder> User2Folder => Connection.Table<User2Folder>();
|
public static TableQuery<FolderAccess> FolderAccess => Connection.Table<FolderAccess>();
|
||||||
public static TableQuery<User2Installation> User2Installation => Connection.Table<User2Installation>();
|
public static TableQuery<InstallationAccess> InstallationAccess => Connection.Table<InstallationAccess>();
|
||||||
|
|
||||||
|
|
||||||
static Db()
|
static Db()
|
||||||
|
@ -33,19 +33,18 @@ public static partial class Db
|
||||||
Connection.CreateTable<User>();
|
Connection.CreateTable<User>();
|
||||||
Connection.CreateTable<Installation>();
|
Connection.CreateTable<Installation>();
|
||||||
Connection.CreateTable<Folder>();
|
Connection.CreateTable<Folder>();
|
||||||
Connection.CreateTable<User2Folder>();
|
Connection.CreateTable<FolderAccess>();
|
||||||
Connection.CreateTable<User2Installation>();
|
Connection.CreateTable<InstallationAccess>();
|
||||||
Connection.CreateTable<Session>();
|
Connection.CreateTable<Session>();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
var installation = Installations.First();
|
|
||||||
UserMethods.CreateAndSaveInstallationS3ApiKey(installation);
|
|
||||||
|
|
||||||
|
Observable.Interval(TimeSpan.FromDays(0.5))
|
||||||
Observable.Interval(TimeSpan.FromDays(1))
|
.StartWith(0) // Do it right away (on startup)
|
||||||
.StartWith(0) // Do it right away (on startup)
|
.SelectMany(Cleanup)
|
||||||
.Subscribe(Cleanup); // and then daily
|
.Subscribe(); // and then daily
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,51 +69,12 @@ public static partial class Db
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static Boolean AddToAccessibleInstallations(Int64 userId, Int64 updatedInstallationId)
|
private static async Task<Boolean> Cleanup(Int64 _)
|
||||||
{
|
{
|
||||||
var con = new User2Installation
|
await UpdateS3Urls();
|
||||||
{
|
|
||||||
UserId = userId,
|
|
||||||
InstallationId = updatedInstallationId
|
|
||||||
};
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Connection.Insert(con);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean AddToAccessibleFolders(Int64 userId, Int64 updatedFolderId)
|
|
||||||
{
|
|
||||||
var con = new User2Folder
|
|
||||||
{
|
|
||||||
UserId = userId,
|
|
||||||
FolderId = updatedFolderId
|
|
||||||
};
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Connection.Insert(con);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static void Cleanup(Int64 _)
|
|
||||||
{
|
|
||||||
DeleteS3Keys();
|
|
||||||
DeleteStaleSessions();
|
DeleteStaleSessions();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DeleteStaleSessions()
|
private static void DeleteStaleSessions()
|
||||||
|
@ -123,10 +83,9 @@ public static partial class Db
|
||||||
Sessions.Delete(s => s.LastSeen < deadline);
|
Sessions.Delete(s => s.LastSeen < deadline);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DeleteS3Keys()
|
private static Task UpdateS3Urls()
|
||||||
{
|
{
|
||||||
void DeleteKeys() => Installations.Do(i => i.S3Key = "").ForEach(Update); // TODO
|
var renewTasks = Installations.Select(i => i.RenewS3BucketUrl()).ToArray();
|
||||||
|
return Task.WhenAll(renewTasks);
|
||||||
Connection.RunInTransaction(DeleteKeys);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,7 +21,7 @@ public static partial class Db
|
||||||
|
|
||||||
Boolean DeleteDescendantFolderAndItsDependencies(Folder f)
|
Boolean DeleteDescendantFolderAndItsDependencies(Folder f)
|
||||||
{
|
{
|
||||||
User2Folder .Delete(r => r.FolderId == f.Id);
|
FolderAccess .Delete(r => r.FolderId == f.Id);
|
||||||
Installations.Delete(r => r.ParentId == f.Id);
|
Installations.Delete(r => r.ParentId == f.Id);
|
||||||
|
|
||||||
return Folders.Delete(r => r.Id == f.Id) > 0;
|
return Folders.Delete(r => r.Id == f.Id) > 0;
|
||||||
|
@ -34,7 +34,7 @@ public static partial class Db
|
||||||
|
|
||||||
Boolean DeleteInstallationAndItsDependencies()
|
Boolean DeleteInstallationAndItsDependencies()
|
||||||
{
|
{
|
||||||
User2Installation.Delete(i => i.InstallationId == installation.Id);
|
InstallationAccess.Delete(i => i.InstallationId == installation.Id);
|
||||||
return Installations.Delete(i => i.Id == installation.Id) > 0;
|
return Installations.Delete(i => i.Id == installation.Id) > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,8 +45,8 @@ public static partial class Db
|
||||||
|
|
||||||
Boolean DeleteUserAndHisDependencies()
|
Boolean DeleteUserAndHisDependencies()
|
||||||
{
|
{
|
||||||
User2Folder .Delete(u => u.UserId == user.Id);
|
FolderAccess .Delete(u => u.UserId == user.Id);
|
||||||
User2Installation.Delete(u => u.UserId == user.Id);
|
InstallationAccess.Delete(u => u.UserId == user.Id);
|
||||||
|
|
||||||
return Users.Delete(u => u.Id == user.Id) > 0;
|
return Users.Delete(u => u.Id == user.Id) > 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ public static partial class Db
|
||||||
|
|
||||||
private static void GiveFakeUsersAccessToFolders()
|
private static void GiveFakeUsersAccessToFolders()
|
||||||
{
|
{
|
||||||
foreach (var uf in User2Folder) // remove existing relations
|
foreach (var uf in FolderAccess) // remove existing relations
|
||||||
Connection.Delete(uf);
|
Connection.Delete(uf);
|
||||||
|
|
||||||
var nFolders = Folders.Count();
|
var nFolders = Folders.Count();
|
||||||
|
@ -70,7 +70,7 @@ public static partial class Db
|
||||||
foreach (var user in Users)
|
foreach (var user in Users)
|
||||||
while (Random.Shared.Next((Int32)(nUsers - user.Id + 1)) != 0)
|
while (Random.Shared.Next((Int32)(nUsers - user.Id + 1)) != 0)
|
||||||
{
|
{
|
||||||
var relation = new User2Folder
|
var relation = new FolderAccess
|
||||||
{
|
{
|
||||||
UserId = user.Id,
|
UserId = user.Id,
|
||||||
FolderId = Random.Shared.Next(nFolders) + 1
|
FolderId = Random.Shared.Next(nFolders) + 1
|
||||||
|
@ -81,7 +81,7 @@ public static partial class Db
|
||||||
|
|
||||||
private static void GiveFakeUsersAccessToInstallations()
|
private static void GiveFakeUsersAccessToInstallations()
|
||||||
{
|
{
|
||||||
foreach (var ui in User2Installation) // remove existing relations
|
foreach (var ui in InstallationAccess) // remove existing relations
|
||||||
Connection.Delete(ui);
|
Connection.Delete(ui);
|
||||||
|
|
||||||
var nbInstallations = Installations.Count();
|
var nbInstallations = Installations.Count();
|
||||||
|
@ -89,7 +89,7 @@ public static partial class Db
|
||||||
foreach (var user in Users)
|
foreach (var user in Users)
|
||||||
while (Random.Shared.Next(5) != 0)
|
while (Random.Shared.Next(5) != 0)
|
||||||
{
|
{
|
||||||
var relation = new User2Installation
|
var relation = new InstallationAccess
|
||||||
{
|
{
|
||||||
UserId = user.Id,
|
UserId = user.Id,
|
||||||
InstallationId = Random.Shared.Next(nbInstallations) + 1
|
InstallationId = Random.Shared.Next(nbInstallations) + 1
|
||||||
|
|
|
@ -2,7 +2,7 @@ using SQLite;
|
||||||
|
|
||||||
namespace InnovEnergy.App.Backend.Relations;
|
namespace InnovEnergy.App.Backend.Relations;
|
||||||
|
|
||||||
public class User2Folder : Relation<Int64, Int64>
|
public class FolderAccess : Relation<Int64, Int64>
|
||||||
{
|
{
|
||||||
[Indexed] public Int64 UserId { get => Left ; init => Left = value;}
|
[Indexed] public Int64 UserId { get => Left ; init => Left = value;}
|
||||||
[Indexed] public Int64 FolderId { get => Right; init => Right = value;}
|
[Indexed] public Int64 FolderId { get => Right; init => Right = value;}
|
|
@ -2,7 +2,7 @@ using SQLite;
|
||||||
|
|
||||||
namespace InnovEnergy.App.Backend.Relations;
|
namespace InnovEnergy.App.Backend.Relations;
|
||||||
|
|
||||||
public class User2Installation : Relation<Int64, Int64>
|
public class InstallationAccess : Relation<Int64, Int64>
|
||||||
{
|
{
|
||||||
[Indexed] public Int64 UserId { get => Left ; init => Left = value;}
|
[Indexed] public Int64 UserId { get => Left ; init => Left = value;}
|
||||||
[Indexed] public Int64 InstallationId { get => Right; init => Right = value;}
|
[Indexed] public Int64 InstallationId { get => Right; init => Right = value;}
|
|
@ -14,7 +14,7 @@ public class Session : Relation<String, Int64>
|
||||||
[Indexed] public DateTime LastSeen { get; set; }
|
[Indexed] public DateTime LastSeen { get; set; }
|
||||||
|
|
||||||
[Ignore] public Boolean Valid => DateTime.Now - LastSeen < MaxAge
|
[Ignore] public Boolean Valid => DateTime.Now - LastSeen < MaxAge
|
||||||
&& !User.IsNull();
|
&& !User.Email.IsNullOrEmpty();
|
||||||
|
|
||||||
[Ignore] public User User => _User ??= Db.GetUserById(UserId)!;
|
[Ignore] public User User => _User ??= Db.GetUserById(UserId)!;
|
||||||
|
|
||||||
|
@ -40,5 +40,4 @@ public class Session : Relation<String, Int64>
|
||||||
return Convert.ToBase64String(token);
|
return Convert.ToBase64String(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
Binary file not shown.
Loading…
Reference in New Issue