AWSCognitoUserManagementController.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzCore/Jobs/JobFunction.h>
  9. #include <UserManagement/AWSCognitoUserManagementController.h>
  10. #include <AWSClientAuthBus.h>
  11. #include <AWSClientAuthResourceMappingConstants.h>
  12. #include <AWSCoreBus.h>
  13. #include <ResourceMapping/AWSResourceMappingBus.h>
  14. #include <aws/core/utils/Outcome.h>
  15. #include <aws/core/utils/memory/stl/AWSVector.h>
  16. #include <aws/cognito-idp/model/SignUpRequest.h>
  17. #include <aws/cognito-idp/CognitoIdentityProviderClient.h>
  18. #include <aws/cognito-idp/model/SignUpResult.h>
  19. #include <aws/cognito-idp/model/ConfirmSignUpRequest.h>
  20. #include <aws/cognito-idp/model/ConfirmSignUpResult.h>
  21. #include <aws/cognito-idp/model/ConfirmSignUpRequest.h>
  22. #include <aws/cognito-idp/model/ConfirmSignUpResult.h>
  23. #include <aws/cognito-idp/model/AttributeType.h>
  24. #include <aws/cognito-idp/model/ForgotPasswordRequest.h>
  25. #include <aws/cognito-idp/model/ForgotPasswordResult.h>
  26. #include <aws/cognito-idp/model/ConfirmForgotPasswordRequest.h>
  27. #include <aws/cognito-idp/model/ConfirmForgotPasswordResult.h>
  28. #include <aws/cognito-idp/model/SetUserMFAPreferenceRequest.h>
  29. #include <aws/cognito-idp/model/SetUserMFAPreferenceResult.h>
  30. namespace AWSClientAuth
  31. {
  32. AWSCognitoUserManagementController::AWSCognitoUserManagementController()
  33. {
  34. AZ::Interface<IAWSCognitoUserManagementRequests>::Register(this);
  35. AWSCognitoUserManagementRequestBus::Handler::BusConnect();
  36. }
  37. AWSCognitoUserManagementController::~AWSCognitoUserManagementController()
  38. {
  39. AWSCognitoUserManagementRequestBus::Handler::BusDisconnect();
  40. AZ::Interface<IAWSCognitoUserManagementRequests>::Unregister(this);
  41. }
  42. bool AWSCognitoUserManagementController::Initialize()
  43. {
  44. AWSCore::AWSResourceMappingRequestBus::BroadcastResult(
  45. m_cognitoAppClientId, &AWSCore::AWSResourceMappingRequests::GetResourceNameId, CognitoAppClientIdResourceMappingKey);
  46. AZ_Warning(
  47. "AWSCognitoUserManagementController", !m_cognitoAppClientId.empty(), "Missing Cognito App Client Id from resource mappings. Calls to Cognito will fail.");
  48. return !m_cognitoAppClientId.empty();
  49. }
  50. // Call Cognito user pool sign up using email. Confirmation code sent to the email set.
  51. // Refer https://docs.aws.amazon.com/cognito/latest/developerguide/signing-up-users-in-your-app.html
  52. void AWSCognitoUserManagementController::EmailSignUpAsync(const AZStd::string& username, const AZStd::string& password, const AZStd::string& email)
  53. {
  54. std::shared_ptr<Aws::CognitoIdentityProvider::CognitoIdentityProviderClient> cognitoIdentityProviderClient =
  55. AZ::Interface<IAWSClientAuthRequests>::Get()->GetCognitoIDPClient();
  56. AZ::JobContext* jobContext = nullptr;
  57. AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext);
  58. AZ::Job* emailSignUpJob = AZ::CreateJobFunction([this, cognitoIdentityProviderClient, username, password, email]()
  59. {
  60. Aws::CognitoIdentityProvider::Model::SignUpRequest signUpRequest;
  61. signUpRequest.SetClientId(m_cognitoAppClientId.c_str());
  62. signUpRequest.SetUsername(username.c_str());
  63. signUpRequest.SetPassword(password.c_str());
  64. Aws::Vector<Aws::CognitoIdentityProvider::Model::AttributeType> attributes;
  65. Aws::CognitoIdentityProvider::Model::AttributeType emailAttribute;
  66. emailAttribute.SetName("email");
  67. emailAttribute.SetValue(email.c_str());
  68. attributes.push_back(emailAttribute);
  69. signUpRequest.SetUserAttributes(attributes);
  70. Aws::CognitoIdentityProvider::Model::SignUpOutcome signUpOutcome{ cognitoIdentityProviderClient->SignUp(signUpRequest) };
  71. if (signUpOutcome.IsSuccess())
  72. {
  73. Aws::CognitoIdentityProvider::Model::SignUpResult signUpResult{ signUpOutcome.GetResult() };
  74. AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnEmailSignUpSuccess, signUpResult.GetUserSub().c_str());
  75. }
  76. else
  77. {
  78. Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error = signUpOutcome.GetError();
  79. AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnEmailSignUpFail, error.GetMessage().c_str());
  80. }
  81. }, true, jobContext);
  82. emailSignUpJob->Start();
  83. }
  84. void AWSCognitoUserManagementController::PhoneSignUpAsync(const AZStd::string& username, const AZStd::string& password, const AZStd::string& phoneNumber)
  85. {
  86. std::shared_ptr<Aws::CognitoIdentityProvider::CognitoIdentityProviderClient> cognitoIdentityProviderClient =
  87. AZ::Interface<IAWSClientAuthRequests>::Get()->GetCognitoIDPClient();
  88. AZ::JobContext* jobContext = nullptr;
  89. AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext);
  90. AZ::Job* phoneSignUpJob = AZ::CreateJobFunction([this, cognitoIdentityProviderClient, username, password, phoneNumber]()
  91. {
  92. Aws::CognitoIdentityProvider::Model::SignUpRequest signUpRequest;
  93. signUpRequest.SetClientId(m_cognitoAppClientId.c_str());
  94. signUpRequest.SetUsername(username.c_str());
  95. signUpRequest.SetPassword(password.c_str());
  96. Aws::Vector<Aws::CognitoIdentityProvider::Model::AttributeType> attributes;
  97. Aws::CognitoIdentityProvider::Model::AttributeType emailAttribute;
  98. emailAttribute.SetName("phone_number");
  99. emailAttribute.SetValue(phoneNumber.c_str());
  100. attributes.push_back(emailAttribute);
  101. signUpRequest.SetUserAttributes(attributes);
  102. Aws::CognitoIdentityProvider::Model::SignUpOutcome signUpOutcome{ cognitoIdentityProviderClient->SignUp(signUpRequest) };
  103. if (signUpOutcome.IsSuccess())
  104. {
  105. Aws::CognitoIdentityProvider::Model::SignUpResult signUpResult{ signUpOutcome.GetResult() };
  106. AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnPhoneSignUpSuccess, signUpResult.GetUserSub().c_str());
  107. }
  108. else
  109. {
  110. Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error = signUpOutcome.GetError();
  111. AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnPhoneSignUpFail, error.GetMessage().c_str());
  112. }
  113. }, true, jobContext);
  114. phoneSignUpJob->Start();
  115. }
  116. // Call Cognito user pool confirm sign up using code from email/phone.
  117. // Refer https://docs.aws.amazon.com/cognito/latest/developerguide/signing-up-users-in-your-app.html
  118. void AWSCognitoUserManagementController::ConfirmSignUpAsync(const AZStd::string& username, const AZStd::string& confirmationCode)
  119. {
  120. std::shared_ptr<Aws::CognitoIdentityProvider::CognitoIdentityProviderClient> cognitoIdentityProviderClient =
  121. AZ::Interface<IAWSClientAuthRequests>::Get()->GetCognitoIDPClient();
  122. AZ::JobContext* jobContext = nullptr;
  123. AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext);
  124. AZ::Job* confirmSignUpJob = AZ::CreateJobFunction([this, cognitoIdentityProviderClient, username, confirmationCode]()
  125. {
  126. Aws::CognitoIdentityProvider::Model::ConfirmSignUpRequest confirmSignupRequest;
  127. confirmSignupRequest.SetClientId(m_cognitoAppClientId.c_str());
  128. confirmSignupRequest.SetUsername(username.c_str());
  129. confirmSignupRequest.SetConfirmationCode(confirmationCode.c_str());
  130. Aws::CognitoIdentityProvider::Model::ConfirmSignUpOutcome confirmSignupOutcome{ cognitoIdentityProviderClient->ConfirmSignUp(confirmSignupRequest) };
  131. if (confirmSignupOutcome.IsSuccess())
  132. {
  133. AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnConfirmSignUpSuccess);
  134. }
  135. else
  136. {
  137. Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error = confirmSignupOutcome.GetError();
  138. AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnConfirmSignUpFail, error.GetMessage().c_str());
  139. }
  140. }, true, jobContext);
  141. confirmSignUpJob->Start();
  142. }
  143. void AWSCognitoUserManagementController::ForgotPasswordAsync(const AZStd::string& username)
  144. {
  145. std::shared_ptr<Aws::CognitoIdentityProvider::CognitoIdentityProviderClient> cognitoIdentityProviderClient =
  146. AZ::Interface<IAWSClientAuthRequests>::Get()->GetCognitoIDPClient();
  147. AZ::JobContext* jobContext = nullptr;
  148. AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext);
  149. AZ::Job* forgotPasswordJob = AZ::CreateJobFunction([this, cognitoIdentityProviderClient, username]()
  150. {
  151. Aws::CognitoIdentityProvider::Model::ForgotPasswordRequest forgotPasswordRequest;
  152. forgotPasswordRequest.SetClientId(m_cognitoAppClientId.c_str());
  153. forgotPasswordRequest.SetUsername(username.c_str());
  154. Aws::CognitoIdentityProvider::Model::ForgotPasswordOutcome forgotPasswordOutcome{ cognitoIdentityProviderClient->ForgotPassword(forgotPasswordRequest) };
  155. if (forgotPasswordOutcome.IsSuccess())
  156. {
  157. AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnForgotPasswordSuccess);
  158. }
  159. else
  160. {
  161. Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error = forgotPasswordOutcome.GetError();
  162. AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnForgotPasswordFail, error.GetMessage().c_str());
  163. }
  164. }, true, jobContext);
  165. forgotPasswordJob->Start();
  166. }
  167. void AWSCognitoUserManagementController::ConfirmForgotPasswordAsync(const AZStd::string& username, const AZStd::string& confirmationCode, const AZStd::string& newPassword)
  168. {
  169. std::shared_ptr<Aws::CognitoIdentityProvider::CognitoIdentityProviderClient> cognitoIdentityProviderClient =
  170. AZ::Interface<IAWSClientAuthRequests>::Get()->GetCognitoIDPClient();
  171. AZ::JobContext* jobContext = nullptr;
  172. AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext);
  173. AZ::Job* confirmForgotPasswordJob = AZ::CreateJobFunction([this, cognitoIdentityProviderClient, username, confirmationCode, newPassword]()
  174. {
  175. Aws::CognitoIdentityProvider::Model::ConfirmForgotPasswordRequest confirmForgotPasswordRequest;
  176. confirmForgotPasswordRequest.SetClientId(m_cognitoAppClientId.c_str());
  177. confirmForgotPasswordRequest.SetUsername(username.c_str());
  178. confirmForgotPasswordRequest.SetConfirmationCode(confirmationCode.c_str());
  179. confirmForgotPasswordRequest.SetPassword(newPassword.c_str());
  180. Aws::CognitoIdentityProvider::Model::ConfirmForgotPasswordOutcome confirmForgotPasswordOutcome{ cognitoIdentityProviderClient->ConfirmForgotPassword(confirmForgotPasswordRequest) };
  181. if (confirmForgotPasswordOutcome.IsSuccess())
  182. {
  183. AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnConfirmForgotPasswordSuccess);
  184. }
  185. else
  186. {
  187. Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error = confirmForgotPasswordOutcome.GetError();
  188. AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnConfirmForgotPasswordFail, error.GetMessage().c_str());
  189. }
  190. }, true, jobContext);
  191. confirmForgotPasswordJob->Start();
  192. }
  193. void AWSCognitoUserManagementController::EnableMFAAsync(const AZStd::string& accessToken)
  194. {
  195. std::shared_ptr<Aws::CognitoIdentityProvider::CognitoIdentityProviderClient> cognitoIdentityProviderClient =
  196. AZ::Interface<IAWSClientAuthRequests>::Get()->GetCognitoIDPClient();
  197. AZ::JobContext* jobContext = nullptr;
  198. AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext);
  199. AZ::Job* enableMFAJob = AZ::CreateJobFunction([cognitoIdentityProviderClient, accessToken]()
  200. {
  201. Aws::CognitoIdentityProvider::Model::SetUserMFAPreferenceRequest confirmForgotPasswordRequest;
  202. Aws::CognitoIdentityProvider::Model::SMSMfaSettingsType settings;
  203. settings.SetEnabled(true);
  204. settings.SetPreferredMfa(true);
  205. confirmForgotPasswordRequest.SetSMSMfaSettings(settings);
  206. confirmForgotPasswordRequest.SetAccessToken(accessToken.c_str());
  207. Aws::CognitoIdentityProvider::Model::SetUserMFAPreferenceOutcome setUserMFAPreferenceOutcome{ cognitoIdentityProviderClient->SetUserMFAPreference(confirmForgotPasswordRequest) };
  208. if (setUserMFAPreferenceOutcome.IsSuccess())
  209. {
  210. AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnEnableMFASuccess);
  211. }
  212. else
  213. {
  214. Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error = setUserMFAPreferenceOutcome.GetError();
  215. AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnEnableMFAFail, error.GetMessage().c_str());
  216. }
  217. }, true, jobContext);
  218. enableMFAJob->Start();
  219. }
  220. } // namespace AWSClientAuth