summaryrefslogtreecommitdiffstats
path: root/BlobBin/Program.cs
blob: e66cd02f7ce2ee1c4c983ce8301338d6348b75c8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
global using BlobBin;
using IOL.Helpers;
using Microsoft.EntityFrameworkCore;
using File = BlobBin.File;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<DB>(opt => opt.UseSqlite("data source=main.db"));
var app = builder.Build();

app.UseFileServer();
app.UseStatusCodePages();
app.MapGet("/upload-link", GetUploadLink);
app.MapPost("/upload/{id}", UploadBig);
app.MapPost("/upload", UploadSimple);
app.MapPost("/text", UploadText);
app.MapGet("/b/{id}", GetBlob);
app.Run();

IResult GetUploadLink(HttpContext context, DB db) {
    var file = new File {
        CreatedBy = context.Request.Headers["X-Forwarded-For"].ToString()
    };
    db.Files.Add(file);
    db.SaveChanges();
    return Results.Text(
        context.Request.GetRequestHost()
        + "/upload/"
        + file.Id
    );
}

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();
}

IResult UploadText(HttpContext context, DB db) {
    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
{
    public string Password { get; set; }
    public bool Singleton { get; set; }
    public string AutoDeleteAfter { get; set; }
}

class PasteRequest : BlobBase
{
    public string Text { get; set; }
    public string Mime { get; set; }
}

class UploadRequest : BlobBase
{
    public IFormFile? File { get; set; }
}