Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add public API to enable obf/deobf of a Dax.Metadata.Model object #16

Merged
merged 1 commit into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 27 additions & 8 deletions src/Dax.Vpax.Obfuscator/IVpaxObfuscator.cs
Original file line number Diff line number Diff line change
@@ -1,31 +1,50 @@
using Dax.Vpax.Obfuscator.Common;
using Dax.Metadata;
using Dax.Vpax.Obfuscator.Common;

namespace Dax.Vpax.Obfuscator;

public interface IVpaxObfuscator
{
/// <summary>
/// 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 <paramref name="stream"/>.
/// </summary>
/// <param name="stream">The VPAX stream</param>
/// <returns>The obfuscation dictionary</returns>
/// <returns>The obfuscation dictionary generated from the obfuscation process</returns>
ObfuscationDictionary Obfuscate(Stream stream);

/// <summary>
/// Obfuscate the DaxModel.json file and delete all other contents from the provided VPAX stream.
/// Obfuscate the <paramref name="model"/>.
/// </summary>
/// <returns>The obfuscation dictionary generated from the obfuscation process</returns>
ObfuscationDictionary Obfuscate(Model model);

/// <summary>
/// Incrementally obfuscate the DaxModel.json file and delete all other contents from the <paramref name="stream"/>.
/// </summary>
/// <remarks>
/// This method updates the obfuscation dictionary to changes applied since a previous obfuscation.
/// </remarks>
/// <param name="stream">The VPAX stream</param>
/// <param name="dictionary">The obfuscation dictionary generated from a previous obfuscation</param>
/// <returns>The obfuscation dictionary updated to changes applied since a previous obfuscation.</returns>
/// <returns>The obfuscation <paramref name="dictionary"/> updated to changes applied since a previous obfuscation.</returns>
ObfuscationDictionary Obfuscate(Stream stream, ObfuscationDictionary dictionary);

/// <summary>
/// Incrementally obfuscate the <paramref name="model"/>.
/// </summary>
/// <param name="stream">The VPAX stream</param>
/// <param name="dictionary">The obfuscation dictionary generated from a previous obfuscation</param>
/// <returns>The obfuscation <paramref name="dictionary"/> updated to changes applied since a previous obfuscation.</returns>
ObfuscationDictionary Obfuscate(Model model, ObfuscationDictionary dictionary);

/// <summary>
/// Deobfuscate the DaxModel.json file using the provided obfuscation dictionary.
/// </summary>
/// <param name="stream">The VPAX stream</param>
/// <param name="dictionary">The obfuscation dictionary</param>
void Deobfuscate(Stream stream, ObfuscationDictionary dictionary);

/// <summary>
/// Deobfuscate the <paramref name="model"/> using the provided obfuscation dictionary.
/// </summary>
/// <param name="stream">The VPAX stream</param>
/// <param name="dictionary">The obfuscation dictionary</param>
void Deobfuscate(Model model, ObfuscationDictionary dictionary);
}
56 changes: 34 additions & 22 deletions src/Dax.Vpax.Obfuscator/VpaxObfuscator.cs
Original file line number Diff line number Diff line change
@@ -1,54 +1,66 @@
using System.IO.Packaging;
using Dax.Metadata;
using Dax.Vpax.Obfuscator.Common;
using Dax.Vpax.Tools;

namespace Dax.Vpax.Obfuscator;

public sealed class VpaxObfuscator : IVpaxObfuscator
{
/// <inheritdoc/>
public ObfuscationDictionary Obfuscate(Stream stream)
=> ObfuscateImpl(stream, dictionary: null);

/// <inheritdoc/>
public ObfuscationDictionary Obfuscate(Stream stream, ObfuscationDictionary dictionary)
=> ObfuscateImpl(stream, dictionary ?? throw new ArgumentNullException(nameof(dictionary)));

/// <inheritdoc/>
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)
{
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)
Expand Down
Loading