static async Task Main(string[] args) { // Load Configuration Files using var authMessagesStream = typeof(IAuthProcess).Assembly.GetManifestResourceStream("LazyStackAuth.AuthMessages.json"); using var methodMapStream = typeof(PetStore).Assembly.GetManifestResourceStream("PetStoreClientSDK.MethodMap.json"); using var awsSettingsStream = typeof(Program).Assembly.GetManifestResourceStream("PetStoreConsoleApp.AwsSettings.json"); using var localApisStream = typeof(Program).Assembly.GetManifestResourceStream("PetStoreConsoleApp.LocalApis.json"); appConfig = new ConfigurationBuilder() .AddJsonStream(authMessagesStream) .AddJsonStream(methodMapStream) .AddJsonStream(awsSettingsStream) .AddJsonStream(localApisStream) .Build(); IServiceCollection services = new ServiceCollection(); IServiceProvider serviceProvider; services.AddSingleton <IConfiguration>(appConfig); // LoginFormat(IConfiguration) services.AddSingleton <ILoginFormat, LoginFormat>(); // PasswordFormat(IConfiguration) services.AddSingleton <IPasswordFormat, PasswordFormat>(); // EmailFormat(IConfiguration) services.AddSingleton <IEmailFormat, EmailFormat>(); // PhoneFormat(IConfiguration) services.AddSingleton <IPhoneFormat, PhoneFormat>(); // CodeFormat(IConfiguration) services.AddSingleton <ICodeFormat, CodeFormat>(); // AuthProviderCognito(IConfiguration, ILoginFormat, IPasswordFormat, IEmailFormat, ICodeFormat, IPhoneFormat) services.AddSingleton <IAuthProvider, AuthProviderCognito>(); // AuthProcess(IConfiguration, IAuthProvider) services.AddSingleton <IAuthProcess, AuthProcess>(); // depends on IConfiguration, IAuthProvider serviceProvider = services.BuildServiceProvider(); var authProvider = serviceProvider.GetService <IAuthProvider>() as AuthProviderCognito; var authProcess = serviceProvider.GetService <IAuthProcess>(); var lzHttpClient = new LzHttpClient(appConfig, authProvider, "Local"); // Init PetStore library -- provides easy to use calls against AWS ApiGateways var petStore = new PetStore(lzHttpClient); // Ask the user if they want to use LocalApi Controller Calls // Note that this does not influence calls to Cognito for authentication Console.WriteLine("Welcome to the PetStoreConsoleApp program"); Console.Write("Use LocalApi? y/n:"); var useLocalApi = Console.ReadLine(); lzHttpClient.UseLocalApi = useLocalApi.Equals("Y", StringComparison.OrdinalIgnoreCase); var input = string.Empty; var alertMsg = string.Empty; var menuMsg = string.Empty; var lastAuthEvent = AuthEventEnum.AuthChallenge; while (true) { alertMsg = (lastAuthEvent > AuthEventEnum.Alert) ? appConfig[$"AuthAlertMessages:{currentLanguage}:{lastAuthEvent}"] : string.Empty; if (!string.IsNullOrEmpty(alertMsg)) { Console.WriteLine($"Alert: {alertMsg}"); } switch (authProcess.CurrentAuthProcess) { case AuthProcessEnum.None: if (authProcess.IsNotSignedIn) { menuMsg = appConfig[$"AuthProcessLabels:{currentLanguage}:{AuthProcessEnum.SigningUp}"]; Console.WriteLine($"1. {menuMsg}"); menuMsg = appConfig[$"AuthProcessLabels:{currentLanguage}:{AuthProcessEnum.SigningIn}"]; Console.WriteLine($"2. {menuMsg}"); menuMsg = appConfig[$"AuthProcessLabels:{currentLanguage}:{AuthProcessEnum.ResettingPassword}"]; Console.WriteLine($"3. {menuMsg}"); Console.WriteLine("4. Quit"); Console.Write(">"); input = Console.ReadLine(); switch (input) { case "1": lastAuthEvent = await authProcess.StartSignUpAsync(); break; case "2": lastAuthEvent = await authProcess.StartSignInAsync(); break; case "3": lastAuthEvent = await authProcess.StartResetPasswordAsync(); break; case "4": return; // exit program default: Console.WriteLine("Sorry, didn't understand that input. Please try again."); continue; } } else { menuMsg = appConfig[$"AuthProcessLabels:{currentLanguage}:{AuthProcessEnum.SigningOut}"]; Console.WriteLine($"1. {menuMsg}"); menuMsg = appConfig[$"AuthProcessLabels:{currentLanguage}:{AuthProcessEnum.UpdatingPassword}"]; Console.WriteLine($"2. {menuMsg}"); menuMsg = appConfig[$"AuthProcessLabels:{currentLanguage}:{AuthProcessEnum.UpdatingPhone}"]; Console.WriteLine($"3. {menuMsg}"); menuMsg = appConfig[$"AuthProcessLabels:{currentLanguage}:{AuthProcessEnum.UpdatingLogin}"]; Console.WriteLine($"4. {menuMsg}"); Console.WriteLine("5. Seed Pets data"); Console.WriteLine("6. Get Pet 1"); Console.WriteLine("7. See Available Pets"); Console.WriteLine("8. GetUserId"); Console.WriteLine("9. Quit"); Console.Write(">"); input = Console.ReadLine(); switch (input) { case "1": lastAuthEvent = await authProcess.SignOutAsync(); break; case "2": lastAuthEvent = await authProcess.StartUpdatePasswordAsync(); break; case "3": lastAuthEvent = await authProcess.StartUpdatePhoneAsync(); break; case "4": lastAuthEvent = await authProcess.StartUpdateLoginAsync(); break; case "5": try { await petStore.SeedPetsAsync(); Console.WriteLine("Pets added to database"); } catch (Exception e) { Console.WriteLine($"Could not add pets to database. {e.Message}"); } break; case "6": try { var pet = await petStore.GetPetByIdAsync(1); Console.WriteLine($"pet: {pet.Id} {pet.Name} {pet.PetStatus}"); } catch (Exception e) { Console.WriteLine($"Could not retrieve pet. {e.Message}"); } break; case "7": try { var petStatus = new List <PetStatus> { PetStatus.Available }; var pets = await petStore.FindPetsByStatusAsync(petStatus); if (pets.Count == 0) { Console.WriteLine("Sorry - No Pets Found"); } else { foreach (var pet in pets) { Console.WriteLine($"- Id: {pet.Id} Name: {pet.Name}"); } } Console.WriteLine(); } catch (Exception e) { Console.WriteLine($"Could not get pets. {e.Message}"); } break; case "8": try { var userId = await petStore.GetUserAsync(); Console.WriteLine($"UserId={userId}"); } catch (Exception e) { Console.WriteLine($"Could not get userId. {e.Message}"); } break; case "9": return; // exit program default: Console.WriteLine("Sorry, didn't understand that input. Please try again."); continue; } } break; default: // Some AuthProcess is active so process CurrentChallenge var prompt = appConfig[$"AuthChallengeMessages:{currentLanguage}:{authProcess.CurrentChallenge}"]; switch (authProcess.CurrentChallenge) { case AuthChallengeEnum.Login: Console.Write($"{prompt}: "); authProcess.Login = Console.ReadLine(); lastAuthEvent = string.IsNullOrEmpty(authProcess.Login) ? await CancelAsync() : await authProcess.VerifyLoginAsync(); break; case AuthChallengeEnum.Password: Console.Write($"{prompt}: "); authProcess.Password = Console.ReadLine(); lastAuthEvent = string.IsNullOrEmpty(authProcess.Password) ? await CancelAsync() : await authProcess.VerifyPasswordAsync(); break; case AuthChallengeEnum.Email: Console.Write($"{prompt}: "); authProcess.Email = Console.ReadLine(); lastAuthEvent = string.IsNullOrEmpty(authProcess.Email) ? await CancelAsync() : await authProcess.VerifyEmailAsync(); break; case AuthChallengeEnum.Code: Console.Write($"{prompt}: "); authProcess.Code = Console.ReadLine(); if (string.IsNullOrEmpty(authProcess.Code)) { Console.Write("Resend Code? y/n"); var resendCode = Console.ReadLine(); lastAuthEvent = resendCode.Equals("y", StringComparison.OrdinalIgnoreCase) ? await CancelAsync() : await authProcess.ResendCodeAsync(); } else { lastAuthEvent = await authProcess.VerifyCodeAsync(); } if (lastAuthEvent == AuthEventEnum.SignedUp) { Console.WriteLine("You are Signed Up! You can now SignIn."); } break; case AuthChallengeEnum.Phone: Console.Write($"{prompt}: "); authProcess.Phone = Console.ReadLine(); lastAuthEvent = string.IsNullOrEmpty(authProcess.Phone) ? await CancelAsync() : await authProcess.VerifyPhoneAsync(); break; case AuthChallengeEnum.NewLogin: Console.Write($"{prompt}: "); authProcess.NewLogin = Console.ReadLine(); lastAuthEvent = string.IsNullOrEmpty(authProcess.NewLogin) ? await CancelAsync() : await authProcess.VerifyNewLoginAsync(); break; case AuthChallengeEnum.NewPassword: Console.Write($"{prompt}: "); authProcess.NewPassword = Console.ReadLine(); lastAuthEvent = string.IsNullOrEmpty(authProcess.NewPassword) ? await CancelAsync() : await authProcess.VerifyNewPasswordAsync(); break; case AuthChallengeEnum.NewEmail: Console.Write($"{prompt}: "); authProcess.NewEmail = Console.ReadLine(); lastAuthEvent = string.IsNullOrEmpty(authProcess.NewEmail) ? await CancelAsync() : await authProcess.VerifyNewEmailAsync(); break; case AuthChallengeEnum.NewPhone: Console.Write($"{prompt}: "); authProcess.NewPhone = Console.ReadLine(); lastAuthEvent = string.IsNullOrEmpty(authProcess.NewPhone) ? await CancelAsync() : await authProcess.VerifyNewPhoneAsync(); break; default: Console.WriteLine("Error: Unknown Challenge!"); lastAuthEvent = await CancelAsync(); break; } break; } } }
public async Task TestMethod1() { using var authMessagesStream = typeof(IAuthProcess).Assembly.GetManifestResourceStream("LazyStackAuth.AuthMessages.json"); using var awsSettingsStream = typeof(PetStoreIntegrationTest).Assembly.GetManifestResourceStream("PetStoreTests.AwsSettings.json"); using var methodMapStream = typeof(PetStore).Assembly.GetManifestResourceStream("PetStoreClientSDK.MethodMap.json"); IConfiguration appConfig = new ConfigurationBuilder() .AddUserSecrets <PetStoreIntegrationTest>() // used to get gmail account credentials for auth code .AddJsonStream(awsSettingsStream) .AddJsonStream(authMessagesStream) .AddJsonStream(methodMapStream) .Build(); IServiceCollection services = new ServiceCollection(); IServiceProvider serviceProvider; services.AddSingleton <IConfiguration>(appConfig); // LoginFormat(IConfiguration) services.AddSingleton <ILoginFormat, LoginFormat>(); // PasswordFormat(IConfiguration) services.AddSingleton <IPasswordFormat, PasswordFormat>(); // EmailFormat(IConfiguration) services.AddSingleton <IEmailFormat, EmailFormat>(); // PhoneFormat(IConfiguration) services.AddSingleton <IPhoneFormat, PhoneFormat>(); // CodeFormat(IConfiguration) services.AddSingleton <ICodeFormat, CodeFormat>(); // AuthProviderCognito(IConfiguration, ILoginFormat, IPasswordFormat, IEmailFormat, ICodeFormat, IPhoneFormat) services.AddSingleton <IAuthProvider, AuthProviderCognito>(); // AuthProcess(IConfiguration, IAuthProvider) services.AddSingleton <IAuthProcess, AuthProcess>(); // depends on IConfiguration, IAuthProvider serviceProvider = services.BuildServiceProvider(); var authProvider = serviceProvider.GetService <IAuthProvider>() as AuthProviderCognito; var authProcess = serviceProvider.GetService <IAuthProcess>(); // Signup var now = DateTime.Now; var login = $"TestUser{now.Year}-{now.Month}-{now.Day}-{now.Hour}-{now.Minute}-{now.Second}"; var password = "******"; // Use Google email alias feature to allow us to use a single gmail account for our testing // ex: [email protected] becomes [email protected] // This avoids AWS complaining that the email already exists // These are one-time use aliases and Cognito accounts var email = appConfig["Gmail:Email"]; var emailParts = email.Split("@"); email = emailParts[0] + "+" + login + "@" + emailParts[1]; // Start Sign Up process Assert.IsTrue(await authProcess.StartSignUpAsync() == AuthEventEnum.AuthChallenge); Assert.IsTrue(authProcess.CurrentAuthProcess == AuthProcessEnum.SigningUp); // Simulate collection of Login from user Assert.IsTrue(authProcess.CurrentChallenge == AuthChallengeEnum.Login); authProcess.Login = login; Assert.IsTrue(await authProcess.VerifyLoginAsync() == AuthEventEnum.AuthChallenge); // Simulate collection of Password from user Assert.IsTrue(authProcess.CurrentChallenge == AuthChallengeEnum.Password); authProcess.Password = password; Assert.IsTrue(await authProcess.VerifyPasswordAsync() == AuthEventEnum.AuthChallenge); // Simulate collection of Email from user Assert.IsTrue(authProcess.CurrentChallenge == AuthChallengeEnum.Email); authProcess.Email = email; var verificationCodeSendTime = DateTime.UtcNow; // verificationCode sent after this time Thread.Sleep(5000); // Account for a little drive among local and remote clock Assert.IsTrue(await authProcess.VerifyEmailAsync() == AuthEventEnum.AuthChallenge); // Simulate collection of Code from user - AWS Sends the code to the email account Assert.IsTrue(authProcess.CurrentChallenge == AuthChallengeEnum.Code); var verificationCode = AuthEmail.GetAuthCode(appConfig, email); Assert.IsNotNull(verificationCode); authProcess.Code = verificationCode; // Verifying the code finalizes the sign up process Assert.IsTrue(await authProcess.VerifyCodeAsync() == AuthEventEnum.SignedUp); Assert.IsTrue(authProcess.CurrentAuthProcess == AuthProcessEnum.None); Assert.IsTrue(authProcess.CurrentChallenge == AuthChallengeEnum.None); Assert.IsTrue(authProcess.IsSignedIn == false); // Start SignIn process Assert.IsTrue(await authProcess.StartSignInAsync() == AuthEventEnum.AuthChallenge); Assert.IsTrue(authProcess.CurrentAuthProcess == AuthProcessEnum.SigningIn); // Simulate collection of Password from user Assert.IsTrue(authProcess.CurrentChallenge == AuthChallengeEnum.Login); authProcess.Password = password; Assert.IsTrue(await authProcess.VerifyLoginAsync() == AuthEventEnum.AuthChallenge); // Simulate collection of Password from user Assert.IsTrue(authProcess.CurrentChallenge == AuthChallengeEnum.Password); authProcess.Password = password; // Verifying password finalizes SigningIn process Assert.IsTrue(await authProcess.VerifyPasswordAsync() == AuthEventEnum.SignedIn); Assert.IsTrue(authProcess.CurrentAuthProcess == AuthProcessEnum.None); Assert.IsTrue(authProcess.CurrentChallenge == AuthChallengeEnum.None); Assert.IsTrue(authProcess.IsSignedIn == true); ////////////////////////////////////////////////////////////// // Use PetStore library to call the ApiGateways in our stack ////////////////////////////////////////////////////////////// // Creating the LzHttpClient which knows how to make secure calls against AWS ApiGateways var lzHttpClient = new LzHttpClient(appConfig, authProvider, null); // Create the PetStore lib instance that makes calling the stack easy var petStore = new PetStore(lzHttpClient); // Call PetStore.SeedPetsAsync -- it's ok if the pet records already exist await petStore.SeedPetsAsync(); // Retrieve pet record by Id var pet = await petStore.GetPetByIdAsync(1); }