Files
Moonlight/Moonlight/App/Helpers/Files/SftpFileAccess.cs
Marcel Baumgartner b3738da1d2 Added website directory limit for website file manager
Added this change to prevent users deleting the log directories
2023-05-17 19:24:01 +02:00

208 lines
5.2 KiB
C#

using Logging.Net;
using Renci.SshNet;
using ConnectionInfo = Renci.SshNet.ConnectionInfo;
namespace Moonlight.App.Helpers.Files;
public class SftpFileAccess : FileAccess
{
private readonly string SftpHost;
private readonly string SftpUser;
private readonly string SftpPassword;
private readonly int SftpPort;
private readonly bool ForceUserDir;
private readonly string AdditionalPath;
private readonly SftpClient Client;
private string InternalPath
{
get
{
if (ForceUserDir)
return $"/home/{SftpUser}{AdditionalPath}{CurrentPath}";
return InternalPath;
}
}
public SftpFileAccess(string sftpHost, string sftpUser, string sftpPassword, int sftpPort,
bool forceUserDir = false, string additionalPath = "")
{
SftpHost = sftpHost;
SftpUser = sftpUser;
SftpPassword = sftpPassword;
SftpPort = sftpPort;
ForceUserDir = forceUserDir;
AdditionalPath = additionalPath;
Client = new(
new ConnectionInfo(
SftpHost,
SftpPort,
SftpUser,
new PasswordAuthenticationMethod(
SftpUser,
SftpPassword
)
)
);
}
private void EnsureConnect()
{
if (!Client.IsConnected)
Client.Connect();
}
public override Task<FileData[]> Ls()
{
EnsureConnect();
var x = new List<FileData>();
foreach (var file in Client.ListDirectory(InternalPath))
{
if (file.Name != "." && file.Name != "..")
{
x.Add(new()
{
Name = file.Name,
Size = file.Attributes.Size,
IsFile = !file.IsDirectory
});
}
}
return Task.FromResult(x.ToArray());
}
public override Task Cd(string dir)
{
var x = Path.Combine(CurrentPath, dir).Replace("\\", "/") + "/";
x = x.Replace("//", "/");
CurrentPath = x;
return Task.CompletedTask;
}
public override Task Up()
{
CurrentPath = Path.GetFullPath(Path.Combine(CurrentPath, "..")).Replace("\\", "/").Replace("C:", "");
return Task.CompletedTask;
}
public override Task SetDir(string dir)
{
CurrentPath = dir;
return Task.CompletedTask;
}
public override Task<string> Read(FileData fileData)
{
EnsureConnect();
var textStream = Client.Open(InternalPath.TrimEnd('/') + "/" + fileData.Name, FileMode.Open);
if (textStream == null)
return Task.FromResult("");
var streamReader = new StreamReader(textStream);
var text = streamReader.ReadToEnd();
streamReader.Close();
textStream.Close();
return Task.FromResult(text);
}
public override Task Write(FileData fileData, string content)
{
EnsureConnect();
var textStream = Client.Open(InternalPath.TrimEnd('/') + "/" + fileData.Name, FileMode.Create);
var streamWriter = new StreamWriter(textStream);
streamWriter.Write(content);
streamWriter.Flush();
textStream.Flush();
streamWriter.Close();
textStream.Close();
return Task.CompletedTask;
}
public override async Task Upload(string name, Stream stream, Action<int>? progressUpdated = null)
{
var dataStream = new SyncStreamAdapter(stream);
await Task.Factory.FromAsync((x, _) => Client.BeginUploadFile(dataStream, InternalPath + name, x, null, u =>
{
progressUpdated?.Invoke((int)((long)u / stream.Length));
}),
Client.EndUploadFile, null);
}
public override Task MkDir(string name)
{
Client.CreateDirectory(InternalPath + name);
return Task.CompletedTask;
}
public override Task<string> Pwd()
{
return Task.FromResult(CurrentPath);
}
public override Task<string> DownloadUrl(FileData fileData)
{
throw new NotImplementedException();
}
public override Task<Stream> DownloadStream(FileData fileData)
{
var stream = new MemoryStream(100 * 1024 * 1024);
Client.DownloadFile(InternalPath + fileData.Name, stream);
return Task.FromResult<Stream>(stream);
}
public override Task Delete(FileData fileData)
{
Client.Delete(InternalPath + fileData.Name);
return Task.CompletedTask;
}
public override Task Move(FileData fileData, string newPath)
{
Client.RenameFile(InternalPath + fileData.Name, InternalPath + newPath);
return Task.CompletedTask;
}
public override Task Compress(params FileData[] files)
{
throw new NotImplementedException();
}
public override Task Decompress(FileData fileData)
{
throw new NotImplementedException();
}
public override Task<string> GetLaunchUrl()
{
return Task.FromResult($"sftp://{SftpUser}@{SftpHost}:{SftpPort}");
}
public override object Clone()
{
return new SftpFileAccess(SftpHost, SftpUser, SftpPassword, SftpPort, ForceUserDir);
}
}