Skip to content

Commit

Permalink
Merge pull request #131 from fiskaltrust/update-system-commandline
Browse files Browse the repository at this point in the history
Update system commandline
  • Loading branch information
volllly authored Nov 8, 2023
2 parents 4467d1c + 7131a79 commit 45ea3d2
Show file tree
Hide file tree
Showing 13 changed files with 557 additions and 400 deletions.
26 changes: 22 additions & 4 deletions src/fiskaltrust.Launcher.Common/Configuration/Converters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,28 @@

namespace fiskaltrust.Launcher.Common.Configuration
{
public class SemVersionConverter : JsonConverter<SemanticVersioning.Range>
public class SemVersionConverter : JsonConverter<SemanticVersioning.Range?>
{
public override SemanticVersioning.Range Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => new(reader.GetString());

public override void Write(Utf8JsonWriter writer, SemanticVersioning.Range semVersionValue, JsonSerializerOptions options) => writer.WriteStringValue(semVersionValue.ToString());
public override SemanticVersioning.Range? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var value = reader.GetString();
if (string.IsNullOrEmpty(value))
{
return null;
}
return new(value);
}
public override void Write(Utf8JsonWriter writer, SemanticVersioning.Range? semVersionValue, JsonSerializerOptions options)
{
var value = semVersionValue?.ToString();
if (string.IsNullOrEmpty(value))
{
writer.WriteNullValue();
}
else
{
writer.WriteStringValue(value);
}
}
}
}
10 changes: 10 additions & 0 deletions src/fiskaltrust.Launcher.Common/Constants/Paths.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ public static string ServiceFolder
get => Path.Combine(CommonFolder, "fiskaltrust");
}

public static string LauncherConfigurationFileName
{
get => "launcher.configuration.json";
}

public static string LegacyConfigurationFileName
{
get => "fiskaltrust.exe.config";
}

public static string CommonFolder
{
get
Expand Down
126 changes: 72 additions & 54 deletions src/fiskaltrust.Launcher/Commands/Common.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.CommandLine.Invocation;
using System.Security.Cryptography;
using fiskaltrust.Launcher.Common.Configuration;
using fiskaltrust.Launcher.Common.Constants;
using fiskaltrust.Launcher.Common.Extensions;
using fiskaltrust.Launcher.Configuration;
using fiskaltrust.Launcher.Download;
Expand Down Expand Up @@ -33,96 +34,111 @@ public CommonCommand(string name, bool addCliOnlyParameters = true) : base(name)

if (addCliOnlyParameters)
{
AddOption(new Option<string>("--launcher-configuration-file", getDefaultValue: () => "launcher.configuration.json"));
AddOption(new Option<string>("--legacy-configuration-file", getDefaultValue: () => "fiskaltrust.exe.config"));
AddOption(new Option<string>("--launcher-configuration-file", getDefaultValue: () => Paths.LauncherConfigurationFileName));
AddOption(new Option<string>("--legacy-configuration-file", getDefaultValue: () => Paths.LegacyConfigurationFileName));
AddOption(new Option<bool>("--merge-legacy-config-if-exists", getDefaultValue: () => true));
}
}
}

public class CommonCommandHandler : ICommandHandler
public class CommonOptions
{
private LauncherConfiguration _argsLauncherConfiguration = null!;
public LauncherConfiguration ArgsLauncherConfiguration
public CommonOptions(LauncherConfiguration argsLauncherConfiguration, string launcherConfigurationFile, string legacyConfigurationFile, bool mergeLegacyConfigIfExists)
{
get => _argsLauncherConfiguration;
set
{
_argsLauncherConfiguration = value;
_argsLauncherConfiguration.LauncherVersion = null;
}
ArgsLauncherConfiguration = argsLauncherConfiguration;
LauncherConfigurationFile = launcherConfigurationFile;
LegacyConfigurationFile = legacyConfigurationFile;
MergeLegacyConfigIfExists = mergeLegacyConfigIfExists;
}

public string LauncherConfigurationFile { get; set; } = null!;
public string LegacyConfigurationFile { get; set; } = null!;
public LauncherConfiguration ArgsLauncherConfiguration { get; set; }
public string LauncherConfigurationFile { get; set; }
public string LegacyConfigurationFile { get; set; }
public bool MergeLegacyConfigIfExists { get; set; }
}

protected LauncherConfiguration _launcherConfiguration = null!;
protected ftCashBoxConfiguration _cashboxConfiguration = null!;
protected ECDiffieHellman _clientEcdh = null!;
public record CommonProperties
{
public CommonProperties(LauncherConfiguration launcherConfiguration, ftCashBoxConfiguration cashboxConfiguration, ECDiffieHellman clientEcdh, IDataProtectionProvider dataProtectionProvider)
{
LauncherConfiguration = launcherConfiguration;
CashboxConfiguration = cashboxConfiguration;
ClientEcdh = clientEcdh;
DataProtectionProvider = dataProtectionProvider;
}

protected IDataProtectionProvider _dataProtectionProvider = null!;
public LauncherConfiguration LauncherConfiguration { get; set; }
public ftCashBoxConfiguration CashboxConfiguration { get; set; }
public ECDiffieHellman ClientEcdh { get; set; }
public IDataProtectionProvider DataProtectionProvider { get; set; }
}

public async Task<int> InvokeAsync(InvocationContext context)
public static class CommonHandler
{
public static async Task<int> HandleAsync<O, S>(
CommonOptions options,
O specificOptions,
IHost host,
Func<CommonOptions, CommonProperties, O, S, Task<int>> handler) where S : notnull
{
var collectionSink = new CollectionSink();
Log.Logger = new LoggerConfiguration()
.WriteTo.Sink(collectionSink)
.CreateLogger();

_launcherConfiguration = new LauncherConfiguration();
var launcherConfiguration = new LauncherConfiguration();

Log.Verbose("Reading launcher config file.");
try
{
LauncherConfigurationFile = Path.GetFullPath(LauncherConfigurationFile);
_launcherConfiguration = LauncherConfiguration.Deserialize(await File.ReadAllTextAsync(LauncherConfigurationFile));
options.LauncherConfigurationFile = Path.GetFullPath(options.LauncherConfigurationFile);
launcherConfiguration = LauncherConfiguration.Deserialize(await File.ReadAllTextAsync(options.LauncherConfigurationFile));
}
catch (Exception e)
{
if (!(MergeLegacyConfigIfExists && File.Exists(LegacyConfigurationFile)))
if (!(options.MergeLegacyConfigIfExists && File.Exists(options.LegacyConfigurationFile)))
{
if (File.Exists(LauncherConfigurationFile))
if (File.Exists(options.LauncherConfigurationFile))
{
Log.Warning(e, "Could not parse launcher configuration file \"{LauncherConfigurationFile}\".", LauncherConfigurationFile);
Log.Warning(e, "Could not parse launcher configuration file \"{LauncherConfigurationFile}\".", options.LauncherConfigurationFile);
}
else
{
Log.Warning("Launcher configuration file \"{LauncherConfigurationFile}\" does not exist.", LauncherConfigurationFile);
Log.Warning("Launcher configuration file \"{LauncherConfigurationFile}\" does not exist.", options.LauncherConfigurationFile);
}
Log.Warning("Using command line parameters only.", LauncherConfigurationFile);
Log.Warning("Using command line parameters only.", options.LauncherConfigurationFile);
}
}
Log.Verbose("Merging legacy launcher config file.");
if (MergeLegacyConfigIfExists && File.Exists(LegacyConfigurationFile))
if (options.MergeLegacyConfigIfExists && File.Exists(options.LegacyConfigurationFile))
{
var legacyConfig = await LegacyConfigFileReader.ReadLegacyConfigFile(LegacyConfigurationFile);
_launcherConfiguration.OverwriteWith(legacyConfig);
var legacyConfig = await LegacyConfigFileReader.ReadLegacyConfigFile(options.LegacyConfigurationFile);
launcherConfiguration.OverwriteWith(legacyConfig);

var configFileDirectory = Path.GetDirectoryName(Path.GetFullPath(LauncherConfigurationFile));
var configFileDirectory = Path.GetDirectoryName(Path.GetFullPath(options.LauncherConfigurationFile));
if (configFileDirectory is not null)
{
Directory.CreateDirectory(configFileDirectory);
}

await File.WriteAllTextAsync(LauncherConfigurationFile, legacyConfig.Serialize());
await File.WriteAllTextAsync(options.LauncherConfigurationFile, legacyConfig.Serialize());

var fi = new FileInfo(LegacyConfigurationFile);
fi.CopyTo(LegacyConfigurationFile + ".legacy");
var fi = new FileInfo(options.LegacyConfigurationFile);
fi.CopyTo(options.LegacyConfigurationFile + ".legacy");
fi.Delete();
}

Log.Verbose("Merging launcher cli args.");
_launcherConfiguration.OverwriteWith(ArgsLauncherConfiguration);
launcherConfiguration.OverwriteWith(options.ArgsLauncherConfiguration);

if (!_launcherConfiguration.UseOffline!.Value && (_launcherConfiguration.CashboxId is null || _launcherConfiguration.AccessToken is null))
if (!launcherConfiguration.UseOffline!.Value && (launcherConfiguration.CashboxId is null || launcherConfiguration.AccessToken is null))
{
Log.Error("CashBoxId and AccessToken are not provided.");
}

try
{
var configFileDirectory = Path.GetDirectoryName(_launcherConfiguration.CashboxConfigurationFile);
var configFileDirectory = Path.GetDirectoryName(launcherConfiguration.CashboxConfigurationFile);
if (configFileDirectory is not null)
{
Directory.CreateDirectory(configFileDirectory);
Expand All @@ -133,22 +149,22 @@ public async Task<int> InvokeAsync(InvocationContext context)
Log.Error(e, "Could not create cashbox-configuration-file folder.");
}

_clientEcdh = await LoadCurve(_launcherConfiguration.AccessToken!, _launcherConfiguration.UseOffline!.Value);
var clientEcdh = await LoadCurve(launcherConfiguration.AccessToken!, launcherConfiguration.UseOffline!.Value);

try
{
using var downloader = new ConfigurationDownloader(_launcherConfiguration);
var exists = await downloader.DownloadConfigurationAsync(_clientEcdh);
if (_launcherConfiguration.UseOffline!.Value && !exists)
using var downloader = new ConfigurationDownloader(launcherConfiguration);
var exists = await downloader.DownloadConfigurationAsync(clientEcdh);
if (launcherConfiguration.UseOffline!.Value && !exists)
{
Log.Warning("Cashbox configuration was not downloaded because UseOffline is set.");
}
}
catch (Exception e)
{
var message = "Could not download Cashbox configuration. ";
message += $"(Launcher is running in {(_launcherConfiguration.Sandbox!.Value ? "sandbox" : "production")} mode.";
if (!_launcherConfiguration.Sandbox!.Value)
message += $"(Launcher is running in {(launcherConfiguration.Sandbox!.Value ? "sandbox" : "production")} mode.";
if (!launcherConfiguration.Sandbox!.Value)
{
message += " Did you forget the --sandbox flag?";
}
Expand All @@ -158,27 +174,28 @@ public async Task<int> InvokeAsync(InvocationContext context)

try
{
var cashboxConfigurationFile = _launcherConfiguration.CashboxConfigurationFile!;
_launcherConfiguration.OverwriteWith(LauncherConfigurationInCashBoxConfiguration.Deserialize(await File.ReadAllTextAsync(cashboxConfigurationFile)));
var cashboxConfigurationFile = launcherConfiguration.CashboxConfigurationFile!;
launcherConfiguration.OverwriteWith(LauncherConfigurationInCashBoxConfiguration.Deserialize(await File.ReadAllTextAsync(cashboxConfigurationFile)));
}
catch (Exception e)
{
Log.Fatal(e, "Could not read Cashbox configuration file.");
}

var cashboxConfiguration = new ftCashBoxConfiguration();
try
{
_cashboxConfiguration = CashBoxConfigurationExt.Deserialize(await File.ReadAllTextAsync(_launcherConfiguration.CashboxConfigurationFile!));
_cashboxConfiguration.Decrypt(_launcherConfiguration, _clientEcdh);
cashboxConfiguration = CashBoxConfigurationExt.Deserialize(await File.ReadAllTextAsync(launcherConfiguration.CashboxConfigurationFile!));
cashboxConfiguration.Decrypt(launcherConfiguration, clientEcdh);
}
catch (Exception e)
{
Log.Fatal(e, "Could not parse Cashbox configuration.");
}

Log.Logger = new LoggerConfiguration()
.AddLoggingConfiguration(_launcherConfiguration)
.AddFileLoggingConfiguration(_launcherConfiguration, new[] { "fiskaltrust.Launcher", _launcherConfiguration.CashboxId?.ToString() })
.AddLoggingConfiguration(launcherConfiguration)
.AddFileLoggingConfiguration(launcherConfiguration, new[] { "fiskaltrust.Launcher", launcherConfiguration.CashboxId?.ToString() })
.Enrich.FromLogContext()
.CreateLogger();

Expand All @@ -192,22 +209,23 @@ public async Task<int> InvokeAsync(InvocationContext context)
return 1;
}

Log.Debug("Launcher Configuration File: {LauncherConfigurationFile}", LauncherConfigurationFile);
Log.Debug("Cashbox Configuration File: {CashboxConfigurationFile}", _launcherConfiguration.CashboxConfigurationFile);
Log.Debug("Launcher Configuration: {@LauncherConfiguration}", _launcherConfiguration.Redacted());
Log.Debug("Launcher Configuration File: {LauncherConfigurationFile}", options.LauncherConfigurationFile);
Log.Debug("Cashbox Configuration File: {CashboxConfigurationFile}", launcherConfiguration.CashboxConfigurationFile);
Log.Debug("Launcher Configuration: {@LauncherConfiguration}", launcherConfiguration.Redacted());


_dataProtectionProvider = DataProtectionExtensions.Create(_launcherConfiguration.AccessToken, useFallback: _launcherConfiguration.UseLegacyDataProtection!.Value);
var dataProtectionProvider = DataProtectionExtensions.Create(launcherConfiguration.AccessToken, useFallback: launcherConfiguration.UseLegacyDataProtection!.Value);

try
{
_launcherConfiguration.Decrypt(_dataProtectionProvider.CreateProtector(LauncherConfiguration.DATA_PROTECTION_DATA_PURPOSE));
launcherConfiguration.Decrypt(dataProtectionProvider.CreateProtector(LauncherConfiguration.DATA_PROTECTION_DATA_PURPOSE));
}
catch (Exception e)
{
Log.Warning(e, "Error decrypring launcher configuration file.");
}
return 0;

return await handler(options, new CommonProperties(launcherConfiguration, cashboxConfiguration, clientEcdh, dataProtectionProvider), specificOptions, host.Services.GetRequiredService<S>());
}

public static async Task<ECDiffieHellman> LoadCurve(string accessToken, bool useOffline = false, bool dryRun = false, bool useFallback = false)
Expand Down
Loading

0 comments on commit 45ea3d2

Please sign in to comment.