More commands and an initial GH action

This commit is contained in:
Gervasio Marchand 2022-12-03 17:27:52 -03:00
parent a5346d1c61
commit cb02d954d1
No known key found for this signature in database
GPG Key ID: B7736CB188DD0A38
18 changed files with 143 additions and 94 deletions

32
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,32 @@
name: build
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0 # get entire git tree, required for nerdbank gitversioning
- name: Get version
shell: pwsh
run: |
cd src
$version = (nbgv get-version -f json | ConvertFrom-Json).SimpleVersion
Write-Host "Version $version"
Write-Output "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
# - name: Login to GitHub Container Registry
# uses: docker/login-action@v2
# with:
# registry: ghcr.io
# username: ${{ github.actor }}
# password: ${{ secrets.GITHUB_TOKEN }}
# - name: Build the hello-docker Docker image
# run: |
# docker build . --tag ghcr.io/g3rv4/fakerelay:latest
# docker run ghcr.io/deselikem/hello-docker-gcr-demo:latest
# docker push ghcr.io/deselikem/hello-docker-gcr-demo:latest

4
.gitignore vendored
View File

@ -5,8 +5,6 @@ obj/
*.csproj.user *.csproj.user
launchSettings.json launchSettings.json
.idea/ .idea/
config.json data/
config-tokens.json
.DS_Store .DS_Store
DataDir*
.build/ .build/

View File

@ -1,10 +1,11 @@
using FakeRelay.Cli.Settings;
using FakeRelay.Core.Helpers; using FakeRelay.Core.Helpers;
using Spectre.Console; using Spectre.Console;
using Spectre.Console.Cli; using Spectre.Console.Cli;
namespace FakeRelay.Cli.Commands; namespace FakeRelay.Cli.Commands;
public class AddHostCommand : AsyncCommand<HostSettings> public class AddHostCommand : ConfigEnabledAsyncCommand<HostSettings>
{ {
public override async Task<int> ExecuteAsync(CommandContext context, HostSettings settings) public override async Task<int> ExecuteAsync(CommandContext context, HostSettings settings)
{ {

View File

@ -0,0 +1,23 @@
using FakeRelay.Cli.Settings;
using FakeRelay.Core;
using FakeRelay.Core.Helpers;
using Spectre.Console.Cli;
namespace FakeRelay.Cli.Commands;
public class ConfigCommand: Command<ConfigSettings>
{
public override int Execute(CommandContext context, ConfigSettings settings)
{
var configPath = Environment.GetEnvironmentVariable("CONFIG_PATH");
if (File.Exists(configPath))
{
throw new Exception("There's a config file");
}
var (pub, priv) = CryptographyHelper.GenerateKeys();
Config.CreateConfig(configPath, settings.Host, pub, priv);
return 0;
}
}

View File

@ -0,0 +1,13 @@
using FakeRelay.Core;
using Spectre.Console.Cli;
namespace FakeRelay.Cli.Commands;
public abstract class ConfigEnabledAsyncCommand<T> : AsyncCommand<T>
where T : CommandSettings
{
protected ConfigEnabledAsyncCommand()
{
Config.Init(Environment.GetEnvironmentVariable("CONFIG_PATH"));
}
}

View File

@ -1,10 +1,11 @@
using FakeRelay.Cli.Settings;
using FakeRelay.Core.Helpers; using FakeRelay.Core.Helpers;
using Spectre.Console; using Spectre.Console;
using Spectre.Console.Cli; using Spectre.Console.Cli;
namespace FakeRelay.Cli.Commands; namespace FakeRelay.Cli.Commands;
public class DeleteHostCommand: AsyncCommand<HostSettings> public class DeleteHostCommand : ConfigEnabledAsyncCommand<HostSettings>
{ {
public override async Task<int> ExecuteAsync(CommandContext context, HostSettings settings) public override async Task<int> ExecuteAsync(CommandContext context, HostSettings settings)
{ {

View File

@ -1,10 +1,11 @@
using FakeRelay.Cli.Settings;
using FakeRelay.Core.Helpers; using FakeRelay.Core.Helpers;
using Spectre.Console; using Spectre.Console;
using Spectre.Console.Cli; using Spectre.Console.Cli;
namespace FakeRelay.Cli.Commands; namespace FakeRelay.Cli.Commands;
public class UpdateHostCommand : AsyncCommand<HostSettings> public class UpdateHostCommand : ConfigEnabledAsyncCommand<HostSettings>
{ {
public override async Task<int> ExecuteAsync(CommandContext context, HostSettings settings) public override async Task<int> ExecuteAsync(CommandContext context, HostSettings settings)
{ {
@ -13,4 +14,4 @@ public class UpdateHostCommand : AsyncCommand<HostSettings>
AnsiConsole.Markup($"[red]{token}[/]\n"); AnsiConsole.Markup($"[red]{token}[/]\n");
return 0; return 0;
} }
} }

View File

@ -1,15 +1,16 @@
using FakeRelay.Cli.Commands; using FakeRelay.Cli.Commands;
using FakeRelay.Core;
using Spectre.Console.Cli; using Spectre.Console.Cli;
var app = new CommandApp(); var app = new CommandApp();
app.Configure(config => app.Configure(config =>
{ {
config.AddCommand<AddHostCommand>("add-host"); config.AddCommand<AddHostCommand>("add-host")
.WithDescription("Adds a host to the relay and generates a key.")
.WithExample(new[] {"mastodon.social"});
config.AddCommand<UpdateHostCommand>("update-host"); config.AddCommand<UpdateHostCommand>("update-host");
config.AddCommand<DeleteHostCommand>("delete-host"); config.AddCommand<DeleteHostCommand>("delete-host");
config.AddCommand<ConfigCommand>("config");
}); });
Config.Init(Environment.GetEnvironmentVariable("CONFIG_PATH")); return app.Run(args);
return app.Run(args);

View File

@ -0,0 +1,11 @@
using System.ComponentModel;
using Spectre.Console.Cli;
namespace FakeRelay.Cli.Settings;
public class ConfigSettings : CommandSettings
{
[Description("The hostname of the relay.")]
[CommandArgument(0, "<HOST>")]
public string Host { get; set; }
}

View File

@ -1,9 +1,11 @@
using System.ComponentModel;
using Spectre.Console.Cli; using Spectre.Console.Cli;
namespace FakeRelay.Cli; namespace FakeRelay.Cli.Settings;
public class HostSettings : CommandSettings public class HostSettings : CommandSettings
{ {
[Description("The instance that connects to this fake relay.")]
[CommandArgument(0, "<HOST>")] [CommandArgument(0, "<HOST>")]
public string Host { get; set; } public string Host { get; set; }
} }

View File

@ -34,13 +34,27 @@ public class Config
throw new Exception("Missing config parameters"); throw new Exception("Missing config parameters");
} }
Instance = new Config(data.PublicKey, Convert.FromBase64String(data.PrivateKey), data.Host, path); using var rsa = RSA.Create();
rsa.ImportFromPem(data.PrivateKey.ToCharArray());
Instance = new Config(data.PublicKey, rsa.ExportRSAPrivateKey(), data.Host, path);
}
public static void CreateConfig(string path, string host, string publicKey, string privateKey)
{
if (File.Exists(path))
{
throw new Exception("Can't create a new config file, there's one at " + path);
}
var data = new ConfigData { Host = host, PublicKey = publicKey, PrivateKey = privateKey };
File.WriteAllText(path, JSON.Serialize(data));
} }
private class ConfigData private class ConfigData
{ {
public string? PublicKey { get; private set; } public string? PublicKey { get; set; }
public string? PrivateKey { get; private set; } public string? PrivateKey { get; set; }
public string? Host { get; private set; } public string? Host { get; set; }
} }
} }

View File

@ -21,4 +21,14 @@ public class CryptographyHelper
var signature = rsaProvider.SignData(Encoding.UTF8.GetBytes(stringToSign), sha256); var signature = rsaProvider.SignData(Encoding.UTF8.GetBytes(stringToSign), sha256);
return Convert.ToBase64String(signature); return Convert.ToBase64String(signature);
} }
}
public static (string publicKey, string privateKey) GenerateKeys()
{
using var rsa = RSA.Create(4096);
var pubKeyPem = new string(PemEncoding.Write("PUBLIC KEY", rsa.ExportSubjectPublicKeyInfo()));
var privKeyPem = new string(PemEncoding.Write("PRIVATE KEY", rsa.ExportPkcs8PrivateKey()));
return (pubKeyPem, privKeyPem);
}
}

View File

@ -1,3 +1,4 @@
using System.Threading.Tasks;
using FakeRelay.Core; using FakeRelay.Core;
using FakeRelay.Core.Helpers; using FakeRelay.Core.Helpers;
using FakeRelay.Web.Services; using FakeRelay.Web.Services;
@ -38,4 +39,4 @@ public class AcitivityPubController : Controller
StatusCode = 404 StatusCode = 404
}; };
} }
} }

View File

@ -1,4 +1,6 @@
using System;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Threading.Tasks;
using FakeRelay.Core.Helpers; using FakeRelay.Core.Helpers;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
@ -48,4 +50,4 @@ public class ApiController : Controller
var response = await MastodonHelper.EnqueueStatusToFetchAsync(host, statusUrl); var response = await MastodonHelper.EnqueueStatusToFetchAsync(host, statusUrl);
return Content(response, "application/activity+json"); return Content(response, "application/activity+json");
} }
} }

View File

@ -4,76 +4,6 @@
<ProjectReference Include="..\FakeRelay.Core\FakeRelay.Core.csproj" /> <ProjectReference Include="..\FakeRelay.Core\FakeRelay.Core.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<_ContentIncludedByDefault Remove="Views\Home\Index.cshtml" />
<_ContentIncludedByDefault Remove="Views\Home\Privacy.cshtml" />
<_ContentIncludedByDefault Remove="Views\Shared\Error.cshtml" />
<_ContentIncludedByDefault Remove="Views\Shared\_Layout.cshtml" />
<_ContentIncludedByDefault Remove="Views\Shared\_ValidationScriptsPartial.cshtml" />
<_ContentIncludedByDefault Remove="Views\_ViewImports.cshtml" />
<_ContentIncludedByDefault Remove="Views\_ViewStart.cshtml" />
<_ContentIncludedByDefault Remove="wwwroot\css\site.css" />
<_ContentIncludedByDefault Remove="wwwroot\favicon.ico" />
<_ContentIncludedByDefault Remove="wwwroot\js\site.js" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-grid.css" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-grid.css.map" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-grid.min.css" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-grid.min.css.map" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-grid.rtl.css" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-grid.rtl.css.map" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-grid.rtl.min.css" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-grid.rtl.min.css.map" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.css" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.css.map" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.min.css" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.min.css.map" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.rtl.css" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.rtl.css.map" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.rtl.min.css" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.rtl.min.css.map" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.css" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.css.map" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.min.css" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.min.css.map" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.rtl.css" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.rtl.css.map" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.rtl.min.css" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.rtl.min.css.map" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap.css" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap.css.map" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap.min.css" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap.min.css.map" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap.rtl.css" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap.rtl.css.map" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap.rtl.min.css" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap.rtl.min.css.map" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.bundle.js" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.bundle.js.map" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.bundle.min.js" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.bundle.min.js.map" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.esm.js" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.esm.js.map" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.esm.min.js" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.esm.min.js.map" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.js" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.js.map" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.min.js" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.min.js.map" />
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\LICENSE" />
<_ContentIncludedByDefault Remove="wwwroot\lib\jquery-validation-unobtrusive\jquery.validate.unobtrusive.js" />
<_ContentIncludedByDefault Remove="wwwroot\lib\jquery-validation-unobtrusive\jquery.validate.unobtrusive.min.js" />
<_ContentIncludedByDefault Remove="wwwroot\lib\jquery-validation-unobtrusive\LICENSE.txt" />
<_ContentIncludedByDefault Remove="wwwroot\lib\jquery-validation\dist\additional-methods.js" />
<_ContentIncludedByDefault Remove="wwwroot\lib\jquery-validation\dist\additional-methods.min.js" />
<_ContentIncludedByDefault Remove="wwwroot\lib\jquery-validation\dist\jquery.validate.js" />
<_ContentIncludedByDefault Remove="wwwroot\lib\jquery-validation\dist\jquery.validate.min.js" />
<_ContentIncludedByDefault Remove="wwwroot\lib\jquery-validation\LICENSE.md" />
<_ContentIncludedByDefault Remove="wwwroot\lib\jquery\dist\jquery.js" />
<_ContentIncludedByDefault Remove="wwwroot\lib\jquery\dist\jquery.min.js" />
<_ContentIncludedByDefault Remove="wwwroot\lib\jquery\dist\jquery.min.map" />
<_ContentIncludedByDefault Remove="wwwroot\lib\jquery\LICENSE.txt" />
</ItemGroup>
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>

View File

@ -1,6 +1,10 @@
using FakeRelay.Core; using FakeRelay.Core;
using FakeRelay.Web.Services; using FakeRelay.Web.Services;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
Config.Init(builder.Configuration.GetValue<string>("CONFIG_PATH")); Config.Init(builder.Configuration.GetValue<string>("CONFIG_PATH"));

View File

@ -1,4 +1,9 @@
using System;
using System.Threading;
using System.Threading.Channels; using System.Threading.Channels;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace FakeRelay.Web.Services; namespace FakeRelay.Web.Services;
@ -94,4 +99,4 @@ public class QueuedHostedService : BackgroundService
await base.StopAsync(stoppingToken); await base.StopAsync(stoppingToken);
} }
} }

View File

@ -1,6 +1,6 @@
{ {
"$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
"version": "1.1", "version": "1.0",
"publicReleaseRefSpec": [ "publicReleaseRefSpec": [
"^refs/heads/main$", "^refs/heads/main$",
"^refs/heads/v\\d+(?:\\.\\d+)?$" "^refs/heads/v\\d+(?:\\.\\d+)?$"