AWSClientAuthSystemComponent.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  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 <AWSClientAuthSystemComponent.h>
  9. #include <AWSClientAuthResourceMappingConstants.h>
  10. #include <Authentication/AuthenticationProviderTypes.h>
  11. #include <Authentication/AuthenticationNotificationBusBehaviorHandler.h>
  12. #include <Authorization/AWSCognitoAuthorizationNotificationBusBehaviorHandler.h>
  13. #include <Authorization/AWSCognitoAuthorizationController.h>
  14. #include <Framework/AWSApiJobConfig.h>
  15. #include <ResourceMapping/AWSResourceMappingBus.h>
  16. #include <ResourceMapping/AWSResourceMappingBus.h>
  17. #include <UserManagement/UserManagementNotificationBusBehaviorHandler.h>
  18. #include <aws/cognito-identity/CognitoIdentityClient.h>
  19. #include <aws/cognito-idp/CognitoIdentityProviderClient.h>
  20. #include <AWSCoreBus.h>
  21. namespace AZ
  22. {
  23. AZ_TYPE_INFO_SPECIALIZE(AWSClientAuth::ProviderNameEnum, "{FB34B23A-B249-47A2-B1F1-C05284B50CCC}");
  24. }
  25. namespace AWSClientAuth
  26. {
  27. constexpr char SerializeComponentName[] = "AWSClientAuth";
  28. void AWSClientAuthSystemComponent::Reflect(AZ::ReflectContext* context)
  29. {
  30. AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
  31. if (serialize)
  32. {
  33. serialize->Class<AWSClientAuthSystemComponent, AZ::Component>()->Version(2);
  34. if (AZ::EditContext* ec = serialize->GetEditContext())
  35. {
  36. ec->Class<AWSClientAuthSystemComponent>("AWSClientAuth", "Provides Client Authentication and Authorization implementations")
  37. ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
  38. ->Attribute(AZ::Edit::Attributes::AutoExpand, true);
  39. }
  40. AWSClientAuth::LWAProviderSetting::Reflect(*serialize);
  41. AWSClientAuth::GoogleProviderSetting::Reflect(*serialize);
  42. }
  43. AWSClientAuth::AuthenticationTokens::Reflect(context);
  44. AWSClientAuth::ClientAuthAWSCredentials::Reflect(context);
  45. if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
  46. {
  47. behaviorContext->Enum<(int)ProviderNameEnum::None>("ProviderNameEnum_None")
  48. ->Enum<(int)ProviderNameEnum::AWSCognitoIDP>("ProviderNameEnum_AWSCognitoIDP")
  49. ->Enum<(int)ProviderNameEnum::LoginWithAmazon>("ProviderNameEnum_LoginWithAmazon")
  50. ->Enum<(int)ProviderNameEnum::Google>("ProviderNameEnum_Google");
  51. behaviorContext->EBus<AuthenticationProviderScriptCanvasRequestBus>("AuthenticationProviderRequestBus")
  52. ->Attribute(AZ::Script::Attributes::Category, SerializeComponentName)
  53. ->Event("Initialize", &AuthenticationProviderScriptCanvasRequestBus::Events::Initialize)
  54. ->Event("IsSignedIn", &AuthenticationProviderScriptCanvasRequestBus::Events::IsSignedIn,
  55. { { { "Provider name", "The identity provider name" } } })
  56. ->Event("GetAuthenticationTokens", &AuthenticationProviderScriptCanvasRequestBus::Events::GetAuthenticationTokens,
  57. { { { "Provider name", "The identity provider name" } } })
  58. ->Event(
  59. "PasswordGrantSingleFactorSignInAsync",
  60. &AuthenticationProviderScriptCanvasRequestBus::Events::PasswordGrantSingleFactorSignInAsync,
  61. { { { "Provider name", "The identity provider" }, { "Username", "The client's username" }, { "Password", "The client's password" } } })
  62. ->Event(
  63. "PasswordGrantMultiFactorSignInAsync",
  64. &AuthenticationProviderScriptCanvasRequestBus::Events::PasswordGrantMultiFactorSignInAsync,
  65. { { { "Provider name", "The identity provider name" },
  66. { "Username", "The client's username" },
  67. { "Password", "The client's password" } } })
  68. ->Event(
  69. "PasswordGrantMultiFactorConfirmSignInAsync",
  70. &AuthenticationProviderScriptCanvasRequestBus::Events::PasswordGrantMultiFactorConfirmSignInAsync,
  71. { { { "Provider name", "The identity provider name" },
  72. { "Username", "The client's username" },
  73. { "Confirmation code", "The client's confirmation code" } } })
  74. ->Event(
  75. "DeviceCodeGrantSignInAsync", &AuthenticationProviderScriptCanvasRequestBus::Events::DeviceCodeGrantSignInAsync,
  76. { { { "Provider name", "The identity provider name" } } })
  77. ->Event(
  78. "DeviceCodeGrantConfirmSignInAsync",
  79. &AuthenticationProviderScriptCanvasRequestBus::Events::DeviceCodeGrantConfirmSignInAsync,
  80. { { { "Provider name", "The identity provider name" } } })
  81. ->Event(
  82. "RefreshTokensAsync", &AuthenticationProviderScriptCanvasRequestBus::Events::RefreshTokensAsync,
  83. { { { "Provider name", "The identity provider name" } } })
  84. ->Event("GetTokensWithRefreshAsync", &AuthenticationProviderScriptCanvasRequestBus::Events::GetTokensWithRefreshAsync,
  85. { { { "Provider name", "The identity provider name" } } })
  86. ->Event(
  87. "SignOut", &AuthenticationProviderScriptCanvasRequestBus::Events::SignOut,
  88. { { { "Provider name", "The identity provider name" } } });
  89. behaviorContext->EBus<AWSCognitoAuthorizationRequestBus>("AWSCognitoAuthorizationRequestBus")
  90. ->Attribute(AZ::Script::Attributes::Category, SerializeComponentName)
  91. ->Event("Initialize", &AWSCognitoAuthorizationRequestBus::Events::Initialize)
  92. ->Event("Reset", &AWSCognitoAuthorizationRequestBus::Events::Reset)
  93. ->Event("GetIdentityId", &AWSCognitoAuthorizationRequestBus::Events::GetIdentityId)
  94. ->Event("HasPersistedLogins", &AWSCognitoAuthorizationRequestBus::Events::HasPersistedLogins)
  95. ->Event("RequestAWSCredentialsAsync", &AWSCognitoAuthorizationRequestBus::Events::RequestAWSCredentialsAsync);
  96. behaviorContext->EBus<AWSCognitoUserManagementRequestBus>("AWSCognitoUserManagementRequestBus")
  97. ->Attribute(AZ::Script::Attributes::Category, SerializeComponentName)
  98. ->Event("Initialize", &AWSCognitoUserManagementRequestBus::Events::Initialize)
  99. ->Event(
  100. "EmailSignUpAsync", &AWSCognitoUserManagementRequestBus::Events::EmailSignUpAsync,
  101. { { { "Username", "The client's username" }, { "Password", "The client's password" }, { "Email", "The email address used to sign up" } } })
  102. ->Event(
  103. "PhoneSignUpAsync", &AWSCognitoUserManagementRequestBus::Events::PhoneSignUpAsync,
  104. { { { "Username", "The client's username" }, { "Password", "The client's password" }, { "Phone number", "The phone number used to sign up" } } })
  105. ->Event(
  106. "ConfirmSignUpAsync", &AWSCognitoUserManagementRequestBus::Events::ConfirmSignUpAsync,
  107. { { { "Username", "The client's username" }, { "Confirmation code", "The client's confirmation code" } } })
  108. ->Event(
  109. "ForgotPasswordAsync", &AWSCognitoUserManagementRequestBus::Events::ForgotPasswordAsync,
  110. { { { "Username", "The client's username" } } })
  111. ->Event(
  112. "ConfirmForgotPasswordAsync", &AWSCognitoUserManagementRequestBus::Events::ConfirmForgotPasswordAsync,
  113. { { { "Username", "The client's username" }, { "Confirmation code", "The client's confirmation code" }, { "New password", "The new password for the client" } } })
  114. ->Event("EnableMFAAsync", &AWSCognitoUserManagementRequestBus::Events::EnableMFAAsync, { { { "Access token", "The MFA access token" } } });
  115. behaviorContext->EBus<AuthenticationProviderNotificationBus>("AuthenticationProviderNotificationBus")
  116. ->Attribute(AZ::Script::Attributes::Category, SerializeComponentName)
  117. ->Handler<AuthenticationNotificationBusBehaviorHandler>();
  118. behaviorContext->EBus<AWSCognitoUserManagementNotificationBus>("AWSCognitoUserManagementNotificationBus")
  119. ->Attribute(AZ::Script::Attributes::Category, SerializeComponentName)
  120. ->Handler<UserManagementNotificationBusBehaviorHandler>();
  121. behaviorContext->EBus<AWSCognitoAuthorizationNotificationBus>("AWSCognitoAuthorizationNotificationBus")
  122. ->Attribute(AZ::Script::Attributes::Category, SerializeComponentName)
  123. ->Handler<AWSCognitoAuthorizationNotificationBusBehaviorHandler>();
  124. }
  125. }
  126. void AWSClientAuthSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
  127. {
  128. provided.push_back(AZ_CRC_CE("AWSClientAuthService"));
  129. }
  130. void AWSClientAuthSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
  131. {
  132. incompatible.push_back(AZ_CRC_CE("AWSClientAuthService"));
  133. }
  134. void AWSClientAuthSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
  135. {
  136. required.push_back(AZ_CRC_CE("AWSCoreService"));
  137. }
  138. void AWSClientAuthSystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
  139. {
  140. AZ_UNUSED(dependent);
  141. }
  142. void AWSClientAuthSystemComponent::Init()
  143. {
  144. m_enabledProviderNames.push_back(ProviderNameEnum::AWSCognitoIDP);
  145. // As this Gem depends on AWSCore, AWSCoreSystemComponent gets activated before AWSClientAuth and will miss the OnSDKInitialized
  146. // notification if BusConnect is not in Init.
  147. AWSCore::AWSCoreNotificationsBus::Handler::BusConnect();
  148. }
  149. void AWSClientAuthSystemComponent::Activate()
  150. {
  151. AZ::Interface<IAWSClientAuthRequests>::Register(this);
  152. AWSClientAuthRequestBus::Handler::BusConnect();
  153. m_authenticationProviderManager = AZStd::make_unique<AuthenticationProviderManager>();
  154. // Sanity check if code should setup Cognito user and autorization controllers.
  155. // Only set up if Cognito settings appear to be provided in resource mapping file.
  156. // Cognito User Pools and Cognito Identity Pools are not dependent on one another, but we need at least one.
  157. // Create a controller for user pools and identity pools.
  158. bool awsCognitoUserPoolDefined = false;
  159. AWSCore::AWSResourceMappingRequestBus::BroadcastResult(
  160. awsCognitoUserPoolDefined, &AWSCore::AWSResourceMappingRequests::HasResource, CognitoUserPoolIdResourceMappingKey);
  161. if (awsCognitoUserPoolDefined)
  162. {
  163. m_awsCognitoUserManagementController = AZStd::make_unique<AWSCognitoUserManagementController>();
  164. }
  165. bool awsCognitoIdentityPoolDefined = false;
  166. AWSCore::AWSResourceMappingRequestBus::BroadcastResult(
  167. awsCognitoIdentityPoolDefined, &AWSCore::AWSResourceMappingRequests::HasResource, CognitoIdentityPoolIdResourceMappingKey);
  168. if (awsCognitoIdentityPoolDefined)
  169. {
  170. m_awsCognitoAuthorizationController = AZStd::make_unique<AWSCognitoAuthorizationController>();
  171. }
  172. if (!awsCognitoUserPoolDefined && !awsCognitoIdentityPoolDefined)
  173. {
  174. AZ_Warning("AWSClientAuthSystemComponent", false,
  175. "Missing Cognito settings in resource mappings. Skipping set up of Cognito controllers.");
  176. }
  177. }
  178. void AWSClientAuthSystemComponent::Deactivate()
  179. {
  180. m_authenticationProviderManager.reset();
  181. m_awsCognitoUserManagementController.reset();
  182. m_awsCognitoAuthorizationController.reset();
  183. AWSClientAuthRequestBus::Handler::BusDisconnect();
  184. AWSCore::AWSCoreNotificationsBus::Handler::BusDisconnect();
  185. AZ::Interface<IAWSClientAuthRequests>::Unregister(this);
  186. m_cognitoIdentityProviderClient.reset();
  187. m_cognitoIdentityClient.reset();
  188. }
  189. void AWSClientAuthSystemComponent::OnSDKInitialized()
  190. {
  191. AWSCore::AwsApiJobConfig* defaultConfig;
  192. AWSCore::AWSCoreRequestBus::BroadcastResult(defaultConfig, &AWSCore::AWSCoreRequests::GetDefaultConfig);
  193. Aws::Client::ClientConfiguration clientConfiguration =
  194. defaultConfig ? defaultConfig->GetClientConfiguration() : Aws::Client::ClientConfiguration();
  195. AZStd::string region;
  196. AWSCore::AWSResourceMappingRequestBus::BroadcastResult(region, &AWSCore::AWSResourceMappingRequests::GetDefaultRegion);
  197. clientConfiguration.region = "us-west-2";
  198. if (!region.empty())
  199. {
  200. clientConfiguration.region = region.c_str();
  201. }
  202. m_cognitoIdentityProviderClient =
  203. std::make_shared<Aws::CognitoIdentityProvider::CognitoIdentityProviderClient>(Aws::Auth::AWSCredentials(), clientConfiguration);
  204. m_cognitoIdentityClient = std::make_shared<Aws::CognitoIdentity::CognitoIdentityClient>(Aws::Auth::AWSCredentials(), clientConfiguration);
  205. }
  206. std::shared_ptr<Aws::CognitoIdentityProvider::CognitoIdentityProviderClient> AWSClientAuthSystemComponent::GetCognitoIDPClient()
  207. {
  208. return m_cognitoIdentityProviderClient;
  209. }
  210. std::shared_ptr<Aws::CognitoIdentity::CognitoIdentityClient> AWSClientAuthSystemComponent::GetCognitoIdentityClient()
  211. {
  212. return m_cognitoIdentityClient;
  213. }
  214. bool AWSClientAuthSystemComponent::HasCognitoControllers() const
  215. {
  216. return (m_awsCognitoUserManagementController != nullptr) || (m_awsCognitoAuthorizationController != nullptr);
  217. }
  218. } // namespace AWSClientAuth