mirror of
https://github.com/chylex/Discord-History-Tracker.git
synced 2024-11-25 14:42:44 +01:00
Compare commits
No commits in common. "3d9d6a454a0ad48e27cc588028f594c18b28f9bb" and "93fe018343d3895b0c538bf8983f920b4e52fcf8" have entirely different histories.
3d9d6a454a
...
93fe018343
@ -3,9 +3,12 @@ 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;
|
||||||
|
|
||||||
@ -13,14 +16,25 @@ 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) {
|
protected BaseEndpoint(IDatabaseFile db, ServerParameters parameters) {
|
||||||
this.Db = db;
|
this.Db = db;
|
||||||
|
this.Parameters = parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Handle(HttpContext ctx) {
|
private async Task Handle(HttpContext ctx, StringValues token) {
|
||||||
|
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);
|
||||||
@ -35,6 +49,14 @@ 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,13 +2,14 @@ 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) : base(db) {}
|
public GetAttachmentEndpoint(IDatabaseFile db, ServerParameters parameters) : base(db, parameters) {}
|
||||||
|
|
||||||
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,16 +13,12 @@ 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());
|
||||||
|
|
||||||
private readonly ServerParameters serverParameters;
|
public GetTrackingScriptEndpoint(IDatabaseFile db, ServerParameters parameters) : base(db, parameters) {}
|
||||||
|
|
||||||
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]*/", "= " + serverParameters.Port + ";")
|
string script = bootstrap.Replace("= 0; /*[PORT]*/", "= " + Parameters.Port + ";")
|
||||||
.Replace("/*[TOKEN]*/", HttpUtility.JavaScriptStringEncode(serverParameters.Token))
|
.Replace("/*[TOKEN]*/", HttpUtility.JavaScriptStringEncode(Parameters.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,13 +3,14 @@ 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) : base(db) {}
|
public TrackChannelEndpoint(IDatabaseFile db, ServerParameters parameters) : base(db, parameters) {}
|
||||||
|
|
||||||
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,6 +9,7 @@ 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;
|
||||||
@ -19,7 +20,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) : base(db) {}
|
public TrackMessagesEndpoint(IDatabaseFile db, ServerParameters parameters) : base(db, parameters) {}
|
||||||
|
|
||||||
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,13 +3,14 @@ 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) : base(db) {}
|
public TrackUsersEndpoint(IDatabaseFile db, ServerParameters parameters) : base(db, parameters) {}
|
||||||
|
|
||||||
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);
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
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,6 +4,7 @@ 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;
|
||||||
@ -74,7 +75,7 @@ public static class ServerLauncher {
|
|||||||
options.ListenLocalhost(port, static listenOptions => listenOptions.Protocols = HttpProtocols.Http1);
|
options.ListenLocalhost(port, static listenOptions => listenOptions.Protocols = HttpProtocols.Http1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Server = new WebHostBuilder()
|
Server = WebHost.CreateDefaultBuilder()
|
||||||
.ConfigureServices(AddServices)
|
.ConfigureServices(AddServices)
|
||||||
.UseKestrel(SetKestrelOptions)
|
.UseKestrel(SetKestrelOptions)
|
||||||
.UseStartup<Startup>()
|
.UseStartup<Startup>()
|
||||||
|
@ -2,7 +2,6 @@ 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;
|
||||||
@ -28,23 +27,27 @@ 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.UseMiddleware<ServerLoggingMiddleware>();
|
|
||||||
app.UseCors();
|
|
||||||
app.UseMiddleware<ServerAuthorizationMiddleware>();
|
|
||||||
app.UseRouting();
|
app.UseRouting();
|
||||||
|
app.UseCors();
|
||||||
app.UseEndpoints(endpoints => {
|
app.UseEndpoints(endpoints => {
|
||||||
endpoints.MapGet("/get-tracking-script", new GetTrackingScriptEndpoint(db, parameters).Handle);
|
GetTrackingScriptEndpoint getTrackingScript = new (db, parameters);
|
||||||
endpoints.MapGet("/get-attachment/{url}", new GetAttachmentEndpoint(db).Handle);
|
endpoints.MapGet("/get-tracking-script", context => getTrackingScript.HandleGet(context));
|
||||||
endpoints.MapPost("/track-channel", new TrackChannelEndpoint(db).Handle);
|
|
||||||
endpoints.MapPost("/track-users", new TrackUsersEndpoint(db).Handle);
|
TrackChannelEndpoint trackChannel = new (db, parameters);
|
||||||
endpoints.MapPost("/track-messages", new TrackMessagesEndpoint(db).Handle);
|
endpoints.MapPost("/track-channel", context => trackChannel.HandlePost(context));
|
||||||
|
|
||||||
|
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