Skip to content

Commit

Permalink
Added salt to the key hash
Browse files Browse the repository at this point in the history
  • Loading branch information
kubagdynia committed May 9, 2024
1 parent 88b850e commit a36c813
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 22 deletions.
25 changes: 17 additions & 8 deletions CacheDrive.ExampleConsoleApp/App.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,20 @@ public async Task Run()
? $"TryGetValue OK - cached value: {cachedValue2}"
: $"TryGetValue NOK - cached value: {cachedValue2}");

Console.WriteLine();

// Set, Get
string cacheKey3 = "testKey2";
cacheService.Set(cacheKey3, 1234567);
int cachedValue3 = cacheService.Get<int>(cacheKey3);
Console.WriteLine($"Get - cached value: {cachedValue3} ");

// ************ with hashKey

Console.WriteLine();
Console.WriteLine("with hashKey");
Console.WriteLine();

// SetAsync, GetAsync and TryGetValue with hashKey
string cacheKey2 = "testKey";
await cacheService.SetAsync(cacheKey2, "test text...", hashKey: true);
Expand All @@ -25,16 +39,11 @@ public async Task Run()
Console.WriteLine(cacheService.TryGetValue(cacheKey2, hashKey: true, out string cachedValueWithHashKey2)
? $"TryGetValue with haskkey OK - cached value: {cachedValueWithHashKey2}"
: $"TryGetValue with haskkey NOK - cached value: {cachedValueWithHashKey2}");

Console.WriteLine();

// Set, Get
string cacheKey3 = "testKey2";
cacheService.Set(cacheKey3, 1234567);
int cachedValue3 = cacheService.Get<int>(cacheKey3);
Console.WriteLine($"Get - cached value: {cachedValue3} ");

// Set, Get with hashKey

Console.WriteLine();

string cacheKey4 = "testKey2";
cacheService.Set(cacheKey4, 1234567, hashKey: true);
int cachedValueWithHashKey3 = cacheService.Get<int>(cacheKey4, hashKey: true);
Expand Down
3 changes: 2 additions & 1 deletion CacheDrive.ExampleConsoleApp/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"CacheExpiration": 60,
"CacheType": "MemoryAndFile",
"InitializeOnStartup": true,
"FlushOnExit": true
"FlushOnExit": true,
"HashKeySalt": "Secret123Secret"
}
}
6 changes: 4 additions & 2 deletions CacheDrive.Tests/Helpers/TestHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@ public static class TestHelper
bool cacheEnabled = true,
CacheExpirationType cacheExpirationType = CacheExpirationType.Hours,
int cacheExpiration = 2,
CacheType cacheType = CacheType.MemoryAndFile)
CacheType cacheType = CacheType.MemoryAndFile,
string hashSalt = "")
{
ServiceCollection services = new ServiceCollection();
services.RegisterCacheDrive(new CacheSettings
{
CacheEnabled = cacheEnabled,
CacheExpirationType = cacheExpirationType,
CacheExpiration = cacheExpiration,
CacheType = cacheType
CacheType = cacheType,
HashKeySalt = hashSalt
});
services.AddSingleton<IDateService>( x => new TestDateService(dateNow));

Expand Down
90 changes: 90 additions & 0 deletions CacheDrive.Tests/MemoryAndFileHashKeyWithSaltTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using CacheDrive.Configuration;
using CacheDrive.Services;
using CacheDrive.Tests.Helpers;
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;

namespace CacheDrive.Tests;

public class MemoryAndFileHashKeyWithSaltTests
{
[Test, Order(1)]
public async Task CacheShouldBeSavedCorrectly()
{
// Arrange
ServiceProvider serviceProvider = TestHelper.CreateServiceProvider(
dateNow: DateTime.Now, cacheEnabled: true, cacheExpirationType: CacheExpirationType.Hours,
cacheExpiration: 2, cacheType: CacheType.MemoryAndFile, hashSalt: "Secret123");

ICacheService cacheService = serviceProvider.GetRequiredService<ICacheService>();

// Act
string key = "name";

await cacheService.SetAsync(key, "John", hashKey: true);

// Assert
if (cacheService.TryGetValue(key, hashKey: true, out string cachedValue))
{
cachedValue.Should().Be("John");
await cacheService.FlushAsync();
}
else
{
await cacheService.FlushAsync();
Assert.Fail();
}

await cacheService.FlushAsync();
}

[Test, Order(2)]
public async Task CacheShouldBeLoadCorrectly()
{
// Arrange
ServiceProvider serviceProvider = TestHelper.CreateServiceProvider(
dateNow: DateTime.Now, cacheEnabled: true, cacheExpirationType: CacheExpirationType.Hours,
cacheExpiration: 2, cacheType: CacheType.MemoryAndFile, hashSalt: "Secret123");

ICacheService cacheService = serviceProvider.GetRequiredService<ICacheService>();

string key = "name";

// Assert
if (cacheService.TryGetValue(key, hashKey: true, out string cachedValue))
{
cachedValue.Should().Be("John");
await cacheService.FlushAsync();
}
else
{
await cacheService.FlushAsync();
Assert.Fail();
}
}

[Test, Order(3)]
public async Task CacheShouldExpired()
{
// Arrange
ServiceProvider serviceProvider = TestHelper.CreateServiceProvider(
dateNow: DateTime.Now.AddHours(3), cacheEnabled: true, cacheExpirationType: CacheExpirationType.Hours,
cacheExpiration: 2, cacheType: CacheType.MemoryAndFile, hashSalt: "Secret123");

ICacheService cacheService = serviceProvider.GetRequiredService<ICacheService>();

string key = "name";

// Assert
if (!cacheService.TryGetValue(key, hashKey: true, out string _))
{
await cacheService.FlushAsync();
Assert.Pass();
}
else
{
await cacheService.FlushAsync();
Assert.Fail();
}
}
}
5 changes: 5 additions & 0 deletions CacheDrive/Configuration/CacheSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,9 @@ public class CacheSettings
/// Default value is true.
/// </summary>
public bool FlushOnExit { get; set; } = true;

/// <summary>
///
/// </summary>
public string HashKeySalt { get; set; } = "";
}
4 changes: 3 additions & 1 deletion CacheDrive/Extensions/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public static void RegisterCacheDrive(this IServiceCollection services, CacheSet
opt.CacheType = settings.CacheType;
opt.InitializeOnStartup = settings.InitializeOnStartup;
opt.FlushOnExit = settings.FlushOnExit;
opt.HashKeySalt = settings.HashKeySalt;
});
}
else
Expand All @@ -57,6 +58,7 @@ public static void RegisterCacheDrive(this IServiceCollection services, CacheSet
opt.CacheType = settings.CacheType;
opt.InitializeOnStartup = settings.InitializeOnStartup;
opt.FlushOnExit = settings.FlushOnExit;
opt.HashKeySalt = settings.HashKeySalt;
});
}
else
Expand All @@ -78,7 +80,7 @@ public static void RegisterCacheDrive(this IServiceCollection services, CacheSet
CacheType.MemoryAndFile => new MemoryCacheFileStorageService(
serviceProvider.GetRequiredService<IOptions<CacheSettings>>(),
serviceProvider.GetRequiredService<IDateService>()),
_ => throw new ArgumentOutOfRangeException()
_ => throw new ArgumentOutOfRangeException(paramName: serviceProvider.GetService<IOptions<CacheSettings>>().Value.CacheType.ToString())
};
});
}
Expand Down
4 changes: 2 additions & 2 deletions CacheDrive/Services/HashString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ namespace CacheDrive.Services;

internal static class HashString
{
public static string HashKey(string key)
public static string HashKey(string key, string salt = "")
{
// Convert the string to a byte array first, to be processed
var textBytes = System.Text.Encoding.UTF8.GetBytes(key);
var textBytes = System.Text.Encoding.UTF8.GetBytes(key + salt);
var hashBytes = SHA256.HashData(textBytes);

// Convert back to a string, removing the '-' that BitConverter adds
Expand Down
16 changes: 8 additions & 8 deletions CacheDrive/Services/MemoryCacheService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public bool HasItem(string key)
}

public bool HasItem(string key, bool hashKey)
=> HasItem(hashKey ? HashString.HashKey(key) : key);
=> HasItem(hashKey ? HashString.HashKey(key, CacheSettings.HashKeySalt) : key);

public bool TryGetValue<T>(string key, out T value)
{
Expand Down Expand Up @@ -79,7 +79,7 @@ public bool TryGetValue<T>(string key, out T value)
}

public bool TryGetValue<T>(string key, bool hashKey, out T value)
=> TryGetValue(hashKey ? HashString.HashKey(key) : key, out value);
=> TryGetValue(hashKey ? HashString.HashKey(key, CacheSettings.HashKeySalt) : key, out value);

private bool TryGetCacheableValue<T>(string key, out T value) where T : ICacheable
{
Expand Down Expand Up @@ -120,7 +120,7 @@ public T Get<T>(string key)
}

public T Get<T>(string key, bool hashKey)
=> Get<T>(hashKey ? HashString.HashKey(key) : key);
=> Get<T>(hashKey ? HashString.HashKey(key, CacheSettings.HashKeySalt) : key);

public async Task<T> GetAsync<T>(string key)
{
Expand All @@ -140,7 +140,7 @@ public async Task<T> GetAsync<T>(string key)
}

public Task<T> GetAsync<T>(string key, bool hashKey)
=> GetAsync<T>(hashKey ? HashString.HashKey(key) : key);
=> GetAsync<T>(hashKey ? HashString.HashKey(key, CacheSettings.HashKeySalt) : key);

private async Task<T> GetCacheableAsync<T>(string key) where T : ICacheable
{
Expand Down Expand Up @@ -189,7 +189,7 @@ public void Set<T>(string key, T value, int expirySeconds = 0)
}

public void Set<T>(string key, T value, bool hashKey, int expirySeconds = 0)
=> Set(hashKey ? HashString.HashKey(key) : key, value, expirySeconds);
=> Set(hashKey ? HashString.HashKey(key, CacheSettings.HashKeySalt) : key, value, expirySeconds);

public Task SetAsync<T>(string key, T value, int expirySeconds = 0)
{
Expand All @@ -202,7 +202,7 @@ public Task SetAsync<T>(string key, T value, int expirySeconds = 0)
}

public Task SetAsync<T>(string key, T value, bool hashKey, int expirySeconds = 0)
=> SetAsync(hashKey ? HashString.HashKey(key) : key, value, expirySeconds);
=> SetAsync(hashKey ? HashString.HashKey(key, CacheSettings.HashKeySalt) : key, value, expirySeconds);

private void SetCacheableItem<T>(T item, int expirySeconds = 0) where T : ICacheable
{
Expand Down Expand Up @@ -272,7 +272,7 @@ public bool Delete<T>(string key)
}

public bool Delete<T>(string key, bool hashKey)
=> Delete<T>(hashKey ? HashString.HashKey(key) : key);
=> Delete<T>(hashKey ? HashString.HashKey(key, CacheSettings.HashKeySalt) : key);

public Task<bool> DeleteAsync<T>(string key)
{
Expand All @@ -285,7 +285,7 @@ public Task<bool> DeleteAsync<T>(string key)
}

public Task<bool> DeleteAsync<T>(string key, bool hashKey)
=> DeleteAsync<T>(hashKey ? HashString.HashKey(key) : key);
=> DeleteAsync<T>(hashKey ? HashString.HashKey(key, CacheSettings.HashKeySalt) : key);

private Task<bool> DeleteAsync(string key)
=> key is null ? Task.FromResult(false) : Task.FromResult(Storage.TryRemove(key, out _));
Expand Down

0 comments on commit a36c813

Please sign in to comment.