Skip to content

Commit

Permalink
Merge pull request #16 from MewsSystems/console-improvements
Browse files Browse the repository at this point in the history
Improved general parts of the code and the CLI input/output
  • Loading branch information
abdallahbeshi authored Aug 6, 2024
2 parents 18d0b09 + d58568f commit be258d6
Show file tree
Hide file tree
Showing 20 changed files with 173 additions and 177 deletions.
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ This is a tool that can be used to verify the signature of the French fiscal arc

### Usage

```Mews.Fiscalization.SignatureChecker.exe --<path-to-archive> --<environment>```
After downloading the latest version of the tool and extracting it:
Windows: run ```Mews.Fiscalization.SignatureChecker.exe``` then provide the path to the ZIP archive and the environment for which the signature should be verified.
Command example: ```2025.zip --production``` or ```2025.zip --develop```

Mac: run ```chmod +x Mews.Fiscalization.SignatureChecker``` then provide the path to the ZIP archive and the environment for which the signature should be verified.
Command example: ```2025.zip --production``` or ```2025.zip --develop```

### Parameters

Expand All @@ -15,8 +20,4 @@ This is a tool that can be used to verify the signature of the French fiscal arc

### Output

The tool will output the result of the signature verification. If the signature is valid, the tool will output `Archive signature is valid.`. If the signature is invalid, the tool will output `Archive signature is invalid.`.

### Example

```Mews.Fiscalization.SignatureChecker.exe --C:\path\to\archive.zip --develop```
The tool will output the result of the signature verification. If the signature is valid, the tool will output `Archive signature is valid.`. If the signature is invalid, the tool will output `Archive signature is invalid.`.
4 changes: 2 additions & 2 deletions src/CryptoServiceProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ namespace Mews.Fiscalization.SignatureChecker;

public static class CryptoServiceProvider
{
private static readonly string ProductionKey = "<RSAKeyValue><Modulus>1NWh/S4jzrtO/N3Dm1gkfaok0A/u04/pExwDES2SmubDSeFwssXGBqWZ4UsIONKXdXkDrJ1kqgednDjkdkCYW6BmYr/Ds1U+3viiZtl6nBaJp2MTGLSGDR/9algLOYr60bk/18KJFbr2xzKMadimrQ5J2p0LVkfPvIcX0d69xbei0Kzn5bFOKlA3WgimOdh9ed9ZZ7IEylVVQQG6dWElWbbMgDiOzwyGiPn7/9Tb+oh6zxBiazc5/HpACC/RBpr85aIJQtXgDTK4mlwjrL/WHoAHyehwQSJ08QsRyd/tux8QxBZDk4hWoipC8W+tlyFg4n/n79AuxQX0TaOmMQFjm4hVVX3cS34zmELpGsZiH2uMtGJqgehchlF+FSE/12v2p9sEesPLANEmajjChmajQgvbnlS/SSPc/gd2FYb0pq8jLM/90idOKKMx7ZbxS/8yro8VbS79VR8UdMKRzJLFDbHeDa0hVVbaSWR8jodnp7gPd55SIZ47AcDrpKNQ4s9R1Ah38Czq/QKInCkNjTCC+JdxrF+XnqsUFL5DbOUDbxDzVq0TJj36xMC/LICcIbTmt7rg0auqXq4RhG6lnwyCpUaUr5YZ4pJm44kA94Zgy+o/7wpqYhYayGIZqu1VgK82gBs5m5uPXHiTFfb4cZzCZG356I8nzr2LQjTe4hXDaRE=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
private static readonly string DevelopKey = "<RSAKeyValue><Modulus>ufmEzn3l/SsD01uvqILxYTEy8XV47r/uMD4sOZ07J4P0kx73LBcbMx+Gag4T9nYzTs0KmBPl6ogSdqA1hsJQ0BBlKFVZK53WTe1GjtXVPyhyuvfTd6pXPuW7ozBcd0xuHU5qhBY4TEjrbRZoSMHLMDsQB4Egdx+H5Y4T9TXSri7yraxUUqNNET5zU1mpxJqC3R6M6UcBiMagNYvcrL/iWLLvfhC3pjFmBiS/0rxAU5TRiWumwlFrkUpt7/dUMBDD1Adt1/nPEA5IZBscoFQWQGi1tCpzs1K71nJF04BgrALpetf3KYucrbiY85ANIAjE8pvDaYQVOSg5xIRIUVkd92uA8dFc2QRd6EL7wxZ6u3y5FsTm9ILaEfc54MlSVWx2E+bTvBL2jK1Pz+hSNBOWnRJbAJFWuToCGOykkyHOqQwmPX5MhbJ5q3qYh//E8D2SeJqc1Nr3NDaUNhJf1gkkr53yN+kbF9M2+xqn8p1jV6BUjQI+qDYeTyuBVgxEz5+H0xEyrSZ5DDjm9HsxXhzdXhHK7HDtvrSjgAr4HGmSODCuWpynzjGdNVEANsfpjT//zhgGEkW0JHiRmXjRbNslmspeW7xG5/uOxlZIFVahM0n544hoQbZx9mYcNMDkuT6d9wgjFEKAXVzn+45gPZ627eeVCF3pbAJCSx5EVPJfZGU=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
private const string ProductionKey = "<RSAKeyValue><Modulus>1NWh/S4jzrtO/N3Dm1gkfaok0A/u04/pExwDES2SmubDSeFwssXGBqWZ4UsIONKXdXkDrJ1kqgednDjkdkCYW6BmYr/Ds1U+3viiZtl6nBaJp2MTGLSGDR/9algLOYr60bk/18KJFbr2xzKMadimrQ5J2p0LVkfPvIcX0d69xbei0Kzn5bFOKlA3WgimOdh9ed9ZZ7IEylVVQQG6dWElWbbMgDiOzwyGiPn7/9Tb+oh6zxBiazc5/HpACC/RBpr85aIJQtXgDTK4mlwjrL/WHoAHyehwQSJ08QsRyd/tux8QxBZDk4hWoipC8W+tlyFg4n/n79AuxQX0TaOmMQFjm4hVVX3cS34zmELpGsZiH2uMtGJqgehchlF+FSE/12v2p9sEesPLANEmajjChmajQgvbnlS/SSPc/gd2FYb0pq8jLM/90idOKKMx7ZbxS/8yro8VbS79VR8UdMKRzJLFDbHeDa0hVVbaSWR8jodnp7gPd55SIZ47AcDrpKNQ4s9R1Ah38Czq/QKInCkNjTCC+JdxrF+XnqsUFL5DbOUDbxDzVq0TJj36xMC/LICcIbTmt7rg0auqXq4RhG6lnwyCpUaUr5YZ4pJm44kA94Zgy+o/7wpqYhYayGIZqu1VgK82gBs5m5uPXHiTFfb4cZzCZG356I8nzr2LQjTe4hXDaRE=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
private const string DevelopKey = "<RSAKeyValue><Modulus>ufmEzn3l/SsD01uvqILxYTEy8XV47r/uMD4sOZ07J4P0kx73LBcbMx+Gag4T9nYzTs0KmBPl6ogSdqA1hsJQ0BBlKFVZK53WTe1GjtXVPyhyuvfTd6pXPuW7ozBcd0xuHU5qhBY4TEjrbRZoSMHLMDsQB4Egdx+H5Y4T9TXSri7yraxUUqNNET5zU1mpxJqC3R6M6UcBiMagNYvcrL/iWLLvfhC3pjFmBiS/0rxAU5TRiWumwlFrkUpt7/dUMBDD1Adt1/nPEA5IZBscoFQWQGi1tCpzs1K71nJF04BgrALpetf3KYucrbiY85ANIAjE8pvDaYQVOSg5xIRIUVkd92uA8dFc2QRd6EL7wxZ6u3y5FsTm9ILaEfc54MlSVWx2E+bTvBL2jK1Pz+hSNBOWnRJbAJFWuToCGOykkyHOqQwmPX5MhbJ5q3qYh//E8D2SeJqc1Nr3NDaUNhJf1gkkr53yN+kbF9M2+xqn8p1jV6BUjQI+qDYeTyuBVgxEz5+H0xEyrSZ5DDjm9HsxXhzdXhHK7HDtvrSjgAr4HGmSODCuWpynzjGdNVEANsfpjT//zhgGEkW0JHiRmXjRbNslmspeW7xG5/uOxlZIFVahM0n544hoQbZx9mYcNMDkuT6d9wgjFEKAXVzn+45gPZ627eeVCF3pbAJCSx5EVPJfZGU=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";

public static RSACryptoServiceProvider GetProduction()
{
Expand Down
3 changes: 0 additions & 3 deletions src/Dto/Archive.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
using System.Collections.Generic;
using FuncSharp;

namespace Mews.Fiscalization.SignatureChecker.Dto;

internal sealed class Archive
Expand Down
1 change: 0 additions & 1 deletion src/Dto/ArchiveMetadata.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using Newtonsoft.Json;

namespace Mews.Fiscalization.SignatureChecker.Dto;
Expand Down
4 changes: 0 additions & 4 deletions src/Dto/ArchiveReader.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
using System.Collections.Generic;
using System.Linq;
using FuncSharp;

namespace Mews.Fiscalization.SignatureChecker.Dto;

internal static class ArchiveReader
Expand Down
3 changes: 0 additions & 3 deletions src/Dto/CsvData.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
using System.Collections.Generic;
using FuncSharp;

namespace Mews.Fiscalization.SignatureChecker.Dto;

internal sealed class CsvData
Expand Down
2 changes: 0 additions & 2 deletions src/Dto/CsvRow.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
using System.Collections.Generic;

namespace Mews.Fiscalization.SignatureChecker.Dto;

internal sealed class CsvRow
Expand Down
15 changes: 0 additions & 15 deletions src/Extensions.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using FuncSharp;
using Mews.Fiscalization.SignatureChecker.Model;

namespace Mews.Fiscalization.SignatureChecker;
Expand Down Expand Up @@ -34,17 +30,6 @@ internal static string ToSignatureString(this TaxSummary taxSummary)
return string.Join("|", parts);
}

internal static Tuple<IReadOnlyCollection<T>, IReadOnlyCollection<T>> Partition<T>(this IEnumerable<T> e, Func<T, bool> predicate)
{
var passing = new List<T>();
var violating = new List<T>();
foreach (var i in e)
{
(predicate(i) ? passing : violating).Add(i);
}
return Tuple.Create<IReadOnlyCollection<T>, IReadOnlyCollection<T>>(passing, violating);
}

private static string ToSignatureString(this TaxRate taxRate)
{
var rateNormalizationConstant = 100 * 100;
Expand Down
6 changes: 6 additions & 0 deletions src/GlobalUsings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Global using directives

global using System;
global using System.Linq;
global using System.Collections.Generic;
global using FuncSharp;
2 changes: 1 addition & 1 deletion src/Mews.Fiscalization.SignatureChecker.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<PackageVersion>1.0.5</PackageVersion>
<PackageVersion>2.0.0</PackageVersion>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>12</LangVersion>
<Title>Mews.Fiscalization.SignatureChecker</Title>
Expand Down
3 changes: 0 additions & 3 deletions src/Model/Amount.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using FuncSharp;

namespace Mews.Fiscalization.SignatureChecker.Model;

Expand Down
5 changes: 1 addition & 4 deletions src/Model/Archive.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
using System.Collections.Generic;
using FuncSharp;

namespace Mews.Fiscalization.SignatureChecker.Model;

internal sealed class Archive
Expand All @@ -27,7 +24,7 @@ public static Try<Archive, IReadOnlyList<string>> Create(IReadOnlyList<Dto.File>
return archive.FlatMap(c => Parse(c));
}

public static Try<Archive, IReadOnlyList<string>> Parse(Dto.Archive archive)
private static Try<Archive, IReadOnlyList<string>> Parse(Dto.Archive archive)
{
return ArchiveMetadata.Create(archive).FlatMap(metadata =>
{
Expand Down
45 changes: 23 additions & 22 deletions src/Model/ArchiveMetadata.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
using System;
using System.Collections.Generic;
using FuncSharp;
using Newtonsoft.Json;

namespace Mews.Fiscalization.SignatureChecker.Model;
Expand Down Expand Up @@ -31,19 +28,22 @@ public static Try<ArchiveMetadata, IReadOnlyList<string>> Create(Dto.Archive arc
var rawMetadata = Try.Catch<Dto.ArchiveMetadata, Exception>(_ => JsonConvert.DeserializeObject<Dto.ArchiveMetadata>(archive.Metadata.Content));
return rawMetadata.MapError(_ => $"Invalid data ({archive.Metadata.Name}).".ToReadOnlyList()).FlatMap(metadata =>
{
var version = metadata.Version.Match(
"1.0", _ => Try.Success<ArchiveVersion, IReadOnlyList<string>>(ArchiveVersion.v100),
"4.0", _ => Try.Success<ArchiveVersion, IReadOnlyList<string>>(ArchiveVersion.v400),
"4.1", _ => Try.Success<ArchiveVersion, IReadOnlyList<string>>(ArchiveVersion.v410),
"4.1.1", _ => Try.Success<ArchiveVersion, IReadOnlyList<string>>(ArchiveVersion.v411),
_ => Try.Error<ArchiveVersion, IReadOnlyList<string>>("Archive version is not supported.".ToReadOnlyList())
);
var archiveType = version.FlatMap(v => v.Match(
ArchiveVersion.v100, u => Try.Success<ArchiveType, IReadOnlyList<string>>(ArchiveType.Archiving),
ArchiveVersion.v400, u => ParseVersion4ArchiveType(metadata),
ArchiveVersion.v410, u => ParseVersion4ArchiveType(metadata),
ArchiveVersion.v411, u => ParseVersion4ArchiveType(metadata)
));
var version = metadata.Version switch
{
"1.0" => Try.Success<ArchiveVersion, IReadOnlyList<string>>(ArchiveVersion.v100),
"4.0" => Try.Success<ArchiveVersion, IReadOnlyList<string>>(ArchiveVersion.v400),
"4.1" => Try.Success<ArchiveVersion, IReadOnlyList<string>>(ArchiveVersion.v410),
"4.1.1" => Try.Success<ArchiveVersion, IReadOnlyList<string>>(ArchiveVersion.v411),
_ => Try.Error<ArchiveVersion, IReadOnlyList<string>>($"Archive version {metadata.Version} is not supported.".ToReadOnlyList())
};
var archiveType = version.FlatMap(v => v switch
{
ArchiveVersion.v100 => Try.Success<ArchiveType, IReadOnlyList<string>>(ArchiveType.Archiving),
ArchiveVersion.v400 => ParseVersion4ArchiveType(metadata),
ArchiveVersion.v410 => ParseVersion4ArchiveType(metadata),
ArchiveVersion.v411 => ParseVersion4ArchiveType(metadata),
_ => Try.Error<ArchiveType, IReadOnlyList<string>>($"Archive type {v} is not supported.".ToReadOnlyList())
});
var previousRecordSignature = metadata.PreviousRecordSignature.ToOption().Match(
s => Signature.Create(s),
_ => Try.Success<Signature, IReadOnlyList<string>>(null)
Expand All @@ -59,11 +59,12 @@ public static Try<ArchiveMetadata, IReadOnlyList<string>> Create(Dto.Archive arc

private static Try<ArchiveType, IReadOnlyList<string>> ParseVersion4ArchiveType(Dto.ArchiveMetadata archiveMetadata)
{
return archiveMetadata.ArchiveType.Match(
"DAY", _ => Try.Success<ArchiveType, IReadOnlyList<string>>(ArchiveType.Day),
"MONTH", _ => Try.Success<ArchiveType, IReadOnlyList<string>>(ArchiveType.Month),
"FISCALYEAR", _ => Try.Success<ArchiveType, IReadOnlyList<string>>(ArchiveType.FiscalYear),
_ => Try.Error<ArchiveType, IReadOnlyList<string>>($"{nameof(Model.ArchiveType)} is not supported.".ToReadOnlyList())
);
return archiveMetadata.ArchiveType switch
{
"DAY" => Try.Success<ArchiveType, IReadOnlyList<string>>(ArchiveType.Day),
"MONTH" => Try.Success<ArchiveType, IReadOnlyList<string>>(ArchiveType.Month),
"FISCALYEAR" => Try.Success<ArchiveType, IReadOnlyList<string>>(ArchiveType.FiscalYear),
_ => Try.Error<ArchiveType, IReadOnlyList<string>>($"Archive type {archiveMetadata.ArchiveType} is not supported.".ToReadOnlyList())
};
}
}
2 changes: 0 additions & 2 deletions src/Model/Parser.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using FuncSharp;

namespace Mews.Fiscalization.SignatureChecker.Model;

Expand Down
18 changes: 8 additions & 10 deletions src/Model/ReportedValue.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
using System.Collections.Generic;
using System.Linq;
using FuncSharp;

namespace Mews.Fiscalization.SignatureChecker.Model;

internal sealed class ReportedValue
Expand All @@ -15,12 +11,14 @@ private ReportedValue(Amount value)

public static Try<ReportedValue, IReadOnlyList<string>> Create(Dto.Archive archive, ArchiveVersion version)
{
var reportedValue = version.Match(
ArchiveVersion.v100, _ => GetReportedValueV1(archive),
ArchiveVersion.v400, _ => GetReportedValueV4(archive),
ArchiveVersion.v410, _ => GetReportedValueV4(archive),
ArchiveVersion.v411, _ => GetReportedValueV4(archive)
);
var reportedValue = version switch
{
ArchiveVersion.v100 => GetReportedValueV1(archive),
ArchiveVersion.v400 => GetReportedValueV4(archive),
ArchiveVersion.v410 => GetReportedValueV4(archive),
ArchiveVersion.v411 => GetReportedValueV4(archive),
_ => Try.Error<Amount, IReadOnlyList<string>>($"Unsupported archive version {version}.".ToReadOnlyList())
};

return reportedValue.Map(value => new ReportedValue(value));
}
Expand Down
6 changes: 1 addition & 5 deletions src/Model/Signature.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
using System;
using System.Collections.Generic;
using FuncSharp;

namespace Mews.Fiscalization.SignatureChecker.Model;

internal sealed class Signature
Expand Down Expand Up @@ -29,6 +25,6 @@ public static Try<Signature, IReadOnlyList<string>> Create(string base64UrlStrin
return Convert.FromBase64String(sourceBase64);
});

return value.Map(v => new Signature(base64UrlString, v)).MapError(e => "Failed to read signature.".ToReadOnlyList());
return value.Map(v => new Signature(base64UrlString, v)).MapError(e => $"Failed to read signature: {e.Message}.".ToReadOnlyList());
}
}
3 changes: 0 additions & 3 deletions src/Model/TaxRate.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
using System;
using FuncSharp;

namespace Mews.Fiscalization.SignatureChecker.Model;

internal sealed class TaxRate : Product1<decimal>, IComparable<TaxRate>
Expand Down
18 changes: 8 additions & 10 deletions src/Model/TaxSummary.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
using System.Collections.Generic;
using System.Linq;
using FuncSharp;

namespace Mews.Fiscalization.SignatureChecker.Model;

internal sealed class TaxSummary
Expand All @@ -15,12 +11,14 @@ private TaxSummary(IReadOnlyDictionary<TaxRate, Amount> data)

public static Try<TaxSummary, IReadOnlyList<string>> Create(Dto.Archive archive, ArchiveVersion version)
{
return version.Match(
ArchiveVersion.v100, _ => GetV1TaxSummary(archive),
ArchiveVersion.v400, _ => GetV4TaxSummary(archive),
ArchiveVersion.v410, _ => GetV4TaxSummary(archive),
ArchiveVersion.v411, _ => GetV4TaxSummary(archive)
);
return version switch
{
ArchiveVersion.v100 => GetV1TaxSummary(archive),
ArchiveVersion.v400 => GetV4TaxSummary(archive),
ArchiveVersion.v410 => GetV4TaxSummary(archive),
ArchiveVersion.v411 => GetV4TaxSummary(archive),
_ => throw new ArgumentOutOfRangeException(nameof(version), version, "Invalid archive version.")
};
}

private static TaxSummary Sum(IEnumerable<TaxSummary> summaries)
Expand Down
Loading

0 comments on commit be258d6

Please sign in to comment.