New file manager complete. Server settings for py, js, mc complete. Fixes

This commit is contained in:
Marcel Baumgartner
2023-04-03 00:09:03 +02:00
parent 02f6386f95
commit 6b8c75d014
39 changed files with 1332 additions and 356 deletions

View File

@@ -0,0 +1,24 @@
namespace Moonlight.App.Helpers.Files;
public abstract class FileAccess : ICloneable
{
public string CurrentPath { get; set; } = "/";
public abstract Task<FileData[]> Ls();
public abstract Task Cd(string dir);
public abstract Task Up();
public abstract Task SetDir(string dir);
public abstract Task<string> Read(FileData fileData);
public abstract Task Write(FileData fileData, string content);
public abstract Task Upload(string name, Stream stream, Action<int>? progressUpdated = null);
public abstract Task MkDir(string name);
public abstract Task<string> Pwd();
public abstract Task<string> DownloadUrl(FileData fileData);
public abstract Task<Stream> DownloadStream(FileData fileData);
public abstract Task Delete(FileData fileData);
public abstract Task Move(FileData fileData, string newPath);
public abstract Task Compress(params FileData[] files);
public abstract Task Decompress(FileData fileData);
public abstract Task<string> GetLaunchUrl();
public abstract object Clone();
}

View File

@@ -1,19 +0,0 @@
namespace Moonlight.App.Helpers.Files;
public interface IFileAccess
{
public Task<FileData[]> Ls();
public Task Cd(string dir);
public Task Up();
public Task SetDir(string dir);
public Task<string> Read(FileData fileData);
public Task Write(FileData fileData, string content);
public Task Upload(string name, Stream stream, Action<int>? progressUpdated = null);
public Task MkDir(string name);
public Task<string> Pwd();
public Task<string> DownloadUrl(FileData fileData);
public Task<Stream> DownloadStream(FileData fileData);
public Task Delete(FileData fileData);
public Task Move(FileData fileData, string newPath);
public Task<string> GetLaunchUrl();
}

View File

@@ -1,21 +1,32 @@
using Moonlight.App.Database.Entities;
using System.Web;
using Moonlight.App.Database.Entities;
using Moonlight.App.Models.Wings.Requests;
using Moonlight.App.Models.Wings.Resources;
using Moonlight.App.Services;
using RestSharp;
namespace Moonlight.App.Helpers.Files;
public class WingsFileAccess : IFileAccess
public class WingsFileAccess : FileAccess
{
private readonly WingsApiHelper WingsApiHelper;
private readonly WingsJwtHelper WingsJwtHelper;
private readonly ConfigService ConfigService;
private readonly Server Server;
private readonly User User;
private string CurrentPath = "/";
public WingsFileAccess(WingsApiHelper wingsApiHelper, WingsJwtHelper wingsJwtHelper,Server server)
public WingsFileAccess(
WingsApiHelper wingsApiHelper,
WingsJwtHelper wingsJwtHelper,
Server server,
ConfigService configService,
User user)
{
WingsApiHelper = wingsApiHelper;
WingsJwtHelper = wingsJwtHelper;
Server = server;
ConfigService = configService;
User = user;
if (server.Node == null)
{
@@ -23,9 +34,9 @@ public class WingsFileAccess : IFileAccess
}
}
public async Task<FileData[]> Ls()
public override async Task<FileData[]> Ls()
{
var res = await WingsApiHelper.Get<ListDirectoryRequest[]>(
var res = await WingsApiHelper.Get<ListDirectory[]>(
Server.Node,
$"api/servers/{Server.Uuid}/files/list-directory?directory={CurrentPath}"
);
@@ -45,7 +56,7 @@ public class WingsFileAccess : IFileAccess
return x.ToArray();
}
public Task Cd(string dir)
public override Task Cd(string dir)
{
var x = Path.Combine(CurrentPath, dir).Replace("\\", "/") + "/";
x = x.Replace("//", "/");
@@ -54,65 +65,168 @@ public class WingsFileAccess : IFileAccess
return Task.CompletedTask;
}
public Task Up()
public override Task Up()
{
CurrentPath = Path.GetFullPath(Path.Combine(CurrentPath, "..")).Replace("\\", "/").Replace("C:", "");
return Task.CompletedTask;
}
public Task SetDir(string dir)
public override Task SetDir(string dir)
{
CurrentPath = dir;
return Task.CompletedTask;
}
public async Task<string> Read(FileData fileData)
public override async Task<string> Read(FileData fileData)
{
return await WingsApiHelper.GetRaw(Server.Node,$"api/servers/{Server.Uuid}/files/contents?file={CurrentPath}{fileData.Name}");
return await WingsApiHelper.GetRaw(Server.Node,
$"api/servers/{Server.Uuid}/files/contents?file={CurrentPath}{fileData.Name}");
}
public async Task Write(FileData fileData, string content)
public override async Task Write(FileData fileData, string content)
{
await WingsApiHelper.PostRaw(Server.Node,$"api/servers/{Server.Uuid}/files/write?file={CurrentPath}{fileData.Name}", content);
await WingsApiHelper.PostRaw(Server.Node,
$"api/servers/{Server.Uuid}/files/write?file={CurrentPath}{fileData.Name}", content);
}
public Task Upload(string name, Stream stream, Action<int>? progressUpdated = null)
public override async Task Upload(string name, Stream dataStream, Action<int>? progressUpdated = null)
{
throw new NotImplementedException();
var token = WingsJwtHelper.Generate(
Server.Node.Token,
claims => { claims.Add("server_uuid", Server.Uuid.ToString()); }
);
var client = new RestClient();
var request = new RestRequest();
if (Server.Node.Ssl)
request.Resource =
$"https://{Server.Node.Fqdn}:{Server.Node.HttpPort}/upload/file?token={token}&directory={CurrentPath}";
else
request.Resource =
$"http://{Server.Node.Fqdn}:{Server.Node.HttpPort}/upload/file?token={token}&directory={CurrentPath}";
request.AddParameter("name", "files");
request.AddParameter("filename", name);
request.AddHeader("Content-Type", "multipart/form-data");
request.AddHeader("Origin", ConfigService.GetSection("Moonlight").GetValue<string>("AppUrl"));
request.AddFile("files", () =>
{
return new StreamProgressHelper(dataStream)
{
Progress = i => { progressUpdated?.Invoke(i); }
};
}, name);
await client.ExecutePostAsync(request);
client.Dispose();
dataStream.Close();
}
public Task MkDir(string name)
public override async Task MkDir(string name)
{
throw new NotImplementedException();
await WingsApiHelper.Post(Server.Node, $"api/servers/{Server.Uuid}/files/create-directory",
new CreateDirectory()
{
Name = name,
Path = CurrentPath
}
);
}
public Task<string> Pwd()
public override Task<string> Pwd()
{
return Task.FromResult(CurrentPath);
}
public Task<string> DownloadUrl(FileData fileData)
public override Task<string> DownloadUrl(FileData fileData)
{
var token = WingsJwtHelper.Generate(Server.Node.Token, claims =>
{
claims.Add("server_uuid", Server.Uuid.ToString());
claims.Add("file_path", CurrentPath + "/" + fileData.Name);
});
if (Server.Node.Ssl)
{
return Task.FromResult(
$"https://{Server.Node.Fqdn}:{Server.Node.HttpPort}/download/file?token={token}"
);
}
else
{
return Task.FromResult(
$"http://{Server.Node.Fqdn}:{Server.Node.HttpPort}/download/file?token={token}"
);
}
}
public override Task<Stream> DownloadStream(FileData fileData)
{
throw new NotImplementedException();
}
public Task<Stream> DownloadStream(FileData fileData)
public override async Task Delete(FileData fileData)
{
throw new NotImplementedException();
await WingsApiHelper.Post(Server.Node, $"api/servers/{Server.Uuid}/files/delete", new DeleteFiles()
{
Root = CurrentPath,
Files = new()
{
fileData.Name
}
});
}
public Task Delete(FileData fileData)
public override async Task Move(FileData fileData, string newPath)
{
throw new NotImplementedException();
var req = new RenameFiles()
{
Root = "/",
Files = new[]
{
new RenameFilesData()
{
From = (CurrentPath + fileData.Name),
To = newPath
}
}
};
await WingsApiHelper.Put(Server.Node, $"api/servers/{Server.Uuid}/files/rename", req);
}
public Task Move(FileData fileData, string newPath)
public override async Task Compress(params FileData[] files)
{
throw new NotImplementedException();
var req = new CompressFiles()
{
Root = CurrentPath,
Files = files.Select(x => x.Name).ToArray()
};
await WingsApiHelper.Post(Server.Node, $"api/servers/{Server.Uuid}/files/compress", req);
}
public Task<string> GetLaunchUrl()
public override async Task Decompress(FileData fileData)
{
throw new NotImplementedException();
var req = new DecompressFile()
{
Root = CurrentPath,
File = fileData.Name
};
await WingsApiHelper.Post(Server.Node, $"api/servers/{Server.Uuid}/files/decompress", req);
}
public override Task<string> GetLaunchUrl()
{
return Task.FromResult(
$"sftp://{User.Id}.{StringHelper.IntToStringWithLeadingZeros(Server.Id, 8)}@{Server.Node.Fqdn}:{Server.Node.SftpPort}");
}
public override object Clone()
{
return new WingsFileAccess(WingsApiHelper, WingsJwtHelper, Server, ConfigService, User);
}
}

View File

@@ -24,11 +24,11 @@ public class PaperApiHelper
else
requrl = ApiUrl + "/" + url;
RestRequest request = new(requrl);
RestRequest request = new(requrl, Method.Get);
request.AddHeader("Content-Type", "application/json");
var response = await client.GetAsync(request);
var response = await client.ExecuteAsync(request);
if (!response.IsSuccessful)
{

View File

@@ -14,24 +14,13 @@ public class WingsApiHelper
Client = new();
}
private string GetApiUrl(Node node)
{
if(node.Ssl)
return $"https://{node.Fqdn}:{node.HttpPort}/";
else
return $"http://{node.Fqdn}:{node.HttpPort}/";
//return $"https://{node.Fqdn}:{node.HttpPort}/";
}
public async Task<T> Get<T>(Node node, string resource)
{
RestRequest request = new(GetApiUrl(node) + resource);
var request = CreateRequest(node, resource);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept", "application/json");
request.AddHeader("Authorization", "Bearer " + node.Token);
request.Method = Method.Get;
var response = await Client.GetAsync(request);
var response = await Client.ExecuteAsync(request);
if (!response.IsSuccessful)
{
@@ -53,13 +42,11 @@ public class WingsApiHelper
public async Task<string> GetRaw(Node node, string resource)
{
RestRequest request = new(GetApiUrl(node) + resource);
var request = CreateRequest(node, resource);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept", "application/json");
request.AddHeader("Authorization", "Bearer " + node.Token);
request.Method = Method.Get;
var response = await Client.GetAsync(request);
var response = await Client.ExecuteAsync(request);
if (!response.IsSuccessful)
{
@@ -81,18 +68,16 @@ public class WingsApiHelper
public async Task<T> Post<T>(Node node, string resource, object? body)
{
RestRequest request = new(GetApiUrl(node) + resource);
var request = CreateRequest(node, resource);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept", "application/json");
request.AddHeader("Authorization", "Bearer " + node.Token);
request.Method = Method.Post;
request.AddParameter("text/plain",
JsonConvert.SerializeObject(body),
ParameterType.RequestBody
);
var response = await Client.PostAsync(request);
var response = await Client.ExecuteAsync(request);
if (!response.IsSuccessful)
{
@@ -114,16 +99,14 @@ public class WingsApiHelper
public async Task Post(Node node, string resource, object? body)
{
RestRequest request = new(GetApiUrl(node) + resource);
var request = CreateRequest(node, resource);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept", "application/json");
request.AddHeader("Authorization", "Bearer " + node.Token);
request.Method = Method.Post;
if(body != null)
if(body != null)
request.AddParameter("text/plain", JsonConvert.SerializeObject(body), ParameterType.RequestBody);
var response = await Client.PostAsync(request);
var response = await Client.ExecuteAsync(request);
if (!response.IsSuccessful)
{
@@ -143,15 +126,13 @@ public class WingsApiHelper
public async Task PostRaw(Node node, string resource, object body)
{
RestRequest request = new(GetApiUrl(node) + resource);
var request = CreateRequest(node, resource);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept", "application/json");
request.AddHeader("Authorization", "Bearer " + node.Token);
request.Method = Method.Post;
request.AddParameter("text/plain", body, ParameterType.RequestBody);
var response = await Client.PostAsync(request);
var response = await Client.ExecuteAsync(request);
if (!response.IsSuccessful)
{
@@ -171,16 +152,14 @@ public class WingsApiHelper
public async Task Delete(Node node, string resource, object? body)
{
RestRequest request = new(GetApiUrl(node) + resource);
var request = CreateRequest(node, resource);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept", "application/json");
request.AddHeader("Authorization", "Bearer " + node.Token);
request.Method = Method.Delete;
if(body != null)
if(body != null)
request.AddParameter("text/plain", JsonConvert.SerializeObject(body), ParameterType.RequestBody);
var response = await Client.DeleteAsync(request);
var response = await Client.ExecuteAsync(request);
if (!response.IsSuccessful)
{
@@ -200,15 +179,13 @@ public class WingsApiHelper
public async Task Put(Node node, string resource, object? body)
{
RestRequest request = new(GetApiUrl(node) + resource);
var request = CreateRequest(node, resource);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept", "application/json");
request.AddHeader("Authorization", "Bearer " + node.Token);
request.Method = Method.Put;
request.AddParameter("text/plain", JsonConvert.SerializeObject(body), ParameterType.RequestBody);
var response = await Client.PutAsync(request);
var response = await Client.ExecuteAsync(request);
if (!response.IsSuccessful)
{
@@ -225,4 +202,20 @@ public class WingsApiHelper
}
}
}
private RestRequest CreateRequest(Node node, string resource)
{
var url = (node.Ssl ? "https" : "http") + $"://{node.Fqdn}:{node.HttpPort}/" + resource;
var request = new RestRequest(url)
{
Timeout = 60 * 15
};
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept", "application/json");
request.AddHeader("Authorization", "Bearer " + node.Token);
return request;
}
}