Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd4cb73b9b | ||
|
|
ab9cdeb682 |
@@ -995,11 +995,11 @@ public partial class LightlessHub
|
||||
return false;
|
||||
}
|
||||
|
||||
var (isOwner, _) = await TryValidateOwner(dto.GID).ConfigureAwait(false);
|
||||
var (isOwner, _) = await TryValidateGroupModeratorOrOwner(dto.GID).ConfigureAwait(false);
|
||||
if (!isOwner)
|
||||
{
|
||||
_logger.LogCallWarning(LightlessHubLogger.Args("Unauthorized syncshell broadcast change", "User", UserUID, "GID", dto.GID));
|
||||
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "You must be the owner of the syncshell to broadcast it.");
|
||||
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "You must be the owner or moderator of the syncshell to broadcast it.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using StackExchange.Redis;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
|
||||
<PackageReference Include="Blake3" Version="2.0.0" />
|
||||
<PackageReference Include="IDisposableAnalyzers" Version="4.0.8">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using K4os.Compression.LZ4.Legacy;
|
||||
using Blake3;
|
||||
using K4os.Compression.LZ4.Legacy;
|
||||
using LightlessSync.API.Dto.Files;
|
||||
using LightlessSync.API.Routes;
|
||||
using LightlessSync.API.SignalR;
|
||||
@@ -208,11 +209,14 @@ public class ServerFilesController : ControllerBase
|
||||
[RequestSizeLimit(200 * 1024 * 1024)]
|
||||
public async Task<IActionResult> UploadFile(string hash, CancellationToken requestAborted)
|
||||
{
|
||||
using var dbContext = await _lightlessDbContext.CreateDbContextAsync();
|
||||
await using var dbContext = await _lightlessDbContext.CreateDbContextAsync();
|
||||
|
||||
_logger.LogInformation("{user}|{file}: Uploading", LightlessUser, hash);
|
||||
if (hash.Length == 40)
|
||||
{
|
||||
hash = hash.ToUpperInvariant();
|
||||
}
|
||||
|
||||
hash = hash.ToUpperInvariant();
|
||||
var existingFile = await dbContext.Files.SingleOrDefaultAsync(f => f.Hash == hash);
|
||||
if (existingFile != null) return Ok();
|
||||
|
||||
@@ -263,10 +267,14 @@ public class ServerFilesController : ControllerBase
|
||||
[RequestSizeLimit(200 * 1024 * 1024)]
|
||||
public async Task<IActionResult> UploadFileMunged(string hash, CancellationToken requestAborted)
|
||||
{
|
||||
using var dbContext = await _lightlessDbContext.CreateDbContextAsync();
|
||||
await using var dbContext = await _lightlessDbContext.CreateDbContextAsync();
|
||||
|
||||
_logger.LogInformation("{user}|{file}: Uploading munged", LightlessUser, hash);
|
||||
hash = hash.ToUpperInvariant();
|
||||
if (hash.Length == 40)
|
||||
{
|
||||
hash = hash.ToUpperInvariant();
|
||||
}
|
||||
|
||||
var existingFile = await dbContext.Files.SingleOrDefaultAsync(f => f.Hash == hash);
|
||||
if (existingFile != null) return Ok();
|
||||
|
||||
@@ -319,20 +327,26 @@ public class ServerFilesController : ControllerBase
|
||||
private async Task StoreData(string hash, LightlessDbContext dbContext, MemoryStream compressedFileStream)
|
||||
{
|
||||
var decompressedData = LZ4Wrapper.Unwrap(compressedFileStream.ToArray());
|
||||
// reset streams
|
||||
compressedFileStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
// compute hash to verify
|
||||
var hashString = BitConverter.ToString(SHA1.HashData(decompressedData))
|
||||
.Replace("-", "", StringComparison.Ordinal).ToUpperInvariant();
|
||||
if (!string.Equals(hashString, hash, StringComparison.Ordinal))
|
||||
throw new InvalidOperationException($"{LightlessUser}|{hash}: Hash does not match file, computed: {hashString}, expected: {hash}");
|
||||
bool valid;
|
||||
|
||||
// save file
|
||||
var path = FilePathUtil.GetFilePath(_basePath, hash);
|
||||
using var fileStream = new FileStream(path, FileMode.Create);
|
||||
await compressedFileStream.CopyToAsync(fileStream).ConfigureAwait(false);
|
||||
_logger.LogDebug("{user}|{file}: Uploaded file saved to {path}", LightlessUser, hash, path);
|
||||
if (hash.Length == 40)
|
||||
{
|
||||
var sha1Hex = Convert.ToHexString(SHA1.HashData(decompressedData));
|
||||
valid = string.Equals(sha1Hex, hash, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
else
|
||||
{
|
||||
var blakeHash = Hasher.Hash(decompressedData);
|
||||
var blakeHex = Convert.ToHexString(blakeHash.AsSpan());
|
||||
valid = string.Equals(blakeHex, hash, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
if (!valid)
|
||||
throw new InvalidOperationException(
|
||||
$"{LightlessUser}|{hash}: Hash does not match file, computed mismatch."
|
||||
);
|
||||
|
||||
// update on db
|
||||
await dbContext.Files.AddAsync(new FileCache()
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Blake3" Version="2.0.0" />
|
||||
<PackageReference Include="IDisposableAnalyzers" Version="4.0.8">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
|
||||
Reference in New Issue
Block a user