Skip to content

Commit

Permalink
chore: adding tests for composed disposable token scopes (#499)
Browse files Browse the repository at this point in the history
* chore: adding tests for composed disposable token scopes

* fix: delete dynamically created caches in finally block
  • Loading branch information
pgautier404 authored Sep 21, 2023
1 parent b1a56db commit 6db0107
Showing 1 changed file with 188 additions and 12 deletions.
200 changes: 188 additions & 12 deletions tests/Integration/Momento.Sdk.Tests/AuthClientCacheTest.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Threading.Tasks;
using Momento.Sdk.Auth;
using Momento.Sdk.Auth.AccessControl;
using Momento.Sdk.Config;
using Newtonsoft.Json.Serialization;

namespace Momento.Sdk.Tests;

Expand Down Expand Up @@ -41,13 +38,13 @@ private async Task<ICacheClient> GetClientForTokenScope(DisposableTokenScope sco
return new CacheClient(Configurations.Laptop.Latest(), authProvider, TimeSpan.FromSeconds(60));
}

private async Task SetCacheKey()
private async Task SetCacheKey(string cacheName, string key, string value)
{
var setResponse = await cacheClient.SetAsync(cacheName, key, value);
Assert.True(setResponse is CacheSetResponse.Success);
}

private async Task VerifyCacheKey()
private async Task VerifyCacheKey(string cacheName, string key, string value)
{
var getResponse = await cacheClient.GetAsync(cacheName, key);
Assert.True(getResponse is CacheGetResponse.Hit);
Expand Down Expand Up @@ -182,7 +179,7 @@ public async Task GenerateDisposableCacheAuthToken_ReadOnly_HappyPath()
);
var setResponse = await readonlyCacheClient.SetAsync(cacheName, key, value);
AssertPermissionError<CacheSetResponse, CacheSetResponse.Error>(setResponse);
await SetCacheKey();
await SetCacheKey(cacheName, key, value);
var getResponse = await readonlyCacheClient.GetAsync(cacheName, key);
Assert.True(getResponse is CacheGetResponse.Hit);
if (getResponse is CacheGetResponse.Hit hit)
Expand All @@ -201,7 +198,7 @@ public async Task GenerateDisposableCacheAuthToken_WriteOnly_HappyPath()
Assert.True(setResponse is CacheSetResponse.Success);
var getResponse = await writeonlyCacheClient.GetAsync(cacheName, key);
AssertPermissionError<CacheGetResponse, CacheGetResponse.Error>(getResponse);
await VerifyCacheKey();
await VerifyCacheKey(cacheName, key, value);
writeonlyCacheClient = await GetClientForTokenScope(
DisposableTokenScopes.CacheWriteOnly("someothercache")
);
Expand Down Expand Up @@ -334,7 +331,7 @@ public async Task GenerateDisposableCacheKeyAuthToken_ReadOnly_HappyPath()
);
var setResponse = await readonlyCacheClient.SetAsync(cacheName, key, value);
AssertPermissionError<CacheSetResponse, CacheSetResponse.Error>(setResponse);
await SetCacheKey();
await SetCacheKey(cacheName, key, value);
var getResponse = await readonlyCacheClient.GetAsync(cacheName, key);
Assert.True(getResponse is CacheGetResponse.Hit);
if (getResponse is CacheGetResponse.Hit hit)
Expand Down Expand Up @@ -363,7 +360,7 @@ public async Task GenerateDisposableCacheKeyAuthToken_WriteOnly_HappyPath()
Assert.True(setResponse is CacheSetResponse.Success);
var getResponse = await writeonlyCacheClient.GetAsync(cacheName, key);
AssertPermissionError<CacheGetResponse, CacheGetResponse.Error>(getResponse);
await VerifyCacheKey();
await VerifyCacheKey(cacheName, key, value);
writeonlyCacheClient = await GetClientForTokenScope(
DisposableTokenScopes.CacheKeyWriteOnly("otherCache", key)
);
Expand Down Expand Up @@ -504,7 +501,7 @@ public async Task GenerateDisposableCacheKeyPrefixAuthToken_ReadOnly_HappyPath()
);
var setResponse = await readonlyCacheClient.SetAsync(cacheName, key, value);
AssertPermissionError<CacheSetResponse, CacheSetResponse.Error>(setResponse);
await SetCacheKey();
await SetCacheKey(cacheName, key, value);
var getResponse = await readonlyCacheClient.GetAsync(cacheName, key);
Assert.True(getResponse is CacheGetResponse.Hit);
if (getResponse is CacheGetResponse.Hit hit)
Expand Down Expand Up @@ -537,7 +534,7 @@ public async Task GenerateDisposableCacheKeyPrefixAuthToken_WriteOnly_HappyPath(
Assert.True(setResponse is CacheSetResponse.Success);
var getResponse = await writeonlyCacheClient.GetAsync(cacheName, key);
AssertPermissionError<CacheGetResponse, CacheGetResponse.Error>(getResponse);
await VerifyCacheKey();
await VerifyCacheKey(cacheName, key, value);
writeonlyCacheClient = await GetClientForTokenScope(
DisposableTokenScopes.CacheKeyPrefixWriteOnly("otherCache", keyPrefix)
);
Expand All @@ -553,4 +550,183 @@ public async Task GenerateDisposableCacheKeyPrefixAuthToken_WriteOnly_HappyPath(
getResponse = await writeonlyCacheClient.GetAsync(cacheName, key);
AssertPermissionError<CacheGetResponse, CacheGetResponse.Error>(getResponse);
}

// Tests using DisposableTokenScopes composed from multiple permissions

[Fact]
public async Task GenerateDisposableMultiPermissionScope_ReadWriteWithSelectors()
{
var scope = new DisposableTokenScope(Permissions: new List<DisposableTokenPermission>{
new DisposableToken.CacheItemPermission(
CacheRole.ReadWrite,
CacheSelector.ByName(cacheName),
CacheItemSelector.ByKey("cow")
),
new DisposableToken.CacheItemPermission(
CacheRole.ReadWrite,
CacheSelector.ByName(cacheName),
CacheItemSelector.ByKeyPrefix("pet")
)
});
var client = await GetClientForTokenScope(scope);

// we can read/write our key and key prefix in the test cache
var setResponse = await client.SetAsync(cacheName, "cow", "moo");
Assert.True(setResponse is CacheSetResponse.Success);
var getResponse = await client.GetAsync(cacheName, "cow");
Assert.True(getResponse is CacheGetResponse.Hit);
if (getResponse is CacheGetResponse.Hit hit)
{
Assert.Equal(hit.ValueString, "moo");
}

setResponse = await client.SetAsync(cacheName, "pet-cat", "meow");
Assert.True(setResponse is CacheSetResponse.Success);
getResponse = await client.GetAsync(cacheName, "pet-cat");
Assert.True(getResponse is CacheGetResponse.Hit);
if (getResponse is CacheGetResponse.Hit hit2)
{
Assert.Equal(hit2.ValueString, "meow");
}

setResponse = await client.SetAsync(cacheName, "giraffe", "noidea");
AssertPermissionError<CacheSetResponse, CacheSetResponse.Error>(setResponse);
getResponse = await client.GetAsync(cacheName, "giraffe");
AssertPermissionError<CacheGetResponse, CacheGetResponse.Error>(getResponse);

// we cannot read/write a specified key or keyPrefix to a different cache
scope = new DisposableTokenScope(Permissions: new List<DisposableTokenPermission>{
new DisposableToken.CacheItemPermission(
CacheRole.ReadWrite,
CacheSelector.ByName("a-totally-different-cache"),
CacheItemSelector.ByKey("cow")
),
new DisposableToken.CacheItemPermission(
CacheRole.ReadWrite,
CacheSelector.ByName("a-totally-different-cache"),
CacheItemSelector.ByKeyPrefix("pet")
)
});
client = await GetClientForTokenScope(scope);

setResponse = await client.SetAsync(cacheName, "cow", "moo");
AssertPermissionError<CacheSetResponse, CacheSetResponse.Error>(setResponse);
getResponse = await client.GetAsync(cacheName, "cow");
AssertPermissionError<CacheGetResponse, CacheGetResponse.Error>(getResponse);

setResponse = await client.SetAsync(cacheName, "pet-cat", "meow");
AssertPermissionError<CacheSetResponse, CacheSetResponse.Error>(setResponse);
getResponse = await client.GetAsync(cacheName, "pet-cat");
AssertPermissionError<CacheGetResponse, CacheGetResponse.Error>(getResponse);
}

[Fact]
public async Task GenerateDisposableMultiPermission_ReadOnlyWithSelectorsAllCaches()
{
var cache2Name = cacheName + "-2";
try
{
// create a second cache
Assert.True(await cacheClient.CreateCacheAsync(cache2Name) is CreateCacheResponse.Success);

var scope = new DisposableTokenScope(Permissions: new List<DisposableTokenPermission>{
new DisposableToken.CacheItemPermission(
CacheRole.ReadOnly,
CacheSelector.AllCaches,
CacheItemSelector.ByKey("cow")
),
new DisposableToken.CacheItemPermission(
CacheRole.ReadOnly,
CacheSelector.AllCaches,
CacheItemSelector.ByKeyPrefix("pet")
)
});
var client = await GetClientForTokenScope(scope);

// sets should fail for both caches
var setResponse = await client.SetAsync(cacheName, "cow", "moo");
AssertPermissionError<CacheSetResponse, CacheSetResponse.Error>(setResponse);
setResponse = await client.SetAsync(cache2Name, "pet-koala", "awwww");
AssertPermissionError<CacheSetResponse, CacheSetResponse.Error>(setResponse);

// gets should succeed for specified key and key prefix but fail for other keys
await SetCacheKey(cacheName, "cow", "moo");
await SetCacheKey(cacheName, "pet-koala", "awww");
await SetCacheKey(cacheName, "dog", "woof");
await SetCacheKey(cache2Name, "cow", "moo");
await SetCacheKey(cache2Name, "pet-koala", "awww");
await SetCacheKey(cache2Name, "dog", "woof");

var getResponse = await client.GetAsync(cacheName, "cow");
Assert.True(getResponse is CacheGetResponse.Hit);
getResponse = await client.GetAsync(cacheName, "pet-koala");
Assert.True(getResponse is CacheGetResponse.Hit);
getResponse = await client.GetAsync(cache2Name, "cow");
Assert.True(getResponse is CacheGetResponse.Hit);
getResponse = await client.GetAsync(cache2Name, "pet-koala");
Assert.True(getResponse is CacheGetResponse.Hit);
getResponse = await client.GetAsync(cacheName, "dog");
AssertPermissionError<CacheGetResponse, CacheGetResponse.Error>(getResponse);
getResponse = await client.GetAsync(cache2Name, "dog");
AssertPermissionError<CacheGetResponse, CacheGetResponse.Error>(getResponse);
}
finally
{
// delete the second cache
Assert.True(await cacheClient.DeleteCacheAsync(cache2Name) is DeleteCacheResponse.Success);
}
}

[Fact]
public async Task GenerateDisposableMultiPermission_ReadOnlyWriteOnly()
{
var cache2Name = cacheName + "-2";
try
{
// create a second cache
Assert.True(await cacheClient.CreateCacheAsync(cache2Name) is CreateCacheResponse.Success);

var scope = new DisposableTokenScope(Permissions: new List<DisposableTokenPermission>{
new DisposableToken.CacheItemPermission(
CacheRole.WriteOnly,
CacheSelector.ByName(cacheName),
CacheItemSelector.ByKey("cow")
),
new DisposableToken.CacheItemPermission(
CacheRole.ReadOnly,
CacheSelector.ByName(cache2Name),
CacheItemSelector.ByKeyPrefix("pet")
)
});
var client = await GetClientForTokenScope(scope);

// we can write to only one key and not read in test cache
var setResponse = await client.SetAsync(cacheName, "cow", "moo");
Assert.True(setResponse is CacheSetResponse.Success);
var getResponse = await client.GetAsync(cacheName, "cow");
AssertPermissionError<CacheGetResponse, CacheGetResponse.Error>(getResponse);
setResponse = await client.SetAsync(cacheName, "parrot", "somethingaboutcrackers");
AssertPermissionError<CacheSetResponse, CacheSetResponse.Error>(setResponse);
await VerifyCacheKey(cacheName, "cow", "moo");

// we can read prefixed keys but no others and cannot write in the second cache
await SetCacheKey(cache2Name, "pet-armadillo", "thunk");
await SetCacheKey(cache2Name, "snake", "hiss");
getResponse = await client.GetAsync(cache2Name, "pet-armadillo");
Assert.True(getResponse is CacheGetResponse.Hit);
if (getResponse is CacheGetResponse.Hit hit)
{
Assert.Equal(hit.ValueString, "thunk");
}
setResponse = await client.SetAsync(cache2Name, "pet-armadillo", "meow");
AssertPermissionError<CacheSetResponse, CacheSetResponse.Error>(setResponse);
getResponse = await client.GetAsync(cache2Name, "snake");
AssertPermissionError<CacheGetResponse, CacheGetResponse.Error>(getResponse);
}
finally
{
// delete the second cache
Assert.True(await cacheClient.DeleteCacheAsync(cache2Name) is DeleteCacheResponse.Success);
}
}
}

0 comments on commit 6db0107

Please sign in to comment.