From ce325ace0dc195a100a490f52206065b758f2cdc Mon Sep 17 00:00:00 2001 From: Alberto Spelta Date: Tue, 5 Mar 2024 14:46:21 +0100 Subject: [PATCH] Add public API to enable the obf/deobf of a `Dax.Metadata.Model` object (#16) Introduce a public API to facilitate obfuscation and deobfuscation of a `Dax.Metadata.Model` object, eliminating the need for the VPAX file stream. --- src/Dax.Vpax.Obfuscator/IVpaxObfuscator.cs | 35 ++++++++++---- src/Dax.Vpax.Obfuscator/VpaxObfuscator.cs | 56 +++++++++++++--------- 2 files changed, 61 insertions(+), 30 deletions(-) diff --git a/src/Dax.Vpax.Obfuscator/IVpaxObfuscator.cs b/src/Dax.Vpax.Obfuscator/IVpaxObfuscator.cs index cc5ed3f..32180fa 100644 --- a/src/Dax.Vpax.Obfuscator/IVpaxObfuscator.cs +++ b/src/Dax.Vpax.Obfuscator/IVpaxObfuscator.cs @@ -1,31 +1,50 @@ -using Dax.Vpax.Obfuscator.Common; +using Dax.Metadata; +using Dax.Vpax.Obfuscator.Common; namespace Dax.Vpax.Obfuscator; public interface IVpaxObfuscator { /// - /// Obfuscate the DaxModel.json file and delete all other contents from the provided VPAX stream. + /// Obfuscate the DaxModel.json file and delete all other contents from the . /// /// The VPAX stream - /// The obfuscation dictionary + /// The obfuscation dictionary generated from the obfuscation process ObfuscationDictionary Obfuscate(Stream stream); /// - /// Obfuscate the DaxModel.json file and delete all other contents from the provided VPAX stream. + /// Obfuscate the . + /// + /// The obfuscation dictionary generated from the obfuscation process + ObfuscationDictionary Obfuscate(Model model); + + /// + /// Incrementally obfuscate the DaxModel.json file and delete all other contents from the . /// - /// - /// This method updates the obfuscation dictionary to changes applied since a previous obfuscation. - /// /// The VPAX stream /// The obfuscation dictionary generated from a previous obfuscation - /// The obfuscation dictionary updated to changes applied since a previous obfuscation. + /// The obfuscation updated to changes applied since a previous obfuscation. ObfuscationDictionary Obfuscate(Stream stream, ObfuscationDictionary dictionary); + /// + /// Incrementally obfuscate the . + /// + /// The VPAX stream + /// The obfuscation dictionary generated from a previous obfuscation + /// The obfuscation updated to changes applied since a previous obfuscation. + ObfuscationDictionary Obfuscate(Model model, ObfuscationDictionary dictionary); + /// /// Deobfuscate the DaxModel.json file using the provided obfuscation dictionary. /// /// The VPAX stream /// The obfuscation dictionary void Deobfuscate(Stream stream, ObfuscationDictionary dictionary); + + /// + /// Deobfuscate the using the provided obfuscation dictionary. + /// + /// The VPAX stream + /// The obfuscation dictionary + void Deobfuscate(Model model, ObfuscationDictionary dictionary); } diff --git a/src/Dax.Vpax.Obfuscator/VpaxObfuscator.cs b/src/Dax.Vpax.Obfuscator/VpaxObfuscator.cs index b53b2e9..a769ff1 100644 --- a/src/Dax.Vpax.Obfuscator/VpaxObfuscator.cs +++ b/src/Dax.Vpax.Obfuscator/VpaxObfuscator.cs @@ -1,4 +1,5 @@ using System.IO.Packaging; +using Dax.Metadata; using Dax.Vpax.Obfuscator.Common; using Dax.Vpax.Tools; @@ -6,35 +7,35 @@ namespace Dax.Vpax.Obfuscator; public sealed class VpaxObfuscator : IVpaxObfuscator { - /// - public ObfuscationDictionary Obfuscate(Stream stream) - => ObfuscateImpl(stream, dictionary: null); - - /// - public ObfuscationDictionary Obfuscate(Stream stream, ObfuscationDictionary dictionary) - => ObfuscateImpl(stream, dictionary ?? throw new ArgumentNullException(nameof(dictionary))); - - /// - public void Deobfuscate(Stream stream, ObfuscationDictionary dictionary) - => DeobfuscateImpl(stream, dictionary); + public ObfuscationDictionary Obfuscate(Stream stream) => ObfuscateImpl(stream, dictionary: null); + public ObfuscationDictionary Obfuscate(Model model) => ObfuscateImpl(model, dictionary: null); + public ObfuscationDictionary Obfuscate(Stream stream, ObfuscationDictionary dictionary) => ObfuscateImpl(stream, dictionary ?? throw new ArgumentNullException(nameof(dictionary))); + public ObfuscationDictionary Obfuscate(Model model, ObfuscationDictionary dictionary) => ObfuscateImpl(model, dictionary ?? throw new ArgumentNullException(nameof(dictionary))); + public void Deobfuscate(Stream stream, ObfuscationDictionary dictionary) => DeobfuscateImpl(stream, dictionary); + public void Deobfuscate(Model model, ObfuscationDictionary dictionary) => DeobfuscateImpl(model, dictionary); private static ObfuscationDictionary ObfuscateImpl(Stream stream, ObfuscationDictionary? dictionary) { if (stream == null) throw new ArgumentNullException(nameof(stream)); - var model = VpaxTools.ImportVpax(stream, importDatabase: false).DaxModel - ?? throw new InvalidOperationException($"The VPAX package does not contain a {VpaxFormat.DAXMODEL} file."); + var model = GetModel(stream); + var result = ObfuscateImpl(model, dictionary); + + ZeroOutPackage(stream); // Zero out the package to remove all contents before writing the obfuscated DaxModel.json + VpaxTools.ExportVpax(stream, model, viewVpa: null, database: null); + + return result; + } - // Zero out the package to remove all contents before writing the obfuscated DaxModel.json - ZeroOutPackage(stream); + private static ObfuscationDictionary ObfuscateImpl(Model model, ObfuscationDictionary? dictionary) + { + if (model == null) throw new ArgumentNullException(nameof(model)); var obfuscator = new DaxModelObfuscator(model, dictionary); obfuscator.Obfuscate(); - var texts = obfuscator.Texts.Select((t) => new ObfuscationText(t.Value, t.ObfuscatedValue)).ToArray(); - var result = new ObfuscationDictionary(id: model.ObfuscatorDictionaryId, texts); - VpaxTools.ExportVpax(stream, model, viewVpa: null, database: null); - return result; + var texts = obfuscator.Texts.Select((t) => new ObfuscationText(t.Value, t.ObfuscatedValue)).ToArray(); + return new ObfuscationDictionary(id: model.ObfuscatorDictionaryId, texts); } private static void DeobfuscateImpl(Stream stream, ObfuscationDictionary dictionary) @@ -42,13 +43,24 @@ private static void DeobfuscateImpl(Stream stream, ObfuscationDictionary diction if (stream == null) throw new ArgumentNullException(nameof(stream)); if (dictionary == null) throw new ArgumentNullException(nameof(dictionary)); - var model = VpaxTools.ImportVpax(stream, importDatabase: false).DaxModel - ?? throw new InvalidOperationException($"The VPAX package does not contain a {VpaxFormat.DAXMODEL} file."); + var model = GetModel(stream); + DeobfuscateImpl(model, dictionary); + VpaxTools.ExportVpax(stream, model, viewVpa: null, database: null); + } + + private static void DeobfuscateImpl(Model model, ObfuscationDictionary dictionary) + { + if (model == null) throw new ArgumentNullException(nameof(model)); + if (dictionary == null) throw new ArgumentNullException(nameof(dictionary)); var deobfuscator = new DaxModelDeobfuscator(model, dictionary); deobfuscator.Deobfuscate(); + } - VpaxTools.ExportVpax(stream, model, viewVpa: null, database: null); + private static Model GetModel(Stream stream) + { + var model = VpaxTools.ImportVpax(stream, importDatabase: false).DaxModel; + return model ?? throw new InvalidOperationException($"The VPAX package does not contain a {VpaxFormat.DAXMODEL} file."); } private static void ZeroOutPackage(Stream stream)