summaryrefslogtreecommitdiffstats
path: root/BlobBin
diff options
context:
space:
mode:
authorivarlovlie <git@ivarlovlie.no>2023-01-13 00:04:12 +0100
committerivarlovlie <git@ivarlovlie.no>2023-01-13 00:04:12 +0100
commit971c00b8f5977db9422eeafa47b262c1030bd4af (patch)
tree09ec55186f0f85d983b3be1754c6393123bc4363 /BlobBin
parenta9860b28f2be123d1f0bfad504165992a4c841ed (diff)
downloadblob-bin-971c00b8f5977db9422eeafa47b262c1030bd4af.tar.xz
blob-bin-971c00b8f5977db9422eeafa47b262c1030bd4af.zip
feat: working file upload
Diffstat (limited to 'BlobBin')
-rw-r--r--BlobBin/DB.cs1
-rw-r--r--BlobBin/Migrations/20230112230354_InitialCreate.Designer.cs (renamed from BlobBin/Migrations/20230110204008_InitialCreate.Designer.cs)15
-rw-r--r--BlobBin/Migrations/20230112230354_InitialCreate.cs (renamed from BlobBin/Migrations/20230110204008_InitialCreate.cs)7
-rw-r--r--BlobBin/Migrations/DBModelSnapshot.cs13
-rw-r--r--BlobBin/Program.cs76
-rw-r--r--BlobBin/appsettings.Development.json8
-rw-r--r--BlobBin/appsettings.json9
-rw-r--r--BlobBin/wwwroot/index.html2
8 files changed, 101 insertions, 30 deletions
diff --git a/BlobBin/DB.cs b/BlobBin/DB.cs
index 5146304..a736dc2 100644
--- a/BlobBin/DB.cs
+++ b/BlobBin/DB.cs
@@ -18,6 +18,7 @@ public class UploadEntityBase
}
public Guid Id { get; set; }
+ public string PublicId { get; set; }
public DateTime CreatedAt { get; set; }
public string CreatedBy { get; set; }
public DateTime? DeletedAt { get; set; }
diff --git a/BlobBin/Migrations/20230110204008_InitialCreate.Designer.cs b/BlobBin/Migrations/20230112230354_InitialCreate.Designer.cs
index f461df5..b5a06c3 100644
--- a/BlobBin/Migrations/20230110204008_InitialCreate.Designer.cs
+++ b/BlobBin/Migrations/20230112230354_InitialCreate.Designer.cs
@@ -11,7 +11,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace BlobBin.Migrations
{
[DbContext(typeof(DB))]
- [Migration("20230110204008_InitialCreate")]
+ [Migration("20230112230354_InitialCreate")]
partial class InitialCreate
{
/// <inheritdoc />
@@ -46,12 +46,15 @@ namespace BlobBin.Migrations
.HasColumnType("TEXT");
b.Property<string>("Name")
- .IsRequired()
.HasColumnType("TEXT");
b.Property<string>("PasswordHash")
.HasColumnType("TEXT");
+ b.Property<string>("PublicId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
b.Property<bool>("Singleton")
.HasColumnType("INTEGER");
@@ -69,6 +72,9 @@ namespace BlobBin.Migrations
b.Property<string>("AutoDeleteAfter")
.HasColumnType("TEXT");
+ b.Property<string>("Content")
+ .HasColumnType("TEXT");
+
b.Property<DateTime>("CreatedAt")
.HasColumnType("TEXT");
@@ -86,12 +92,15 @@ namespace BlobBin.Migrations
.HasColumnType("TEXT");
b.Property<string>("Name")
- .IsRequired()
.HasColumnType("TEXT");
b.Property<string>("PasswordHash")
.HasColumnType("TEXT");
+ b.Property<string>("PublicId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
b.Property<bool>("Singleton")
.HasColumnType("INTEGER");
diff --git a/BlobBin/Migrations/20230110204008_InitialCreate.cs b/BlobBin/Migrations/20230112230354_InitialCreate.cs
index 1614b01..97f9c36 100644
--- a/BlobBin/Migrations/20230110204008_InitialCreate.cs
+++ b/BlobBin/Migrations/20230112230354_InitialCreate.cs
@@ -16,8 +16,9 @@ namespace BlobBin.Migrations
columns: table => new
{
Id = table.Column<Guid>(type: "TEXT", nullable: false),
- Name = table.Column<string>(type: "TEXT", nullable: false),
+ Name = table.Column<string>(type: "TEXT", nullable: true),
Length = table.Column<long>(type: "INTEGER", nullable: false),
+ PublicId = table.Column<string>(type: "TEXT", nullable: false),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
CreatedBy = table.Column<string>(type: "TEXT", nullable: false),
DeletedAt = table.Column<DateTime>(type: "TEXT", nullable: true),
@@ -36,8 +37,10 @@ namespace BlobBin.Migrations
columns: table => new
{
Id = table.Column<Guid>(type: "TEXT", nullable: false),
- Name = table.Column<string>(type: "TEXT", nullable: false),
+ Name = table.Column<string>(type: "TEXT", nullable: true),
+ Content = table.Column<string>(type: "TEXT", nullable: true),
Length = table.Column<long>(type: "INTEGER", nullable: false),
+ PublicId = table.Column<string>(type: "TEXT", nullable: false),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
CreatedBy = table.Column<string>(type: "TEXT", nullable: false),
DeletedAt = table.Column<DateTime>(type: "TEXT", nullable: true),
diff --git a/BlobBin/Migrations/DBModelSnapshot.cs b/BlobBin/Migrations/DBModelSnapshot.cs
index b81feae..8c9fb26 100644
--- a/BlobBin/Migrations/DBModelSnapshot.cs
+++ b/BlobBin/Migrations/DBModelSnapshot.cs
@@ -43,12 +43,15 @@ namespace BlobBin.Migrations
.HasColumnType("TEXT");
b.Property<string>("Name")
- .IsRequired()
.HasColumnType("TEXT");
b.Property<string>("PasswordHash")
.HasColumnType("TEXT");
+ b.Property<string>("PublicId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
b.Property<bool>("Singleton")
.HasColumnType("INTEGER");
@@ -66,6 +69,9 @@ namespace BlobBin.Migrations
b.Property<string>("AutoDeleteAfter")
.HasColumnType("TEXT");
+ b.Property<string>("Content")
+ .HasColumnType("TEXT");
+
b.Property<DateTime>("CreatedAt")
.HasColumnType("TEXT");
@@ -83,12 +89,15 @@ namespace BlobBin.Migrations
.HasColumnType("TEXT");
b.Property<string>("Name")
- .IsRequired()
.HasColumnType("TEXT");
b.Property<string>("PasswordHash")
.HasColumnType("TEXT");
+ b.Property<string>("PublicId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
b.Property<bool>("Singleton")
.HasColumnType("INTEGER");
diff --git a/BlobBin/Program.cs b/BlobBin/Program.cs
index acf3e5f..e66cd02 100644
--- a/BlobBin/Program.cs
+++ b/BlobBin/Program.cs
@@ -1,4 +1,5 @@
global using BlobBin;
+using IOL.Helpers;
using Microsoft.EntityFrameworkCore;
using File = BlobBin.File;
@@ -9,7 +10,8 @@ var app = builder.Build();
app.UseFileServer();
app.UseStatusCodePages();
app.MapGet("/upload-link", GetUploadLink);
-app.MapPost("/upload/{id}", GetUploadLink);
+app.MapPost("/upload/{id}", UploadBig);
+app.MapPost("/upload", UploadSimple);
app.MapPost("/text", UploadText);
app.MapGet("/b/{id}", GetBlob);
app.Run();
@@ -20,10 +22,47 @@ IResult GetUploadLink(HttpContext context, DB db) {
};
db.Files.Add(file);
db.SaveChanges();
- return Results.Ok(context.Request.Host.Value + "/upload/" + file.Id);
+ return Results.Text(
+ context.Request.GetRequestHost()
+ + "/upload/"
+ + file.Id
+ );
}
-IResult Upload(HttpContext context, DB db) {
+async Task<IResult> UploadSimple(HttpContext context, DB db) {
+ if (!context.Request.Form.Files.Any()) {
+ return Results.BadRequest("No files was found in request");
+ }
+
+ var file = new File {
+ CreatedBy = context.Request.Headers["X-Forwarded-For"].ToString(),
+ Singleton = context.Request.Form["singleton"] == "on",
+ AutoDeleteAfter = context.Request.Form["autoDeleteAfter"],
+ Length = context.Request.Form.Files[0].Length,
+ Name = context.Request.Form.Files[0].FileName,
+ MimeType = context.Request.Form.Files[0].ContentType,
+ PublicId = GetUnusedBlobId(db)
+ };
+
+ if (context.Request.Form["password"].ToString().HasValue()) {
+ file.PasswordHash = PasswordHelper.HashPassword(context.Request.Form["password"]);
+ }
+
+
+ await using var write = System.IO.File.OpenWrite(
+ Path.Combine(GetFilesDirectoryPath(), file.Id.ToString())
+ );
+ await context.Request.Form.Files[0].CopyToAsync(write);
+ db.Files.Add(file);
+ db.SaveChanges();
+ return Results.Text(
+ context.Request.GetRequestHost()
+ + "/b/"
+ + file.PublicId
+ );
+}
+
+IResult UploadBig(HttpContext context, DB db) {
return Results.Ok();
}
@@ -31,8 +70,35 @@ IResult UploadText(HttpContext context, DB db) {
return Results.Ok();
}
-IResult GetBlob(string id) {
- return Results.Ok();
+async Task<IResult> GetBlob(string id, DB db) {
+ var file = db.Files.FirstOrDefault(c => c.PublicId == id.Trim());
+ if (file == default) return Results.NotFound();
+ var reader = await System.IO.File.ReadAllBytesAsync(
+ Path.Combine(
+ GetFilesDirectoryPath(), file.Id.ToString()
+ )
+ );
+ return Results.File(reader, file.MimeType, file.Name);
+}
+
+string GetFilesDirectoryPath() {
+ var filesDirectoryPath = Path.Combine(
+ Directory.GetCurrentDirectory(),
+ "AppData",
+ "files"
+ );
+ Directory.CreateDirectory(filesDirectoryPath);
+ return filesDirectoryPath;
+}
+
+string GetUnusedBlobId(DB db) {
+ string id() => RandomString.Generate(5);
+ var res = id();
+ while (db.Files.Any(c => c.PublicId == res)) {
+ res = id();
+ }
+
+ return res;
}
class BlobBase
diff --git a/BlobBin/appsettings.Development.json b/BlobBin/appsettings.Development.json
deleted file mode 100644
index 0c208ae..0000000
--- a/BlobBin/appsettings.Development.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "Logging": {
- "LogLevel": {
- "Default": "Information",
- "Microsoft.AspNetCore": "Warning"
- }
- }
-}
diff --git a/BlobBin/appsettings.json b/BlobBin/appsettings.json
deleted file mode 100644
index 10f68b8..0000000
--- a/BlobBin/appsettings.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "Logging": {
- "LogLevel": {
- "Default": "Information",
- "Microsoft.AspNetCore": "Warning"
- }
- },
- "AllowedHosts": "*"
-}
diff --git a/BlobBin/wwwroot/index.html b/BlobBin/wwwroot/index.html
index f252fe3..fa25951 100644
--- a/BlobBin/wwwroot/index.html
+++ b/BlobBin/wwwroot/index.html
@@ -35,7 +35,7 @@
<main id="forms">
<details>
<summary>Upload a file</summary>
- <form action="/upload" method="post">
+ <form action="/upload" enctype="multipart/form-data" method="post">
<input type="file" id="file" name="files" required>
<label for="file-password">Password (optional)</label>
<input type="password" name="password" id="file-password">