Files
.github
.idx
DysonNetwork.Sphere
Account
Activity
Auth
Chat
Connection
Developer
Email
Localization
Migrations
Pages
Permission
Post
Properties
Publisher
Realm
Resources
Sticker
Storage
Handlers
CacheService.cs
CloudFile.cs
CloudFileUnusedRecyclingJob.cs
FileController.cs
FileExpirationJob.cs
FileReferenceService.cs
FileService.ReferenceMigration.cs
FileService.cs
FlushBufferService.cs
ICloudFile.cs
TextSanitizer.cs
TusService.cs
Wallet
wwwroot
.DS_Store
.gitignore
AppDatabase.cs
Dockerfile
DysonNetwork.Sphere.csproj
DysonNetwork.Sphere.csproj.DotSettings.user
DysonNetwork.Sphere.http
Program.cs
appsettings.json
package.json
postcss.config.js
tailwind.config.js
.dockerignore
.gitignore
DysonNetwork.sln
DysonNetwork.sln.DotSettings.user
compose.yaml
Swarm/DysonNetwork.Sphere/Storage/TusService.cs

78 lines
3.3 KiB
C#

using System.Net;
using System.Text;
using System.Text.Json;
using DysonNetwork.Sphere.Permission;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using tusdotnet.Interfaces;
using tusdotnet.Models;
using tusdotnet.Models.Configuration;
namespace DysonNetwork.Sphere.Storage;
public abstract class TusService
{
public static DefaultTusConfiguration BuildConfiguration(ITusStore store) => new()
{
Store = store,
Events = new Events
{
OnAuthorizeAsync = async eventContext =>
{
if (eventContext.Intent == IntentType.DeleteFile)
{
eventContext.FailRequest(
HttpStatusCode.BadRequest,
"Deleting files from this endpoint was disabled, please refer to the Dyson Network File API."
);
return;
}
var httpContext = eventContext.HttpContext;
if (httpContext.Items["CurrentUser"] is not Account.Account user)
{
eventContext.FailRequest(HttpStatusCode.Unauthorized);
return;
}
if (!user.IsSuperuser)
{
using var scope = httpContext.RequestServices.CreateScope();
var pm = scope.ServiceProvider.GetRequiredService<PermissionService>();
var allowed = await pm.HasPermissionAsync($"user:{user.Id}", "global", "files.create");
if (!allowed)
eventContext.FailRequest(HttpStatusCode.Forbidden);
}
},
OnFileCompleteAsync = async eventContext =>
{
using var scope = eventContext.HttpContext.RequestServices.CreateScope();
var services = scope.ServiceProvider;
var httpContext = eventContext.HttpContext;
if (httpContext.Items["CurrentUser"] is not Account.Account user) return;
var file = await eventContext.GetFileAsync();
var metadata = await file.GetMetadataAsync(eventContext.CancellationToken);
var fileName = metadata.TryGetValue("filename", out var fn)
? fn.GetString(Encoding.UTF8)
: "uploaded_file";
var contentType = metadata.TryGetValue("content-type", out var ct) ? ct.GetString(Encoding.UTF8) : null;
var fileStream = await file.GetContentAsync(eventContext.CancellationToken);
var fileService = services.GetRequiredService<FileService>();
var info = await fileService.ProcessNewFileAsync(user, file.Id, fileStream, fileName, contentType);
using var finalScope = eventContext.HttpContext.RequestServices.CreateScope();
var jsonOptions = finalScope.ServiceProvider.GetRequiredService<IOptions<JsonOptions>>().Value
.JsonSerializerOptions;
var infoJson = JsonSerializer.Serialize(info, jsonOptions);
eventContext.HttpContext.Response.Headers.Append("X-FileInfo", infoJson);
// Dispose the stream after all processing is complete
await fileStream.DisposeAsync();
}
}
};
}