From d3630a90d7b333011376f0f3faab842f189f9265 Mon Sep 17 00:00:00 2001
From: Rachel Hagerman <110480692+rlhagerm@users.noreply.github.com>
Date: Fri, 7 Feb 2025 16:05:57 -0600
Subject: [PATCH 1/3] v4 Cognito code
---
.../Cognito/Actions/CognitoActions.csproj | 17 +
dotnetv4/Cognito/Actions/CognitoWrapper.cs | 347 ++++++++++++++++++
dotnetv4/Cognito/Actions/HelloCognito.cs | 64 ++++
dotnetv4/Cognito/Actions/Usings.cs | 13 +
dotnetv4/Cognito/CognitoExamples.sln | 48 +++
dotnetv4/Cognito/README.md | 138 +++++++
.../Scenarios/Cognito_Basics/CognitoBasics.cs | 160 ++++++++
.../Cognito_Basics/CognitoBasics.csproj | 29 ++
.../Scenarios/Cognito_Basics/UIMethods.cs | 44 +++
.../Scenarios/Cognito_Basics/Usings.cs | 14 +
.../Scenarios/Cognito_Basics/settings.json | 9 +
dotnetv4/Cognito/Tests/CognitoBasicsTests.cs | 198 ++++++++++
dotnetv4/Cognito/Tests/CognitoTests.csproj | 38 ++
dotnetv4/Cognito/Tests/Usings.cs | 8 +
dotnetv4/Cognito/Tests/testsettings.json | 8 +
15 files changed, 1135 insertions(+)
create mode 100644 dotnetv4/Cognito/Actions/CognitoActions.csproj
create mode 100644 dotnetv4/Cognito/Actions/CognitoWrapper.cs
create mode 100644 dotnetv4/Cognito/Actions/HelloCognito.cs
create mode 100644 dotnetv4/Cognito/Actions/Usings.cs
create mode 100644 dotnetv4/Cognito/CognitoExamples.sln
create mode 100644 dotnetv4/Cognito/README.md
create mode 100644 dotnetv4/Cognito/Scenarios/Cognito_Basics/CognitoBasics.cs
create mode 100644 dotnetv4/Cognito/Scenarios/Cognito_Basics/CognitoBasics.csproj
create mode 100644 dotnetv4/Cognito/Scenarios/Cognito_Basics/UIMethods.cs
create mode 100644 dotnetv4/Cognito/Scenarios/Cognito_Basics/Usings.cs
create mode 100644 dotnetv4/Cognito/Scenarios/Cognito_Basics/settings.json
create mode 100644 dotnetv4/Cognito/Tests/CognitoBasicsTests.cs
create mode 100644 dotnetv4/Cognito/Tests/CognitoTests.csproj
create mode 100644 dotnetv4/Cognito/Tests/Usings.cs
create mode 100644 dotnetv4/Cognito/Tests/testsettings.json
diff --git a/dotnetv4/Cognito/Actions/CognitoActions.csproj b/dotnetv4/Cognito/Actions/CognitoActions.csproj
new file mode 100644
index 00000000000..653035419c0
--- /dev/null
+++ b/dotnetv4/Cognito/Actions/CognitoActions.csproj
@@ -0,0 +1,17 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
diff --git a/dotnetv4/Cognito/Actions/CognitoWrapper.cs b/dotnetv4/Cognito/Actions/CognitoWrapper.cs
new file mode 100644
index 00000000000..188a6bb1cd2
--- /dev/null
+++ b/dotnetv4/Cognito/Actions/CognitoWrapper.cs
@@ -0,0 +1,347 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+// snippet-start:[Cognito.dotnetv4.CognitoWrapper]
+using System.Net;
+
+namespace CognitoActions;
+
+///
+/// Methods to perform Amazon Cognito Identity Provider actions.
+///
+public class CognitoWrapper
+{
+ private readonly IAmazonCognitoIdentityProvider _cognitoService;
+
+ ///
+ /// Constructor for the wrapper class containing Amazon Cognito actions.
+ ///
+ /// The Amazon Cognito client object.
+ public CognitoWrapper(IAmazonCognitoIdentityProvider cognitoService)
+ {
+ _cognitoService = cognitoService;
+ }
+
+ // snippet-start:[Cognito.dotnetv4.ListUserPools]
+ ///
+ /// List the Amazon Cognito user pools for an account.
+ ///
+ /// A list of UserPoolDescriptionType objects.
+ public async Task> ListUserPoolsAsync()
+ {
+ var userPools = new List();
+
+ var userPoolsPaginator = _cognitoService.Paginators.ListUserPools(new ListUserPoolsRequest());
+
+ await foreach (var response in userPoolsPaginator.Responses)
+ {
+ userPools.AddRange(response.UserPools);
+ }
+
+ return userPools;
+ }
+
+ // snippet-end:[Cognito.dotnetv4.ListUserPools]
+
+ // snippet-start:[Cognito.dotnetv4.ListUsers]
+ ///
+ /// Get a list of users for the Amazon Cognito user pool.
+ ///
+ /// The user pool ID.
+ /// A list of users.
+ public async Task> ListUsersAsync(string userPoolId)
+ {
+ var request = new ListUsersRequest
+ {
+ UserPoolId = userPoolId
+ };
+
+ var users = new List();
+
+ var usersPaginator = _cognitoService.Paginators.ListUsers(request);
+ await foreach (var response in usersPaginator.Responses)
+ {
+ users.AddRange(response.Users);
+ }
+
+ return users;
+ }
+
+ // snippet-end:[Cognito.dotnetv4.ListUsers]
+
+ // snippet-start:[Cognito.dotnetv4.AdminRespondToAuthChallenge]
+ ///
+ /// Respond to an admin authentication challenge.
+ ///
+ /// The name of the user.
+ /// The client ID.
+ /// The multi-factor authentication code.
+ /// The current application session.
+ /// The user pool ID.
+ /// The result of the authentication response.
+ public async Task AdminRespondToAuthChallengeAsync(
+ string userName,
+ string clientId,
+ string mfaCode,
+ string session,
+ string userPoolId)
+ {
+ Console.WriteLine("SOFTWARE_TOKEN_MFA challenge is generated");
+
+ var challengeResponses = new Dictionary();
+ challengeResponses.Add("USERNAME", userName);
+ challengeResponses.Add("SOFTWARE_TOKEN_MFA_CODE", mfaCode);
+
+ var respondToAuthChallengeRequest = new AdminRespondToAuthChallengeRequest
+ {
+ ChallengeName = ChallengeNameType.SOFTWARE_TOKEN_MFA,
+ ClientId = clientId,
+ ChallengeResponses = challengeResponses,
+ Session = session,
+ UserPoolId = userPoolId,
+ };
+
+ var response = await _cognitoService.AdminRespondToAuthChallengeAsync(respondToAuthChallengeRequest);
+ Console.WriteLine($"Response to Authentication {response.AuthenticationResult.TokenType}");
+ return response.AuthenticationResult;
+ }
+
+ // snippet-end:[Cognito.dotnetv4.AdminRespondToAuthChallenge]
+
+ // snippet-start:[Cognito.dotnetv4.VerifySoftwareToken]
+ ///
+ /// Verify the TOTP and register for MFA.
+ ///
+ /// The name of the session.
+ /// The MFA code.
+ /// The status of the software token.
+ public async Task VerifySoftwareTokenAsync(string session, string code)
+ {
+ var tokenRequest = new VerifySoftwareTokenRequest
+ {
+ UserCode = code,
+ Session = session,
+ };
+
+ var verifyResponse = await _cognitoService.VerifySoftwareTokenAsync(tokenRequest);
+
+ return verifyResponse.Status;
+ }
+
+ // snippet-end:[Cognito.dotnetv4.VerifySoftwareToken]
+
+ // snippet-start:[Cognito.dotnetv4.AssociateSoftwareToken]
+ ///
+ /// Get an MFA token to authenticate the user with the authenticator.
+ ///
+ /// The session name.
+ /// The session name.
+ public async Task AssociateSoftwareTokenAsync(string session)
+ {
+ var softwareTokenRequest = new AssociateSoftwareTokenRequest
+ {
+ Session = session,
+ };
+
+ var tokenResponse = await _cognitoService.AssociateSoftwareTokenAsync(softwareTokenRequest);
+ var secretCode = tokenResponse.SecretCode;
+
+ Console.WriteLine($"Use the following secret code to set up the authenticator: {secretCode}");
+
+ return tokenResponse.Session;
+ }
+
+ // snippet-end:[Cognito.dotnetv4.AssociateSoftwareToken]
+
+ // snippet-start:[Cognito.dotnetv4.AdminInitiateAuth]
+ ///
+ /// Initiate an admin auth request.
+ ///
+ /// The client ID to use.
+ /// The ID of the user pool.
+ /// The username to authenticate.
+ /// The user's password.
+ /// The session to use in challenge-response.
+ public async Task AdminInitiateAuthAsync(string clientId, string userPoolId, string userName, string password)
+ {
+ var authParameters = new Dictionary();
+ authParameters.Add("USERNAME", userName);
+ authParameters.Add("PASSWORD", password);
+
+ var request = new AdminInitiateAuthRequest
+ {
+ ClientId = clientId,
+ UserPoolId = userPoolId,
+ AuthParameters = authParameters,
+ AuthFlow = AuthFlowType.ADMIN_USER_PASSWORD_AUTH,
+ };
+
+ var response = await _cognitoService.AdminInitiateAuthAsync(request);
+ return response.Session;
+ }
+ // snippet-end:[Cognito.dotnetv4.AdminInitiateAuth]
+
+ // snippet-start:[Cognito.dotnetv4.InitiateAuth]
+ ///
+ /// Initiate authorization.
+ ///
+ /// The client Id of the application.
+ /// The name of the user who is authenticating.
+ /// The password for the user who is authenticating.
+ /// The response from the initiate auth request.
+ public async Task InitiateAuthAsync(string clientId, string userName, string password)
+ {
+ var authParameters = new Dictionary();
+ authParameters.Add("USERNAME", userName);
+ authParameters.Add("PASSWORD", password);
+
+ var authRequest = new InitiateAuthRequest
+
+ {
+ ClientId = clientId,
+ AuthParameters = authParameters,
+ AuthFlow = AuthFlowType.USER_PASSWORD_AUTH,
+ };
+
+ var response = await _cognitoService.InitiateAuthAsync(authRequest);
+ Console.WriteLine($"Result Challenge is : {response.ChallengeName}");
+
+ return response;
+ }
+ // snippet-end:[Cognito.dotnetv4.InitiateAuth]
+
+ // snippet-start:[Cognito.dotnetv4.ConfirmSignUp]
+ ///
+ /// Confirm that the user has signed up.
+ ///
+ /// The Id of this application.
+ /// The confirmation code sent to the user.
+ /// The username.
+ /// True if successful.
+ public async Task ConfirmSignupAsync(string clientId, string code, string userName)
+ {
+ var signUpRequest = new ConfirmSignUpRequest
+ {
+ ClientId = clientId,
+ ConfirmationCode = code,
+ Username = userName,
+ };
+
+ var response = await _cognitoService.ConfirmSignUpAsync(signUpRequest);
+ if (response.HttpStatusCode == HttpStatusCode.OK)
+ {
+ Console.WriteLine($"{userName} was confirmed");
+ return true;
+ }
+ return false;
+ }
+
+ // snippet-end:[Cognito.dotnetv4.ConfirmSignUp]
+
+ // snippet-start:[Cognito.dotnetv4.ConfirmDevice]
+ ///
+ /// Initiates and confirms tracking of the device.
+ ///
+ /// The user's access token.
+ /// The key of the device from Amazon Cognito.
+ /// The device name.
+ ///
+ public async Task ConfirmDeviceAsync(string accessToken, string deviceKey, string deviceName)
+ {
+ var request = new ConfirmDeviceRequest
+ {
+ AccessToken = accessToken,
+ DeviceKey = deviceKey,
+ DeviceName = deviceName
+ };
+
+ var response = await _cognitoService.ConfirmDeviceAsync(request);
+ return response.UserConfirmationNecessary;
+ }
+
+ // snippet-end:[Cognito.dotnetv4.ConfirmDevice]
+
+ // snippet-start:[Cognito.dotnetv4.ResendConfirmationCode]
+ ///
+ /// Send a new confirmation code to a user.
+ ///
+ /// The Id of the client application.
+ /// The username of user who will receive the code.
+ /// The delivery details.
+ public async Task ResendConfirmationCodeAsync(string clientId, string userName)
+ {
+ var codeRequest = new ResendConfirmationCodeRequest
+ {
+ ClientId = clientId,
+ Username = userName,
+ };
+
+ var response = await _cognitoService.ResendConfirmationCodeAsync(codeRequest);
+
+ Console.WriteLine($"Method of delivery is {response.CodeDeliveryDetails.DeliveryMedium}");
+
+ return response.CodeDeliveryDetails;
+ }
+
+ // snippet-end:[Cognito.dotnetv4.ResendConfirmationCode]
+
+ // snippet-start:[Cognito.dotnetv4.GetAdminUser]
+ ///
+ /// Get the specified user from an Amazon Cognito user pool with administrator access.
+ ///
+ /// The name of the user.
+ /// The Id of the Amazon Cognito user pool.
+ /// Async task.
+ public async Task GetAdminUserAsync(string userName, string poolId)
+ {
+ AdminGetUserRequest userRequest = new AdminGetUserRequest
+ {
+ Username = userName,
+ UserPoolId = poolId,
+ };
+
+ var response = await _cognitoService.AdminGetUserAsync(userRequest);
+
+ Console.WriteLine($"User status {response.UserStatus}");
+ return response.UserStatus;
+ }
+
+ // snippet-end:[Cognito.dotnetv4.GetAdminUser]
+
+ // snippet-start:[Cognito.dotnetv4.SignUp]
+ ///
+ /// Sign up a new user.
+ ///
+ /// The client Id of the application.
+ /// The username to use.
+ /// The user's password.
+ /// The email address of the user.
+ /// A Boolean value indicating whether the user was confirmed.
+ public async Task SignUpAsync(string clientId, string userName, string password, string email)
+ {
+ var userAttrs = new AttributeType
+ {
+ Name = "email",
+ Value = email,
+ };
+
+ var userAttrsList = new List();
+
+ userAttrsList.Add(userAttrs);
+
+ var signUpRequest = new SignUpRequest
+ {
+ UserAttributes = userAttrsList,
+ Username = userName,
+ ClientId = clientId,
+ Password = password
+ };
+
+ var response = await _cognitoService.SignUpAsync(signUpRequest);
+ return response.HttpStatusCode == HttpStatusCode.OK;
+ }
+
+ // snippet-end:[Cognito.dotnetv4.SignUp]
+}
+
+// snippet-end:[Cognito.dotnetv4.CognitoWrapper]
\ No newline at end of file
diff --git a/dotnetv4/Cognito/Actions/HelloCognito.cs b/dotnetv4/Cognito/Actions/HelloCognito.cs
new file mode 100644
index 00000000000..4d850395336
--- /dev/null
+++ b/dotnetv4/Cognito/Actions/HelloCognito.cs
@@ -0,0 +1,64 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+// snippet-start:[Cognito.dotnetv4.HelloCognito]
+
+using LogLevel = Microsoft.Extensions.Logging.LogLevel;
+
+namespace CognitoActions;
+
+///
+/// A class that introduces the Amazon Cognito Identity Provider by listing the
+/// user pools for the account.
+///
+public class HelloCognito
+{
+ private static ILogger logger = null!;
+
+ static async Task Main(string[] args)
+ {
+ // Set up dependency injection for Amazon Cognito.
+ using var host = Host.CreateDefaultBuilder(args)
+ .ConfigureLogging(logging =>
+ logging.AddFilter("System", LogLevel.Debug)
+ .AddFilter("Microsoft", LogLevel.Information)
+ .AddFilter("Microsoft", LogLevel.Trace))
+ .ConfigureServices((_, services) =>
+ services.AddAWSService()
+ .AddTransient()
+ )
+ .Build();
+
+ logger = LoggerFactory.Create(builder => { builder.AddConsole(); })
+ .CreateLogger();
+
+ var amazonClient = host.Services.GetRequiredService();
+
+ Console.Clear();
+ Console.WriteLine("Hello Amazon Cognito.");
+ Console.WriteLine("Let's get a list of your Amazon Cognito user pools.");
+
+ var userPools = new List();
+
+ var userPoolsPaginator = amazonClient.Paginators.ListUserPools(new ListUserPoolsRequest());
+
+ await foreach (var response in userPoolsPaginator.Responses)
+ {
+ userPools.AddRange(response.UserPools);
+ }
+
+ if (userPools.Count > 0)
+ {
+ userPools.ForEach(userPool =>
+ {
+ Console.WriteLine($"{userPool.Name}\t{userPool.Id}\t{userPool.Status}");
+ });
+ }
+ else
+ {
+ Console.WriteLine("No user pools were found.");
+ }
+ }
+}
+
+// snippet-end:[Cognito.dotnetv4.HelloCognito]
\ No newline at end of file
diff --git a/dotnetv4/Cognito/Actions/Usings.cs b/dotnetv4/Cognito/Actions/Usings.cs
new file mode 100644
index 00000000000..5b7cea27136
--- /dev/null
+++ b/dotnetv4/Cognito/Actions/Usings.cs
@@ -0,0 +1,13 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+// snippet-start:[Cognito.dotnetv3.Usings]
+global using Amazon.CognitoIdentityProvider;
+global using Amazon.CognitoIdentityProvider.Model;
+global using Microsoft.Extensions.DependencyInjection;
+global using Microsoft.Extensions.Hosting;
+global using Microsoft.Extensions.Logging;
+global using Microsoft.Extensions.Logging.Console;
+global using Microsoft.Extensions.Logging.Debug;
+
+// snippet-end:[Cognito.dotnetv3.Usings]
\ No newline at end of file
diff --git a/dotnetv4/Cognito/CognitoExamples.sln b/dotnetv4/Cognito/CognitoExamples.sln
new file mode 100644
index 00000000000..694f56abe02
--- /dev/null
+++ b/dotnetv4/Cognito/CognitoExamples.sln
@@ -0,0 +1,48 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.2.32630.192
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{7907FB6A-1353-4735-95DC-EEC5DF8C0649}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scenarios", "Scenarios", "{B987097B-189C-4D0B-99BC-E67CD705BCA0}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{5455D423-2AFC-4BC6-B79D-9DC4270D8F7D}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CognitoActions", "Actions\CognitoActions.csproj", "{796910FA-6E94-460B-8CB4-97DF01B9ADC8}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CognitoBasics", "Scenarios\Cognito_Basics\CognitoBasics.csproj", "{B1731AE1-381F-4044-BEBE-269FF7E24B1F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CognitoTests", "Tests\CognitoTests.csproj", "{6046A2FC-6A39-4C2D-8DD9-AA3740B17B88}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {796910FA-6E94-460B-8CB4-97DF01B9ADC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {796910FA-6E94-460B-8CB4-97DF01B9ADC8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {796910FA-6E94-460B-8CB4-97DF01B9ADC8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {796910FA-6E94-460B-8CB4-97DF01B9ADC8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B1731AE1-381F-4044-BEBE-269FF7E24B1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B1731AE1-381F-4044-BEBE-269FF7E24B1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B1731AE1-381F-4044-BEBE-269FF7E24B1F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B1731AE1-381F-4044-BEBE-269FF7E24B1F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6046A2FC-6A39-4C2D-8DD9-AA3740B17B88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6046A2FC-6A39-4C2D-8DD9-AA3740B17B88}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6046A2FC-6A39-4C2D-8DD9-AA3740B17B88}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6046A2FC-6A39-4C2D-8DD9-AA3740B17B88}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {796910FA-6E94-460B-8CB4-97DF01B9ADC8} = {7907FB6A-1353-4735-95DC-EEC5DF8C0649}
+ {B1731AE1-381F-4044-BEBE-269FF7E24B1F} = {B987097B-189C-4D0B-99BC-E67CD705BCA0}
+ {6046A2FC-6A39-4C2D-8DD9-AA3740B17B88} = {5455D423-2AFC-4BC6-B79D-9DC4270D8F7D}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {870D888D-5C8B-4057-8722-F73ECF38E513}
+ EndGlobalSection
+EndGlobal
diff --git a/dotnetv4/Cognito/README.md b/dotnetv4/Cognito/README.md
new file mode 100644
index 00000000000..eb9c4e7777b
--- /dev/null
+++ b/dotnetv4/Cognito/README.md
@@ -0,0 +1,138 @@
+# Amazon Cognito Identity Provider code examples for the SDK for .NET
+
+## Overview
+
+Shows how to use the AWS SDK for .NET to work with Amazon Cognito Identity Provider.
+
+
+
+
+_Amazon Cognito Identity Provider handles user authentication and authorization for your web and mobile apps._
+
+## ⚠ Important
+
+* Running this code might result in charges to your AWS account. For more details, see [AWS Pricing](https://aws.amazon.com/pricing/) and [Free Tier](https://aws.amazon.com/free/).
+* Running the tests might result in charges to your AWS account.
+* We recommend that you grant your code least privilege. At most, grant only the minimum permissions required to perform the task. For more information, see [Grant least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege).
+* This code is not tested in every AWS Region. For more information, see [AWS Regional Services](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services).
+
+
+
+
+## Code examples
+
+### Prerequisites
+
+For prerequisites, see the [README](../README.md#Prerequisites) in the `dotnetv3` folder.
+
+
+
+These examples also require the following resources:
+
+* An existing Amazon Cognito user pool that is configured to allow self sign-up.
+* A client ID to use for authenticating with Amazon Cognito.
+
+
+To create these resources, run the AWS CloudFormation script in the
+[resources/cdk/cognito_scenario_user_pool_with_mfa](../../../resources/cdk/cognito_scenario_user_pool_with_mfa)
+folder. This script outputs a user pool ID and a client ID that you can use to run
+the scenario.
+
+
+### Single actions
+
+Code excerpts that show you how to call individual service functions.
+
+- [AdminGetUser](Actions/CognitoWrapper.cs#L288)
+- [AdminInitiateAuth](Actions/CognitoWrapper.cs#L156)
+- [AdminRespondToAuthChallenge](Actions/CognitoWrapper.cs#L72)
+- [AssociateSoftwareToken](Actions/CognitoWrapper.cs#L133)
+- [ConfirmDevice](Actions/CognitoWrapper.cs#L241)
+- [ConfirmSignUp](Actions/CognitoWrapper.cs#L213)
+- [InitiateAuth](Actions/CognitoWrapper.cs#L184)
+- [ListUserPools](Actions/CognitoWrapper.cs#L25)
+- [ListUsers](Actions/CognitoWrapper.cs#L46)
+- [ResendConfirmationCode](Actions/CognitoWrapper.cs#L264)
+- [SignUp](Actions/CognitoWrapper.cs#L311)
+- [VerifySoftwareToken](Actions/CognitoWrapper.cs#L111)
+
+### Scenarios
+
+Code examples that show you how to accomplish a specific task by calling multiple
+functions within the same service.
+
+- [Sign up a user with a user pool that requires MFA](Actions/CognitoWrapper.cs)
+
+
+
+
+
+## Run the examples
+
+### Instructions
+
+For general instructions to run the examples, see the
+[README](../README.md#building-and-running-the-code-examples) in the `dotnetv3` folder.
+
+Some projects might include a settings.json file. Before compiling the project,
+you can change these values to match your own account and resources. Alternatively,
+add a settings.local.json file with your local settings, which will be loaded automatically
+when the application runs.
+
+After the example compiles, you can run it from the command line. To do so, navigate to
+the folder that contains the .csproj file and run the following command:
+
+```
+dotnet run
+```
+
+Alternatively, you can run the example from within your IDE.
+
+
+
+
+
+
+
+#### Sign up a user with a user pool that requires MFA
+
+This example shows you how to do the following:
+
+- Sign up and confirm a user with a username, password, and email address.
+- Set up multi-factor authentication by associating an MFA application with the user.
+- Sign in by using a password and an MFA code.
+
+
+
+
+
+
+
+
+### Tests
+
+⚠ Running tests might result in charges to your AWS account.
+
+
+To find instructions for running these tests, see the [README](../README.md#Tests)
+in the `dotnetv3` folder.
+
+
+
+
+
+
+## Additional resources
+
+- [Amazon Cognito Identity Provider Developer Guide](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools.html)
+- [Amazon Cognito Identity Provider API Reference](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/Welcome.html)
+- [SDK for .NET Amazon Cognito Identity Provider reference](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/CognitoIdentity/NCognitoIdentity.html)
+
+
+
+
+---
+
+Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
\ No newline at end of file
diff --git a/dotnetv4/Cognito/Scenarios/Cognito_Basics/CognitoBasics.cs b/dotnetv4/Cognito/Scenarios/Cognito_Basics/CognitoBasics.cs
new file mode 100644
index 00000000000..b79ddc1a59a
--- /dev/null
+++ b/dotnetv4/Cognito/Scenarios/Cognito_Basics/CognitoBasics.cs
@@ -0,0 +1,160 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+// snippet-start:[Cognito.dotnetv4.Main]
+
+using LogLevel = Microsoft.Extensions.Logging.LogLevel;
+
+namespace CognitoBasics;
+
+public static class CognitoBasics
+{
+ public static bool _interactive = true;
+
+ public static async Task Main(string[] args)
+ {
+ // Set up dependency injection for Amazon Cognito.
+ using var host = Host.CreateDefaultBuilder(args)
+ .ConfigureLogging(logging =>
+ logging.AddFilter("System", LogLevel.Debug)
+ .AddFilter("Microsoft", LogLevel.Information)
+ .AddFilter("Microsoft", LogLevel.Trace))
+ .ConfigureServices((_, services) =>
+ services.AddAWSService()
+ .AddTransient()
+ )
+ .Build(); ;
+
+ var configuration = new ConfigurationBuilder()
+ .SetBasePath(Directory.GetCurrentDirectory())
+ .AddJsonFile("settings.json") // Load settings from .json file.
+ .AddJsonFile("settings.local.json",
+ true) // Optionally load local settings.
+ .Build();
+
+ var cognitoWrapper = host.Services.GetRequiredService();
+
+ await RunScenario(cognitoWrapper, configuration);
+ }
+
+ ///
+ /// Run the example scenario.
+ ///
+ /// Wrapper for service actions.
+ /// Scenario configuration.
+ ///
+ public static async Task RunScenario(CognitoWrapper cognitoWrapper, IConfigurationRoot configuration)
+ {
+ Console.WriteLine(new string('-', 80));
+ UiMethods.DisplayOverview();
+ Console.WriteLine(new string('-', 80));
+
+ // clientId - The app client Id value that you get from the AWS CDK script.
+ var clientId =
+ configuration[
+ "ClientId"]; // "*** REPLACE WITH CLIENT ID VALUE FROM CDK SCRIPT";
+
+ // poolId - The pool Id that you get from the AWS CDK script.
+ var poolId =
+ configuration["PoolId"]!; // "*** REPLACE WITH POOL ID VALUE FROM CDK SCRIPT";
+ var userName = configuration["UserName"];
+ var password = configuration["Password"];
+ var email = configuration["Email"];
+
+ // If the username wasn't set in the configuration file,
+ // get it from the user now.
+ if (userName is null)
+ {
+ do
+ {
+ Console.Write("Username: ");
+ userName = Console.ReadLine();
+ } while (string.IsNullOrEmpty(userName));
+ }
+
+ Console.WriteLine($"\nUsername: {userName}");
+
+ // If the password wasn't set in the configuration file,
+ // get it from the user now.
+ if (password is null)
+ {
+ do
+ {
+ Console.Write("Password: ");
+ password = Console.ReadLine();
+ } while (string.IsNullOrEmpty(password));
+ }
+
+ // If the email address wasn't set in the configuration file,
+ // get it from the user now.
+ if (email is null)
+ {
+ do
+ {
+ Console.Write("Email: ");
+ email = Console.ReadLine();
+ } while (string.IsNullOrEmpty(email));
+ }
+
+ // Now sign up the user.
+ Console.WriteLine($"\nSigning up {userName} with email address: {email}");
+ await cognitoWrapper.SignUpAsync(clientId, userName, password, email);
+
+ // Add the user to the user pool.
+ Console.WriteLine($"Adding {userName} to the user pool");
+ await cognitoWrapper.GetAdminUserAsync(userName, poolId);
+
+ UiMethods.DisplayTitle("Get confirmation code");
+ Console.WriteLine($"Conformation code sent to {userName}.");
+
+ Console.Write("Would you like to send a new code? (Y/N) ");
+ var answer = _interactive ? Console.ReadLine() : "y";
+
+ if (answer!.ToLower() == "y")
+ {
+ await cognitoWrapper.ResendConfirmationCodeAsync(clientId, userName);
+ Console.WriteLine("Sending a new confirmation code");
+ }
+
+ Console.Write("Enter confirmation code (from Email): ");
+ var code = _interactive ? Console.ReadLine() : "-";
+
+ await cognitoWrapper.ConfirmSignupAsync(clientId, code, userName);
+
+
+ UiMethods.DisplayTitle("Checking status");
+ Console.WriteLine($"Rechecking the status of {userName} in the user pool");
+ await cognitoWrapper.GetAdminUserAsync(userName, poolId);
+
+ Console.WriteLine($"Setting up authenticator for {userName} in the user pool");
+ var setupResponse = await cognitoWrapper.InitiateAuthAsync(clientId, userName, password);
+
+ var setupSession = await cognitoWrapper.AssociateSoftwareTokenAsync(setupResponse.Session);
+ Console.Write("Enter the 6-digit code displayed in Google Authenticator: ");
+ var setupCode = _interactive ? Console.ReadLine() : "-";
+ var setupResult =
+ await cognitoWrapper.VerifySoftwareTokenAsync(setupSession, setupCode);
+ Console.WriteLine($"Setup status: {setupResult}");
+
+ Console.WriteLine($"Now logging in {userName} in the user pool");
+ var authSession =
+ await cognitoWrapper.AdminInitiateAuthAsync(clientId, poolId, userName,
+ password);
+
+ Console.Write("Enter a new 6-digit code displayed in Google Authenticator: ");
+ var authCode = _interactive ? Console.ReadLine() : "-";
+ var authResult =
+ await cognitoWrapper.AdminRespondToAuthChallengeAsync(userName, clientId,
+ authCode, authSession, poolId);
+ Console.WriteLine(
+ $"Authenticated and received access token: {authResult.AccessToken}");
+
+
+ Console.WriteLine(new string('-', 80));
+ Console.WriteLine("Cognito scenario is complete.");
+ Console.WriteLine(new string('-', 80));
+ return true;
+ }
+}
+
+// snippet-end:[Cognito.dotnetv4.Main]
\ No newline at end of file
diff --git a/dotnetv4/Cognito/Scenarios/Cognito_Basics/CognitoBasics.csproj b/dotnetv4/Cognito/Scenarios/Cognito_Basics/CognitoBasics.csproj
new file mode 100644
index 00000000000..fdf7a548655
--- /dev/null
+++ b/dotnetv4/Cognito/Scenarios/Cognito_Basics/CognitoBasics.csproj
@@ -0,0 +1,29 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+ settings.json
+
+
+
+
diff --git a/dotnetv4/Cognito/Scenarios/Cognito_Basics/UIMethods.cs b/dotnetv4/Cognito/Scenarios/Cognito_Basics/UIMethods.cs
new file mode 100644
index 00000000000..ccc9c967e24
--- /dev/null
+++ b/dotnetv4/Cognito/Scenarios/Cognito_Basics/UIMethods.cs
@@ -0,0 +1,44 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+// snippet-start:[Cognito.dotnetv4.UIMethods]
+namespace CognitoBasics;
+
+///
+/// Some useful methods to make screen display easier.
+///
+public static class UiMethods
+{
+ ///
+ /// Show information about the scenario.
+ ///
+ public static void DisplayOverview()
+ {
+ DisplayTitle("Welcome to the Amazon Cognito Demo");
+
+ Console.WriteLine("This example application does the following:");
+ Console.WriteLine("\t 1. Signs up a user.");
+ Console.WriteLine("\t 2. Gets the user's confirmation status.");
+ Console.WriteLine("\t 3. Resends the confirmation code if the user requested another code.");
+ Console.WriteLine("\t 4. Confirms that the user signed up.");
+ Console.WriteLine("\t 5. Invokes the initiateAuth to sign in. This results in being prompted to set up TOTP (time-based one-time password). (The response is “ChallengeName”: “MFA_SETUP”).");
+ Console.WriteLine("\t 6. Invokes the AssociateSoftwareToken method to generate a TOTP MFA private key. This can be used with Google Authenticator.");
+ Console.WriteLine("\t 7. Invokes the VerifySoftwareToken method to verify the TOTP and register for MFA.");
+ Console.WriteLine("\t 8. Invokes the AdminInitiateAuth to sign in again. This results in being prompted to submit a TOTP (Response: “ChallengeName”: “SOFTWARE_TOKEN_MFA”).");
+ Console.WriteLine("\t 9. Invokes the AdminRespondToAuthChallenge to get back a token.");
+ }
+
+ ///
+ /// Display a line of hyphens, the centered text of the title and another
+ /// line of hyphens.
+ ///
+ /// The string to be displayed.
+ public static void DisplayTitle(string strTitle)
+ {
+ Console.WriteLine();
+ Console.WriteLine(strTitle);
+ Console.WriteLine();
+ }
+}
+
+// snippet-end:[Cognito.dotnetv4.UIMethods]
\ No newline at end of file
diff --git a/dotnetv4/Cognito/Scenarios/Cognito_Basics/Usings.cs b/dotnetv4/Cognito/Scenarios/Cognito_Basics/Usings.cs
new file mode 100644
index 00000000000..8a06b87643b
--- /dev/null
+++ b/dotnetv4/Cognito/Scenarios/Cognito_Basics/Usings.cs
@@ -0,0 +1,14 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+// snippet-start:[Cognito.dotnetv4.CognitoBasics.Usings]
+global using Amazon.CognitoIdentityProvider;
+global using CognitoActions;
+global using Microsoft.Extensions.Configuration;
+global using Microsoft.Extensions.DependencyInjection;
+global using Microsoft.Extensions.Hosting;
+global using Microsoft.Extensions.Logging;
+global using Microsoft.Extensions.Logging.Console;
+global using Microsoft.Extensions.Logging.Debug;
+
+// snippet-end:[Cognito.dotnetv4.CognitoBasics.Usings]
\ No newline at end of file
diff --git a/dotnetv4/Cognito/Scenarios/Cognito_Basics/settings.json b/dotnetv4/Cognito/Scenarios/Cognito_Basics/settings.json
new file mode 100644
index 00000000000..4bfac53daa4
--- /dev/null
+++ b/dotnetv4/Cognito/Scenarios/Cognito_Basics/settings.json
@@ -0,0 +1,9 @@
+{
+ "ClientId": "client_id_from_cdk",
+ "PoolId": "client_id_from_cdk",
+ "UserName": "username",
+ "Password": "EXAMPLEPASSWORD",
+ "Email": "useremail",
+ "adminUserName": "admin",
+ "adminPassword": "EXAMPLEPASSWORD"
+}
diff --git a/dotnetv4/Cognito/Tests/CognitoBasicsTests.cs b/dotnetv4/Cognito/Tests/CognitoBasicsTests.cs
new file mode 100644
index 00000000000..2b66715604b
--- /dev/null
+++ b/dotnetv4/Cognito/Tests/CognitoBasicsTests.cs
@@ -0,0 +1,198 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+using System.Net;
+using Amazon.CognitoIdentityProvider;
+using Amazon.CognitoIdentityProvider.Model;
+using Amazon.Runtime;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using Moq;
+
+namespace CognitoWrapperTests;
+
+///
+/// Tests for the Cognito scenario.
+///
+public class CognitoBasicsTests
+{
+ private ILoggerFactory _loggerFactory;
+
+ [Trait("Category", "Unit")]
+ [Fact]
+ public async Task ScenarioTest()
+ {
+ // Arrange.
+ _loggerFactory = LoggerFactory.Create(builder =>
+ {
+ builder.AddConsole();
+ });
+
+ var mockCognitoService = new Mock();
+
+ mockCognitoService.Setup(client => client.Paginators.ListUserPools(
+ It.IsAny()))
+ .Returns(new TestUserPoolPaginator() as IListUserPoolsPaginator);
+
+ mockCognitoService.Setup(client => client.Paginators.ListUserPools(
+ It.IsAny()))
+ .Returns(new TestUserPoolPaginator() as IListUserPoolsPaginator);
+
+ mockCognitoService.Setup(client => client.AdminRespondToAuthChallengeAsync(
+ It.IsAny(),
+ It.IsAny()))
+ .Returns((AdminRespondToAuthChallengeRequest r,
+ CancellationToken token) =>
+ {
+ return Task.FromResult(new AdminRespondToAuthChallengeResponse()
+ {
+ HttpStatusCode = HttpStatusCode.OK,
+ AuthenticationResult = new AuthenticationResultType()
+ });
+ });
+
+ mockCognitoService.Setup(client => client.VerifySoftwareTokenAsync(
+ It.IsAny(),
+ It.IsAny()))
+ .Returns((VerifySoftwareTokenRequest r,
+ CancellationToken token) =>
+ {
+ return Task.FromResult(new VerifySoftwareTokenResponse()
+ {
+ HttpStatusCode = HttpStatusCode.OK,
+ });
+ });
+
+ mockCognitoService.Setup(client => client.AssociateSoftwareTokenAsync(
+ It.IsAny(),
+ It.IsAny()))
+ .Returns((AssociateSoftwareTokenRequest r,
+ CancellationToken token) =>
+ {
+ return Task.FromResult(new AssociateSoftwareTokenResponse()
+ {
+ HttpStatusCode = HttpStatusCode.OK,
+ });
+ });
+
+ mockCognitoService.Setup(client => client.AdminInitiateAuthAsync(
+ It.IsAny(),
+ It.IsAny()))
+ .Returns((AdminInitiateAuthRequest r,
+ CancellationToken token) =>
+ {
+ return Task.FromResult(new AdminInitiateAuthResponse()
+ {
+ HttpStatusCode = HttpStatusCode.OK,
+ });
+ });
+
+ mockCognitoService.Setup(client => client.InitiateAuthAsync(
+ It.IsAny(),
+ It.IsAny()))
+ .Returns((InitiateAuthRequest r,
+ CancellationToken token) =>
+ {
+ return Task.FromResult(new InitiateAuthResponse()
+ {
+ HttpStatusCode = HttpStatusCode.OK,
+ });
+ });
+
+ mockCognitoService.Setup(client => client.ConfirmSignUpAsync(
+ It.IsAny(),
+ It.IsAny()))
+ .Returns((ConfirmSignUpRequest r,
+ CancellationToken token) =>
+ {
+ return Task.FromResult(new ConfirmSignUpResponse()
+ {
+ HttpStatusCode = HttpStatusCode.OK,
+ });
+ });
+
+ mockCognitoService.Setup(client => client.ResendConfirmationCodeAsync(
+ It.IsAny(),
+ It.IsAny()))
+ .Returns((ResendConfirmationCodeRequest r,
+ CancellationToken token) =>
+ {
+ return Task.FromResult(new ResendConfirmationCodeResponse()
+ {
+ HttpStatusCode = HttpStatusCode.OK,
+ CodeDeliveryDetails = new CodeDeliveryDetailsType()
+ });
+ });
+
+ mockCognitoService.Setup(client => client.AdminGetUserAsync(
+ It.IsAny(),
+ It.IsAny()))
+ .Returns((AdminGetUserRequest r,
+ CancellationToken token) =>
+ {
+ return Task.FromResult(new AdminGetUserResponse()
+ {
+ HttpStatusCode = HttpStatusCode.OK,
+ UserStatus = UserStatusType.CONFIRMED
+ });
+ });
+
+ mockCognitoService.Setup(client => client.SignUpAsync(
+ It.IsAny(),
+ It.IsAny()))
+ .Returns((SignUpRequest r,
+ CancellationToken token) =>
+ {
+ return Task.FromResult(new SignUpResponse()
+ {
+ HttpStatusCode = HttpStatusCode.OK,
+ });
+ });
+
+ var configuration = new ConfigurationBuilder()
+ .SetBasePath(Directory.GetCurrentDirectory())
+ .AddJsonFile("testsettings.json") // Load test settings from .json file.
+ .AddJsonFile("testsettings.local.json",
+ true) // Optionally load local settings.
+ .Build();
+
+ var wrapper = new CognitoWrapper(mockCognitoService.Object);
+ CognitoBasics.CognitoBasics._interactive = false;
+
+ var success =
+ await CognitoBasics.CognitoBasics.RunScenario(wrapper, configuration);
+ Assert.True(success);
+ }
+
+}
+
+
+///
+/// Mock Paginator for user pool response.
+///
+public class TestUsersPaginator : IPaginator, IListUsersPaginator
+{
+ public IAsyncEnumerable PaginateAsync(
+ CancellationToken cancellationToken = new CancellationToken())
+ {
+ throw new NotImplementedException();
+ }
+
+ public IPaginatedEnumerable Responses { get; } = null!;
+ public IPaginatedEnumerable Users { get; } = null!;
+}
+
+///
+/// Mock Paginator for user response.
+///
+public class TestUserPoolPaginator : IPaginator, IListUserPoolsPaginator
+{
+ public IAsyncEnumerable PaginateAsync(
+ CancellationToken cancellationToken = new CancellationToken())
+ {
+ throw new NotImplementedException();
+ }
+
+ public IPaginatedEnumerable Responses { get; } = null!;
+ public IPaginatedEnumerable UserPools { get; } = null!;
+}
\ No newline at end of file
diff --git a/dotnetv4/Cognito/Tests/CognitoTests.csproj b/dotnetv4/Cognito/Tests/CognitoTests.csproj
new file mode 100644
index 00000000000..fb9883ad93d
--- /dev/null
+++ b/dotnetv4/Cognito/Tests/CognitoTests.csproj
@@ -0,0 +1,38 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+ false
+
+
+
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+ testsettings.json
+
+
+
+
+
+
+
+
+
diff --git a/dotnetv4/Cognito/Tests/Usings.cs b/dotnetv4/Cognito/Tests/Usings.cs
new file mode 100644
index 00000000000..d77a2d566c5
--- /dev/null
+++ b/dotnetv4/Cognito/Tests/Usings.cs
@@ -0,0 +1,8 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+global using CognitoActions;
+global using Xunit;
+
+// Optional.
+[assembly: CollectionBehavior(DisableTestParallelization = true)]
\ No newline at end of file
diff --git a/dotnetv4/Cognito/Tests/testsettings.json b/dotnetv4/Cognito/Tests/testsettings.json
new file mode 100644
index 00000000000..eefdb2c8435
--- /dev/null
+++ b/dotnetv4/Cognito/Tests/testsettings.json
@@ -0,0 +1,8 @@
+{
+ "UserName": "someuser",
+ "Email": "someone@example.com",
+ "Password": "AGoodPassword1234",
+ "UserPoolId": "IDENTIFY_POOL_ID",
+ "ClientId": "CLIENT_ID_FROM_CDK_SCRIPT",
+ "PoolId": "USER_POOL_ID_FROM_CDK_SCRIPT"
+}
From 3d14f3225da5489e937b5c4e66574d16bc22de5e Mon Sep 17 00:00:00 2001
From: Rachel Hagerman <110480692+rlhagerm@users.noreply.github.com>
Date: Mon, 10 Feb 2025 10:05:26 -0600
Subject: [PATCH 2/3] Cognito updates for v4.
---
dotnetv3/Cognito/README.md | 2 +-
dotnetv4/Cognito/Actions/HelloCognito.cs | 2 +-
dotnetv4/Cognito/README.md | 8 +++---
.../Scenarios/Cognito_Basics/CognitoBasics.cs | 4 +--
dotnetv4/Cognito/Tests/CognitoBasicsTests.cs | 2 +-
dotnetv4/DotNetV4Examples.sln | 26 +++++++++++++++++++
6 files changed, 35 insertions(+), 9 deletions(-)
diff --git a/dotnetv3/Cognito/README.md b/dotnetv3/Cognito/README.md
index eb9c4e7777b..9158cda1f7e 100644
--- a/dotnetv3/Cognito/README.md
+++ b/dotnetv3/Cognito/README.md
@@ -34,7 +34,7 @@ These examples also require the following resources:
To create these resources, run the AWS CloudFormation script in the
-[resources/cdk/cognito_scenario_user_pool_with_mfa](../../../resources/cdk/cognito_scenario_user_pool_with_mfa)
+[resources/cdk/cognito_scenario_user_pool_with_mfa](../../resources/cdk/cognito_scenario_user_pool_with_mfa)
folder. This script outputs a user pool ID and a client ID that you can use to run
the scenario.
diff --git a/dotnetv4/Cognito/Actions/HelloCognito.cs b/dotnetv4/Cognito/Actions/HelloCognito.cs
index 4d850395336..230a4d86799 100644
--- a/dotnetv4/Cognito/Actions/HelloCognito.cs
+++ b/dotnetv4/Cognito/Actions/HelloCognito.cs
@@ -51,7 +51,7 @@ static async Task Main(string[] args)
{
userPools.ForEach(userPool =>
{
- Console.WriteLine($"{userPool.Name}\t{userPool.Id}\t{userPool.Status}");
+ Console.WriteLine($"{userPool.Name}\t{userPool.Id}");
});
}
else
diff --git a/dotnetv4/Cognito/README.md b/dotnetv4/Cognito/README.md
index eb9c4e7777b..677b1901dae 100644
--- a/dotnetv4/Cognito/README.md
+++ b/dotnetv4/Cognito/README.md
@@ -23,7 +23,7 @@ _Amazon Cognito Identity Provider handles user authentication and authorization
### Prerequisites
-For prerequisites, see the [README](../README.md#Prerequisites) in the `dotnetv3` folder.
+For prerequisites, see the [README](../README.md#Prerequisites) in the `dotnetv4` folder.
@@ -34,7 +34,7 @@ These examples also require the following resources:
To create these resources, run the AWS CloudFormation script in the
-[resources/cdk/cognito_scenario_user_pool_with_mfa](../../../resources/cdk/cognito_scenario_user_pool_with_mfa)
+[resources/cdk/cognito_scenario_user_pool_with_mfa](../../resources/cdk/cognito_scenario_user_pool_with_mfa)
folder. This script outputs a user pool ID and a client ID that you can use to run
the scenario.
@@ -72,7 +72,7 @@ functions within the same service.
### Instructions
For general instructions to run the examples, see the
-[README](../README.md#building-and-running-the-code-examples) in the `dotnetv3` folder.
+[README](../README.md#building-and-running-the-code-examples) in the `dotnetv4` folder.
Some projects might include a settings.json file. Before compiling the project,
you can change these values to match your own account and resources. Alternatively,
@@ -115,7 +115,7 @@ This example shows you how to do the following:
To find instructions for running these tests, see the [README](../README.md#Tests)
-in the `dotnetv3` folder.
+in the `dotnetv4` folder.
diff --git a/dotnetv4/Cognito/Scenarios/Cognito_Basics/CognitoBasics.cs b/dotnetv4/Cognito/Scenarios/Cognito_Basics/CognitoBasics.cs
index b79ddc1a59a..a5418365f5f 100644
--- a/dotnetv4/Cognito/Scenarios/Cognito_Basics/CognitoBasics.cs
+++ b/dotnetv4/Cognito/Scenarios/Cognito_Basics/CognitoBasics.cs
@@ -120,7 +120,7 @@ public static async Task RunScenario(CognitoWrapper cognitoWrapper, IConfi
var code = _interactive ? Console.ReadLine() : "-";
await cognitoWrapper.ConfirmSignupAsync(clientId, code, userName);
-
+
UiMethods.DisplayTitle("Checking status");
Console.WriteLine($"Rechecking the status of {userName} in the user pool");
@@ -148,7 +148,7 @@ await cognitoWrapper.AdminRespondToAuthChallengeAsync(userName, clientId,
authCode, authSession, poolId);
Console.WriteLine(
$"Authenticated and received access token: {authResult.AccessToken}");
-
+
Console.WriteLine(new string('-', 80));
Console.WriteLine("Cognito scenario is complete.");
diff --git a/dotnetv4/Cognito/Tests/CognitoBasicsTests.cs b/dotnetv4/Cognito/Tests/CognitoBasicsTests.cs
index 2b66715604b..974973c7b8f 100644
--- a/dotnetv4/Cognito/Tests/CognitoBasicsTests.cs
+++ b/dotnetv4/Cognito/Tests/CognitoBasicsTests.cs
@@ -16,7 +16,7 @@ namespace CognitoWrapperTests;
///
public class CognitoBasicsTests
{
- private ILoggerFactory _loggerFactory;
+ private ILoggerFactory _loggerFactory = null!;
[Trait("Category", "Unit")]
[Fact]
diff --git a/dotnetv4/DotNetV4Examples.sln b/dotnetv4/DotNetV4Examples.sln
index ab7be69d4d9..d46afcd8c1e 100644
--- a/dotnetv4/DotNetV4Examples.sln
+++ b/dotnetv4/DotNetV4Examples.sln
@@ -119,6 +119,16 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Basics", "EC2\Scenarios\EC2
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EC2Actions", "EC2\Actions\EC2Actions.csproj", "{0633CB2B-3508-48E5-A8C2-427A83A5CA6E}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Cognito", "Cognito", "{F5214562-85F4-4FD8-B56D-C5D8E7914901}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CognitoTests", "Cognito\Tests\CognitoTests.csproj", "{63DC05A0-5B16-45A4-BDE5-90DD2E200507}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scenarios", "Scenarios", "{D38A409C-EE40-4E70-B500-F3D6EF8E82A4}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CognitoBasics", "Cognito\Scenarios\Cognito_Basics\CognitoBasics.csproj", "{38C8C3B0-163D-4B7B-86A2-3EFFBC165E99}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CognitoActions", "Cognito\Actions\CognitoActions.csproj", "{1AF980DF-DEEA-4E5D-9001-6EC67EB96AD1}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -293,6 +303,18 @@ Global
{0633CB2B-3508-48E5-A8C2-427A83A5CA6E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0633CB2B-3508-48E5-A8C2-427A83A5CA6E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0633CB2B-3508-48E5-A8C2-427A83A5CA6E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {63DC05A0-5B16-45A4-BDE5-90DD2E200507}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {63DC05A0-5B16-45A4-BDE5-90DD2E200507}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {63DC05A0-5B16-45A4-BDE5-90DD2E200507}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {63DC05A0-5B16-45A4-BDE5-90DD2E200507}.Release|Any CPU.Build.0 = Release|Any CPU
+ {38C8C3B0-163D-4B7B-86A2-3EFFBC165E99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {38C8C3B0-163D-4B7B-86A2-3EFFBC165E99}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {38C8C3B0-163D-4B7B-86A2-3EFFBC165E99}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {38C8C3B0-163D-4B7B-86A2-3EFFBC165E99}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1AF980DF-DEEA-4E5D-9001-6EC67EB96AD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1AF980DF-DEEA-4E5D-9001-6EC67EB96AD1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1AF980DF-DEEA-4E5D-9001-6EC67EB96AD1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1AF980DF-DEEA-4E5D-9001-6EC67EB96AD1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -349,6 +371,10 @@ Global
{6C167F25-F97F-4854-8CD8-A2D446B6799B} = {9424FB14-B6DE-44CE-B675-AC2B57EC1E69}
{D95519CA-BD27-45AE-B83B-3FB02E7AE445} = {6C167F25-F97F-4854-8CD8-A2D446B6799B}
{0633CB2B-3508-48E5-A8C2-427A83A5CA6E} = {9424FB14-B6DE-44CE-B675-AC2B57EC1E69}
+ {63DC05A0-5B16-45A4-BDE5-90DD2E200507} = {F5214562-85F4-4FD8-B56D-C5D8E7914901}
+ {D38A409C-EE40-4E70-B500-F3D6EF8E82A4} = {F5214562-85F4-4FD8-B56D-C5D8E7914901}
+ {38C8C3B0-163D-4B7B-86A2-3EFFBC165E99} = {D38A409C-EE40-4E70-B500-F3D6EF8E82A4}
+ {1AF980DF-DEEA-4E5D-9001-6EC67EB96AD1} = {F5214562-85F4-4FD8-B56D-C5D8E7914901}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {08502818-E8E1-4A91-A51C-4C8C8D4FF9CA}
From b2628796c0a1ecbad2c07a93854e2eb274bf3c26 Mon Sep 17 00:00:00 2001
From: Rachel Hagerman <110480692+rlhagerm@users.noreply.github.com>
Date: Mon, 10 Feb 2025 11:01:40 -0600
Subject: [PATCH 3/3] Fix for code warning.
---
dotnetv4/Aurora/Actions/AuroraWrapper.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dotnetv4/Aurora/Actions/AuroraWrapper.cs b/dotnetv4/Aurora/Actions/AuroraWrapper.cs
index 18c7646cc9e..9f469df9fb2 100644
--- a/dotnetv4/Aurora/Actions/AuroraWrapper.cs
+++ b/dotnetv4/Aurora/Actions/AuroraWrapper.cs
@@ -124,7 +124,7 @@ public async Task ModifyIntegerParametersInGroupAsync(string groupName,
{
foreach (var p in parameters)
{
- if (p.IsModifiable.Value && p.DataType == "integer")
+ if (p.IsModifiable.GetValueOrDefault() && p.DataType == "integer")
{
while (newValue == 0)
{