Added Rule and Route system
This commit is contained in:
6
VirtualDDNSRouter.Server/Interfaces/IYamlParser.cs
Normal file
6
VirtualDDNSRouter.Server/Interfaces/IYamlParser.cs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
namespace VirtualDDNSRouter.Server.Interfaces;
|
||||||
|
|
||||||
|
public interface IYamlParser
|
||||||
|
{
|
||||||
|
Task<List<Models.Rule>> GetRules();
|
||||||
|
}
|
24
VirtualDDNSRouter.Server/Models/Rule.cs
Normal file
24
VirtualDDNSRouter.Server/Models/Rule.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
using System.Net;
|
||||||
|
using YamlDotNet.Serialization;
|
||||||
|
|
||||||
|
namespace VirtualDDNSRouter.Server.Models;
|
||||||
|
|
||||||
|
public record Rule
|
||||||
|
{
|
||||||
|
public string name { get; init; } = string.Empty;
|
||||||
|
public string apiKey { get; init; } = string.Empty;
|
||||||
|
public string path { get; init; } = string.Empty;
|
||||||
|
|
||||||
|
public Rule() { } // Needed for AOT static deserializer
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public record Route
|
||||||
|
{
|
||||||
|
public string path { get; set; } = string.Empty;
|
||||||
|
public IPAddress ipAddress { get; set; } = IPAddress.None;
|
||||||
|
|
||||||
|
public UInt16 port { get; set; } = 80;
|
||||||
|
|
||||||
|
public Route() { }
|
||||||
|
}
|
@@ -1,5 +1,10 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using Microsoft.AspNetCore.Http.HttpResults;
|
using Microsoft.AspNetCore.Http.HttpResults;
|
||||||
|
using VirtualDDNSRouter.Server.Interfaces;
|
||||||
|
using VirtualDDNSRouter.Server.Models;
|
||||||
|
using VirtualDDNSRouter.Server.Services;
|
||||||
|
using Route = VirtualDDNSRouter.Server.Models.Route;
|
||||||
|
|
||||||
|
|
||||||
var builder = WebApplication.CreateSlimBuilder(args);
|
var builder = WebApplication.CreateSlimBuilder(args);
|
||||||
|
|
||||||
@@ -8,6 +13,8 @@ builder.Services.ConfigureHttpJsonOptions(options =>
|
|||||||
options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
|
options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
builder.Services.AddSingleton<IYamlParser, YamlParser>();
|
||||||
|
|
||||||
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
|
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
|
||||||
builder.Services.AddOpenApi();
|
builder.Services.AddOpenApi();
|
||||||
|
|
||||||
@@ -18,12 +25,42 @@ if (app.Environment.IsDevelopment())
|
|||||||
app.MapOpenApi();
|
app.MapOpenApi();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Route> routes = new List<Route>();
|
||||||
|
|
||||||
|
app.MapPut("/setip/{path}/{port}/{apiKey}", async (IYamlParser yamlParser ,HttpContext context, string path, UInt16 port, string apiKey) =>
|
||||||
|
{
|
||||||
|
var rules = await yamlParser.GetRules();
|
||||||
|
var ruleValid = rules.Any(r => r.path == path && r.apiKey == apiKey);
|
||||||
|
if (!ruleValid)
|
||||||
|
{
|
||||||
|
return Results.StatusCode(StatusCodes.Status403Forbidden);
|
||||||
|
}
|
||||||
|
var clientIp = context.Connection.RemoteIpAddress;
|
||||||
|
if (clientIp is null) return Results.BadRequest("Could not get the client ip address");
|
||||||
|
routes.Add(new Route
|
||||||
|
{
|
||||||
|
ipAddress = clientIp,
|
||||||
|
path = path,
|
||||||
|
port = port
|
||||||
|
});
|
||||||
|
return Results.Created();
|
||||||
|
});
|
||||||
|
|
||||||
|
app.MapGet("/goto/{path}", async (string path) =>
|
||||||
|
{
|
||||||
|
var ruleExists = routes.Any(r => r.path == path);
|
||||||
|
if (!ruleExists) Results.NoContent();
|
||||||
|
var redirectRoute = routes.FirstOrDefault(r => r.path == path);
|
||||||
|
return Results.Redirect($"http://{redirectRoute.ipAddress}:{redirectRoute.port}");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
|
|
||||||
|
|
||||||
[JsonSerializable(typeof(Object))]
|
|
||||||
|
//[JsonSerializable(typeof(Rule))]
|
||||||
|
[JsonSerializable(typeof(Route))]
|
||||||
internal partial class AppJsonSerializerContext : JsonSerializerContext
|
internal partial class AppJsonSerializerContext : JsonSerializerContext
|
||||||
{
|
{
|
||||||
}
|
}
|
31
VirtualDDNSRouter.Server/Services/YamlParser.cs
Normal file
31
VirtualDDNSRouter.Server/Services/YamlParser.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using VirtualDDNSRouter.Server.Interfaces;
|
||||||
|
using VirtualDDNSRouter.Server.Models;
|
||||||
|
using YamlDotNet.Serialization;
|
||||||
|
using YamlDotNet.Serialization.NamingConventions;
|
||||||
|
|
||||||
|
namespace VirtualDDNSRouter.Server.Services;
|
||||||
|
|
||||||
|
public class YamlParser : IYamlParser
|
||||||
|
{
|
||||||
|
private readonly string _yamlFilePath = "rules.yaml";
|
||||||
|
|
||||||
|
public async Task<List<Rule>> GetRules()
|
||||||
|
{
|
||||||
|
if (!File.Exists(_yamlFilePath))
|
||||||
|
throw new FileNotFoundException($"YAML file not found: {_yamlFilePath}");
|
||||||
|
|
||||||
|
var yamlContent = await File.ReadAllTextAsync(_yamlFilePath).ConfigureAwait(false);
|
||||||
|
|
||||||
|
// Build the deserializer with explicit naming convention
|
||||||
|
var deserializer = new DeserializerBuilder()
|
||||||
|
.WithNamingConvention(UnderscoredNamingConvention.Instance) // maps api_key -> apiKey
|
||||||
|
.IgnoreUnmatchedProperties()
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
// Deserialize into a list of Rule
|
||||||
|
var rules = deserializer.Deserialize<List<Rule>>(yamlContent);
|
||||||
|
|
||||||
|
return rules ?? new List<Rule>();
|
||||||
|
}
|
||||||
|
}
|
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.0-preview.6.25358.103"/>
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.0-preview.6.25358.103"/>
|
||||||
|
<PackageReference Include="Vecc.YamlDotNet.Analyzers.StaticGenerator" Version="16.3.0" />
|
||||||
<PackageReference Include="YamlDotNet" Version="16.3.0" />
|
<PackageReference Include="YamlDotNet" Version="16.3.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
8
VirtualDDNSRouter.Server/rules.example.yaml
Normal file
8
VirtualDDNSRouter.Server/rules.example.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Rules:
|
||||||
|
- Name: "B"
|
||||||
|
ApiKey: "abc123XYZ"
|
||||||
|
Route: "B"
|
||||||
|
|
||||||
|
- Name: "A"
|
||||||
|
ApiKey: "def456ABC"
|
||||||
|
Route: "A"
|
Reference in New Issue
Block a user