File uploading

This commit is contained in:
2025-04-13 13:50:30 +08:00
parent 31d98199e7
commit d22a15c42d
11 changed files with 918 additions and 3 deletions

View File

@ -1,3 +1,4 @@
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
@ -6,6 +7,7 @@ using Casbin.Persist.Adapter.EFCore;
using DysonNetwork.Sphere;
using DysonNetwork.Sphere.Account;
using DysonNetwork.Sphere.Auth;
using DysonNetwork.Sphere.Storage;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.EntityFrameworkCore;
@ -13,6 +15,9 @@ using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using NodaTime;
using NodaTime.Serialization.SystemTextJson;
using tusdotnet;
using tusdotnet.Models;
using File = System.IO.File;
var builder = WebApplication.CreateBuilder(args);
@ -106,6 +111,7 @@ builder.Services.AddOpenApi();
builder.Services.AddScoped<AccountService>();
builder.Services.AddScoped<AuthService>();
builder.Services.AddScoped<FileService>();
var app = builder.Build();
@ -129,11 +135,74 @@ app.UseCors(opts =>
opts.SetIsOriginAllowed(_ => true)
.AllowCredentials()
.AllowAnyHeader()
.AllowAnyMethod());
.AllowAnyMethod()
);
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
var tusDiskStore = new tusdotnet.Stores.TusDiskStore(
builder.Configuration.GetSection("Tus").GetValue<string>("StorePath")!
);
app.MapTus("/files/tus", (_) => Task.FromResult<DefaultTusConfiguration>(new()
{
Store = tusDiskStore,
Events = new()
{
OnAuthorizeAsync = async eventContext =>
{
var httpContext = eventContext.HttpContext;
var user = httpContext.User;
if (!user.Identity?.IsAuthenticated ?? true)
{
eventContext.FailRequest(HttpStatusCode.Unauthorized);
return;
}
var userId = httpContext.User.FindFirst("user_id")?.Value;
if (userId == null) return;
var isSuperuser = httpContext.User.FindFirst("is_superuser")?.Value == "1";
if (isSuperuser) userId = "super:" + userId;
var enforcer = httpContext.RequestServices.GetRequiredService<IEnforcer>();
var allowed = await enforcer.EnforceAsync(userId, "global", "files", "create");
if (!allowed)
{
eventContext.FailRequest(HttpStatusCode.Forbidden);
}
},
OnFileCompleteAsync = async eventContext =>
{
var httpContext = eventContext.HttpContext;
var user = httpContext.User;
var userId = long.Parse(user.FindFirst("user_id")!.Value);
var db = httpContext.RequestServices.GetRequiredService<AppDatabase>();
var account = await db.Accounts.FindAsync(userId);
if (account is null) 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 = eventContext.HttpContext.RequestServices.GetRequiredService<FileService>();
var info = await fileService.AnalyzeFileAsync(account, file.Id, fileStream, fileName, contentType);
await fileService.UploadFileToRemoteAsync(info, fileStream, null);
await tusDiskStore.DeleteFileAsync(file.Id, eventContext.CancellationToken);
},
OnCreateCompleteAsync = eventContext =>
{
// var baseUrl = builder.Configuration.GetValue<string>("Storage:BaseUrl")!;
// eventContext.SetUploadUrl(new Uri($"{baseUrl}/files/{eventContext.FileId}"));
return Task.CompletedTask;
}
}
}));
app.Run();