added installation specific s3 keys
This commit is contained in:
parent
7295e6482b
commit
d04ebffc76
|
@ -58,18 +58,26 @@ public class Controller
|
||||||
|
|
||||||
[Returns(HttpStatusCode.OK)]
|
[Returns(HttpStatusCode.OK)]
|
||||||
[Returns(HttpStatusCode.Unauthorized)]
|
[Returns(HttpStatusCode.Unauthorized)]
|
||||||
[HttpPost($"{nameof(UpdateS3Credentials)}")]
|
[HttpGet($"{nameof(GetInstallationS3Key)}")]
|
||||||
public Object UpdateS3Credentials()
|
public Object GetInstallationS3Key(Int64 installationId)
|
||||||
{
|
{
|
||||||
// TODO: S3Credentials should be per session, not per user
|
|
||||||
|
|
||||||
var caller = GetCaller();
|
var caller = GetCaller();
|
||||||
if (caller is null)
|
if (caller is null)
|
||||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||||
|
|
||||||
using var db = Db.Connect();
|
using var db = Db.Connect();
|
||||||
|
|
||||||
|
var installation = db
|
||||||
|
.GetAllAccessibleInstallations(caller)
|
||||||
|
.FirstOrDefault(i => i.Id == installationId);
|
||||||
|
|
||||||
return db.CreateAndSaveUserS3ApiKey(caller);
|
if(installation == null)
|
||||||
|
{
|
||||||
|
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||||
|
}
|
||||||
|
|
||||||
|
var key = db.GetInstallationS3Key(installationId);
|
||||||
|
return key ?? db.CreateAndSaveInstallationS3ApiKey(installation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -229,10 +237,9 @@ public class Controller
|
||||||
// TODO: distinguish between create and update
|
// TODO: distinguish between create and update
|
||||||
|
|
||||||
var caller = GetCaller();
|
var caller = GetCaller();
|
||||||
if (caller == null)
|
|
||||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
|
||||||
|
|
||||||
using var db = Db.Connect();
|
using var db = Db.Connect();
|
||||||
|
if (caller == null || !db.IsParentOfChild(caller.Id, updatedUser))
|
||||||
|
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||||
|
|
||||||
return db.GetUserById(updatedUser.Id) != null
|
return db.GetUserById(updatedUser.Id) != null
|
||||||
? db.UpdateUser(updatedUser)
|
? db.UpdateUser(updatedUser)
|
||||||
|
@ -252,15 +259,21 @@ public class Controller
|
||||||
|
|
||||||
using var db = Db.Connect();
|
using var db = Db.Connect();
|
||||||
|
|
||||||
var hasAccessToInstallation = db
|
var installationFromAccessibleInstallations = db
|
||||||
.GetAllAccessibleInstallations(caller)
|
.GetAllAccessibleInstallations(caller)
|
||||||
.Any(i => i.Id == installation.Id);
|
.FirstOrDefault(i => i.Id == installation.Id);
|
||||||
|
|
||||||
if (!hasAccessToInstallation)
|
if (installationFromAccessibleInstallations == null)
|
||||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||||
|
|
||||||
// TODO: accessibility by other users etc
|
// TODO: accessibility by other users etc
|
||||||
// TODO: sanity check changes
|
// TODO: sanity check changes
|
||||||
|
// foreach(var property in installationFromAccessibleInstallations.GetType().GetProperties()){
|
||||||
|
// if(installation.GetType().GetProperties().Contains(property))
|
||||||
|
// {
|
||||||
|
// property.SetValue(installationFromAccessibleInstallations, property.GetValue(installation));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
return db.UpdateInstallation(installation);
|
return db.UpdateInstallation(installation);
|
||||||
}
|
}
|
||||||
|
@ -278,17 +291,24 @@ public class Controller
|
||||||
|
|
||||||
using var db = Db.Connect();
|
using var db = Db.Connect();
|
||||||
|
|
||||||
var hasAccessToFolder = db
|
var installationFromAccessibleFolders = db
|
||||||
.GetAllAccessibleFolders(caller)
|
.GetAllAccessibleFolders(caller)
|
||||||
.Any(f => f.Id == folder.Id);
|
.FirstOrDefault(f => f.Id == folder.Id);
|
||||||
|
|
||||||
if (!hasAccessToFolder)
|
if (installationFromAccessibleFolders == null)
|
||||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||||
|
|
||||||
// TODO: accessibility by other users etc
|
// TODO: accessibility by other users etc
|
||||||
// TODO: sanity check changes
|
// TODO: sanity check changes
|
||||||
|
|
||||||
return db.UpdateFolder(folder);
|
// foreach(var property in installationFromAccessibleFolders.GetType().GetProperties()){
|
||||||
|
// if(folder.GetType().GetProperties().Contains(property))
|
||||||
|
// {
|
||||||
|
// property.SetValue(installationFromAccessibleFolders, property.GetValue(folder));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
return db.UpdateFolder(installationFromAccessibleFolders);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Returns(HttpStatusCode.OK)]
|
[Returns(HttpStatusCode.OK)]
|
||||||
|
|
|
@ -209,6 +209,12 @@ public partial class Db : IDisposable
|
||||||
|
|
||||||
return Result.Ok;
|
return Result.Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Object? GetInstallationS3Key(Int64 installationId)
|
||||||
|
{
|
||||||
|
return Installations
|
||||||
|
.Where(installation => installation.Id == installationId)
|
||||||
|
.Select(installation => installation.S3Key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,5 +31,6 @@ public partial class Db
|
||||||
|
|
||||||
return Delete(installation);
|
return Delete(installation);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,12 +28,12 @@ public partial class Db
|
||||||
return Users.FirstOrDefault(u => u.Id == id);
|
return Users.FirstOrDefault(u => u.Id == id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean IsParentOfChild(User parent, User child)
|
public Boolean IsParentOfChild(Int64 parentId, User child)
|
||||||
{
|
{
|
||||||
return child
|
return child
|
||||||
.Unfold(u => GetUserById(u.ParentId))
|
.Unfold(u => GetUserById(u.ParentId))
|
||||||
.Select(u => u.Id)
|
.Select(u => u.Id)
|
||||||
.Contains(parent.Id);
|
.Contains(parentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public User? GetUserByEmail(String email) => Users.FirstOrDefault(u => u.Email == email);
|
public User? GetUserByEmail(String email) => Users.FirstOrDefault(u => u.Email == email);
|
||||||
|
@ -66,7 +66,7 @@ public partial class Db
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String BuildSignature(String method, String path, String data, Int64 time, String secret)
|
private static String BuildSignature(String method, String path, String data, Int64 time, String secret)
|
||||||
{
|
{
|
||||||
var messageToSign = "";
|
var messageToSign = "";
|
||||||
messageToSign += method + " /v2/" + path + "\n";
|
messageToSign += method + " /v2/" + path + "\n";
|
||||||
|
@ -85,7 +85,59 @@ public partial class Db
|
||||||
var hmac = HmacSha256Digest(messageToSign, secret);
|
var hmac = HmacSha256Digest(messageToSign, secret);
|
||||||
return Convert.ToBase64String(hmac);
|
return Convert.ToBase64String(hmac);
|
||||||
}
|
}
|
||||||
public Object CreateAndSaveUserS3ApiKey(User user)
|
|
||||||
|
// 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 Object CreateAndSaveInstallationS3ApiKey(Installation installation)
|
||||||
{
|
{
|
||||||
//EXOSCALE API URL
|
//EXOSCALE API URL
|
||||||
const String url = "https://api-ch-dk-2.exoscale.com/v2/";
|
const String url = "https://api-ch-dk-2.exoscale.com/v2/";
|
||||||
|
@ -95,20 +147,10 @@ public partial class Db
|
||||||
const String secret = "S2K1okphiCSNK4mzqr4swguFzngWAMb1OoSlZsJa9F0";
|
const String secret = "S2K1okphiCSNK4mzqr4swguFzngWAMb1OoSlZsJa9F0";
|
||||||
const String apiKey = "EXOb98ec9008e3ec16e19d7b593";
|
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();
|
var instList = new JsonArray();
|
||||||
|
instList.Add(new JsonObject {["domain"] = "sos",["resource-name"] = installation.Name,["resource-type"] = "bucket"});
|
||||||
foreach (var installation in installationList)
|
|
||||||
{
|
var jsonPayload = new JsonObject { ["name"] = installation.Id, ["operations"] = new JsonArray{ "list-sos-bucket", "get-sos-object" }, ["content"] = instList};
|
||||||
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 stringPayload = jsonPayload.ToJsonString();
|
||||||
|
|
||||||
var unixExpiration = DateTimeOffset.UtcNow.ToUnixTimeSeconds()+60;
|
var unixExpiration = DateTimeOffset.UtcNow.ToUnixTimeSeconds()+60;
|
||||||
|
@ -132,16 +174,12 @@ public partial class Db
|
||||||
|
|
||||||
var responseString = response.Content.ReadAsStringAsync().Result;
|
var responseString = response.Content.ReadAsStringAsync().Result;
|
||||||
var newKey = Enumerable.Last(Regex.Match(responseString, "key\\\":\\\"([A-Z])\\w+").ToString().Split('"'));
|
var newKey = Enumerable.Last(Regex.Match(responseString, "key\\\":\\\"([A-Z])\\w+").ToString().Split('"'));
|
||||||
return SetUserS3ApiKey(user, newKey);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public Result SetUserS3ApiKey(User user, String key)
|
installation.S3Key = newKey;
|
||||||
{
|
UpdateInstallation(installation);
|
||||||
user.S3Key = key;
|
return newKey;
|
||||||
return Update(user);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result UpdateUser(User user)
|
public Result UpdateUser(User user)
|
||||||
{
|
{
|
||||||
var oldUser = GetUserById(user.Id);
|
var oldUser = GetUserById(user.Id);
|
||||||
|
|
|
@ -14,6 +14,7 @@ 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; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ public class User : TreeNode
|
||||||
[Indexed]
|
[Indexed]
|
||||||
public String Email { get; set; } = "";
|
public String Email { get; set; } = "";
|
||||||
public Boolean HasWriteAccess { get; set; }
|
public Boolean HasWriteAccess { get; set; }
|
||||||
public String S3Key { get; set; }
|
|
||||||
public String Salt { get; set; }
|
public String Salt { get; set; }
|
||||||
public String Password { get; set; }
|
public String Password { get; set; }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue