Skip to content

Commit

Permalink
Added support for Sha256 hasing and Base64 conversion of RowKey
Browse files Browse the repository at this point in the history
  • Loading branch information
dei79 committed Sep 12, 2022
1 parent 67478eb commit adc3ff0
Show file tree
Hide file tree
Showing 16 changed files with 220 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using CoreHelpers.WindowsAzure.Storage.Table.Abstractions;

namespace CoreHelpers.WindowsAzure.Storage.Table
{
Expand All @@ -27,6 +26,8 @@ public interface IStorageContext : IDisposable

void AddEntityMapper(Type entityType, String partitionKeyFormat, String rowKeyFormat, String tableName);

void AddEntityMapper(Type entityType, String partitionKeyFormat, String rowKeyFormat, nVirtualValueEncoding rowKeyEncoding, String tableName);

IStorageContext CreateChildContext();

IStorageContext EnableAutoCreateTable();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using System.Linq;
using System.Threading.Tasks;

namespace CoreHelpers.WindowsAzure.Storage.Table.Abstractions
namespace CoreHelpers.WindowsAzure.Storage.Table
{
public interface IStorageContextQueryNow<T>
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;
namespace CoreHelpers.WindowsAzure.Storage.Table
{
public enum nVirtualValueEncoding
{
None,
Base64,
Sha256
}
}

113 changes: 113 additions & 0 deletions CoreHelpers.WindowsAzure.Storage.Table.Tests/ITS24VirtualRowKey.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
using System;
using CoreHelpers.WindowsAzure.Storage.Table.Attributes;
using CoreHelpers.WindowsAzure.Storage.Table.Serialization;
using CoreHelpers.WindowsAzure.Storage.Table.Tests.Extensions;
using CoreHelpers.WindowsAzure.Storage.Table.Tests.Models;

namespace CoreHelpers.WindowsAzure.Storage.Table.Tests
{
[Storable(Tablename = "VirtualRowKeyNone")]
[VirtualRowKey("{{RK}}")]
public class VirtualRowKeyNone
{
[PartitionKey]
public string PK { get; set; } = String.Empty;

public string RK { get; set; } = String.Empty;
}

[Storable(Tablename = "VirtualRowKeyNone")]
[VirtualRowKey("{{RK}}-{{RK2}}")]
public class VirtualRowKeyCombinedNone: VirtualRowKeyNone
{
public string RK2 { get; set; } = String.Empty;
}

[Storable(Tablename = "VirtualRowKeyNone")]
[VirtualRowKey("{{RK}}", nVirtualValueEncoding.Base64)]
public class VirtualRowKeyBase64 : VirtualRowKeyNone
{}

[Storable(Tablename = "VirtualRowKeyNone")]
[VirtualRowKey("{{RK}}", nVirtualValueEncoding.Sha256)]
public class VirtualRowKeySha256: VirtualRowKeyNone
{ }

public class ITS24VirtualRowKey
{
private readonly IStorageContext _rootContext;

public ITS24VirtualRowKey(IStorageContext context)
{
_rootContext = context;
}

[Fact]
public void VerifyVirtualRowKeyNoneEncoding()
{
using (var scp = _rootContext.CreateChildContext())
{
// set the tablename context
scp.SetTableContext();

// configure the entity mapper
scp.AddAttributeMapper<VirtualRowKeyNone>();

// check the entity
var entity = TableEntityDynamic.ToEntity<VirtualRowKeyNone>(new VirtualRowKeyNone() { PK = "P01", RK = "R01" }, scp);
Assert.Equal("R01", entity.RowKey);
}
}

[Fact]
public void VerifyVirtualRowKeyNoneEncodingCombined()
{
using (var scp = _rootContext.CreateChildContext())
{
// set the tablename context
scp.SetTableContext();

// configure the entity mapper
scp.AddAttributeMapper<VirtualRowKeyCombinedNone>();

// check the entity
var entity = TableEntityDynamic.ToEntity<VirtualRowKeyCombinedNone>(new VirtualRowKeyCombinedNone() { PK = "P01", RK = "R01", RK2 = "CMB" }, scp);
Assert.Equal("R01-CMB", entity.RowKey);
}
}

[Fact]
public void VerifyVirtualRowKeyBase64Encoding()
{
using (var scp = _rootContext.CreateChildContext())
{
// set the tablename context
scp.SetTableContext();

// configure the entity mapper
scp.AddAttributeMapper<VirtualRowKeyBase64>();

// check the entity
var entity = TableEntityDynamic.ToEntity<VirtualRowKeyBase64>(new VirtualRowKeyBase64() { PK = "P01", RK = "R01" }, scp);
Assert.Equal("UjAx", entity.RowKey);
}
}

[Fact]
public void VerifyVirtualRowKeySha256Encoding()
{
using (var scp = _rootContext.CreateChildContext())
{
// set the tablename context
scp.SetTableContext();

// configure the entity mapper
scp.AddAttributeMapper<VirtualRowKeySha256>();

// check the entity
var entity = TableEntityDynamic.ToEntity<VirtualRowKeySha256>(new VirtualRowKeySha256() { PK = "P01", RK = "R01" }, scp);
Assert.Equal("e0a64b0b6d837fa4edc328ab9ddea0e3e7e0e4f715304c1d6bf3d0adc9d5292a", entity.RowKey);
}
}
}
}
5 changes: 4 additions & 1 deletion CoreHelpers.WindowsAzure.Storage.Table/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Reflection;
using System.Runtime.CompilerServices;

[assembly: AssemblyCompany("Core Helpers")]
[assembly: AssemblyProduct("WindowsAzure.Storage.Table")]
Expand All @@ -12,4 +13,6 @@
[assembly: AssemblyConfiguration("Debug")]
#else
[assembly: AssemblyConfiguration("Release")]
#endif
#endif

[assembly: InternalsVisibleTo("CoreHelpers.WindowsAzure.Storage.Table.Tests")]
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
using System;
using CoreHelpers.WindowsAzure.Storage.Table;

namespace CoreHelpers.WindowsAzure.Storage.Table.Attributes
{
{
[AttributeUsage(AttributeTargets.Class)]
public class VirtualRowKeyAttribute : Attribute
{
public string RowKeyFormat { get; set; }

public VirtualRowKeyAttribute(string RowKeyFormat) {

public nVirtualValueEncoding Encoding { get; set; }

public VirtualRowKeyAttribute(string RowKeyFormat, nVirtualValueEncoding Encoding = nVirtualValueEncoding.None) {
this.RowKeyFormat = RowKeyFormat;
this.Encoding = Encoding;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System;
using System.Text;

namespace CoreHelpers.WindowsAzure.Storage.Table.Extensions
{
public static class StringExternsions
{
public static string ToBase64(this string plainText)
{
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
return System.Convert.ToBase64String(plainTextBytes);
}

public static string ToSha256(this string value)
{
// convert the string
byte[] toBytes = Encoding.ASCII.GetBytes(value);

// generate the SHA1 key
var sha256 = global::System.Security.Cryptography.SHA256.Create();
var hash = sha256.ComputeHash(toBytes);

// done
return GenerateHexStringFromBytes(hash);
}

private static string GenerateHexStringFromBytes(byte[] bytes)
{
var sb = new StringBuilder();
foreach (byte b in bytes)
{
var hex = b.ToString("x2");
sb.Append(hex);
}
return sb.ToString();
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using System.Threading;
using System.Threading.Tasks;
using Azure.Data.Tables;
using CoreHelpers.WindowsAzure.Storage.Table.Abstractions;
using CoreHelpers.WindowsAzure.Storage.Table.Serialization;

namespace CoreHelpers.WindowsAzure.Storage.Table.Internal
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using CoreHelpers.WindowsAzure.Storage.Table.Abstractions;
using CoreHelpers.WindowsAzure.Storage.Table.Serialization;

namespace CoreHelpers.WindowsAzure.Storage.Table.Internal
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using CoreHelpers.WindowsAzure.Storage.Table.Abstractions;

namespace CoreHelpers.WindowsAzure.Storage.Table.Internal
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using CoreHelpers.WindowsAzure.Storage.Table.Abstractions;

namespace CoreHelpers.WindowsAzure.Storage.Table.Internal
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using Azure.Data.Tables;
using CoreHelpers.WindowsAzure.Storage.Table.Attributes;
using CoreHelpers.WindowsAzure.Storage.Table.Extensions;

namespace CoreHelpers.WindowsAzure.Storage.Table.Serialization
{
Expand All @@ -15,9 +17,22 @@ public TableEntityBuilder AddPartitionKey(string pkey)
return this;
}

public TableEntityBuilder AddRowKey(string rkey)
public TableEntityBuilder AddRowKey(string rkey, nVirtualValueEncoding encoding = nVirtualValueEncoding.None)
{
_data.Add("RowKey", rkey);

switch (encoding)
{
case nVirtualValueEncoding.None:
_data.Add("RowKey", rkey);
break;
case nVirtualValueEncoding.Base64:
_data.Add("RowKey", rkey.ToBase64());
break;
case nVirtualValueEncoding.Sha256:
_data.Add("RowKey", rkey.ToSha256());
break;
}

return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,22 @@
namespace CoreHelpers.WindowsAzure.Storage.Table.Serialization
{
internal static class TableEntityDynamic
{
{
public static TableEntity ToEntity<T>(T model, IStorageContext context) where T : new()
{
if (context as StorageContext == null)
throw new Exception("Invalid interface implemnetation");
else
return TableEntityDynamic.ToEntity<T>(model, (context as StorageContext).GetEntityMapper<T>());
}

public static TableEntity ToEntity<T>(T model, StorageEntityMapper entityMapper) where T: new()
{
var builder = new TableEntityBuilder();

// set the keys
builder.AddPartitionKey(GetTableStorageDefaultProperty<string, T>(entityMapper.PartitionKeyFormat, model));
builder.AddRowKey(GetTableStorageDefaultProperty<string, T>(entityMapper.RowKeyFormat, model));
builder.AddRowKey(GetTableStorageDefaultProperty<string, T>(entityMapper.RowKeyFormat, model), entityMapper.RowKeyEncoding);

// get all properties from model
IEnumerable<PropertyInfo> objectProperties = model.GetType().GetTypeInfo().GetProperties();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
using System;
using CoreHelpers.WindowsAzure.Storage.Table.Attributes;

namespace CoreHelpers.WindowsAzure.Storage.Table
{
public class StorageEntityMapper
{
public String PartitionKeyFormat { get; set; }
public String RowKeyFormat { get; set; }
public String TableName { get; set; }
public nVirtualValueEncoding RowKeyEncoding { get; set; }
public String TableName { get; set; }

public StorageEntityMapper()
{}
Expand All @@ -15,6 +17,7 @@ public StorageEntityMapper(StorageEntityMapper src)
{
this.PartitionKeyFormat = src.PartitionKeyFormat;
this.RowKeyFormat = src.RowKeyFormat;
this.RowKeyEncoding = src.RowKeyEncoding;
this.TableName = src.TableName;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,17 @@ public void AddEntityMapper(Type entityType, StorageEntityMapper entityMapper)
=> _entityMapperRegistry.Add(entityType, entityMapper);

public void AddEntityMapper(Type entityType, string partitionKeyFormat, string rowKeyFormat, string tableName)
{
AddEntityMapper(entityType, partitionKeyFormat, rowKeyFormat, nVirtualValueEncoding.None, tableName);
}

public void AddEntityMapper(Type entityType, String partitionKeyFormat, String rowKeyFormat, nVirtualValueEncoding rowKeyEncoding, String tableName)
{
_entityMapperRegistry.Add(entityType, new StorageEntityMapper()
{
PartitionKeyFormat = partitionKeyFormat,
RowKeyFormat = rowKeyFormat,
RowKeyEncoding = rowKeyEncoding,
TableName = tableName
});
}
Expand Down Expand Up @@ -66,6 +72,7 @@ public void AddAttributeMapper(Type type, String optionalTablenameOverride)
// store the neded properties
string partitionKeyFormat = null;
string rowKeyFormat = null;
var rowKeyEncoding = nVirtualValueEncoding.None;

// get the partitionkey property & rowkey property
var properties = type.GetRuntimeProperties();
Expand All @@ -91,6 +98,9 @@ public void AddAttributeMapper(Type type, String optionalTablenameOverride)
if (virtualRowKeyAttribute != null && !String.IsNullOrEmpty(virtualRowKeyAttribute.RowKeyFormat))
rowKeyFormat = virtualRowKeyAttribute.RowKeyFormat;

if (virtualRowKeyAttribute != null && virtualRowKeyAttribute.Encoding != nVirtualValueEncoding.None)
rowKeyEncoding = virtualRowKeyAttribute.Encoding;

// check
if (partitionKeyFormat == null || rowKeyFormat == null)
throw new Exception("Missing Partition or RowKey Attribute");
Expand All @@ -100,7 +110,8 @@ public void AddAttributeMapper(Type type, String optionalTablenameOverride)
{
TableName = String.IsNullOrEmpty(optionalTablenameOverride) ? storableAttribute.Tablename : optionalTablenameOverride,
PartitionKeyFormat = partitionKeyFormat,
RowKeyFormat = rowKeyFormat
RowKeyFormat = rowKeyFormat,
RowKeyEncoding = rowKeyEncoding
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CoreHelpers.WindowsAzure.Storage.Table.Abstractions;
using CoreHelpers.WindowsAzure.Storage.Table.Internal;

namespace CoreHelpers.WindowsAzure.Storage.Table
Expand Down

0 comments on commit adc3ff0

Please sign in to comment.