2023-02-28 10:16:19 +00:00
|
|
|
using System.Diagnostics.CodeAnalysis;
|
2023-02-16 12:57:06 +00:00
|
|
|
using System.Net.Mail;
|
2023-02-22 13:46:36 +00:00
|
|
|
using System.Security.Cryptography;
|
2023-02-16 14:08:50 +00:00
|
|
|
using System.Text;
|
2023-02-28 10:16:19 +00:00
|
|
|
using System.Text.Json;
|
|
|
|
using System.Text.Json.Nodes;
|
2023-02-22 13:46:36 +00:00
|
|
|
using Flurl.Http;
|
2023-02-24 11:58:47 +00:00
|
|
|
using Innovenergy.Backend.Model;
|
|
|
|
using Innovenergy.Backend.Utils;
|
2023-02-22 13:46:36 +00:00
|
|
|
using InnovEnergy.Lib.Utils;
|
2023-02-16 12:57:06 +00:00
|
|
|
using SQLite;
|
2023-02-24 11:58:47 +00:00
|
|
|
|
2023-02-16 12:57:06 +00:00
|
|
|
#pragma warning disable CS0472
|
|
|
|
#pragma warning disable CS8602
|
|
|
|
|
2023-02-24 11:58:47 +00:00
|
|
|
namespace Innovenergy.Backend.Database;
|
2023-02-16 12:57:06 +00:00
|
|
|
|
|
|
|
public partial class Db
|
|
|
|
{
|
|
|
|
private TableQuery<User> Users => _Db.Table<User>();
|
|
|
|
|
|
|
|
public Int32 NbUsers => Users.Count();
|
|
|
|
|
|
|
|
public User? GetUserById(Int64 id)
|
|
|
|
{
|
2023-02-24 11:58:47 +00:00
|
|
|
return Users.FirstOrDefault(u => u.Id == id);
|
2023-02-16 12:57:06 +00:00
|
|
|
}
|
2023-02-24 11:58:47 +00:00
|
|
|
|
2023-02-16 12:57:06 +00:00
|
|
|
public Boolean IsParentOfChild(User parent, User child)
|
|
|
|
{
|
|
|
|
var parentPointer = child.ParentId;
|
2023-02-24 11:58:47 +00:00
|
|
|
|
2023-02-16 12:57:06 +00:00
|
|
|
if (parent.Id == child.Id)
|
|
|
|
return true;
|
2023-02-24 11:58:47 +00:00
|
|
|
|
2023-02-16 12:57:06 +00:00
|
|
|
while (parentPointer != null && parentPointer != parent.Id)
|
|
|
|
{
|
|
|
|
parentPointer = GetUserById(parentPointer).ParentId;
|
|
|
|
}
|
|
|
|
|
|
|
|
return parentPointer == parent.Id;
|
|
|
|
}
|
|
|
|
|
|
|
|
public User? GetUserByEmail(String email) => Users.FirstOrDefault(u => u.Email == email);
|
|
|
|
|
|
|
|
public Result CreateUser(User user)
|
|
|
|
{
|
|
|
|
if (GetUserByEmail(user.Email) is not null)
|
|
|
|
return Result.Error("User with that email already exists");
|
2023-02-24 11:58:47 +00:00
|
|
|
|
2023-02-16 14:08:50 +00:00
|
|
|
//Salting and Hashing password
|
|
|
|
var salt = Crypto.GenerateSalt();
|
2023-02-24 11:58:47 +00:00
|
|
|
var hashedPassword = Crypto.ComputeHash(Encoding.UTF8.GetBytes(user.Password),
|
2023-02-16 14:08:50 +00:00
|
|
|
Encoding.UTF8.GetBytes(salt + "innovEnergy"));
|
|
|
|
|
|
|
|
user.Salt = salt;
|
|
|
|
user.Password = hashedPassword;
|
2023-02-16 12:57:06 +00:00
|
|
|
|
2023-02-16 14:08:50 +00:00
|
|
|
return Create(user);
|
2023-02-16 12:57:06 +00:00
|
|
|
}
|
2023-02-24 11:58:47 +00:00
|
|
|
|
2023-02-28 10:16:19 +00:00
|
|
|
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")]
|
2023-02-22 13:46:36 +00:00
|
|
|
public Object CreateAndSaveUserS3ApiKey(User user)
|
|
|
|
{
|
|
|
|
//EXOSCALE API URL
|
2023-02-24 11:58:47 +00:00
|
|
|
const String url = "https://api-ch-dk-2.exoscale.com/v2/access-key";
|
2023-02-22 13:46:36 +00:00
|
|
|
const String secret = "S2K1okphiCSNK4mzqr4swguFzngWAMb1OoSlZsJa9F0";
|
|
|
|
const String apiKey = "EXOb98ec9008e3ec16e19d7b593";
|
2023-02-24 11:58:47 +00:00
|
|
|
|
2023-02-28 10:16:19 +00:00
|
|
|
var installationList = User2Installation
|
2023-02-22 13:46:36 +00:00
|
|
|
.Where(i => i.UserId == user.Id)
|
|
|
|
.SelectMany(i => Installations.Where(f => i.InstallationId == f.Id))
|
|
|
|
.ToList();
|
2023-02-24 11:58:47 +00:00
|
|
|
|
2023-02-28 10:16:19 +00:00
|
|
|
|
|
|
|
var instList = new JsonArray();
|
|
|
|
|
|
|
|
foreach (var installation in installationList)
|
2023-02-22 13:46:36 +00:00
|
|
|
{
|
2023-02-28 10:16:19 +00:00
|
|
|
instList.Add(new JsonObject {["domain"] = "sos",["resource-name"] = installation.Name,["resource-type"] = "bucket"});
|
2023-02-22 13:46:36 +00:00
|
|
|
}
|
2023-02-28 10:16:19 +00:00
|
|
|
|
|
|
|
var jsonPayload = new JsonObject { ["name"] = user.Email, ["operations"] = new JsonArray{ "getObject", "listBucket" }, ["content"] = instList};
|
2023-02-28 11:34:36 +00:00
|
|
|
var expiration = DateTime.Now.AddSeconds(60);
|
2023-02-28 10:16:19 +00:00
|
|
|
|
2023-02-28 11:34:36 +00:00
|
|
|
var signature = $"POST /v2/access-key\n{jsonPayload}\n\n\n{((DateTimeOffset)expiration).ToUnixTimeSeconds()}";
|
|
|
|
using var hmacSha256 = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
|
2023-02-28 10:16:19 +00:00
|
|
|
|
|
|
|
signature = Encoding.UTF8
|
|
|
|
.GetBytes(signature)
|
2023-02-28 11:34:36 +00:00
|
|
|
.Apply(hmacSha256.ComputeHash)
|
2023-02-22 13:46:36 +00:00
|
|
|
.Apply(Convert.ToBase64String);
|
2023-02-24 11:58:47 +00:00
|
|
|
|
2023-02-22 13:46:36 +00:00
|
|
|
var keyJson = url
|
2023-02-28 11:34:36 +00:00
|
|
|
.WithHeader("Authorization",
|
|
|
|
$"EXO2-HMAC-SHA256 credential={apiKey},expires={((DateTimeOffset)expiration).ToUnixTimeSeconds()},signature={signature}");
|
|
|
|
|
|
|
|
|
|
|
|
var result = keyJson.PostJsonAsync(jsonPayload.ToString())
|
2023-02-22 13:46:36 +00:00
|
|
|
.ReceiveJson()
|
|
|
|
.Result;
|
2023-02-28 11:34:36 +00:00
|
|
|
return result;
|
|
|
|
// return SetUserS3ApiKey(user, keyJson.GetValue("key"));
|
2023-02-22 13:46:36 +00:00
|
|
|
}
|
2023-02-24 11:58:47 +00:00
|
|
|
|
|
|
|
public Result SetUserS3ApiKey(User user, String key)
|
2023-02-22 13:46:36 +00:00
|
|
|
{
|
|
|
|
user.S3Key = key;
|
|
|
|
return Update(user);
|
|
|
|
}
|
2023-02-24 11:58:47 +00:00
|
|
|
|
2023-02-16 12:57:06 +00:00
|
|
|
public Result UpdateUser(User user)
|
|
|
|
{
|
|
|
|
var oldUser = GetUserById(user.Id);
|
|
|
|
if (oldUser == null)
|
|
|
|
return Result.Error("User doesn't exist");
|
|
|
|
|
|
|
|
//Checking for unchangeable things
|
2023-02-23 10:26:55 +00:00
|
|
|
// TODO: depends on privileges of caller
|
2023-02-24 11:58:47 +00:00
|
|
|
|
|
|
|
user.Id = oldUser.Id;
|
2023-02-16 12:57:06 +00:00
|
|
|
user.ParentId = oldUser.ParentId;
|
2023-02-24 11:58:47 +00:00
|
|
|
user.Email = oldUser.Email;
|
|
|
|
|
2023-02-16 12:57:06 +00:00
|
|
|
return Update(user);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Result DeleteUser(User user)
|
|
|
|
{
|
2023-02-24 11:58:47 +00:00
|
|
|
User2Folder.Delete(u => u.UserId == user.Id);
|
2023-02-23 10:26:55 +00:00
|
|
|
User2Installation.Delete(u => u.UserId == user.Id);
|
2023-02-24 11:58:47 +00:00
|
|
|
|
2023-02-16 14:08:50 +00:00
|
|
|
//Todo check for orphaned Installations/Folders
|
2023-02-24 11:58:47 +00:00
|
|
|
|
2023-02-23 10:26:55 +00:00
|
|
|
// GetChildUsers()
|
2023-02-24 11:58:47 +00:00
|
|
|
|
2023-02-16 12:57:06 +00:00
|
|
|
return Delete(user);
|
|
|
|
}
|
2023-02-24 11:58:47 +00:00
|
|
|
|
2023-02-16 12:57:06 +00:00
|
|
|
|
|
|
|
// TODO
|
|
|
|
private static Boolean IsValidEmail(String email)
|
|
|
|
{
|
|
|
|
try
|
2023-02-24 11:58:47 +00:00
|
|
|
{
|
2023-02-16 12:57:06 +00:00
|
|
|
var emailAddress = new MailAddress(email);
|
|
|
|
}
|
|
|
|
catch
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2023-02-24 11:58:47 +00:00
|
|
|
|
2023-02-16 12:57:06 +00:00
|
|
|
return true;
|
|
|
|
}
|
2023-02-24 11:58:47 +00:00
|
|
|
}
|