mirror of
https://github.com/chylex/Discord-History-Tracker.git
synced 2024-11-25 05:42:45 +01:00
Compare commits
3 Commits
93fe018343
...
3d9d6a454a
Author | SHA1 | Date | |
---|---|---|---|
3d9d6a454a | |||
ee39780928 | |||
7b58f973a0 |
@ -3,12 +3,9 @@ using System.Net;
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using DHT.Server.Database;
|
using DHT.Server.Database;
|
||||||
using DHT.Server.Service;
|
|
||||||
using DHT.Utils.Http;
|
using DHT.Utils.Http;
|
||||||
using DHT.Utils.Logging;
|
using DHT.Utils.Logging;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Http.Extensions;
|
|
||||||
using Microsoft.Extensions.Primitives;
|
|
||||||
|
|
||||||
namespace DHT.Server.Endpoints;
|
namespace DHT.Server.Endpoints;
|
||||||
|
|
||||||
@ -16,25 +13,14 @@ abstract class BaseEndpoint {
|
|||||||
private static readonly Log Log = Log.ForType<BaseEndpoint>();
|
private static readonly Log Log = Log.ForType<BaseEndpoint>();
|
||||||
|
|
||||||
protected IDatabaseFile Db { get; }
|
protected IDatabaseFile Db { get; }
|
||||||
protected ServerParameters Parameters { get; }
|
|
||||||
|
|
||||||
protected BaseEndpoint(IDatabaseFile db, ServerParameters parameters) {
|
protected BaseEndpoint(IDatabaseFile db) {
|
||||||
this.Db = db;
|
this.Db = db;
|
||||||
this.Parameters = parameters;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Handle(HttpContext ctx, StringValues token) {
|
public async Task Handle(HttpContext ctx) {
|
||||||
var request = ctx.Request;
|
|
||||||
var response = ctx.Response;
|
var response = ctx.Response;
|
||||||
|
|
||||||
Log.Info("Request: " + request.GetDisplayUrl() + " (" + request.ContentLength + " B)");
|
|
||||||
|
|
||||||
if (token.Count != 1 || token[0] != Parameters.Token) {
|
|
||||||
Log.Error("Token: " + (token.Count == 1 ? token[0] : "<missing>"));
|
|
||||||
response.StatusCode = (int) HttpStatusCode.Forbidden;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
response.StatusCode = (int) HttpStatusCode.OK;
|
response.StatusCode = (int) HttpStatusCode.OK;
|
||||||
var output = await Respond(ctx);
|
var output = await Respond(ctx);
|
||||||
@ -49,14 +35,6 @@ abstract class BaseEndpoint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task HandleGet(HttpContext ctx) {
|
|
||||||
await Handle(ctx, ctx.Request.Query["token"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task HandlePost(HttpContext ctx) {
|
|
||||||
await Handle(ctx, ctx.Request.Headers["X-DHT-Token"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract Task<IHttpOutput> Respond(HttpContext ctx);
|
protected abstract Task<IHttpOutput> Respond(HttpContext ctx);
|
||||||
|
|
||||||
protected static async Task<JsonElement> ReadJson(HttpContext ctx) {
|
protected static async Task<JsonElement> ReadJson(HttpContext ctx) {
|
||||||
|
@ -2,14 +2,13 @@ using System.Net;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using DHT.Server.Data;
|
using DHT.Server.Data;
|
||||||
using DHT.Server.Database;
|
using DHT.Server.Database;
|
||||||
using DHT.Server.Service;
|
|
||||||
using DHT.Utils.Http;
|
using DHT.Utils.Http;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace DHT.Server.Endpoints;
|
namespace DHT.Server.Endpoints;
|
||||||
|
|
||||||
sealed class GetAttachmentEndpoint : BaseEndpoint {
|
sealed class GetAttachmentEndpoint : BaseEndpoint {
|
||||||
public GetAttachmentEndpoint(IDatabaseFile db, ServerParameters parameters) : base(db, parameters) {}
|
public GetAttachmentEndpoint(IDatabaseFile db) : base(db) {}
|
||||||
|
|
||||||
protected override Task<IHttpOutput> Respond(HttpContext ctx) {
|
protected override Task<IHttpOutput> Respond(HttpContext ctx) {
|
||||||
string attachmentUrl = WebUtility.UrlDecode((string) ctx.Request.RouteValues["url"]!);
|
string attachmentUrl = WebUtility.UrlDecode((string) ctx.Request.RouteValues["url"]!);
|
||||||
|
@ -13,12 +13,16 @@ namespace DHT.Server.Endpoints;
|
|||||||
sealed class GetTrackingScriptEndpoint : BaseEndpoint {
|
sealed class GetTrackingScriptEndpoint : BaseEndpoint {
|
||||||
private static ResourceLoader Resources { get; } = new (Assembly.GetExecutingAssembly());
|
private static ResourceLoader Resources { get; } = new (Assembly.GetExecutingAssembly());
|
||||||
|
|
||||||
public GetTrackingScriptEndpoint(IDatabaseFile db, ServerParameters parameters) : base(db, parameters) {}
|
private readonly ServerParameters serverParameters;
|
||||||
|
|
||||||
|
public GetTrackingScriptEndpoint(IDatabaseFile db, ServerParameters parameters) : base(db) {
|
||||||
|
serverParameters = parameters;
|
||||||
|
}
|
||||||
|
|
||||||
protected override async Task<IHttpOutput> Respond(HttpContext ctx) {
|
protected override async Task<IHttpOutput> Respond(HttpContext ctx) {
|
||||||
string bootstrap = await Resources.ReadTextAsync("Tracker/bootstrap.js");
|
string bootstrap = await Resources.ReadTextAsync("Tracker/bootstrap.js");
|
||||||
string script = bootstrap.Replace("= 0; /*[PORT]*/", "= " + Parameters.Port + ";")
|
string script = bootstrap.Replace("= 0; /*[PORT]*/", "= " + serverParameters.Port + ";")
|
||||||
.Replace("/*[TOKEN]*/", HttpUtility.JavaScriptStringEncode(Parameters.Token))
|
.Replace("/*[TOKEN]*/", HttpUtility.JavaScriptStringEncode(serverParameters.Token))
|
||||||
.Replace("/*[IMPORTS]*/", await Resources.ReadJoinedAsync("Tracker/scripts/", '\n'))
|
.Replace("/*[IMPORTS]*/", await Resources.ReadJoinedAsync("Tracker/scripts/", '\n'))
|
||||||
.Replace("/*[CSS-CONTROLLER]*/", await Resources.ReadTextAsync("Tracker/styles/controller.css"))
|
.Replace("/*[CSS-CONTROLLER]*/", await Resources.ReadTextAsync("Tracker/styles/controller.css"))
|
||||||
.Replace("/*[CSS-SETTINGS]*/", await Resources.ReadTextAsync("Tracker/styles/settings.css"))
|
.Replace("/*[CSS-SETTINGS]*/", await Resources.ReadTextAsync("Tracker/styles/settings.css"))
|
||||||
|
@ -3,14 +3,13 @@ using System.Text.Json;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using DHT.Server.Data;
|
using DHT.Server.Data;
|
||||||
using DHT.Server.Database;
|
using DHT.Server.Database;
|
||||||
using DHT.Server.Service;
|
|
||||||
using DHT.Utils.Http;
|
using DHT.Utils.Http;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace DHT.Server.Endpoints;
|
namespace DHT.Server.Endpoints;
|
||||||
|
|
||||||
sealed class TrackChannelEndpoint : BaseEndpoint {
|
sealed class TrackChannelEndpoint : BaseEndpoint {
|
||||||
public TrackChannelEndpoint(IDatabaseFile db, ServerParameters parameters) : base(db, parameters) {}
|
public TrackChannelEndpoint(IDatabaseFile db) : base(db) {}
|
||||||
|
|
||||||
protected override async Task<IHttpOutput> Respond(HttpContext ctx) {
|
protected override async Task<IHttpOutput> Respond(HttpContext ctx) {
|
||||||
var root = await ReadJson(ctx);
|
var root = await ReadJson(ctx);
|
||||||
|
@ -9,7 +9,6 @@ using DHT.Server.Data;
|
|||||||
using DHT.Server.Data.Filters;
|
using DHT.Server.Data.Filters;
|
||||||
using DHT.Server.Database;
|
using DHT.Server.Database;
|
||||||
using DHT.Server.Download;
|
using DHT.Server.Download;
|
||||||
using DHT.Server.Service;
|
|
||||||
using DHT.Utils.Collections;
|
using DHT.Utils.Collections;
|
||||||
using DHT.Utils.Http;
|
using DHT.Utils.Http;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
@ -20,7 +19,7 @@ sealed class TrackMessagesEndpoint : BaseEndpoint {
|
|||||||
private const string HasNewMessages = "1";
|
private const string HasNewMessages = "1";
|
||||||
private const string NoNewMessages = "0";
|
private const string NoNewMessages = "0";
|
||||||
|
|
||||||
public TrackMessagesEndpoint(IDatabaseFile db, ServerParameters parameters) : base(db, parameters) {}
|
public TrackMessagesEndpoint(IDatabaseFile db) : base(db) {}
|
||||||
|
|
||||||
protected override async Task<IHttpOutput> Respond(HttpContext ctx) {
|
protected override async Task<IHttpOutput> Respond(HttpContext ctx) {
|
||||||
var root = await ReadJson(ctx);
|
var root = await ReadJson(ctx);
|
||||||
|
@ -3,14 +3,13 @@ using System.Text.Json;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using DHT.Server.Data;
|
using DHT.Server.Data;
|
||||||
using DHT.Server.Database;
|
using DHT.Server.Database;
|
||||||
using DHT.Server.Service;
|
|
||||||
using DHT.Utils.Http;
|
using DHT.Utils.Http;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace DHT.Server.Endpoints;
|
namespace DHT.Server.Endpoints;
|
||||||
|
|
||||||
sealed class TrackUsersEndpoint : BaseEndpoint {
|
sealed class TrackUsersEndpoint : BaseEndpoint {
|
||||||
public TrackUsersEndpoint(IDatabaseFile db, ServerParameters parameters) : base(db, parameters) {}
|
public TrackUsersEndpoint(IDatabaseFile db) : base(db) {}
|
||||||
|
|
||||||
protected override async Task<IHttpOutput> Respond(HttpContext ctx) {
|
protected override async Task<IHttpOutput> Respond(HttpContext ctx) {
|
||||||
var root = await ReadJson(ctx);
|
var root = await ReadJson(ctx);
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
using System.Net;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using DHT.Utils.Logging;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Primitives;
|
||||||
|
|
||||||
|
namespace DHT.Server.Service.Middlewares;
|
||||||
|
|
||||||
|
sealed class ServerAuthorizationMiddleware {
|
||||||
|
private static readonly Log Log = Log.ForType<ServerAuthorizationMiddleware>();
|
||||||
|
|
||||||
|
private readonly RequestDelegate next;
|
||||||
|
private readonly ServerParameters serverParameters;
|
||||||
|
|
||||||
|
public ServerAuthorizationMiddleware(RequestDelegate next, ServerParameters serverParameters) {
|
||||||
|
this.next = next;
|
||||||
|
this.serverParameters = serverParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task InvokeAsync(HttpContext context) {
|
||||||
|
var request = context.Request;
|
||||||
|
|
||||||
|
bool success = HttpMethods.IsGet(request.Method)
|
||||||
|
? CheckToken(request.Query["token"])
|
||||||
|
: CheckToken(request.Headers["X-DHT-Token"]);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
await next(context);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
context.Response.StatusCode = (int) HttpStatusCode.Forbidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CheckToken(StringValues token) {
|
||||||
|
if (token.Count == 1 && token[0] == serverParameters.Token) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Log.Error("Invalid token: " + (token.Count == 1 ? token[0] : "<missing>"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
29
app/Server/Service/Middlewares/ServerLoggingMiddleware.cs
Normal file
29
app/Server/Service/Middlewares/ServerLoggingMiddleware.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using DHT.Utils.Logging;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Http.Extensions;
|
||||||
|
|
||||||
|
namespace DHT.Server.Service.Middlewares;
|
||||||
|
|
||||||
|
sealed class ServerLoggingMiddleware {
|
||||||
|
private static readonly Log Log = Log.ForType<ServerLoggingMiddleware>();
|
||||||
|
|
||||||
|
private readonly RequestDelegate next;
|
||||||
|
|
||||||
|
public ServerLoggingMiddleware(RequestDelegate next) {
|
||||||
|
this.next = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task InvokeAsync(HttpContext context) {
|
||||||
|
var stopwatch = Stopwatch.StartNew();
|
||||||
|
await next(context);
|
||||||
|
stopwatch.Stop();
|
||||||
|
|
||||||
|
var request = context.Request;
|
||||||
|
var requestLength = request.ContentLength ?? 0L;
|
||||||
|
var responseStatus = context.Response.StatusCode;
|
||||||
|
var elapsedMs = stopwatch.ElapsedMilliseconds;
|
||||||
|
Log.Debug("Request to " + request.GetEncodedPathAndQuery() + " (" + requestLength + " B) returned " + responseStatus + ", took " + elapsedMs + " ms");
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,6 @@ using System.Diagnostics.CodeAnalysis;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using DHT.Server.Database;
|
using DHT.Server.Database;
|
||||||
using DHT.Utils.Logging;
|
using DHT.Utils.Logging;
|
||||||
using Microsoft.AspNetCore;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
@ -75,11 +74,11 @@ public static class ServerLauncher {
|
|||||||
options.ListenLocalhost(port, static listenOptions => listenOptions.Protocols = HttpProtocols.Http1);
|
options.ListenLocalhost(port, static listenOptions => listenOptions.Protocols = HttpProtocols.Http1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Server = WebHost.CreateDefaultBuilder()
|
Server = new WebHostBuilder()
|
||||||
.ConfigureServices(AddServices)
|
.ConfigureServices(AddServices)
|
||||||
.UseKestrel(SetKestrelOptions)
|
.UseKestrel(SetKestrelOptions)
|
||||||
.UseStartup<Startup>()
|
.UseStartup<Startup>()
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
Server.Start();
|
Server.Start();
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis;
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using DHT.Server.Database;
|
using DHT.Server.Database;
|
||||||
using DHT.Server.Endpoints;
|
using DHT.Server.Endpoints;
|
||||||
|
using DHT.Server.Service.Middlewares;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Http.Json;
|
using Microsoft.AspNetCore.Http.Json;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
@ -27,27 +28,23 @@ sealed class Startup {
|
|||||||
builder.WithOrigins(AllowedOrigins).AllowCredentials().AllowAnyMethod().AllowAnyHeader().WithExposedHeaders("X-DHT");
|
builder.WithOrigins(AllowedOrigins).AllowCredentials().AllowAnyMethod().AllowAnyHeader().WithExposedHeaders("X-DHT");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
services.AddRoutingCore();
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||||
public void Configure(IApplicationBuilder app, IHostApplicationLifetime lifetime, IDatabaseFile db, ServerParameters parameters) {
|
public void Configure(IApplicationBuilder app, IHostApplicationLifetime lifetime, IDatabaseFile db, ServerParameters parameters) {
|
||||||
app.UseRouting();
|
app.UseMiddleware<ServerLoggingMiddleware>();
|
||||||
app.UseCors();
|
app.UseCors();
|
||||||
|
app.UseMiddleware<ServerAuthorizationMiddleware>();
|
||||||
|
app.UseRouting();
|
||||||
|
|
||||||
app.UseEndpoints(endpoints => {
|
app.UseEndpoints(endpoints => {
|
||||||
GetTrackingScriptEndpoint getTrackingScript = new (db, parameters);
|
endpoints.MapGet("/get-tracking-script", new GetTrackingScriptEndpoint(db, parameters).Handle);
|
||||||
endpoints.MapGet("/get-tracking-script", context => getTrackingScript.HandleGet(context));
|
endpoints.MapGet("/get-attachment/{url}", new GetAttachmentEndpoint(db).Handle);
|
||||||
|
endpoints.MapPost("/track-channel", new TrackChannelEndpoint(db).Handle);
|
||||||
TrackChannelEndpoint trackChannel = new (db, parameters);
|
endpoints.MapPost("/track-users", new TrackUsersEndpoint(db).Handle);
|
||||||
endpoints.MapPost("/track-channel", context => trackChannel.HandlePost(context));
|
endpoints.MapPost("/track-messages", new TrackMessagesEndpoint(db).Handle);
|
||||||
|
|
||||||
TrackUsersEndpoint trackUsers = new (db, parameters);
|
|
||||||
endpoints.MapPost("/track-users", context => trackUsers.HandlePost(context));
|
|
||||||
|
|
||||||
TrackMessagesEndpoint trackMessages = new (db, parameters);
|
|
||||||
endpoints.MapPost("/track-messages", context => trackMessages.HandlePost(context));
|
|
||||||
|
|
||||||
GetAttachmentEndpoint getAttachment = new (db, parameters);
|
|
||||||
endpoints.MapGet("/get-attachment/{url}", context => getAttachment.HandleGet(context));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user