From cb02d954d13c23560b674c65a2889e08c2112aed Mon Sep 17 00:00:00 2001 From: Gervasio Marchand Date: Sat, 3 Dec 2022 17:27:52 -0300 Subject: [PATCH] More commands and an initial GH action --- .github/workflows/build.yml | 32 +++++++++ .gitignore | 4 +- src/FakeRelay.Cli/Commands/AddHostCommand.cs | 3 +- src/FakeRelay.Cli/Commands/ConfigCommand.cs | 23 ++++++ .../Commands/ConfigEnabledAsyncCommand.cs | 13 ++++ .../Commands/DeleteHostCommand.cs | 3 +- .../Commands/UpdateHostCommand.cs | 5 +- src/FakeRelay.Cli/Program.cs | 11 +-- src/FakeRelay.Cli/Settings/ConfigSettings.cs | 11 +++ .../{ => Settings}/HostSettings.cs | 6 +- src/FakeRelay.Core/Config.cs | 24 +++++-- .../Helpers/CryptographyHelper.cs | 12 +++- .../Controllers/AcitivityPubController.cs | 3 +- .../Controllers/ApiController.cs | 4 +- src/FakeRelay.Web/FakeRelay.Web.csproj | 70 ------------------- src/FakeRelay.Web/Program.cs | 4 ++ .../Services/QueuedHostedService.cs | 7 +- src/version.json | 2 +- 18 files changed, 143 insertions(+), 94 deletions(-) create mode 100644 .github/workflows/build.yml create mode 100644 src/FakeRelay.Cli/Commands/ConfigCommand.cs create mode 100644 src/FakeRelay.Cli/Commands/ConfigEnabledAsyncCommand.cs create mode 100644 src/FakeRelay.Cli/Settings/ConfigSettings.cs rename src/FakeRelay.Cli/{ => Settings}/HostSettings.cs (52%) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..6829601 --- /dev/null +++ b/.github/workflows/build.yml @@ -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 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 8d38503..9c6c24c 100644 --- a/.gitignore +++ b/.gitignore @@ -5,8 +5,6 @@ obj/ *.csproj.user launchSettings.json .idea/ -config.json -config-tokens.json +data/ .DS_Store -DataDir* .build/ \ No newline at end of file diff --git a/src/FakeRelay.Cli/Commands/AddHostCommand.cs b/src/FakeRelay.Cli/Commands/AddHostCommand.cs index 5dde2aa..41255b4 100644 --- a/src/FakeRelay.Cli/Commands/AddHostCommand.cs +++ b/src/FakeRelay.Cli/Commands/AddHostCommand.cs @@ -1,10 +1,11 @@ +using FakeRelay.Cli.Settings; using FakeRelay.Core.Helpers; using Spectre.Console; using Spectre.Console.Cli; namespace FakeRelay.Cli.Commands; -public class AddHostCommand : AsyncCommand +public class AddHostCommand : ConfigEnabledAsyncCommand { public override async Task ExecuteAsync(CommandContext context, HostSettings settings) { diff --git a/src/FakeRelay.Cli/Commands/ConfigCommand.cs b/src/FakeRelay.Cli/Commands/ConfigCommand.cs new file mode 100644 index 0000000..2f36dda --- /dev/null +++ b/src/FakeRelay.Cli/Commands/ConfigCommand.cs @@ -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 +{ + 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; + } +} diff --git a/src/FakeRelay.Cli/Commands/ConfigEnabledAsyncCommand.cs b/src/FakeRelay.Cli/Commands/ConfigEnabledAsyncCommand.cs new file mode 100644 index 0000000..324203f --- /dev/null +++ b/src/FakeRelay.Cli/Commands/ConfigEnabledAsyncCommand.cs @@ -0,0 +1,13 @@ +using FakeRelay.Core; +using Spectre.Console.Cli; + +namespace FakeRelay.Cli.Commands; + +public abstract class ConfigEnabledAsyncCommand : AsyncCommand + where T : CommandSettings +{ + protected ConfigEnabledAsyncCommand() + { + Config.Init(Environment.GetEnvironmentVariable("CONFIG_PATH")); + } +} diff --git a/src/FakeRelay.Cli/Commands/DeleteHostCommand.cs b/src/FakeRelay.Cli/Commands/DeleteHostCommand.cs index 9598159..d774549 100644 --- a/src/FakeRelay.Cli/Commands/DeleteHostCommand.cs +++ b/src/FakeRelay.Cli/Commands/DeleteHostCommand.cs @@ -1,10 +1,11 @@ +using FakeRelay.Cli.Settings; using FakeRelay.Core.Helpers; using Spectre.Console; using Spectre.Console.Cli; namespace FakeRelay.Cli.Commands; -public class DeleteHostCommand: AsyncCommand +public class DeleteHostCommand : ConfigEnabledAsyncCommand { public override async Task ExecuteAsync(CommandContext context, HostSettings settings) { diff --git a/src/FakeRelay.Cli/Commands/UpdateHostCommand.cs b/src/FakeRelay.Cli/Commands/UpdateHostCommand.cs index eba8a58..5957d6c 100644 --- a/src/FakeRelay.Cli/Commands/UpdateHostCommand.cs +++ b/src/FakeRelay.Cli/Commands/UpdateHostCommand.cs @@ -1,10 +1,11 @@ +using FakeRelay.Cli.Settings; using FakeRelay.Core.Helpers; using Spectre.Console; using Spectre.Console.Cli; namespace FakeRelay.Cli.Commands; -public class UpdateHostCommand : AsyncCommand +public class UpdateHostCommand : ConfigEnabledAsyncCommand { public override async Task ExecuteAsync(CommandContext context, HostSettings settings) { @@ -13,4 +14,4 @@ public class UpdateHostCommand : AsyncCommand AnsiConsole.Markup($"[red]{token}[/]\n"); return 0; } -} \ No newline at end of file +} diff --git a/src/FakeRelay.Cli/Program.cs b/src/FakeRelay.Cli/Program.cs index fd4484a..4bdbfc3 100644 --- a/src/FakeRelay.Cli/Program.cs +++ b/src/FakeRelay.Cli/Program.cs @@ -1,15 +1,16 @@ using FakeRelay.Cli.Commands; -using FakeRelay.Core; using Spectre.Console.Cli; var app = new CommandApp(); app.Configure(config => { - config.AddCommand("add-host"); + config.AddCommand("add-host") + .WithDescription("Adds a host to the relay and generates a key.") + .WithExample(new[] {"mastodon.social"}); + config.AddCommand("update-host"); config.AddCommand("delete-host"); + config.AddCommand("config"); }); -Config.Init(Environment.GetEnvironmentVariable("CONFIG_PATH")); - -return app.Run(args); \ No newline at end of file +return app.Run(args); diff --git a/src/FakeRelay.Cli/Settings/ConfigSettings.cs b/src/FakeRelay.Cli/Settings/ConfigSettings.cs new file mode 100644 index 0000000..51fd350 --- /dev/null +++ b/src/FakeRelay.Cli/Settings/ConfigSettings.cs @@ -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, "")] + public string Host { get; set; } +} diff --git a/src/FakeRelay.Cli/HostSettings.cs b/src/FakeRelay.Cli/Settings/HostSettings.cs similarity index 52% rename from src/FakeRelay.Cli/HostSettings.cs rename to src/FakeRelay.Cli/Settings/HostSettings.cs index 7543675..4ef44ab 100644 --- a/src/FakeRelay.Cli/HostSettings.cs +++ b/src/FakeRelay.Cli/Settings/HostSettings.cs @@ -1,9 +1,11 @@ +using System.ComponentModel; using Spectre.Console.Cli; -namespace FakeRelay.Cli; +namespace FakeRelay.Cli.Settings; public class HostSettings : CommandSettings { + [Description("The instance that connects to this fake relay.")] [CommandArgument(0, "")] public string Host { get; set; } -} \ No newline at end of file +} diff --git a/src/FakeRelay.Core/Config.cs b/src/FakeRelay.Core/Config.cs index f6cfb52..c92d123 100644 --- a/src/FakeRelay.Core/Config.cs +++ b/src/FakeRelay.Core/Config.cs @@ -34,13 +34,27 @@ public class Config 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 { - public string? PublicKey { get; private set; } - public string? PrivateKey { get; private set; } - public string? Host { get; private set; } + public string? PublicKey { get; set; } + public string? PrivateKey { get; set; } + public string? Host { get; set; } } -} \ No newline at end of file +} diff --git a/src/FakeRelay.Core/Helpers/CryptographyHelper.cs b/src/FakeRelay.Core/Helpers/CryptographyHelper.cs index 7dcd471..441292c 100644 --- a/src/FakeRelay.Core/Helpers/CryptographyHelper.cs +++ b/src/FakeRelay.Core/Helpers/CryptographyHelper.cs @@ -21,4 +21,14 @@ public class CryptographyHelper var signature = rsaProvider.SignData(Encoding.UTF8.GetBytes(stringToSign), sha256); return Convert.ToBase64String(signature); } -} \ No newline at end of file + + 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); + } +} diff --git a/src/FakeRelay.Web/Controllers/AcitivityPubController.cs b/src/FakeRelay.Web/Controllers/AcitivityPubController.cs index a569193..6e02867 100644 --- a/src/FakeRelay.Web/Controllers/AcitivityPubController.cs +++ b/src/FakeRelay.Web/Controllers/AcitivityPubController.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using FakeRelay.Core; using FakeRelay.Core.Helpers; using FakeRelay.Web.Services; @@ -38,4 +39,4 @@ public class AcitivityPubController : Controller StatusCode = 404 }; } -} \ No newline at end of file +} diff --git a/src/FakeRelay.Web/Controllers/ApiController.cs b/src/FakeRelay.Web/Controllers/ApiController.cs index f4631ae..d344d8e 100644 --- a/src/FakeRelay.Web/Controllers/ApiController.cs +++ b/src/FakeRelay.Web/Controllers/ApiController.cs @@ -1,4 +1,6 @@ +using System; using System.Collections.Immutable; +using System.Threading.Tasks; using FakeRelay.Core.Helpers; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Memory; @@ -48,4 +50,4 @@ public class ApiController : Controller var response = await MastodonHelper.EnqueueStatusToFetchAsync(host, statusUrl); return Content(response, "application/activity+json"); } -} \ No newline at end of file +} diff --git a/src/FakeRelay.Web/FakeRelay.Web.csproj b/src/FakeRelay.Web/FakeRelay.Web.csproj index e33ab3b..a3cf4d0 100644 --- a/src/FakeRelay.Web/FakeRelay.Web.csproj +++ b/src/FakeRelay.Web/FakeRelay.Web.csproj @@ -4,76 +4,6 @@ - - <_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" /> - - net6.0 enable diff --git a/src/FakeRelay.Web/Program.cs b/src/FakeRelay.Web/Program.cs index 332f894..41b14ab 100644 --- a/src/FakeRelay.Web/Program.cs +++ b/src/FakeRelay.Web/Program.cs @@ -1,6 +1,10 @@ using FakeRelay.Core; using FakeRelay.Web.Services; +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.HttpOverrides; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; var builder = WebApplication.CreateBuilder(args); Config.Init(builder.Configuration.GetValue("CONFIG_PATH")); diff --git a/src/FakeRelay.Web/Services/QueuedHostedService.cs b/src/FakeRelay.Web/Services/QueuedHostedService.cs index 0ccbe1a..abf4453 100644 --- a/src/FakeRelay.Web/Services/QueuedHostedService.cs +++ b/src/FakeRelay.Web/Services/QueuedHostedService.cs @@ -1,4 +1,9 @@ +using System; +using System.Threading; using System.Threading.Channels; +using System.Threading.Tasks; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; namespace FakeRelay.Web.Services; @@ -94,4 +99,4 @@ public class QueuedHostedService : BackgroundService await base.StopAsync(stoppingToken); } -} \ No newline at end of file +} diff --git a/src/version.json b/src/version.json index 798813c..be8e5de 100644 --- a/src/version.json +++ b/src/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "1.1", + "version": "1.0", "publicReleaseRefSpec": [ "^refs/heads/main$", "^refs/heads/v\\d+(?:\\.\\d+)?$"