Skip to content

Commit

Permalink
Merge pull request #484 from momentohq/disposable-tokens-docs-example
Browse files Browse the repository at this point in the history
chore: add topics and disposable token code snippets for dev docs
  • Loading branch information
anitarua authored Sep 13, 2023
2 parents ea56860 + e6c6a97 commit 4678836
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 1 deletion.
2 changes: 1 addition & 1 deletion examples/DocExampleApis/DocExampleApis.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Momento.Sdk" Version="1.19.0" />
<PackageReference Include="Momento.Sdk" Version="1.21.1" />
</ItemGroup>

</Project>
145 changes: 145 additions & 0 deletions examples/DocExampleApis/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Momento.Sdk;
using Momento.Sdk.Auth;
using Momento.Sdk.Auth.AccessControl;
using Momento.Sdk.Config;
using Momento.Sdk.Responses;

Expand All @@ -12,6 +13,14 @@ public static async Task Main(string[] args)
var client = new CacheClient(config,
new EnvMomentoTokenProvider("MOMENTO_AUTH_TOKEN"),
TimeSpan.FromSeconds(10));
IAuthClient authClient = new AuthClient(
AuthConfigurations.Default.Latest(),
new EnvMomentoTokenProvider("MOMENTO_AUTH_TOKEN")
);
ITopicClient topicClient = new TopicClient(
TopicConfigurations.Laptop.latest(),
new EnvMomentoTokenProvider("MOMENTO_AUTH_TOKEN")
);

await Example_API_CreateCache(client);
await Example_API_FlushCache(client);
Expand All @@ -22,6 +31,12 @@ public static async Task Main(string[] args)
await Example_API_Set(client);
await Example_API_Get(client);
await Example_API_Delete(client);

await Example_API_GenerateDisposableToken(authClient);

await Example_API_InstantiateTopicClient();
await Example_API_TopicSubscribe(topicClient);
await Example_API_TopicPublish(topicClient);
}

public static async Task Example_API_CreateCache(CacheClient cacheClient)
Expand Down Expand Up @@ -122,4 +137,134 @@ public static async Task Example_API_Delete(CacheClient cacheClient)
throw new Exception($"An error occurred while attempting to delete key 'test-key' from cache 'test-cache': {error.ErrorCode}: {error}");
}
}

public static async Task Example_API_GenerateDisposableToken(IAuthClient authClient)
{
// Generate a disposable token with read-write access to a specific key in one cache
var oneKeyOneCacheToken = await authClient.GenerateDisposableTokenAsync(
DisposableTokenScopes.CacheKeyReadWrite("squirrels", "mo"),
ExpiresIn.Minutes(30)
);

if (oneKeyOneCacheToken is GenerateDisposableTokenResponse.Success token1)
{
// logging only a substring of the tokens, because logging security credentials is not advisable :)
Console.WriteLine("The generated disposable token starts with: " + token1.AuthToken.Substring(0, 10));
Console.WriteLine("The token expires at (epoch timestamp): " + token1.ExpiresAt.Epoch());
}
else if (oneKeyOneCacheToken is GenerateDisposableTokenResponse.Error err)
{
Console.WriteLine("Error generating disposable token: " + err.Message);
}

// Generate a disposable token with read-write access to a specific key prefix in all caches
var keyPrefixAllCachesToken = await authClient.GenerateDisposableTokenAsync(
DisposableTokenScopes.CacheKeyPrefixReadWrite(CacheSelector.AllCaches, "squirrel"),
ExpiresIn.Minutes(30)
);

if (keyPrefixAllCachesToken is GenerateDisposableTokenResponse.Success token2)
{
// logging only a substring of the tokens, because logging security credentials is not advisable :)
Console.WriteLine("The generated disposable token starts with: " + token2.AuthToken.Substring(0, 10));
Console.WriteLine("The token expires at (epoch timestamp): " + token2.ExpiresAt.Epoch());
}
else if (keyPrefixAllCachesToken is GenerateDisposableTokenResponse.Error err)
{
Console.WriteLine("Error generating disposable token: " + err.Message);
}

// Generate a disposable token with read-only access to all topics in one cache
var allTopicsOneCacheToken = await authClient.GenerateDisposableTokenAsync(
DisposableTokenScopes.TopicSubscribeOnly(CacheSelector.ByName("squirrel"), TopicSelector.AllTopics),
ExpiresIn.Minutes(30)
);

if (allTopicsOneCacheToken is GenerateDisposableTokenResponse.Success token3)
{
// logging only a substring of the tokens, because logging security credentials is not advisable :)
Console.WriteLine("The generated disposable token starts with: " + token3.AuthToken.Substring(0, 10));
Console.WriteLine("The token expires at (epoch timestamp): " + token3.ExpiresAt.Epoch());
}
else if (allTopicsOneCacheToken is GenerateDisposableTokenResponse.Error err)
{
Console.WriteLine("Error generating disposable token: " + err.Message);
}

// Generate a disposable token with write-only access to a single topic in all caches
var oneTopicAllCachesToken = await authClient.GenerateDisposableTokenAsync(
DisposableTokenScopes.TopicPublishOnly(CacheSelector.AllCaches, "acorn"),
ExpiresIn.Minutes(30)
);

if (oneTopicAllCachesToken is GenerateDisposableTokenResponse.Success token4)
{
// logging only a substring of the tokens, because logging security credentials is not advisable :)
Console.WriteLine("The generated disposable token starts with: " + token4.AuthToken.Substring(0, 10));
Console.WriteLine("The token expires at (epoch timestamp): " + token4.ExpiresAt.Epoch());
}
else if (oneTopicAllCachesToken is GenerateDisposableTokenResponse.Error err)
{
Console.WriteLine("Error generating disposable token: " + err.Message);
}

}

public static async Task Example_API_InstantiateTopicClient()
{
new TopicClient(
TopicConfigurations.Laptop.latest(),
new EnvMomentoTokenProvider("MOMENTO_AUTH_TOKEN")
);
}
public static async Task Example_API_TopicPublish(ITopicClient topicClient)
{
var publishResponse =
await topicClient.PublishAsync("test-cache", "test-topic", "test-topic-value");
switch (publishResponse)
{
case TopicPublishResponse.Success:
Console.WriteLine("Successfully published message to 'test-topic'");
break;
case TopicPublishResponse.Error error:
throw new Exception($"An error occurred while publishing topic message: {error.ErrorCode}: {error}");
}
}
public static async Task Example_API_TopicSubscribe(ITopicClient topicClient)
{
var produceCancellation = new CancellationTokenSource();
produceCancellation.CancelAfter(2000);

var subscribeResponse = await topicClient.SubscribeAsync("test-cache", "test-topic");
switch (subscribeResponse)
{
case TopicSubscribeResponse.Subscription subscription:
var cancellableSubscription = subscription.WithCancellation(produceCancellation.Token);

await Task.Delay(1_000);
await topicClient.PublishAsync("test-cache", "test-topic", "test-topic-value");
await Task.Delay(1_000);

await foreach (var message in cancellableSubscription)
{
switch (message)
{
case TopicMessage.Binary:
Console.WriteLine("Received unexpected binary message from topic.");
break;
case TopicMessage.Text text:
Console.WriteLine($"Received string message from topic: {text.Value}");
break;
case TopicMessage.Error error:
throw new Exception($"An error occurred while receiving topic message: {error.ErrorCode}: {error}");
default:
throw new Exception("Bad message received");
}
}
subscription.Dispose();
break;
case TopicSubscribeResponse.Error error:
throw new Exception($"An error occurred subscribing to a topic: {error.ErrorCode}: {error}");
}
}
}
15 changes: 15 additions & 0 deletions src/Momento.Sdk/Auth/AccessControl/DisposableTokenScopes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,11 @@ public static DisposableTokenScope TopicPublishSubscribe(CacheSelector cacheSele
return TopicPublishSubscribe(cacheSelector, TopicSelector.ByName(topicName));
}

public static DisposableTokenScope TopicPublishSubscribe(string cacheName, TopicSelector topicSelector)
{
return TopicPublishSubscribe(CacheSelector.ByName(cacheName), topicSelector);
}

public static DisposableTokenScope TopicPublishSubscribe(CacheSelector cacheSelector, TopicSelector topicSelector)
{
return new DisposableTokenScope(Permissions: new List<DisposableTokenPermission>
Expand All @@ -225,6 +230,11 @@ public static DisposableTokenScope TopicSubscribeOnly(CacheSelector cacheSelecto
return TopicSubscribeOnly(cacheSelector, TopicSelector.ByName(topicName));
}

public static DisposableTokenScope TopicSubscribeOnly(string cacheName, TopicSelector topicSelector)
{
return TopicSubscribeOnly(CacheSelector.ByName(cacheName), topicSelector);
}

public static DisposableTokenScope TopicSubscribeOnly(CacheSelector cacheSelector, TopicSelector topicSelector)
{
return new DisposableTokenScope(Permissions: new List<DisposableTokenPermission>
Expand All @@ -247,6 +257,11 @@ public static DisposableTokenScope TopicPublishOnly(CacheSelector cacheSelector,
return TopicPublishOnly(cacheSelector, TopicSelector.ByName(topicName));
}

public static DisposableTokenScope TopicPublishOnly(string cacheName, TopicSelector topicSelector)
{
return TopicPublishOnly(CacheSelector.ByName(cacheName), topicSelector);
}

public static DisposableTokenScope TopicPublishOnly(CacheSelector cacheSelector, TopicSelector topicSelector)
{
return new DisposableTokenScope(Permissions: new List<DisposableTokenPermission>
Expand Down

0 comments on commit 4678836

Please sign in to comment.