Integrating latest 47acbe8

This commit is contained in:
alexpete
2021-03-25 13:57:57 -07:00
parent 448c549698
commit 75dc720198
10312 changed files with 2711566 additions and 671451 deletions
+83
View File
@@ -0,0 +1,83 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME})
ly_add_target(
NAME AWSClientAuth.Static STATIC
NAMESPACE Gem
FILES_CMAKE
awsclientauth_files.cmake
INCLUDE_DIRECTORIES
PUBLIC
Include/Public
PRIVATE
Include/Private
BUILD_DEPENDENCIES
PRIVATE
AZ::AzCore
AZ::AzFramework
Gem::AWSCore
Gem::HttpRequestor
3rdParty::AWSNativeSDK::AWSClientAuth
3rdParty::AWSNativeSDK::Core
)
ly_add_target(
NAME AWSClientAuth ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
NAMESPACE Gem
OUTPUT_NAME Gem.AWSClientAuth.c74f2756f5874c0d8d29646dfc9cb0ad.v0.1.0
FILES_CMAKE
awsclientauth_shared_files.cmake
INCLUDE_DIRECTORIES
PRIVATE
Include/Private
BUILD_DEPENDENCIES
PRIVATE
AZ::AzCore
AZ::AzFramework
Gem::AWSCore
Gem::HttpRequestor
3rdParty::AWSNativeSDK::AWSClientAuth
3rdParty::AWSNativeSDK::Core
PUBLIC
Gem::AWSClientAuth.Static
)
################################################################################
# Tests
################################################################################
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
ly_add_target(
NAME AWSClientAuth.Tests MODULE
NAMESPACE Gem
FILES_CMAKE
awsclientauth_test_files.cmake
INCLUDE_DIRECTORIES
PRIVATE
"Include/Private"
"Include/Public"
Tests
BUILD_DEPENDENCIES
PRIVATE
AZ::AzTest
3rdParty::AWSNativeSDK::AWSClientAuth
AZ::AzCore
AZ::AzFramework
Gem::AWSCore
Gem::AWSClientAuth.Static
AZ::AWSNativeSDKInit
Gem::HttpRequestor
)
ly_add_googletest(
NAME Gem::AWSClientAuth.Tests
)
endif()
@@ -0,0 +1,60 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
namespace Aws
{
namespace CognitoIdentityProvider
{
class CognitoIdentityProviderClient;
}
namespace CognitoIdentity
{
class CognitoIdentityClient;
}
}
namespace AWSClientAuth
{
//! Abstract class for AWS client auth requests.
class IAWSClientAuthRequests
{
public:
AZ_TYPE_INFO(IAWSClientAuthRequests, "{1798CB8B-A334-40BD-913A-4739BF939201}");
//! std shared_ptr as the ownership has to be shared with AWS Native SDK.
//! @return AWS Native SDK Cognito IDP client
virtual std::shared_ptr<Aws::CognitoIdentityProvider::CognitoIdentityProviderClient> GetCognitoIDPClient() = 0;
//! std shared_ptr as the ownership has to be shared with AWS Native SDK.
//! @return AWS Native SDK Cognito Identity client
virtual std::shared_ptr<Aws::CognitoIdentity::CognitoIdentityClient> GetCognitoIdentityClient() = 0;
};
//! Responsible for fetching AWS Cognito IDP and Identity service client objetcs.
class AWSClientAuthRequests
: public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
using MutexType = AZ::NullMutex;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
};
using AWSClientAuthRequestBus = AZ::EBus<IAWSClientAuthRequests, AWSClientAuthRequests>;
} // namespace AWSClientAuth
@@ -0,0 +1,29 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Module/Module.h>
namespace AWSClientAuth
{
//! Entry point for the Gem.
class AWSClientAuthModule
: public AZ::Module
{
public:
AZ_RTTI(AWSClientAuthModule, "{85AD4C5F-A40A-4503-9202-4B8BE6AF0DCD}", AZ::Module);
AWSClientAuthModule();
virtual ~AWSClientAuthModule() override = default;
virtual AZ::ComponentTypeList GetRequiredSystemComponents() const override;
};
}
@@ -0,0 +1,66 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Component/Component.h>
#include <Authorization/AWSCognitoAuthorizationController.h>
#include <Authentication/AuthenticationProviderManager.h>
#include <UserManagement/AWSCognitoUserManagementController.h>
#include <AWSClientAuthBus.h>
#include <AWSCoreBus.h>
namespace AWSClientAuth
{
//! Gem System Component. Responsible for instantiating and managing Authentication and Authroziation Controller
class AWSClientAuthSystemComponent
: public AZ::Component
, public AWSCore::AWSCoreNotificationsBus::Handler
, public AWSClientAuthRequestBus::Handler
{
public:
virtual ~AWSClientAuthSystemComponent() = default;
AZ_COMPONENT(AWSClientAuthSystemComponent, "{0C2660C8-1B4A-4474-BE65-B487E2DE8649}");
static void Reflect(AZ::ReflectContext* context);
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
protected:
// AZ::Component interface implementation
void Init() override;
void Activate() override;
void Deactivate() override;
// AWSCoreNotification interface
void OnSDKInitialized() override;
void OnSDKShutdownStarted() override {}
// AWSClientAuthRequests interface
std::shared_ptr<Aws::CognitoIdentityProvider::CognitoIdentityProviderClient> GetCognitoIDPClient() override;
std::shared_ptr<Aws::CognitoIdentity::CognitoIdentityClient> GetCognitoIdentityClient() override;
AZStd::vector<ProviderNameEnum> m_enabledProviderNames;
AZStd::unique_ptr<AuthenticationProviderManager> m_authenticationProviderManager;
AZStd::unique_ptr<AWSCognitoUserManagementController> m_awsCognitoUserManagementController;
AZStd::unique_ptr<AWSCognitoAuthorizationController> m_awsCognitoAuthorizationController;
std::shared_ptr<Aws::CognitoIdentityProvider::CognitoIdentityProviderClient> m_cognitoIdentityProviderClient;
std::shared_ptr<Aws::CognitoIdentity::CognitoIdentityClient> m_cognitoIdentityClient;
};
} // namespace AWSClientAuth
@@ -0,0 +1,48 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Authentication/AuthenticationProviderInterface.h>
#include <Authentication/AuthenticationProviderTypes.h>
#include <aws/core/utils/Outcome.h>
#include <aws/cognito-idp/CognitoIdentityProviderClient.h>
namespace AWSClientAuth
{
//! Implements AWS Cognito User pool authentication
class AWSCognitoAuthenticationProvider
: public AuthenticationProviderInterface
{
public:
AWSCognitoAuthenticationProvider();
virtual ~AWSCognitoAuthenticationProvider();
// AuthenticationProviderInterface overrides
bool Initialize(AZStd::weak_ptr<AZ::SettingsRegistryInterface> settingsRegistry) override;
void PasswordGrantSingleFactorSignInAsync(const AZStd::string& username, const AZStd::string& password) override;
void PasswordGrantMultiFactorSignInAsync(const AZStd::string& username, const AZStd::string& password) override;
void PasswordGrantMultiFactorConfirmSignInAsync(const AZStd::string& username, const AZStd::string& confirmationCode) override;
void DeviceCodeGrantSignInAsync() override;
void DeviceCodeGrantConfirmSignInAsync() override;
void RefreshTokensAsync() override;
private:
void InitiateAuthInternalAsync(const AZStd::string& username, const AZStd::string& password
, AZStd::function<void(Aws::CognitoIdentityProvider::Model::InitiateAuthOutcome outcome)> outcomeCallback);
void UpdateTokens(const Aws::CognitoIdentityProvider::Model::AuthenticationResultType& authenticationResult);
protected:
AZStd::unique_ptr<AWSCognitoProviderSetting> m_settings;
AZStd::string m_session;
};
} // namespace AWSClientAuth
@@ -0,0 +1,101 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Authentication/AuthenticationProviderBus.h>
namespace AWSClientAuth
{
//! Authentication behavior EBus handler
class AuthenticationNotificationBusBehaviorHandler
: public AuthenticationProviderNotificationBus::Handler
, public AZ::BehaviorEBusHandler
{
public:
AZ_EBUS_BEHAVIOR_BINDER(
AuthenticationNotificationBusBehaviorHandler, "{221D74E0-B55A-4086-8B83-B52070A57217}", AZ::SystemAllocator,
OnPasswordGrantSingleFactorSignInSuccess, OnPasswordGrantSingleFactorSignInFail,
OnPasswordGrantMultiFactorSignInSuccess, OnPasswordGrantMultiFactorSignInFail,
OnPasswordGrantMultiFactorConfirmSignInSuccess, OnPasswordGrantMultiFactorConfirmSignInFail,
OnDeviceCodeGrantSignInSuccess, OnDeviceCodeGrantSignInFail,
OnDeviceCodeGrantConfirmSignInSuccess, OnDeviceCodeGrantConfirmSignInFail,
OnRefreshTokensSuccess, OnRefreshTokensFail,
OnSignOut
);
void OnPasswordGrantSingleFactorSignInSuccess(const AuthenticationTokens& authenticationToken) override
{
Call(FN_OnPasswordGrantSingleFactorSignInSuccess, authenticationToken);
}
void OnPasswordGrantSingleFactorSignInFail(const AZStd::string& error) override
{
Call(FN_OnPasswordGrantSingleFactorSignInFail, error);
}
void OnPasswordGrantMultiFactorSignInSuccess() override
{
Call(FN_OnPasswordGrantMultiFactorSignInSuccess);
}
void OnPasswordGrantMultiFactorSignInFail(const AZStd::string& error) override
{
Call(FN_OnPasswordGrantMultiFactorSignInFail, error);
}
void OnPasswordGrantMultiFactorConfirmSignInSuccess(const AuthenticationTokens& authenticationToken) override
{
Call(FN_OnPasswordGrantMultiFactorConfirmSignInSuccess, authenticationToken);
}
void OnPasswordGrantMultiFactorConfirmSignInFail(const AZStd::string& error) override
{
Call(FN_OnPasswordGrantMultiFactorConfirmSignInFail, error);
}
void OnDeviceCodeGrantSignInSuccess(
const AZStd::string& userCode, const AZStd::string& verificationUrl, const int codeExpiresInSeconds) override
{
Call(FN_OnDeviceCodeGrantSignInSuccess, userCode, verificationUrl, codeExpiresInSeconds);
}
void OnDeviceCodeGrantSignInFail(const AZStd::string& error) override
{
Call(FN_OnDeviceCodeGrantSignInFail, error);
}
void OnDeviceCodeGrantConfirmSignInSuccess(const AuthenticationTokens& authenticationToken) override
{
Call(FN_OnDeviceCodeGrantConfirmSignInSuccess, authenticationToken);
}
void OnDeviceCodeGrantConfirmSignInFail(const AZStd::string& error) override
{
Call(FN_OnDeviceCodeGrantConfirmSignInFail, error);
}
void OnRefreshTokensSuccess(const AuthenticationTokens& authenticationToken) override
{
Call(FN_OnRefreshTokensSuccess, authenticationToken);
}
void OnRefreshTokensFail(const AZStd::string& error) override
{
Call(FN_OnRefreshTokensFail, error);
}
void OnSignOut(const ProviderNameEnum& provideName) override
{
Call(FN_OnSignOut, provideName);
}
};
} // namespace AWSClientAuth
@@ -0,0 +1,67 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Settings/SettingsRegistry.h>
#include <AzCore/std/smart_ptr/weak_ptr.h>
#include <Authentication/AuthenticationTokens.h>
namespace AWSClientAuth
{
//! Interface to be implemented by AuthenticationProviders to interact with AuthenticationManager.
//! Follows grant types for password and device from following: https://oauth.net/2/grant-types/
class AuthenticationProviderInterface
{
public:
AuthenticationProviderInterface() = default;
virtual ~AuthenticationProviderInterface() = default;
//! Extract required settings for the provider from setting registry.
//! @param settingsRegistry Passed in initialized settings registry object.
//! @return bool True: if provider can parse required settings and validate. False: fails to parse required settings.
virtual bool Initialize(AZStd::weak_ptr<AZ::SettingsRegistryInterface> settingsRegistry) = 0;
//! Call sign in endpoint for provider password grant flow.
//! @param username Username to use to for sign in.
//! @param password Password to use to for sign in.
virtual void PasswordGrantSingleFactorSignInAsync(const AZStd::string& username, const AZStd::string& password) = 0;
//! Call sign in endpoint for provider password grant multi factor authentication flow.
//! @param username Username to use for MFA sign in.
//! @param password Password to use for MFA sign in.
virtual void PasswordGrantMultiFactorSignInAsync(const AZStd::string& username, const AZStd::string& password) = 0;
//! Call confirm endpoint for provider password grant multi factor authentication flow .
//! @param username Username to use for MFA confirm.
//! @param confirmationCode Confirmation code (sent to email/text) to use for MFA confirm.
virtual void PasswordGrantMultiFactorConfirmSignInAsync(const AZStd::string& username, const AZStd::string& confirmationCode) = 0;
//! Call code-pair endpoint for provider device grant flow.
virtual void DeviceCodeGrantSignInAsync() = 0;
//! Call tokens endpoint for provider device grant flow.
virtual void DeviceCodeGrantConfirmSignInAsync() = 0;
//! Call refresh endpoint for provider refresh grant flow.
virtual void RefreshTokensAsync() = 0;
//! @return Authentication tokens from last successful sign in.
virtual AuthenticationTokens GetAuthenticationTokens();
//! Clears all cached tokens and expiry
virtual void SignOut();
protected:
AuthenticationTokens m_authenticationTokens;
};
} // namespace AWSClientAuth
@@ -0,0 +1,58 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <AzCore/std/containers/map.h>
#include <AzCore/std/containers/vector.h>
#include <Authentication/AuthenticationProviderBus.h>
#include <Authentication/AuthenticationProviderInterface.h>
#include <Authentication/AuthenticationTokens.h>
namespace AWSClientAuth
{
//! Manages various authentication provider implementations and implements AuthenticationProvider Request bus.
class AuthenticationProviderManager
: AuthenticationProviderRequestBus::Handler
{
public:
AZ_RTTI(AuthenticationProviderManager, "{45813BA5-9A46-4A2A-A923-C79CFBA0E63D}", IAuthenticationProviderRequests);
AuthenticationProviderManager();
virtual ~AuthenticationProviderManager();
protected:
// AuthenticationProviderRequestsBus Interface
bool Initialize(const AZStd::vector<ProviderNameEnum>& providerNames, const AZStd::string& settingsRegistryPath) override;
void PasswordGrantSingleFactorSignInAsync(const ProviderNameEnum& providerName, const AZStd::string& username, const AZStd::string& password) override;
void PasswordGrantMultiFactorSignInAsync(const ProviderNameEnum& providerName, const AZStd::string& username, const AZStd::string& password) override;
void PasswordGrantMultiFactorConfirmSignInAsync(const ProviderNameEnum& providerName, const AZStd::string& username, const AZStd::string& confirmationCode) override;
void DeviceCodeGrantSignInAsync(const ProviderNameEnum& providerName) override;
void DeviceCodeGrantConfirmSignInAsync(const ProviderNameEnum& providerName) override;
void RefreshTokensAsync(const ProviderNameEnum& providerName) override;
void GetTokensWithRefreshAsync(const ProviderNameEnum& providerName) override;
bool IsSignedIn(const ProviderNameEnum& providerName) override;
bool SignOut(const ProviderNameEnum& providerName) override;
AuthenticationTokens GetAuthenticationTokens(const ProviderNameEnum& providerName) override;
virtual AZStd::unique_ptr<AuthenticationProviderInterface> CreateAuthenticationProviderObject(const ProviderNameEnum& providerName);
AZStd::map<ProviderNameEnum, AZStd::unique_ptr<AuthenticationProviderInterface>> m_authenticationProvidersMap;
private:
bool IsProviderInitialized(const ProviderNameEnum& providerName);
void ResetProviders();
AZStd::shared_ptr<AZ::SettingsRegistryInterface> m_settingsRegistry;
};
} // namespace AWSClientAuth
@@ -0,0 +1,102 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Serialization/EditContext.h>
namespace AWSClientAuth
{
//! Holds Login with Amazon provider serialized settings
class LWAProviderSetting
{
public:
LWAProviderSetting() = default;
~LWAProviderSetting() = default;
AZ_TYPE_INFO(LWAProviderSetting, "{AA7A0B0E-626B-4D87-B862-8961BA0C843E}");
AZStd::string m_appClientId;
AZStd::string m_responseType;
AZStd::string m_grantType;
AZStd::string m_oAuthCodeURL;
AZStd::string m_oAuthTokensURL;
static void Reflect(AZ::SerializeContext& context)
{
context.Class<LWAProviderSetting>()
->Field("AppClientId", &LWAProviderSetting::m_appClientId)
->Field("ResponseType", &LWAProviderSetting::m_responseType)
->Field("GrantType", &LWAProviderSetting::m_grantType)
->Field("OAuthCodeURL", &LWAProviderSetting::m_oAuthCodeURL)
->Field("OAuthTokensURL", &LWAProviderSetting::m_oAuthTokensURL);
}
};
//! Holds Google provider serialized settings
class GoogleProviderSetting
{
public:
GoogleProviderSetting() = default;
~GoogleProviderSetting() = default;
AZ_TYPE_INFO(GoogleProviderSetting, "{C501E0DB-EEA5-4BC9-8E2E-CAE037AEE95F}");
AZStd::string m_appClientId;
AZStd::string m_clientSecret;
AZStd::string m_grantType;
AZStd::string m_oAuthCodeURL;
AZStd::string m_oAuthTokensURL;
static void Reflect(AZ::SerializeContext& context)
{
context.Class<GoogleProviderSetting>()
->Field("AppClientId", &GoogleProviderSetting::m_appClientId)
->Field("ClientSecret", &GoogleProviderSetting::m_clientSecret)
->Field("GrantType", &GoogleProviderSetting::m_grantType)
->Field("OAuthCodeURL", &GoogleProviderSetting::m_oAuthCodeURL)
->Field("OAuthTokensURL", &GoogleProviderSetting::m_oAuthTokensURL);
}
};
//! Holds AWS Cognito provider serialized Settings.
class AWSCognitoProviderSetting
{
public:
AWSCognitoProviderSetting() = default;
~AWSCognitoProviderSetting() = default;
AZ_TYPE_INFO(AWSCognitoProviderSetting, "{46EF239C-D3CF-4B17-BA68-FD6B3B249305}");
AZStd::string m_appClientId;
static void Reflect(AZ::SerializeContext& context)
{
context.Class<AWSCognitoProviderSetting>()
->Field("AppClientId", &AWSCognitoProviderSetting::m_appClientId)
;
AZ::EditContext* editContext = context.GetEditContext();
if (editContext)
{
editContext->Class<AWSCognitoProviderSetting>("AWSCognitoProviderSetting", "AWSCognitoProviderSetting Settings")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Category, "AWSClientAuth")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game"))
->DataElement(AZ::Edit::UIHandlers::Default, &AWSCognitoProviderSetting::m_appClientId, "ClientId", "Cognito User Pool App Client Id");
}
}
};
} // namespace AWSClientAuth
@@ -0,0 +1,46 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Authentication/AuthenticationProviderInterface.h>
#include <Authentication/AuthenticationProviderTypes.h>
#include <aws/core/utils/json/JsonSerializer.h>
namespace AWSClientAuth
{
//! Implements OAuth2.0 device flow for Google authentication service.
class GoogleAuthenticationProvider
: public AuthenticationProviderInterface
{
public:
GoogleAuthenticationProvider();
virtual ~GoogleAuthenticationProvider();
// AuthenticationProviderInterface overrides
bool Initialize(AZStd::weak_ptr<AZ::SettingsRegistryInterface> settingsRegistry) override;
void PasswordGrantSingleFactorSignInAsync(const AZStd::string& username, const AZStd::string& password) override;
void PasswordGrantMultiFactorSignInAsync(const AZStd::string& username, const AZStd::string& password) override;
void PasswordGrantMultiFactorConfirmSignInAsync(const AZStd::string& username, const AZStd::string& confirmationCode) override;
void DeviceCodeGrantSignInAsync() override;
void DeviceCodeGrantConfirmSignInAsync() override;
void RefreshTokensAsync() override;
private:
void UpdateTokens(const Aws::Utils::Json::JsonView& jsonView);
protected:
AZStd::unique_ptr<GoogleProviderSetting> m_settings;
private:
AZStd::string m_cachedDeviceCode;
};
} // namespace AWSClientAuth
@@ -0,0 +1,47 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Authentication/AuthenticationProviderInterface.h>
#include <Authentication/AuthenticationProviderTypes.h>
#include <aws/core/utils/json/JsonSerializer.h>
namespace AWSClientAuth
{
//! Implements OAuth2.0 device flow for Login with Amazon authentication service.
class LWAAuthenticationProvider
: public AuthenticationProviderInterface
{
public:
LWAAuthenticationProvider();
virtual ~LWAAuthenticationProvider();
// AuthenticationProviderInterface overrides
bool Initialize(AZStd::weak_ptr<AZ::SettingsRegistryInterface> settingsRegistry) override;
void PasswordGrantSingleFactorSignInAsync(const AZStd::string& username, const AZStd::string& password) override;
void PasswordGrantMultiFactorSignInAsync(const AZStd::string& username, const AZStd::string& password) override;
void PasswordGrantMultiFactorConfirmSignInAsync(const AZStd::string& username, const AZStd::string& confirmationCode) override;
void DeviceCodeGrantSignInAsync() override;
void DeviceCodeGrantConfirmSignInAsync() override;
void RefreshTokensAsync() override;
private:
void UpdateTokens(const Aws::Utils::Json::JsonView& jsonView);
protected:
AZStd::unique_ptr<LWAProviderSetting> m_settings;
private:
AZStd::string m_cachedUserCode;
AZStd::string m_cachedDeviceCode;
};
} // namespace AWSClientAuth
@@ -0,0 +1,40 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
namespace AWSClientAuth
{
constexpr char OAUTH_CLIENT_ID_BODY_KEY[] = "client_id";
constexpr char OAUTH_CLIENT_SECRET_BODY_KEY[] = "client_secret";
constexpr char OAUTH_DEVICE_CODE_BODY_KEY[] = "device_code";
constexpr char OAUTH_SCOPE_BODY_KEY[] = "scope";
constexpr char OAUTH_SCOPE_BODY_VALUE[] = "profile";
constexpr char OAUTH_GRANT_TYPE_BODY_KEY[] = "grant_type";
constexpr char OAUTH_REFRESH_TOKEN_BODY_KEY[] = "refresh_token";
constexpr char OAUTH_REFRESH_TOKEN_BODY_VALUE[] = "refresh_token";
constexpr char OAUTH_RESPONSE_TYPE_BODY_KEY[] = "response_type";
constexpr char OAUTH_CONTENT_TYPE_HEADER_KEY[] = "Content-Type";
constexpr char OAUTH_CONTENT_TYPE_HEADER_VALUE[] = "application/x-www-form-urlencoded";
constexpr char OAUTH_CONTENT_LENGTH_HEADER_KEY[] = "Content-Length";
constexpr char OAUTH_USER_CODE_RESPONSE_KEY[] = "user_code";
constexpr char OAUTH_ID_TOKEN_RESPONSE_KEY[] = "id_token";
constexpr char OAUTH_ACCESS_TOKEN_RESPONSE_KEY[] = "access_token";
constexpr char OAUTH_REFRESH_TOKEN_RESPONSE_KEY[] = "refresh_token";
constexpr char OAUTH_EXPIRES_IN_RESPONSE_KEY[] = "expires_in";
constexpr char OAUTH_ERROR_RESPONSE_KEY[] = "error";
} // namespace AWSClientAuth
@@ -0,0 +1,48 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Authorization/AWSCognitoAuthorizationTypes.h>
#include <aws/identity-management/auth/PersistentCognitoIdentityProvider.h>
namespace AWSClientAuth
{
//! Persistent Cognito Identity provider implementation that is shared with AWS Native SDK client.
//! Use std::shared_ptr to create instance.
class AWSClientAuthPersistentCognitoIdentityProvider
: public Aws::Auth::PersistentCognitoIdentityProvider
{
public:
AWSClientAuthPersistentCognitoIdentityProvider() = default;
virtual ~AWSClientAuthPersistentCognitoIdentityProvider();
// PersistentCognitoIdentityProvider Interface
void Initialize(const Aws::String& awsAccountId, const Aws::String& identityPoolId);
bool HasIdentityId() const override;
bool HasLogins() const override;
Aws::String GetIdentityId() const override;
Aws::Map<Aws::String, Aws::Auth::LoginAccessTokens> GetLogins() override;
Aws::String GetAccountId() const override;
Aws::String GetIdentityPoolId() const override;
void PersistIdentityId(const Aws::String&) override;
void PersistLogins(const Aws::Map<Aws::String, Aws::Auth::LoginAccessTokens>&) override;
void RemoveLogin(const Aws::String&);
private:
Aws::Map<Aws::String, Aws::Auth::LoginAccessTokens> m_logins;
Aws::String m_identityId;
Aws::String m_awsAccountId;
Aws::String m_identityPoolId;
};
} // namespace AWSClientAuth
@@ -0,0 +1,71 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Authorization/AWSCognitoAuthorizationBus.h>
#include <Authorization/AWSCognitoAuthorizationTypes.h>
#include <Authorization/AWSClientAuthPersistentCognitoIdentityProvider.h>
#include <Authentication/AuthenticationProviderBus.h>
#include <Credential/AWSCredentialBus.h>
#include <aws/cognito-identity/CognitoIdentityClient.h>
#include <aws/identity-management/auth/CognitoCachingCredentialsProvider.h>
namespace AWSClientAuth
{
//! Implements AWS Cognito Identity pool authorization.
class AWSCognitoAuthorizationController
: public AWSCognitoAuthorizationRequestBus::Handler
, public AuthenticationProviderNotificationBus::Handler
, public AWSCore::AWSCredentialRequestBus::Handler
{
public:
AZ_RTTI(AWSCognitoAuthorizationController, "{0E731ED1-2F08-4B3C-9282-D452700F58D1}", IAWSCognitoAuthorizationRequests);
AWSCognitoAuthorizationController();
virtual ~AWSCognitoAuthorizationController();
// AWSCognitoAuthorizationRequestsBus interface methods
bool Initialize(const AZStd::string& settingsRegistryPath) override;
void Reset() override;
AZStd::string GetIdentityId() override;
bool HasPersistedLogins() override;
std::shared_ptr<Aws::Auth::AWSCredentialsProvider> GetCognitoCredentialsProvider() override;
std::shared_ptr<Aws::Auth::AWSCredentialsProvider> GetAnonymousCognitoCredentialsProvider() override;
void RequestAWSCredentialsAsync() override;
protected:
// AuthenticationProviderNotificationsBus interface. Update persistent login tokens on successful sign in.
void OnPasswordGrantSingleFactorSignInSuccess(const AWSClientAuth::AuthenticationTokens& authenticationTokens) override;
void OnPasswordGrantMultiFactorConfirmSignInSuccess(const AWSClientAuth::AuthenticationTokens& authenticationTokens) override;
void OnDeviceCodeGrantConfirmSignInSuccess(const AWSClientAuth::AuthenticationTokens& authenticationTokens) override;
void OnRefreshTokensSuccess(const AWSClientAuth::AuthenticationTokens& authenticationTokens) override;
void OnSignOut(const ProviderNameEnum& provideName) override;
// AWSCredentialRequestBus interface implementation
int GetCredentialHandlerOrder() const override;
std::shared_ptr<Aws::Auth::AWSCredentialsProvider> GetCredentialsProvider() override;
AZStd::unique_ptr<CognitoAuthorizationSettings> m_settings;
std::shared_ptr<AWSClientAuthPersistentCognitoIdentityProvider> m_persistentCognitoIdentityProvider;
std::shared_ptr<AWSClientAuthPersistentCognitoIdentityProvider> m_persistentAnonymousCognitoIdentityProvider;
std::shared_ptr<Aws::Auth::CognitoCachingAuthenticatedCredentialsProvider> m_cognitoCachingCredentialsProvider;
std::shared_ptr<Aws::Auth::CognitoCachingAnonymousCredentialsProvider> m_cognitoCachingAnonymousCredentialsProvider;
private:
void PersistLoginsAndRefreshAWSCredentials(const AuthenticationTokens& authenticationTokens);
AZStd::string GetAuthenticationProviderId(const ProviderNameEnum& providerName);
AZStd::mutex m_persistentCognitoIdentityProviderMutex;
AZStd::mutex m_persistentAnonymousCognitoIdentityProviderMutex;
};
} // namespace AWSClientAuth
@@ -0,0 +1,39 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Authorization/AWSCognitoAuthorizationBus.h>
#include <AzCore/RTTI/BehaviorContext.h>
namespace AWSClientAuth
{
//! Authorization behavior EBus handler
class AWSCognitoAuthorizationNotificationBusBehaviorHandler
: public AWSCognitoAuthorizationNotificationBus::Handler
, public AZ::BehaviorEBusHandler
{
public:
AZ_EBUS_BEHAVIOR_BINDER(AWSCognitoAuthorizationNotificationBusBehaviorHandler, "{F2BCAB42-97FD-41AC-AF7A-7E3BD64B7089}", AZ::SystemAllocator,
OnRequestAWSCredentialsSuccess, OnRequestAWSCredentialsFail
);
void OnRequestAWSCredentialsSuccess(const ClientAuthAWSCredentials& awsCredentials) override
{
Call(FN_OnRequestAWSCredentialsSuccess, awsCredentials);
}
void OnRequestAWSCredentialsFail(const AZStd::string& error) override
{
Call(FN_OnRequestAWSCredentialsFail, error);
}
};
} // namespace AWSClientAuth
@@ -0,0 +1,59 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Serialization/EditContext.h>
namespace AWSClientAuth
{
//! Holds Cognito Authorization Identity pool settings.
class CognitoAuthorizationSettings
{
public:
AZ_TYPE_INFO(CognitoAuthorizationSettings, "{2F2080CD-E575-42BD-9717-E42E43C13956}");
static void Reflect(AZ::SerializeContext& context)
{
context.Class<CognitoAuthorizationSettings>()
->Field("CognitoUserPoolId", &CognitoAuthorizationSettings::m_cognitoUserPoolId)
->Field("LoginWithAmazonId", &CognitoAuthorizationSettings::m_loginWithAmazonId)
->Field("GoogleId", &CognitoAuthorizationSettings::m_googleId)
->Field("AWSAccountId", &CognitoAuthorizationSettings::m_awsAccountId)
->Field("IdentityPoolId", &CognitoAuthorizationSettings::m_cognitoIdentityPoolId);
AZ::EditContext* editContext = context.GetEditContext();
if (editContext)
{
editContext->Class<CognitoAuthorizationSettings>("CognitoAuthorizationSettings", "CognitoAuthorizationSettings")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Category, "AWSClientAuth")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game"))
->DataElement(AZ::Edit::UIHandlers::Default, &CognitoAuthorizationSettings::m_cognitoUserPoolId, "CognitoUserPoolId", "Cognito User pool Id")
->DataElement(AZ::Edit::UIHandlers::Default, &CognitoAuthorizationSettings::m_loginWithAmazonId, "LoginWithAmazonId", "Login with Amazon id. default: www.amazon.com")
->DataElement(AZ::Edit::UIHandlers::Default, &CognitoAuthorizationSettings::m_googleId, "Google Endpoint", "Google endpoint. default: accounts.google.com")
->DataElement(AZ::Edit::UIHandlers::Default, &CognitoAuthorizationSettings::m_cognitoUserPoolId, "AWSAccountId", "AWS account Cognito for Cognito identity pool")
->DataElement(AZ::Edit::UIHandlers::Default, &CognitoAuthorizationSettings::m_cognitoUserPoolId, "IdentityPoolId", "Cognito Identity pool Id")
;
}
}
AZStd::string m_cognitoUserPoolId;
AZStd::string m_loginWithAmazonId = "www.amazon.com";
AZStd::string m_googleId = "accounts.google.com";
AZStd::string m_awsAccountId;
AZStd::string m_cognitoIdentityPoolId;
};
} // namespace AWSClientAuth
@@ -0,0 +1,42 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <UserManagement/AWSCognitoUserManagementBus.h>
#include <UserManagement/AWSCognitoUserManagementTypes.h>
namespace AWSClientAuth
{
//! Implements AWS Cognito User pool user management.
class AWSCognitoUserManagementController
: public AWSCognitoUserManagementRequestBus::Handler
{
public:
AZ_RTTI(AWSCognitoUserManagementController, "{2645D1CC-EB55-4A8D-8F45-5DFE94032813}", IAWSCognitoUserManagementRequests);
AWSCognitoUserManagementController();
virtual ~AWSCognitoUserManagementController();
// AWSCognitoUserManagementRequestsBus interface methods
bool Initialize(const AZStd::string& settingsRegistryPath);
void EmailSignUpAsync(const AZStd::string& username, const AZStd::string& password, const AZStd::string& email) override;
void PhoneSignUpAsync(const AZStd::string& username, const AZStd::string& password, const AZStd::string& phoneNumber) override;
void ConfirmSignUpAsync(const AZStd::string& username, const AZStd::string& confirmationCode) override;
void ForgotPasswordAsync(const AZStd::string& username) override;
void ConfirmForgotPasswordAsync(const AZStd::string& userName, const AZStd::string& confirmationCode, const AZStd::string& newPassword) override;
void EnableMFAAsync(const AZStd::string& accessToken) override;
protected:
AZStd::unique_ptr<AWSCognitoUserManagementSetting> m_settings;
};
} // namespace AWSClientAuth
@@ -0,0 +1,50 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Serialization/EditContext.h>
namespace AWSClientAuth
{
//! Holds AWS Cognito user management serialized Settings.
class AWSCognitoUserManagementSetting
{
public:
AWSCognitoUserManagementSetting() = default;
~AWSCognitoUserManagementSetting() = default;
AZ_TYPE_INFO(AWSCognitoUserManagementSetting, "{58FC34F1-B84B-4677-B986-45A226F0328D}");
AZStd::string m_appClientId;
static void Reflect(AZ::SerializeContext& context)
{
context.Class<AWSCognitoUserManagementSetting>()
->Field("AppClientId", &AWSCognitoUserManagementSetting::m_appClientId)
;
AZ::EditContext* editContext = context.GetEditContext();
if (editContext)
{
editContext->Class<AWSCognitoUserManagementSetting>("AWSCognitoUserManagementSetting", "AWSCognitoUserManagementSetting Settings")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Category, "AWSClientAuth")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game"))
->DataElement(AZ::Edit::UIHandlers::Default, &AWSCognitoUserManagementSetting::m_appClientId, "ClientId", "Cognito User Pool App Client Id")
;
}
}
};
} // namespace AWSClientAuth
@@ -0,0 +1,93 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <UserManagement/AWSCognitoUserManagementBus.h>
namespace AWSClientAuth
{
//! User management behavior EBus handler
class UserManagementNotificationBusBehaviorHandler
: public AWSCognitoUserManagementNotificationBus::Handler
, public AZ::BehaviorEBusHandler
{
public:
AZ_EBUS_BEHAVIOR_BINDER(UserManagementNotificationBusBehaviorHandler, "{57289595-2CDC-4834-8017-4A96B983E028}", AZ::SystemAllocator,
OnEmailSignUpSuccess, OnEmailSignUpFail,
OnPhoneSignUpSuccess, OnPhoneSignUpFail,
OnConfirmSignUpSuccess, OnConfirmSignUpFail,
OnForgotPasswordSuccess, OnForgotPasswordFail,
OnConfirmForgotPasswordSuccess, OnConfirmForgotPasswordFail,
OnEnableMFASuccess, OnEnableMFAFail
);
void OnEmailSignUpSuccess(const AZStd::string& uuid) override
{
Call(FN_OnEmailSignUpSuccess, uuid);
}
void OnEmailSignUpFail(const AZStd::string& error) override
{
Call(FN_OnEmailSignUpFail, error);
}
void OnPhoneSignUpSuccess(const AZStd::string& uuid) override
{
Call(FN_OnPhoneSignUpSuccess, uuid);
}
void OnPhoneSignUpFail(const AZStd::string& error) override
{
Call(FN_OnPhoneSignUpFail, error);
}
void OnConfirmSignUpSuccess() override
{
Call(FN_OnConfirmSignUpSuccess);
}
void OnConfirmSignUpFail(const AZStd::string& error) override
{
Call(FN_OnConfirmSignUpFail, error);
}
void OnForgotPasswordSuccess() override
{
Call(FN_OnForgotPasswordSuccess);
}
void OnForgotPasswordFail(const AZStd::string& error) override
{
Call(FN_OnForgotPasswordFail, error);
}
void OnConfirmForgotPasswordSuccess() override
{
Call(FN_OnConfirmForgotPasswordSuccess);
}
void OnConfirmForgotPasswordFail(const AZStd::string& error) override
{
Call(FN_OnConfirmForgotPasswordFail, error);
}
void OnEnableMFASuccess() override
{
Call(FN_OnEnableMFASuccess);
}
void OnEnableMFAFail(const AZStd::string& error) override
{
Call(FN_OnEnableMFAFail, error);
}
};
} // namespace AWSClientAuth
@@ -0,0 +1,208 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
#include <Authentication/AuthenticationTokens.h>
namespace AWSClientAuth
{
//@ Abstract class for authentication provider requests.
class IAuthenticationProviderRequests
{
public:
AZ_TYPE_INFO(IAuthenticationProviderRequests, "{4A8017C4-2742-48C4-AF07-1177CBF5E6E9}");
//! Parse the settings file for required settings for authentication providers. Instantiate and initialize authentication providers
//! @param providerNames List of provider names to instantiate and initialize for Authentication.
//! @param settingsRegistryPath Path for the settings registry file to use to configure providers.
//! @return bool True: if all providers initialized successfully. False: If any provider fails initialization.
virtual bool Initialize(const AZStd::vector<ProviderNameEnum>& providerNames, const AZStd::string& settingsRegistryPath) = 0;
//! Checks if user is signed in.
//! If access tokens are available and not expired.
//! @param providerName Provider to check signed in for
//! @return bool True if valid access token available, else False
virtual bool IsSignedIn(const ProviderNameEnum& providerName) = 0;
//! Get cached tokens from last last successful sign-in for the provider.
virtual AuthenticationTokens GetAuthenticationTokens(const ProviderNameEnum& providerName) = 0;
// Below methods have corresponding notifications for success and failures.
//! Call sign in endpoint for provider password grant flow.
//! @param username Username to use to for sign in.
//! @param password Password to use to for sign in.
virtual void PasswordGrantSingleFactorSignInAsync(const ProviderNameEnum& providerName, const AZStd::string& username, const AZStd::string& password) = 0;
//! Call sign in endpoint for provider password grant multi factor authentication flow.
//! @param username Username to use for MFA sign in.
//! @param password Password to use for MFA sign in.
virtual void PasswordGrantMultiFactorSignInAsync(const ProviderNameEnum& providerName, const AZStd::string& username, const AZStd::string& password) = 0;
//! Call confirm endpoint for provider password grant multi factor authentication flow .
//! @param username Username to use for MFA confirm.
//! @param confirmationCode Confirmation code (sent to email/text) to use for MFA confirm.
virtual void PasswordGrantMultiFactorConfirmSignInAsync(const ProviderNameEnum& providerName, const AZStd::string& username, const AZStd::string& confirmationCode) = 0;
//! Call code-pair endpoint for provider device grant flow.
virtual void DeviceCodeGrantSignInAsync(const ProviderNameEnum& providerName) = 0;
//! Call tokens endpoint for provider device grant flow.
virtual void DeviceCodeGrantConfirmSignInAsync(const ProviderNameEnum& providerName) = 0;
//! Call refresh endpoint for provider refresh grant flow.
virtual void RefreshTokensAsync(const ProviderNameEnum& providerName) = 0;
//! Call refresh token if token not valid. If token valid, fires corresponding event.
//! @param providerName Provider to get access token for.
//! events: OnRefreshTokensSuccess, OnRefreshTokensFail
virtual void GetTokensWithRefreshAsync(const ProviderNameEnum& providerName) = 0;
//! Signs user out.
//! Clears all cached tokens.
//! @param providerName Provider to sign out.
//! @return bool True: Successfully sign out.
virtual bool SignOut(const ProviderNameEnum& providerName) = 0;
//////////////////////////////////////////////////////////////////////////
};
//! Authentication Request bus for different supported providers.
class AuthenticationProviderRequests
: public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
using MutexType = AZ::NullMutex;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
};
using AuthenticationProviderRequestBus = AZ::EBus<IAuthenticationProviderRequests, AuthenticationProviderRequests>;
//! Notification bus for Authentication Request bus.
class AuthenticationProviderNotifications
: public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
////////////////////////////ss//////////////////////////////////////////////
// Notifications interface
//! Event for PasswordGrantSingleFactorSignIn success.
//! @param authenticationToken Tokens on successful sign in.
virtual void OnPasswordGrantSingleFactorSignInSuccess(const AuthenticationTokens& authenticationToken)
{
AZ_UNUSED(authenticationToken);
}
//! Event for PasswordGrantSingleFactorSignIn fail.
//! @param error Error message
virtual void OnPasswordGrantSingleFactorSignInFail(const AZStd::string& error)
{
AZ_UNUSED(error);
}
//! Event for PasswordGrantMultiFactorSignIn success.
//! Event use to notify user to take corresponding challenge action.
virtual void OnPasswordGrantMultiFactorSignInSuccess()
{
}
//! Event for PasswordGrantMultiFactorSignIn fail.
//! @param error Error message
virtual void OnPasswordGrantMultiFactorSignInFail(const AZStd::string& error)
{
AZ_UNUSED(error);
}
//! Event for PasswordGrantMultiFactorConfirm success.
//! @param authenticationToken Tokens on successful sign in.
virtual void OnPasswordGrantMultiFactorConfirmSignInSuccess(const AuthenticationTokens& authenticationToken)
{
AZ_UNUSED(authenticationToken);
}
//! Event for PasswordGrantMultiFactorConfirm fail.
//! @param error Error message
virtual void OnPasswordGrantMultiFactorConfirmSignInFail(const AZStd::string& error)
{
AZ_UNUSED(error);
}
//! Event for DeviceCodeGrantSignIn success.
//! Event use to notify user to take open verification url and enter displayed code.
//! @param userCode Unique code generated for user for the session.
//! @param verificationUrl Verification URL to enter user code in after signing in for the provider.
//! @param codeExpiresInSeconds Code expiry in seconds.
virtual void OnDeviceCodeGrantSignInSuccess(const AZStd::string& userCode, const AZStd::string& verificationUrl, const int codeExpiresInSeconds)
{
AZ_UNUSED(userCode);
AZ_UNUSED(verificationUrl);
AZ_UNUSED(codeExpiresInSeconds);
}
//! Event for DeviceCodeGrantSignIn fail.
//! @param error Error message
virtual void OnDeviceCodeGrantSignInFail(const AZStd::string& error)
{
AZ_UNUSED(error);
}
//! Event for DeviceCodeGrantConfirmSignIn success.
//! @param authenticationToken Tokens on successful sign in..
virtual void OnDeviceCodeGrantConfirmSignInSuccess(const AuthenticationTokens& authenticationToken)
{
AZ_UNUSED(authenticationToken);
}
//! Event for DeviceCodeGrantConfirmSignIn fail.
//! @param error Error message
virtual void OnDeviceCodeGrantConfirmSignInFail(const AZStd::string& error)
{
AZ_UNUSED(error);
}
//! Event for RequestAccessTokenWithRefresh success.
//! @param authenticationToken Tokens on successful sign in.
virtual void OnRefreshTokensSuccess(const AuthenticationTokens& authenticationToken)
{
AZ_UNUSED(authenticationToken);
}
//! Event for RequestAccessTokenWithRefresh fail.
//! @param error Error message
virtual void OnRefreshTokensFail(const AZStd::string& error)
{
AZ_UNUSED(error);
}
//! Event for Sing out.
//! @param providerName provider that signed out.
virtual void OnSignOut(const ProviderNameEnum& provideName)
{
AZ_UNUSED(provideName);
}
//////////////////////////////////////////////////////////////////////////
};
using AuthenticationProviderNotificationBus = AZ::EBus<AuthenticationProviderNotifications>;
} // namespace AWSClientAuth
@@ -0,0 +1,66 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/std/string/string.h>
#include <AzCore/std/chrono/clocks.h>
namespace AWSClientAuth
{
enum class ProviderNameEnum
{
None,
AWSCognitoIDP,
LoginWithAmazon,
Google,
Apple,
Facebook
};
//! Used to share authentication tokens to caller and to AWSCognitoAuthorizationController.
class AuthenticationTokens
{
public:
AZ_TYPE_INFO(AuthenticationTokens, "{F965D1B2-9DE3-4900-B44B-E58D9F083ACB}");
AuthenticationTokens();
AuthenticationTokens(const AuthenticationTokens& other);
AuthenticationTokens(const AZStd::string& accessToken, const AZStd::string& refreshToken, const AZStd::string& openidToken
, const ProviderNameEnum& providerName, int tokensExpireTimeSeconds);
//! Compares current time stamp to expired time stamp.
//! @return True if current TS less than expiry TS.
bool AreTokensValid() const;
//! @return Open id token from authentication.
AZStd::string GetOpenIdToken() const;
//! @return Access token from authentication.
AZStd::string GetAccessToken() const;
//! @return Refresh token from authentication.
AZStd::string GetRefreshToken() const;
//! @return Provide name for the tokens.
ProviderNameEnum GetProviderName() const;
//! @return Expiration time in seconds.
int GetTokensExpireTimeSeconds() const;
private:
int m_tokensExpireTimeSeconds = 0;
AZStd::string m_accessToken;
AZStd::string m_refreshToken;
AZStd::string m_openIdToken;
ProviderNameEnum m_providerName;
AZStd::chrono::system_clock::time_point m_tokensExpireTimeStamp;
};
} // namespace AWSClientAuth
@@ -0,0 +1,105 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/std/string/string.h>
#include <Authorization/ClientAuthAWSCredentials.h>
#include <aws/core/auth/AWSCredentialsProvider.h>
namespace AWSClientAuth
{
//! Abstract class for AWS Cognito authorization requests.
class IAWSCognitoAuthorizationRequests
{
public:
AZ_TYPE_INFO(IAWSCognitoAuthorizationRequests, "{F60A2C40-48F5-49A1-ABFA-A08D0DD4ECCC}");
//! Initializes settings for Cognito identity pool from settings registry.
//! @param settingsRegistryPath Path for the settings registry file to use.
virtual bool Initialize(const AZStd::string& settingsRegistryPath) = 0;
//! Once credentials provider are set they cannot be reset. So recreates new Cognito credentials provider on reset.
//! Service clients need to be created with the new AWSCredentialsProvider after reset.
virtual void Reset() = 0;
//! Get cached Cognito identity id from last successful GetId call to Cognito.
//! @return Cognito identity id
virtual AZStd::string GetIdentityId() = 0;
//! Checks if logins are persisted.
//! @return True if logins persists else false.
virtual bool HasPersistedLogins() = 0;
//! Returns AWSCredentialsProvider to initialize up AWS Native SDK clients.
//! std::shared_ptr to allow sharing ownership with AWS Native SDK.
//! @return std::shared_ptr for Aws::Auth::AWSCredentialProvider.
virtual std::shared_ptr<Aws::Auth::AWSCredentialsProvider> GetCognitoCredentialsProvider() = 0;
//! Returns anonymous AWSCredentialsProvider to initialize up AWS Native SDK clients.
//! std::shared_ptr to allow sharing ownership with AWS Native SDK.
//! @return std::shared_ptr for Aws::Auth::AWSCredentialProvider.
virtual std::shared_ptr<Aws::Auth::AWSCredentialsProvider> GetAnonymousCognitoCredentialsProvider() = 0;
//! Get cached AWS credentials or fetch credentials from Cognito.
//! Will fetch authenticated role credentials if login are cached else fetches unauthenticated role credentials if enabled in Cognito Identity pool.
//! If multiple logins are persisted and no cached credentials found, GetId call to Cognito will link the login provider to same identity.
virtual void RequestAWSCredentialsAsync() = 0;
};
//! Request bus to handle AWS Cognito Identity pool authorization.
class AWSCognitoAuthorizationRequests
: public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
using MutexType = AZ::NullMutex;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
};
using AWSCognitoAuthorizationRequestBus = AZ::EBus<IAWSCognitoAuthorizationRequests, AWSCognitoAuthorizationRequests>;
//! Notification bus for corresponding Authorization Request bus.
class AWSCognitoAuthorizationNotifications
: public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// Notifications interface
//! Event called on request AWS credentials success.
//! @param awsCredentials Credentials for authenticated role associated with Cognito identity pool.
virtual void OnRequestAWSCredentialsSuccess(const ClientAuthAWSCredentials& awsCredentials)
{
AZ_UNUSED(awsCredentials);
}
//! Event called on request AWS credentials fail.
//! @param error Error message
virtual void OnRequestAWSCredentialsFail(const AZStd::string& error)
{
AZ_UNUSED(error);
}
//////////////////////////////////////////////////////////////////////////
};
using AWSCognitoAuthorizationNotificationBus = AZ::EBus<AWSCognitoAuthorizationNotifications>;
} // namespace AWSClientAuth
@@ -0,0 +1,58 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/RTTI/TypeInfo.h>
#include <AzCore/std/string/string.h>
#include <aws/core/auth/AWSCredentialsProvider.h>
namespace AWSClientAuth
{
//! Client auth AWS Credentials object for serialization.
class ClientAuthAWSCredentials
{
public:
AZ_TYPE_INFO(ClientAuthAWSCredentials, "{02FB32C4-B94E-4084-9049-3DF32F87BD76}");
ClientAuthAWSCredentials(const AZStd::string& accessKeyId, const AZStd::string& secretKey, const AZStd::string& sessionToken)
{
m_accessKeyId = accessKeyId;
m_secretKey = secretKey;
m_sessionToken = sessionToken;
}
//! Gets the access key
inline const AZStd::string& GetAWSAccessKeyId() const
{
return m_accessKeyId;
}
//! Gets the secret key
inline const AZStd::string& GetAWSSecretKey() const
{
return m_secretKey;
}
//! Gets the session token
inline const AZStd::string& GetSessionToken() const
{
return m_sessionToken;
}
private:
AZStd::string m_accessKeyId;
AZStd::string m_secretKey;
AZStd::string m_sessionToken;
};
} // namespace AWSClientAuth
@@ -0,0 +1,167 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/Settings/SettingsRegistryImpl.h>
namespace AWSClientAuth
{
//! Abstract class for AWS Cognito user management requests.
class IAWSCognitoUserManagementRequests
{
public:
AZ_TYPE_INFO(IAWSCognitoUserManagementRequests, "{A4C90F21-7056-4827-8C6B-401E6945697D}");
//! Initialize Cognito User pool.
//! @param settingsRegistryPath settingsRegistryPath Path for the settings registry file to use.
virtual bool Initialize(const AZStd::string& settingsRegistryPath) = 0;
// Requests interface
//! Cognito user pool email sign up start.
//! @param username User name to use for sign up.
//! @param password Password to use for sign up.
//! @param email Email used to send confirmation code.
virtual void EmailSignUpAsync(const AZStd::string& userName, const AZStd::string& password, const AZStd::string& email) = 0;
//! Cognito user pool phone sign up start.
//! @param username User name to use for sign up.
//! @param password Password to use for sign up.
//! @param phoneNumber Phone number used to send confirmation code.
virtual void PhoneSignUpAsync(const AZStd::string& userName, const AZStd::string& password, const AZStd::string& phoneNumber) = 0;
//! Cognito user pool confirm sign up with confirmation code. Used to confirm email or phone sign up.
//! @param username User name to use to confirm sign up.
//! @param confirmationCode Code sent to email/phone from sign up call.
virtual void ConfirmSignUpAsync(const AZStd::string& userName, const AZStd::string& confirmationCode) = 0;
//! Cognito user forgot password start
//! @param username User name to use to reset password for.
virtual void ForgotPasswordAsync(const AZStd::string& userName) = 0;
//! Cognito user pool confirm forgot password with confirmation code.
//! @param username User name to use to confirm reset password for.
//! @param confirmationCode Code sent to email/phone for forgot password step.
//! @param newPassword New password to set the changed value to.
virtual void ConfirmForgotPasswordAsync(const AZStd::string& userName, const AZStd::string& confirmationCode, const AZStd::string& newPassword) = 0;
//! Cognito user pool enable multi factor authentication for signed in user.
//! @param accessToken Access token from successful sign in.
virtual void EnableMFAAsync(const AZStd::string& accessToken) = 0;
};
//! Manages various authentication provider implementations and implements AuthenticationProvider Request bus.
class AWSCognitoUserManagementRequests
: public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
using MutexType = AZ::NullMutex;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
};
using AWSCognitoUserManagementRequestBus = AZ::EBus<IAWSCognitoUserManagementRequests, AWSCognitoUserManagementRequests>;
class AWSCognitoUserManagementNotifications
: public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
////////////////////////////ss//////////////////////////////////////////////
// Notifications interface
//! Event for Cognito user pool email sign up success
//! @param uuid Unique identified from Cognito User pool for new user
virtual void OnEmailSignUpSuccess(const AZStd::string& uuid)
{
AZ_UNUSED(uuid);
}
//! Event for Cognito user pool email sign up fail
//! @param error Error message
virtual void OnEmailSignUpFail(const AZStd::string& error)
{
AZ_UNUSED(error);
}
//! Event for Cognito user pool phone sign up success
//! @param error Error message
virtual void OnPhoneSignUpSuccess(const AZStd::string& uuid)
{
AZ_UNUSED(uuid);
}
//! Event for Cognito user pool phone sign up fail
//! @param error Error message
virtual void OnPhoneSignUpFail(const AZStd::string& error)
{
AZ_UNUSED(error);
}
//! Event for Cognito confirm sign up success
virtual void OnConfirmSignUpSuccess()
{
}
//! Event for Cognito confirm sign up fail
//! @param error Error message
virtual void OnConfirmSignUpFail(const AZStd::string& error)
{
AZ_UNUSED(error);
}
//! Event for Cognito forgot password success
virtual void OnForgotPasswordSuccess()
{
}
//! Event for Cognito forgot password fail
//! @param error Error message
virtual void OnForgotPasswordFail(const AZStd::string& error)
{
AZ_UNUSED(error);
}
//! Event for Cognito confirm forgot password success
virtual void OnConfirmForgotPasswordSuccess()
{
}
//! Event for Cognito confirm forgot password fail
//! @param error Error message
virtual void OnConfirmForgotPasswordFail(const AZStd::string& error)
{
AZ_UNUSED(error);
}
//! Event for Cognito enable mfa success
virtual void OnEnableMFASuccess()
{
}
//! Event for Cognito enable mfa fail
//! @param error Error message
virtual void OnEnableMFAFail(const AZStd::string& error)
{
AZ_UNUSED(error);
}
//////////////////////////////////////////////////////////////////////////
};
using AWSCognitoUserManagementNotificationBus = AZ::EBus<AWSCognitoUserManagementNotifications>;
} // namespace AWSClientAuth
@@ -0,0 +1,42 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AWSClientAuthModule.h>
#include <AWSClientAuthSystemComponent.h>
namespace AWSClientAuth
{
AWSClientAuthModule::AWSClientAuthModule()
: AZ::Module()
{
// Push results of [MyComponent]::CreateDescriptor() into m_descriptors here.
m_descriptors.insert(m_descriptors.end(), {
AWSClientAuthSystemComponent::CreateDescriptor()
});
}
/**
* Add required SystemComponents to the SystemEntity.
*/
AZ::ComponentTypeList AWSClientAuthModule::GetRequiredSystemComponents() const
{
return AZ::ComponentTypeList{
azrtti_typeid<AWSClientAuthSystemComponent>(),
};
}
}
// DO NOT MODIFY THIS LINE UNLESS YOU RENAME THE GEM
// The first parameter should be GemName_GemIdLower
// The second should be the fully qualified name of the class above
AZ_DECLARE_MODULE_CLASS(AWSClientAuth_c74f2756f5874c0d8d29646dfc9cb0ad, AWSClientAuth::AWSClientAuthModule)
@@ -0,0 +1,176 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AWSClientAuthSystemComponent.h>
#include <Authentication/AuthenticationProviderTypes.h>
#include <Authentication/AuthenticationNotificationBusBehaviorHandler.h>
#include <UserManagement/UserManagementNotificationBusBehaviorHandler.h>
#include <Authorization/AWSCognitoAuthorizationNotificationBusBehaviorHandler.h>
#include <Authorization/AWSCognitoAuthorizationController.h>
#include <Authorization/AWSCognitoAuthorizationTypes.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <ResourceMapping/AWSResourceMappingBus.h>
#include <aws/cognito-identity/CognitoIdentityClient.h>
#include <aws/cognito-idp/CognitoIdentityProviderClient.h>
namespace AWSClientAuth
{
constexpr char SERIALIZE_COMPONENT_NAME[] = "AWSClientAuth";
void AWSClientAuthSystemComponent::Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<AWSClientAuthSystemComponent, AZ::Component>()->Version(0);
if (AZ::EditContext* ec = serialize->GetEditContext())
{
ec->Class<AWSClientAuthSystemComponent>("AWSClientAuth", "Provides Client Authentication and Authorization implementations")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System"))
->Attribute(AZ::Edit::Attributes::AutoExpand, true);
}
AWSClientAuth::AWSCognitoProviderSetting::Reflect(*serialize);
AWSClientAuth::LWAProviderSetting::Reflect(*serialize);
AWSClientAuth::GoogleProviderSetting::Reflect(*serialize);
AWSClientAuth::CognitoAuthorizationSettings::Reflect(*serialize);
AWSClientAuth::AWSCognitoUserManagementSetting::Reflect(*serialize);
}
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->EBus<AuthenticationProviderRequestBus>("AuthenticationProviderRequestBus")
->Attribute(AZ::Script::Attributes::Category, SERIALIZE_COMPONENT_NAME)
->Event("Initialize", &AuthenticationProviderRequestBus::Events::Initialize)
->Event("IsSignedIn", &AuthenticationProviderRequestBus::Events::IsSignedIn)
->Event("GetAuthenticationTokens", &AuthenticationProviderRequestBus::Events::GetAuthenticationTokens)
->Event(
"PasswordGrantSingleFactorSignInAsync", &AuthenticationProviderRequestBus::Events::PasswordGrantSingleFactorSignInAsync)
->Event("DeviceCodeGrantSignInAsync", &AuthenticationProviderRequestBus::Events::DeviceCodeGrantSignInAsync)
->Event("DeviceCodeGrantConfirmSignInAsync", &AuthenticationProviderRequestBus::Events::DeviceCodeGrantConfirmSignInAsync)
->Event("RefreshTokensAsync", &AuthenticationProviderRequestBus::Events::RefreshTokensAsync)
->Event("GetTokensWithRefreshAsync", &AuthenticationProviderRequestBus::Events::GetTokensWithRefreshAsync)
->Event("SignOut", &AuthenticationProviderRequestBus::Events::SignOut);
behaviorContext->EBus<AWSCognitoAuthorizationRequestBus>("AWSCognitoAuthorizationRequestBus")
->Attribute(AZ::Script::Attributes::Category, SERIALIZE_COMPONENT_NAME)
->Event("Initialize", &AWSCognitoAuthorizationRequestBus::Events::Initialize)
->Event("Reset", &AWSCognitoAuthorizationRequestBus::Events::Reset)
->Event("GetIdentityId", &AWSCognitoAuthorizationRequestBus::Events::GetIdentityId)
->Event("HasPersistedLogins", &AWSCognitoAuthorizationRequestBus::Events::HasPersistedLogins)
->Event("RequestAWSCredentialsAsync", &AWSCognitoAuthorizationRequestBus::Events::RequestAWSCredentialsAsync);
behaviorContext->EBus<AWSCognitoUserManagementRequestBus>("AWSCognitoUserManagementRequestBus")
->Attribute(AZ::Script::Attributes::Category, SERIALIZE_COMPONENT_NAME)
->Event("Initialize", &AWSCognitoUserManagementRequestBus::Events::Initialize)
->Event("EmailSignUpAsync", &AWSCognitoUserManagementRequestBus::Events::EmailSignUpAsync)
->Event("PhoneSignUpAsync", &AWSCognitoUserManagementRequestBus::Events::PhoneSignUpAsync)
->Event("ConfirmSignUpAsync", &AWSCognitoUserManagementRequestBus::Events::ConfirmSignUpAsync)
->Event("ForgotPasswordAsync", &AWSCognitoUserManagementRequestBus::Events::ForgotPasswordAsync)
->Event("ConfirmForgotPasswordAsync", &AWSCognitoUserManagementRequestBus::Events::ConfirmForgotPasswordAsync)
->Event("EnableMFAAsync", &AWSCognitoUserManagementRequestBus::Events::EnableMFAAsync);
behaviorContext->EBus<AuthenticationProviderNotificationBus>("AuthenticationProviderNotificationBus")
->Handler<AuthenticationNotificationBusBehaviorHandler>();
behaviorContext->EBus<AWSCognitoUserManagementNotificationBus>("AWSCognitoUserManagementNotificationBus")
->Handler<UserManagementNotificationBusBehaviorHandler>();
behaviorContext->EBus<AWSCognitoAuthorizationNotificationBus>("AWSCognitoAuthorizationNotificationBus")
->Handler<AWSCognitoAuthorizationNotificationBusBehaviorHandler>();
}
}
void AWSClientAuthSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{
provided.push_back(AZ_CRC_CE("AWSClientAuthService"));
}
void AWSClientAuthSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
{
incompatible.push_back(AZ_CRC_CE("AWSClientAuthService"));
}
void AWSClientAuthSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
{
required.push_back(AZ_CRC_CE("AWSCoreService"));
}
void AWSClientAuthSystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
{
AZ_UNUSED(dependent);
}
void AWSClientAuthSystemComponent::Init()
{
m_enabledProviderNames.push_back(ProviderNameEnum::AWSCognitoIDP);
// As this Gem depends on AWSCore, AWSCoreSystemComponent gets activated before AWSClientAuth and will miss the OnSDKInitialized
// notification if BusConnect is not in Init.
AWSCore::AWSCoreNotificationsBus::Handler::BusConnect();
}
void AWSClientAuthSystemComponent::Activate()
{
AZ::Interface<IAWSClientAuthRequests>::Register(this);
AWSClientAuthRequestBus::Handler::BusConnect();
// Objects below depend on bus above.
m_authenticationProviderManager = AZStd::make_unique<AuthenticationProviderManager>();
m_awsCognitoUserManagementController = AZStd::make_unique<AWSCognitoUserManagementController>();
m_awsCognitoAuthorizationController = AZStd::make_unique<AWSCognitoAuthorizationController>();
AWSCore::AWSCoreEditorRequestBus::Broadcast(&AWSCore::AWSCoreEditorRequests::SetAWSClientAuthEnabled);
}
void AWSClientAuthSystemComponent::Deactivate()
{
m_authenticationProviderManager.reset();
m_awsCognitoUserManagementController.reset();
m_awsCognitoAuthorizationController.reset();
AWSClientAuthRequestBus::Handler::BusDisconnect();
AWSCore::AWSCoreNotificationsBus::Handler::BusDisconnect();
AZ::Interface<IAWSClientAuthRequests>::Unregister(this);
m_cognitoIdentityProviderClient.reset();
m_cognitoIdentityClient.reset();
}
void AWSClientAuthSystemComponent::OnSDKInitialized()
{
Aws::Client::ClientConfiguration clientConfiguration;
AZStd::string region;
AWSCore::AWSResourceMappingRequestBus::BroadcastResult(region, &AWSCore::AWSResourceMappingRequests::GetDefaultRegion);
clientConfiguration.region = "us-west-2";
if (!region.empty())
{
clientConfiguration.region = region.c_str();
}
m_cognitoIdentityProviderClient =
std::make_shared<Aws::CognitoIdentityProvider::CognitoIdentityProviderClient>(clientConfiguration);
m_cognitoIdentityClient = std::make_shared<Aws::CognitoIdentity::CognitoIdentityClient>(clientConfiguration);
}
std::shared_ptr<Aws::CognitoIdentityProvider::CognitoIdentityProviderClient> AWSClientAuthSystemComponent::GetCognitoIDPClient()
{
return m_cognitoIdentityProviderClient;
}
std::shared_ptr<Aws::CognitoIdentity::CognitoIdentityClient> AWSClientAuthSystemComponent::GetCognitoIdentityClient()
{
return m_cognitoIdentityClient;
}
} // namespace AWSClientAuth
@@ -0,0 +1,254 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzCore/std/smart_ptr/weak_ptr.h>
#include <AzCore/Jobs/JobFunction.h>
#include <Authentication/AWSCognitoAuthenticationProvider.h>
#include <Authentication/AuthenticationProviderTypes.h>
#include <Authentication/AuthenticationProviderBus.h>
#include <AWSClientAuthBus.h>
#include <AWSCoreBus.h>
#include <aws/cognito-idp/model/InitiateAuthRequest.h>
#include <aws/cognito-idp/model/InitiateAuthResult.h>
#include <aws/cognito-idp/model/RespondToAuthChallengeRequest.h>
#include <aws/cognito-idp/model/RespondToAuthChallengeResult.h>
#include <aws/cognito-idp/CognitoIdentityProviderClient.h>
#include <aws/cognito-idp/CognitoIdentityProviderErrors.h>
namespace AWSClientAuth
{
constexpr char COGNITO_IDP_SETTINGS_PATH[] = "/AWS/CognitoIDP";
constexpr char COGNITO_USERNAME_KEY[] = "USERNAME";
constexpr char COGNITO_PASSWORD_KEY[] = "PASSWORD";
constexpr char COGNITO_REFRESH_TOKEN_AUTHPARAM_KEY[] = "REFRESH_TOKEN";
constexpr char COGNITO_SMS_MFA_CODE_KEY[] = "SMS_MFA_CODE";
AWSCognitoAuthenticationProvider::AWSCognitoAuthenticationProvider()
{
m_settings = AZStd::make_unique<AWSCognitoProviderSetting>();
}
AWSCognitoAuthenticationProvider::~AWSCognitoAuthenticationProvider()
{
m_settings.reset();
}
bool AWSCognitoAuthenticationProvider::Initialize(AZStd::weak_ptr<AZ::SettingsRegistryInterface> settingsRegistry)
{
if (!settingsRegistry.lock()->GetObject(m_settings.get(), azrtti_typeid(m_settings.get()), COGNITO_IDP_SETTINGS_PATH))
{
AZ_Warning("AWSCognitoAuthenticationProvider", true, "Failed to get settings object for path %s", COGNITO_IDP_SETTINGS_PATH);
return false;
}
return true;
}
void AWSCognitoAuthenticationProvider::PasswordGrantSingleFactorSignInAsync(const AZStd::string& username, const AZStd::string& password)
{
InitiateAuthInternalAsync(username, password, [this](Aws::CognitoIdentityProvider::Model::InitiateAuthOutcome initiateAuthOutcome)
{
if (initiateAuthOutcome.IsSuccess())
{
Aws::CognitoIdentityProvider::Model::InitiateAuthResult initiateAuthResult{ initiateAuthOutcome.GetResult() };
if (initiateAuthResult.GetChallengeName() == Aws::CognitoIdentityProvider::Model::ChallengeNameType::NOT_SET)
{
Aws::CognitoIdentityProvider::Model::AuthenticationResultType authenticationResult = initiateAuthResult.GetAuthenticationResult();
UpdateTokens(authenticationResult);
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnPasswordGrantSingleFactorSignInSuccess
, m_authenticationTokens);
}
else
{
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnPasswordGrantSingleFactorSignInFail
, AZStd::string::format("Unexpected Challenge type: %s"
, Aws::CognitoIdentityProvider::Model::ChallengeNameTypeMapper::GetNameForChallengeNameType(initiateAuthResult.GetChallengeName()).c_str()));
}
}
else
{
Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error = initiateAuthOutcome.GetError();
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnPasswordGrantSingleFactorSignInFail, error.GetMessage().c_str());
}
});
}
void AWSCognitoAuthenticationProvider::PasswordGrantMultiFactorSignInAsync(const AZStd::string& username, const AZStd::string& password)
{
InitiateAuthInternalAsync(username, password, [this](Aws::CognitoIdentityProvider::Model::InitiateAuthOutcome initiateAuthOutcome)
{
if (initiateAuthOutcome.IsSuccess())
{
Aws::CognitoIdentityProvider::Model::InitiateAuthResult initiateAuthResult{ initiateAuthOutcome.GetResult() };
if (initiateAuthResult.GetChallengeName() == Aws::CognitoIdentityProvider::Model::ChallengeNameType::SMS_MFA)
{
Aws::CognitoIdentityProvider::Model::AuthenticationResultType authenticationResult = initiateAuthResult.GetAuthenticationResult();
// Call on sign in success for MFA
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnPasswordGrantMultiFactorSignInSuccess);
m_session = initiateAuthResult.GetSession().c_str();
}
else
{
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnPasswordGrantMultiFactorSignInFail
, AZStd::string::format("Unexpected Challenge type: %s"
, Aws::CognitoIdentityProvider::Model::ChallengeNameTypeMapper::GetNameForChallengeNameType(initiateAuthResult.GetChallengeName()).c_str()));
}
}
else
{
Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error = initiateAuthOutcome.GetError();
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnPasswordGrantMultiFactorSignInFail, error.GetMessage().c_str());
}
});
}
// Call RespondToAuthChallenge for Cognito authentication flow.
// Refer https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-authentication-flow.html.
void AWSCognitoAuthenticationProvider::PasswordGrantMultiFactorConfirmSignInAsync(const AZStd::string& username, const AZStd::string& confirmationCode)
{
std::shared_ptr<Aws::CognitoIdentityProvider::CognitoIdentityProviderClient> cognitoIdentityProviderClient =
AZ::Interface<IAWSClientAuthRequests>::Get()->GetCognitoIDPClient();
AZ::JobContext* jobContext = nullptr;
AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext);
AZ::Job* confirmSignInJob = AZ::CreateJobFunction([this, cognitoIdentityProviderClient, confirmationCode, username]()
{
// Set Request parameters for SMS Multi factor authentication.
// Note: Email MFA is no longer supported by Cognito, use SMS as MFA
Aws::CognitoIdentityProvider::Model::RespondToAuthChallengeRequest respondToAuthChallengeRequest;
respondToAuthChallengeRequest.SetClientId(m_settings->m_appClientId.c_str());
respondToAuthChallengeRequest.AddChallengeResponses(COGNITO_SMS_MFA_CODE_KEY, confirmationCode.c_str());
respondToAuthChallengeRequest.AddChallengeResponses(COGNITO_USERNAME_KEY, username.c_str());
respondToAuthChallengeRequest.SetChallengeName(Aws::CognitoIdentityProvider::Model::ChallengeNameType::SMS_MFA);
respondToAuthChallengeRequest.SetSession(m_session.c_str());
Aws::CognitoIdentityProvider::Model::RespondToAuthChallengeOutcome respondToAuthChallengeOutcome{ cognitoIdentityProviderClient->RespondToAuthChallenge(respondToAuthChallengeRequest) };
if (respondToAuthChallengeOutcome.IsSuccess())
{
Aws::CognitoIdentityProvider::Model::RespondToAuthChallengeResult respondToAuthChallengeResult{ respondToAuthChallengeOutcome.GetResult() };
if (respondToAuthChallengeResult.GetChallengeName() == Aws::CognitoIdentityProvider::Model::ChallengeNameType::NOT_SET)
{
Aws::CognitoIdentityProvider::Model::AuthenticationResultType authenticationResult = respondToAuthChallengeResult.GetAuthenticationResult();
UpdateTokens(authenticationResult);
AuthenticationProviderNotificationBus::Broadcast(
&AuthenticationProviderNotifications::OnPasswordGrantMultiFactorConfirmSignInSuccess, m_authenticationTokens);
}
}
else
{
Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error = respondToAuthChallengeOutcome.GetError();
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnPasswordGrantMultiFactorConfirmSignInFail, error.GetMessage().c_str());
}
}, true, jobContext);
confirmSignInJob->Start();
}
void AWSCognitoAuthenticationProvider::DeviceCodeGrantSignInAsync()
{
AZ_Assert(true, "Not supported");
}
void AWSCognitoAuthenticationProvider::DeviceCodeGrantConfirmSignInAsync()
{
AZ_Assert(true, "Not supported");
}
void AWSCognitoAuthenticationProvider::RefreshTokensAsync()
{
std::shared_ptr<Aws::CognitoIdentityProvider::CognitoIdentityProviderClient> cognitoIdentityProviderClient =
AZ::Interface<IAWSClientAuthRequests>::Get()->GetCognitoIDPClient();
AZ::JobContext* jobContext = nullptr;
AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext);
AZ::Job* initiateAuthJob = AZ::CreateJobFunction([this, cognitoIdentityProviderClient]()
{
// Set Request parameters.
Aws::CognitoIdentityProvider::Model::InitiateAuthRequest initiateAuthRequest;
initiateAuthRequest.SetClientId(m_settings->m_appClientId.c_str());
initiateAuthRequest.SetAuthFlow(Aws::CognitoIdentityProvider::Model::AuthFlowType::REFRESH_TOKEN_AUTH);
// Set username and password for Password grant/ Initiate Auth flow.
Aws::Map<Aws::String, Aws::String> authParameters
{
{COGNITO_REFRESH_TOKEN_AUTHPARAM_KEY, GetAuthenticationTokens().GetRefreshToken().c_str()}
};
initiateAuthRequest.SetAuthParameters(authParameters);
Aws::CognitoIdentityProvider::Model::InitiateAuthOutcome initiateAuthOutcome{ cognitoIdentityProviderClient->InitiateAuth(initiateAuthRequest) };
if (initiateAuthOutcome.IsSuccess())
{
Aws::CognitoIdentityProvider::Model::InitiateAuthResult initiateAuthResult{ initiateAuthOutcome.GetResult() };
if (initiateAuthResult.GetChallengeName() == Aws::CognitoIdentityProvider::Model::ChallengeNameType::NOT_SET)
{
Aws::CognitoIdentityProvider::Model::AuthenticationResultType authenticationResult = initiateAuthResult.GetAuthenticationResult();
UpdateTokens(authenticationResult);
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnRefreshTokensSuccess, m_authenticationTokens);
}
else
{
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnRefreshTokensFail
, AZStd::string::format("Unexpected Challenge type: %s"
, Aws::CognitoIdentityProvider::Model::ChallengeNameTypeMapper::GetNameForChallengeNameType(initiateAuthResult.GetChallengeName()).c_str()));
}
}
else
{
Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error = initiateAuthOutcome.GetError();
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnRefreshTokensFail, error.GetMessage().c_str());
}
}, true, jobContext);
initiateAuthJob->Start();
}
// Call InitiateAuth for Cognito authentication flow.
// Refer https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-authentication-flow.html.
void AWSCognitoAuthenticationProvider::InitiateAuthInternalAsync(const AZStd::string& username, const AZStd::string& password
, AZStd::function<void(Aws::CognitoIdentityProvider::Model::InitiateAuthOutcome outcome)> outcomeCallback)
{
std::shared_ptr<Aws::CognitoIdentityProvider::CognitoIdentityProviderClient> cognitoIdentityProviderClient =
AZ::Interface<IAWSClientAuthRequests>::Get()->GetCognitoIDPClient();
AZ::JobContext* jobContext = nullptr;
AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext);
AZ::Job* initiateAuthJob = AZ::CreateJobFunction([this, cognitoIdentityProviderClient, username, password, outcomeCallback]()
{
// Set Request parameters.
Aws::CognitoIdentityProvider::Model::InitiateAuthRequest initiateAuthRequest;
initiateAuthRequest.SetClientId(m_settings->m_appClientId.c_str());
initiateAuthRequest.SetAuthFlow(Aws::CognitoIdentityProvider::Model::AuthFlowType::USER_PASSWORD_AUTH);
// Set username and password for Password grant/ Initiate Auth flow.
Aws::Map<Aws::String, Aws::String> authParameters
{
{COGNITO_USERNAME_KEY, username.c_str()},
{COGNITO_PASSWORD_KEY, password.c_str()}
};
initiateAuthRequest.SetAuthParameters(authParameters);
Aws::CognitoIdentityProvider::Model::InitiateAuthOutcome initiateAuthOutcome{ cognitoIdentityProviderClient->InitiateAuth(initiateAuthRequest) };
outcomeCallback(initiateAuthOutcome);
}, true, jobContext);
initiateAuthJob->Start();
}
void AWSCognitoAuthenticationProvider::UpdateTokens(const Aws::CognitoIdentityProvider::Model::AuthenticationResultType& authenticationResult)
{
m_authenticationTokens = AuthenticationTokens(authenticationResult.GetAccessToken().c_str(), authenticationResult.GetRefreshToken().c_str(),
authenticationResult.GetIdToken().c_str(), ProviderNameEnum::AWSCognitoIDP,
authenticationResult.GetExpiresIn());
}
} // namespace AWSClientAuth
@@ -0,0 +1,28 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <Authentication/AuthenticationProviderInterface.h>
namespace AWSClientAuth
{
AuthenticationTokens AuthenticationProviderInterface::GetAuthenticationTokens()
{
return m_authenticationTokens;
}
void AuthenticationProviderInterface::SignOut()
{
m_authenticationTokens = AuthenticationTokens();
}
} // namespace AWSClientAuth
@@ -0,0 +1,185 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzCore/Settings/SettingsRegistryImpl.h>
#include <Authentication/AuthenticationProviderTypes.h>
#include <Authentication/AWSCognitoAuthenticationProvider.h>
#include <Authentication/LWAAuthenticationProvider.h>
#include <Authentication/GoogleAuthenticationProvider.h>
#include <Authentication/AuthenticationProviderManager.h>
namespace AWSClientAuth
{
AuthenticationProviderManager::AuthenticationProviderManager()
{
AZ::Interface<IAuthenticationProviderRequests>::Register(this);
AuthenticationProviderRequestBus::Handler::BusConnect();
}
AuthenticationProviderManager::~AuthenticationProviderManager()
{
ResetProviders();
m_settingsRegistry.reset();
AuthenticationProviderRequestBus::Handler::BusDisconnect();
AZ::Interface<IAuthenticationProviderRequests>::Unregister(this);
}
bool AuthenticationProviderManager::Initialize(const AZStd::vector<ProviderNameEnum>& providerNames, const AZStd::string& settingsRegistryPath)
{
ResetProviders();
m_settingsRegistry.reset();
m_settingsRegistry = AZStd::make_shared<AZ::SettingsRegistryImpl>();
if (!m_settingsRegistry->MergeSettingsFile(settingsRegistryPath, AZ::SettingsRegistryInterface::Format::JsonMergePatch))
{
AZ_Error("AuthenticationProviderManager", true, "Error merging settings registry for path: %s", settingsRegistryPath.c_str());
return false;
}
bool initializeSuccess = true;
for (auto providerName : providerNames)
{
m_authenticationProvidersMap[providerName] = CreateAuthenticationProviderObject(providerName);
initializeSuccess = initializeSuccess && m_authenticationProvidersMap[providerName]->Initialize(m_settingsRegistry);
}
return initializeSuccess;
}
void AuthenticationProviderManager::PasswordGrantSingleFactorSignInAsync(const ProviderNameEnum& providerName, const AZStd::string& username, const AZStd::string& password)
{
if (IsProviderInitialized(providerName))
{
m_authenticationProvidersMap[providerName]->PasswordGrantSingleFactorSignInAsync(username, password);
}
}
void AuthenticationProviderManager::PasswordGrantMultiFactorSignInAsync(const ProviderNameEnum& providerName, const AZStd::string& username, const AZStd::string& password)
{
if (IsProviderInitialized(providerName))
{
m_authenticationProvidersMap[providerName]->PasswordGrantMultiFactorSignInAsync(username, password);
}
}
void AuthenticationProviderManager::PasswordGrantMultiFactorConfirmSignInAsync(const ProviderNameEnum& providerName, const AZStd::string& username, const AZStd::string& confirmationCode)
{
if (IsProviderInitialized(providerName))
{
m_authenticationProvidersMap[providerName]->PasswordGrantMultiFactorConfirmSignInAsync(username, confirmationCode);
}
}
void AuthenticationProviderManager::DeviceCodeGrantSignInAsync(const ProviderNameEnum& providerName)
{
if (IsProviderInitialized(providerName))
{
m_authenticationProvidersMap[providerName]->DeviceCodeGrantSignInAsync();
}
}
void AuthenticationProviderManager::DeviceCodeGrantConfirmSignInAsync(const ProviderNameEnum& providerName)
{
if (IsProviderInitialized(providerName))
{
m_authenticationProvidersMap[providerName]->DeviceCodeGrantConfirmSignInAsync();
}
}
void AuthenticationProviderManager::RefreshTokensAsync(const ProviderNameEnum& providerName)
{
if (IsProviderInitialized(providerName))
{
m_authenticationProvidersMap[providerName]->RefreshTokensAsync();
}
}
void AuthenticationProviderManager::GetTokensWithRefreshAsync(const ProviderNameEnum& providerName)
{
if (!IsProviderInitialized(providerName))
{
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnRefreshTokensFail
, "Provider is not initialized");
}
AuthenticationTokens tokens = m_authenticationProvidersMap[providerName]->GetAuthenticationTokens();
if (tokens.AreTokensValid())
{
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnRefreshTokensSuccess, tokens);
}
else
{
m_authenticationProvidersMap[providerName]->RefreshTokensAsync();
}
}
bool AuthenticationProviderManager::IsSignedIn(const ProviderNameEnum& providerName)
{
if (IsProviderInitialized(providerName))
{
return m_authenticationProvidersMap[providerName]->GetAuthenticationTokens().AreTokensValid();
}
return false;
}
bool AuthenticationProviderManager::SignOut(const ProviderNameEnum& providerName)
{
if (IsProviderInitialized(providerName))
{
m_authenticationProvidersMap[providerName]->SignOut();
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnSignOut, providerName);
return true;
}
return false;
}
AuthenticationTokens AuthenticationProviderManager::GetAuthenticationTokens(const ProviderNameEnum& providerName)
{
return m_authenticationProvidersMap[providerName]->GetAuthenticationTokens();
}
AZStd::unique_ptr<AuthenticationProviderInterface> AuthenticationProviderManager::CreateAuthenticationProviderObject(const ProviderNameEnum& providerName)
{
switch (providerName)
{
case ProviderNameEnum::AWSCognitoIDP:
return AZStd::make_unique<AWSCognitoAuthenticationProvider>();
case ProviderNameEnum::LoginWithAmazon:
return AZStd::make_unique<LWAAuthenticationProvider>();
case ProviderNameEnum::Google:
return AZStd::make_unique<GoogleAuthenticationProvider>();
default:
return nullptr;
}
}
bool AuthenticationProviderManager::IsProviderInitialized(const ProviderNameEnum& providerName)
{
bool ret = m_authenticationProvidersMap.contains(providerName);
AZ_Assert(ret, "ProviderName enum %i not initialized. Please call initialize first");
return ret;
}
void AuthenticationProviderManager::ResetProviders()
{
for (auto& [providerName, providerInterface] : m_authenticationProvidersMap)
{
providerInterface.reset();
}
}
} // namespace AWSClientAuth
@@ -0,0 +1,82 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <Authentication/AuthenticationTokens.h>
namespace AWSClientAuth
{
//! Used to share authentication tokens to caller and to AWSCognitoAuthorizationController.
AuthenticationTokens::AuthenticationTokens()
{
m_tokensExpireTimeStamp = AZStd::chrono::system_clock::time_point::min();
m_providerName = ProviderNameEnum::None;
}
AuthenticationTokens::AuthenticationTokens(const AuthenticationTokens& other)
{
m_accessToken = other.m_accessToken;
m_refreshToken = other.m_refreshToken;
m_openIdToken = other.m_openIdToken;
m_providerName = other.m_providerName;
m_tokensExpireTimeSeconds = other.m_tokensExpireTimeSeconds;
m_tokensExpireTimeStamp = other.m_tokensExpireTimeStamp;
}
AuthenticationTokens::AuthenticationTokens(
const AZStd::string& accessToken, const AZStd::string& refreshToken, const AZStd::string& openidToken, const ProviderNameEnum& providerName, int tokensExpireTimeSeconds)
{
m_accessToken = accessToken;
m_refreshToken = refreshToken;
m_openIdToken = openidToken;
m_providerName = providerName;
m_tokensExpireTimeSeconds = tokensExpireTimeSeconds;
m_tokensExpireTimeStamp = AZStd::chrono::system_clock::now() + AZStd::chrono::seconds(tokensExpireTimeSeconds);
}
//! Compares current time stamp to expired time stamp.
//! @return True if current TS less than expiry TS.
bool AuthenticationTokens::AreTokensValid() const
{
return AZStd::chrono::system_clock::now() < m_tokensExpireTimeStamp;
}
//! @return Open id token from authentication.
AZStd::string AuthenticationTokens::GetOpenIdToken() const
{
return m_openIdToken;
}
//! @return Access token from authentication.
AZStd::string AuthenticationTokens::GetAccessToken() const
{
return m_accessToken;
}
//! @return Refresh token from authentication.
AZStd::string AuthenticationTokens::GetRefreshToken() const
{
return m_refreshToken;
}
//! @return Provide name for the tokens.
ProviderNameEnum AuthenticationTokens::GetProviderName() const
{
return m_providerName;
}
//! @return Expiration time in seconds.
int AuthenticationTokens::GetTokensExpireTimeSeconds() const
{
return m_tokensExpireTimeSeconds;
}
} // namespace AWSClientAuth
@@ -0,0 +1,172 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzCore/std/smart_ptr/make_shared.h>
#include <Authentication/GoogleAuthenticationProvider.h>
#include <Authentication/AuthenticationProviderBus.h>
#include <Authentication/OAuthConstants.h>
#include <HttpRequestor/HttpRequestorBus.h>
#include <HttpRequestor/HttpTypes.h>
#include <aws/core/http/HttpResponse.h>
namespace AWSClientAuth
{
constexpr char GOOGLE_SETTINGS_PATH[] = "/AWS/Google";
constexpr char GOOGLE_VERIFICATION_URL_RESPONSE_KEY[] = "verification_url";
GoogleAuthenticationProvider::GoogleAuthenticationProvider()
{
m_settings = AZStd::make_unique<GoogleProviderSetting>();
}
GoogleAuthenticationProvider::~GoogleAuthenticationProvider()
{
m_settings.reset();
}
bool GoogleAuthenticationProvider::Initialize(AZStd::weak_ptr<AZ::SettingsRegistryInterface> settingsRegistry)
{
if (!settingsRegistry.lock()->GetObject(m_settings.get(), azrtti_typeid(m_settings.get()), GOOGLE_SETTINGS_PATH))
{
AZ_Warning("AWSCognitoAuthenticationProvider", true, "Failed to get Google settings object for path %s", GOOGLE_SETTINGS_PATH);
return false;
}
return true;
}
void GoogleAuthenticationProvider::PasswordGrantSingleFactorSignInAsync(const AZStd::string& username, const AZStd::string& password)
{
AZ_UNUSED(username);
AZ_UNUSED(password);
AZ_Assert(true, "Not supported");
}
void GoogleAuthenticationProvider::PasswordGrantMultiFactorSignInAsync(const AZStd::string& username, const AZStd::string& password)
{
AZ_UNUSED(username);
AZ_UNUSED(password);
AZ_Assert(true, "Not supported");
}
void GoogleAuthenticationProvider::PasswordGrantMultiFactorConfirmSignInAsync(const AZStd::string& username, const AZStd::string& confirmationCode)
{
AZ_UNUSED(username);
AZ_UNUSED(confirmationCode);
AZ_Assert(true, "Not supported");
}
// Call Google authentication provider device code end point.
// Refer https://developers.google.com/identity/protocols/oauth2/limited-input-device#step-1:-request-device-and-user-codes.
void GoogleAuthenticationProvider::DeviceCodeGrantSignInAsync()
{
AZStd::string body = AZStd::string::format("%s=%s&%s=%s", OAUTH_CLIENT_ID_BODY_KEY, m_settings->m_appClientId.c_str()
, OAUTH_SCOPE_BODY_KEY, OAUTH_SCOPE_BODY_VALUE);
// Set headers and body for device sign in http requests.
AZStd::map<AZStd::string, AZStd::string> headers;
headers[OAUTH_CONTENT_TYPE_HEADER_KEY] = OAUTH_CONTENT_TYPE_HEADER_VALUE;
headers[OAUTH_CONTENT_LENGTH_HEADER_KEY] = AZStd::to_string(body.length());
HttpRequestor::HttpRequestorRequestBus::Broadcast(&HttpRequestor::HttpRequestorRequests::AddRequestWithHeadersAndBody, m_settings->m_oAuthCodeURL
, Aws::Http::HttpMethod::HTTP_POST, headers, body
, [this](const Aws::Utils::Json::JsonView& jsonView, Aws::Http::HttpResponseCode responseCode)
{
if (responseCode == Aws::Http::HttpResponseCode::OK)
{
m_cachedDeviceCode = jsonView.GetString(OAUTH_DEVICE_CODE_BODY_KEY).c_str();
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnDeviceCodeGrantSignInSuccess
, jsonView.GetString(OAUTH_USER_CODE_RESPONSE_KEY).c_str(), jsonView.GetString(GOOGLE_VERIFICATION_URL_RESPONSE_KEY).c_str()
, jsonView.GetInteger(OAUTH_EXPIRES_IN_RESPONSE_KEY));
}
else
{
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnDeviceCodeGrantSignInFail
, jsonView.GetString(OAUTH_ERROR_RESPONSE_KEY).c_str());
}
}
);
}
// Call Google authentication provider OAuth tokens endpoint
// Refer https://developers.google.com/identity/protocols/oauth2/limited-input-device#step-4:-poll-googles-authorization-server.
void GoogleAuthenticationProvider::DeviceCodeGrantConfirmSignInAsync()
{
// Set headers and body for device confirm sign in http requests.
AZStd::map<AZStd::string, AZStd::string> headers;
AZStd::string body = AZStd::string::format("%s=%s&%s=%s&%s=%s&%s=%s", OAUTH_CLIENT_ID_BODY_KEY, m_settings->m_appClientId.c_str()
, OAUTH_CLIENT_SECRET_BODY_KEY, m_settings->m_clientSecret.c_str(), OAUTH_DEVICE_CODE_BODY_KEY, m_cachedDeviceCode.c_str()
, OAUTH_GRANT_TYPE_BODY_KEY, m_settings->m_grantType.c_str());
headers[OAUTH_CONTENT_TYPE_HEADER_KEY] = OAUTH_CONTENT_TYPE_HEADER_VALUE;
headers[OAUTH_CONTENT_LENGTH_HEADER_KEY] = AZStd::to_string(body.length());
HttpRequestor::HttpRequestorRequestBus::Broadcast(&HttpRequestor::HttpRequestorRequests::AddRequestWithHeadersAndBody, m_settings->m_oAuthTokensURL
, Aws::Http::HttpMethod::HTTP_POST, headers, body
, [this](const Aws::Utils::Json::JsonView& jsonView, Aws::Http::HttpResponseCode responseCode)
{
if (responseCode == Aws::Http::HttpResponseCode::OK)
{
UpdateTokens(jsonView);
AuthenticationProviderNotificationBus::Broadcast(
&AuthenticationProviderNotifications::OnDeviceCodeGrantConfirmSignInSuccess, m_authenticationTokens);
}
else
{
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnDeviceCodeGrantConfirmSignInFail
, jsonView.GetString(OAUTH_ERROR_RESPONSE_KEY).c_str());
}
}
);
}
// Call Google authentication provider OAuth tokens endpoint
// Refer https://developers.google.com/identity/protocols/oauth2/limited-input-device#offline.
void GoogleAuthenticationProvider::RefreshTokensAsync()
{
AZStd::map<AZStd::string, AZStd::string> headers;
AZStd::string body = AZStd::string::format("%s=%s&%s=%s&%s=%s&%s=%s", OAUTH_CLIENT_ID_BODY_KEY, m_settings->m_appClientId.c_str()
, OAUTH_CLIENT_SECRET_BODY_KEY, m_settings->m_clientSecret.c_str()
, OAUTH_GRANT_TYPE_BODY_KEY, OAUTH_REFRESH_TOKEN_BODY_VALUE, OAUTH_REFRESH_TOKEN_BODY_KEY, m_authenticationTokens.GetRefreshToken().c_str());
headers[OAUTH_CONTENT_TYPE_HEADER_KEY] = OAUTH_CONTENT_TYPE_HEADER_VALUE;
headers[OAUTH_CONTENT_LENGTH_HEADER_KEY] = AZStd::to_string(body.length());
HttpRequestor::HttpRequestorRequestBus::Broadcast(&HttpRequestor::HttpRequestorRequests::AddRequestWithHeadersAndBody, m_settings->m_oAuthTokensURL
, Aws::Http::HttpMethod::HTTP_POST, headers, body
, [this](const Aws::Utils::Json::JsonView& jsonView, Aws::Http::HttpResponseCode responseCode)
{
if (responseCode == Aws::Http::HttpResponseCode::OK)
{
UpdateTokens(jsonView);
AuthenticationProviderNotificationBus::Broadcast(
&AuthenticationProviderNotifications::OnRefreshTokensSuccess, m_authenticationTokens);
}
else
{
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnRefreshTokensFail
, jsonView.GetString(OAUTH_ERROR_RESPONSE_KEY).c_str());
}
}
);
}
void GoogleAuthenticationProvider::UpdateTokens(const Aws::Utils::Json::JsonView& jsonView)
{
m_authenticationTokens = AuthenticationTokens(jsonView.GetString(OAUTH_ACCESS_TOKEN_RESPONSE_KEY).c_str(),
jsonView.GetString(OAUTH_REFRESH_TOKEN_RESPONSE_KEY).c_str() ,jsonView.GetString(OAUTH_ID_TOKEN_RESPONSE_KEY).c_str(), ProviderNameEnum::Google
, jsonView.GetInteger(OAUTH_EXPIRES_IN_RESPONSE_KEY));
}
} // namespace AWSClientAuth
@@ -0,0 +1,173 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzCore/std/smart_ptr/make_shared.h>
#include <Authentication/LWAAuthenticationProvider.h>
#include <Authentication/AuthenticationProviderBus.h>
#include <Authentication/OAuthConstants.h>
#include <HttpRequestor/HttpRequestorBus.h>
#include <HttpRequestor/HttpTypes.h>
#include <aws/core/http/HttpResponse.h>
namespace AWSClientAuth
{
constexpr char LWA_SETTINGS_PATH[] = "/AWS/LoginWithAmazon";
constexpr char LWA_VERIFICATION_URL_RESPONSE_KEY[] = "verification_uri";
LWAAuthenticationProvider::LWAAuthenticationProvider()
{
m_settings = AZStd::make_unique<LWAProviderSetting>();
}
LWAAuthenticationProvider::~LWAAuthenticationProvider()
{
m_settings.reset();
}
bool LWAAuthenticationProvider::Initialize(AZStd::weak_ptr<AZ::SettingsRegistryInterface> settingsRegistry)
{
if (!settingsRegistry.lock()->GetObject(m_settings.get(), azrtti_typeid(m_settings.get()), LWA_SETTINGS_PATH))
{
AZ_Warning("AWSCognitoAuthenticationProvider", true, "Failed to get login with Amazon settings object for path %s", LWA_SETTINGS_PATH);
return false;
}
return true;
}
void LWAAuthenticationProvider::PasswordGrantSingleFactorSignInAsync(const AZStd::string& username, const AZStd::string& password)
{
AZ_UNUSED(username);
AZ_UNUSED(password);
AZ_Assert(true, "Not supported");
}
void LWAAuthenticationProvider::PasswordGrantMultiFactorSignInAsync(const AZStd::string& username, const AZStd::string& password)
{
AZ_UNUSED(username);
AZ_UNUSED(password);
AZ_Assert(true, "Not supported");
}
void LWAAuthenticationProvider::PasswordGrantMultiFactorConfirmSignInAsync(const AZStd::string& username, const AZStd::string& confirmationCode)
{
AZ_UNUSED(username);
AZ_UNUSED(confirmationCode);
AZ_Assert(true, "Not supported");
}
// Call LWA authentication provider device code end point.
// Refer https://developer.amazon.com/docs/login-with-amazon/retrieve-code-other-platforms-cbl-docs.html.
void LWAAuthenticationProvider::DeviceCodeGrantSignInAsync()
{
// Set headers and body for device sign in http requests.
AZStd::string body = AZStd::string::format("%s=%s&%s=%s&%s=%s", OAUTH_RESPONSE_TYPE_BODY_KEY, m_settings->m_responseType.c_str()
, OAUTH_CLIENT_ID_BODY_KEY, m_settings->m_appClientId.c_str(), OAUTH_SCOPE_BODY_KEY, OAUTH_SCOPE_BODY_VALUE);
AZStd::map<AZStd::string, AZStd::string> headers;
headers[OAUTH_CONTENT_TYPE_HEADER_KEY] = OAUTH_CONTENT_TYPE_HEADER_VALUE;
headers[OAUTH_CONTENT_LENGTH_HEADER_KEY] = AZStd::to_string(body.length());
HttpRequestor::HttpRequestorRequestBus::Broadcast(&HttpRequestor::HttpRequestorRequests::AddRequestWithHeadersAndBody, m_settings->m_oAuthCodeURL
, Aws::Http::HttpMethod::HTTP_POST, headers, body
, [this](const Aws::Utils::Json::JsonView& jsonView, Aws::Http::HttpResponseCode responseCode)
{
if (responseCode == Aws::Http::HttpResponseCode::OK)
{
m_cachedUserCode = jsonView.GetString(OAUTH_USER_CODE_RESPONSE_KEY).c_str();
m_cachedDeviceCode = jsonView.GetString(OAUTH_DEVICE_CODE_BODY_KEY).c_str();
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnDeviceCodeGrantSignInSuccess
, jsonView.GetString(OAUTH_USER_CODE_RESPONSE_KEY).c_str()
, jsonView.GetString(LWA_VERIFICATION_URL_RESPONSE_KEY).c_str()
, jsonView.GetInteger(OAUTH_EXPIRES_IN_RESPONSE_KEY));
}
else
{
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnDeviceCodeGrantSignInFail
, jsonView.GetString(OAUTH_ERROR_RESPONSE_KEY).c_str());
}
}
);
}
// Call LWA authentication provider OAuth tokens endpoint
// Refer https://developer.amazon.com/docs/login-with-amazon/retrieve-token-other-platforms-cbl-docs.html
void LWAAuthenticationProvider::DeviceCodeGrantConfirmSignInAsync()
{
// Set headers and body for device confirm sign in http requests.
AZStd::string body = AZStd::string::format("%s=%s&%s=%s&%s=%s", OAUTH_USER_CODE_RESPONSE_KEY, m_cachedUserCode.c_str()
, OAUTH_GRANT_TYPE_BODY_KEY, m_settings->m_grantType.c_str(), OAUTH_DEVICE_CODE_BODY_KEY, m_cachedDeviceCode.c_str());
AZStd::map<AZStd::string, AZStd::string> headers;
headers[OAUTH_CONTENT_TYPE_HEADER_KEY] = OAUTH_CONTENT_TYPE_HEADER_VALUE;
headers[OAUTH_CONTENT_LENGTH_HEADER_KEY] = AZStd::to_string(body.length());
HttpRequestor::HttpRequestorRequestBus::Broadcast(&HttpRequestor::HttpRequestorRequests::AddRequestWithHeadersAndBody, m_settings->m_oAuthTokensURL
, Aws::Http::HttpMethod::HTTP_POST, headers, body
, [this](const Aws::Utils::Json::JsonView& jsonView, Aws::Http::HttpResponseCode responseCode)
{
if (responseCode == Aws::Http::HttpResponseCode::OK)
{
// Id and access token are the same.
UpdateTokens(jsonView);
AuthenticationProviderNotificationBus::Broadcast(
&AuthenticationProviderNotifications::OnDeviceCodeGrantConfirmSignInSuccess, m_authenticationTokens);
m_cachedUserCode = "";
m_cachedDeviceCode = "";
}
else
{
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnDeviceCodeGrantConfirmSignInFail
, jsonView.GetString("error").c_str());
}
}
);
}
void LWAAuthenticationProvider::RefreshTokensAsync()
{
// Set headers and body for device confirm sign in http requests.
AZStd::string body = AZStd::string::format("%s=%s&%s=%s&%s=%s", OAUTH_CLIENT_ID_BODY_KEY, m_settings->m_appClientId.c_str(), OAUTH_GRANT_TYPE_BODY_KEY,
OAUTH_REFRESH_TOKEN_BODY_VALUE, OAUTH_REFRESH_TOKEN_BODY_KEY, m_authenticationTokens.GetRefreshToken().c_str());
AZStd::map<AZStd::string, AZStd::string> headers;
headers[OAUTH_CONTENT_TYPE_HEADER_KEY] = OAUTH_CONTENT_TYPE_HEADER_VALUE;
headers[OAUTH_CONTENT_LENGTH_HEADER_KEY] = AZStd::to_string(body.length());
HttpRequestor::HttpRequestorRequestBus::Broadcast(&HttpRequestor::HttpRequestorRequests::AddRequestWithHeadersAndBody, m_settings->m_oAuthTokensURL
, Aws::Http::HttpMethod::HTTP_POST, headers, body
, [this](const Aws::Utils::Json::JsonView& jsonView, Aws::Http::HttpResponseCode responseCode)
{
if (responseCode == Aws::Http::HttpResponseCode::OK)
{
// Id and access token are the same.
UpdateTokens(jsonView);
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnRefreshTokensSuccess, m_authenticationTokens);
}
else
{
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnRefreshTokensFail
, jsonView.GetString("error").c_str());
}
}
);
}
void LWAAuthenticationProvider::UpdateTokens(const Aws::Utils::Json::JsonView& jsonView)
{
// For Login with Amazon openId and access tokens are the same.
m_authenticationTokens = AuthenticationTokens(jsonView.GetString(OAUTH_ACCESS_TOKEN_RESPONSE_KEY).c_str(), jsonView.GetString(OAUTH_REFRESH_TOKEN_RESPONSE_KEY).c_str(),
jsonView.GetString(OAUTH_ACCESS_TOKEN_RESPONSE_KEY).c_str(), ProviderNameEnum::LoginWithAmazon
, jsonView.GetInteger(OAUTH_EXPIRES_IN_RESPONSE_KEY));
}
} // namespace AWSClientAuth
@@ -0,0 +1,90 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <Authorization/AWSClientAuthPersistentCognitoIdentityProvider.h>
namespace AWSClientAuth
{
AWSClientAuthPersistentCognitoIdentityProvider::~AWSClientAuthPersistentCognitoIdentityProvider()
{
m_logins.clear();
m_awsAccountId = "";
m_identityPoolId = "";
m_identityId = "";
m_identityIdUpdatedCallback = nullptr;
m_loginsUpdatedCallback = nullptr;
}
void AWSClientAuthPersistentCognitoIdentityProvider::Initialize(const Aws::String& awsAccountId, const Aws::String& identityPoolId)
{
m_identityPoolId = identityPoolId;
m_awsAccountId = awsAccountId;
}
bool AWSClientAuthPersistentCognitoIdentityProvider::HasIdentityId() const
{
return !m_identityId.empty();
}
bool AWSClientAuthPersistentCognitoIdentityProvider::HasLogins() const
{
return m_logins.size() > 0;
}
Aws::String AWSClientAuthPersistentCognitoIdentityProvider::GetIdentityId() const
{
return m_identityId;
}
Aws::Map<Aws::String, Aws::Auth::LoginAccessTokens> AWSClientAuthPersistentCognitoIdentityProvider::GetLogins()
{
return m_logins;
}
Aws::String AWSClientAuthPersistentCognitoIdentityProvider::GetAccountId() const
{
return m_awsAccountId;
}
Aws::String AWSClientAuthPersistentCognitoIdentityProvider::GetIdentityPoolId() const
{
return m_identityPoolId;
}
void AWSClientAuthPersistentCognitoIdentityProvider::PersistIdentityId(const Aws::String& identityId)
{
m_identityId = identityId;
if (m_identityIdUpdatedCallback)
{
m_identityIdUpdatedCallback(*this);
}
}
void AWSClientAuthPersistentCognitoIdentityProvider::PersistLogins(const Aws::Map<Aws::String, Aws::Auth::LoginAccessTokens>& logins)
{
m_logins = logins;
if (m_loginsUpdatedCallback)
{
m_loginsUpdatedCallback(*this);
}
}
void AWSClientAuthPersistentCognitoIdentityProvider::RemoveLogin(const Aws::String& key)
{
m_logins.erase(key);
if (m_loginsUpdatedCallback)
{
m_loginsUpdatedCallback(*this);
}
}
} // namespace AWSClientAuth
@@ -0,0 +1,276 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AWSClientAuthBus.h>
#include <AWSCoreBus.h>
#include <Authorization/AWSCognitoAuthorizationController.h>
#include <AzCore/EBus/Internal/BusContainer.h>
#include <AzCore/Jobs/JobFunction.h>
#include <AzCore/Interface/Interface.h>
#include <AzCore/Settings/SettingsRegistryImpl.h>
#include <aws/identity-management/auth/CognitoCachingCredentialsProvider.h>
namespace AWSClientAuth
{
constexpr char COGNITO_AUTHORIZATION_SETTINGS_PATH[] = "/AWS/CognitoIdentityPool";
AWSCognitoAuthorizationController::AWSCognitoAuthorizationController()
{
AZ::Interface<IAWSCognitoAuthorizationRequests>::Register(this);
AWSCognitoAuthorizationRequestBus::Handler::BusConnect();
AuthenticationProviderNotificationBus::Handler::BusConnect();
AWSCore::AWSCredentialRequestBus::Handler::BusConnect();
m_settings = AZStd::make_unique<CognitoAuthorizationSettings>();
m_persistentCognitoIdentityProvider = std::make_shared<AWSClientAuthPersistentCognitoIdentityProvider>();
m_persistentAnonymousCognitoIdentityProvider = std::make_shared<AWSClientAuthPersistentCognitoIdentityProvider>();
auto identityClient = AZ::Interface<IAWSClientAuthRequests>::Get()->GetCognitoIdentityClient();
m_cognitoCachingCredentialsProvider =
std::make_shared<Aws::Auth::CognitoCachingAuthenticatedCredentialsProvider>(m_persistentCognitoIdentityProvider, identityClient);
m_cognitoCachingAnonymousCredentialsProvider =
std::make_shared<Aws::Auth::CognitoCachingAnonymousCredentialsProvider>(m_persistentAnonymousCognitoIdentityProvider, identityClient);
}
AWSCognitoAuthorizationController::~AWSCognitoAuthorizationController()
{
m_cognitoCachingCredentialsProvider.reset();
m_persistentAnonymousCognitoIdentityProvider.reset();
m_persistentCognitoIdentityProvider.reset();
m_persistentAnonymousCognitoIdentityProvider.reset();
m_settings.reset();
AWSCore::AWSCredentialRequestBus::Handler::BusDisconnect();
AuthenticationProviderNotificationBus::Handler::BusDisconnect();
AWSCognitoAuthorizationRequestBus::Handler::BusDisconnect();
AZ::Interface<IAWSCognitoAuthorizationRequests>::Unregister(this);
}
bool AWSCognitoAuthorizationController::Initialize(const AZStd::string& settingsRegistryPath)
{
AZStd::unique_ptr<AZ::SettingsRegistryInterface> settingsRegistry = AZStd::make_unique<AZ::SettingsRegistryImpl>();
if (!settingsRegistry->MergeSettingsFile(settingsRegistryPath, AZ::SettingsRegistryInterface::Format::JsonMergePatch))
{
AZ_Error("AWSCognitoAuthorizationController", true, "Failed to merge settings file for path %s", settingsRegistryPath.c_str());
return false;
}
if (!settingsRegistry->GetObject(m_settings.get(), azrtti_typeid(m_settings.get()), COGNITO_AUTHORIZATION_SETTINGS_PATH))
{
AZ_Error("AWSCognitoAuthorizationController", true, "Failed to get settings object for path %s", COGNITO_AUTHORIZATION_SETTINGS_PATH);
return false;
}
m_persistentCognitoIdentityProvider->Initialize(m_settings->m_awsAccountId.c_str(), m_settings->m_cognitoIdentityPoolId.c_str());
m_persistentAnonymousCognitoIdentityProvider->Initialize(m_settings->m_awsAccountId.c_str(), m_settings->m_cognitoIdentityPoolId.c_str());
return true;
}
void AWSCognitoAuthorizationController::Reset()
{
// Brackets for lock guard scopes
{
AZStd::lock_guard<AZStd::mutex> lock(m_persistentAnonymousCognitoIdentityProviderMutex);
m_persistentAnonymousCognitoIdentityProvider->ClearLogins();
m_persistentAnonymousCognitoIdentityProvider->ClearIdentity();
}
{
AZStd::lock_guard<AZStd::mutex> lock(m_persistentCognitoIdentityProviderMutex);
m_persistentCognitoIdentityProvider->ClearLogins();
m_persistentCognitoIdentityProvider->ClearIdentity();
}
}
AZStd::string AWSCognitoAuthorizationController::GetIdentityId()
{
// Give preference to authenticated credentials provider.
if (HasPersistedLogins())
{
AZStd::lock_guard<AZStd::mutex> lock(m_persistentCognitoIdentityProviderMutex);
return m_persistentCognitoIdentityProvider->GetIdentityId().c_str();
}
else
{
AZStd::lock_guard<AZStd::mutex> lock(m_persistentAnonymousCognitoIdentityProviderMutex);
return m_persistentAnonymousCognitoIdentityProvider->GetIdentityId().c_str();
}
}
bool AWSCognitoAuthorizationController::HasPersistedLogins()
{
AZStd::lock_guard<AZStd::mutex> lock(m_persistentCognitoIdentityProviderMutex);
return m_persistentCognitoIdentityProvider->HasLogins();
}
std::shared_ptr<Aws::Auth::AWSCredentialsProvider> AWSCognitoAuthorizationController::GetCognitoCredentialsProvider()
{
return m_cognitoCachingCredentialsProvider;
}
std::shared_ptr<Aws::Auth::AWSCredentialsProvider> AWSCognitoAuthorizationController::GetAnonymousCognitoCredentialsProvider()
{
return m_cognitoCachingAnonymousCredentialsProvider;
}
void AWSCognitoAuthorizationController::RequestAWSCredentialsAsync()
{
bool anonymous = true;
// Give preference to authenticated credentials provider.
if (m_persistentCognitoIdentityProvider->HasLogins())
{
anonymous = false;
}
else
{
AZ_Warning("AWSCognitoAuthorizationController", true, "No logins found. Fetching anonymous/unauthenticated credentials");
}
AZ::JobContext* jobContext = nullptr;
AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext);
AZ::Job* job = AZ::CreateJobFunction(
[this, anonymous]() {
Aws::Auth::AWSCredentials credentials;
// GetAWSCredentials makes Cognito GetId and GetCredentialsForIdentity Cognito identity pool API request if no valid cached credentials found.
if (anonymous)
{
AZStd::lock_guard<AZStd::mutex> lock(m_persistentAnonymousCognitoIdentityProviderMutex);
credentials = m_cognitoCachingAnonymousCredentialsProvider->GetAWSCredentials();
}
else
{
AZStd::lock_guard<AZStd::mutex> lock(m_persistentCognitoIdentityProviderMutex);
credentials = m_cognitoCachingCredentialsProvider->GetAWSCredentials();
}
if (!credentials.IsEmpty())
{
ClientAuthAWSCredentials clientAuthAWSCrendentials(credentials.GetAWSAccessKeyId().c_str(), credentials.GetAWSSecretKey().c_str(), credentials.GetSessionToken().c_str());
AWSClientAuth::AWSCognitoAuthorizationNotificationBus::Broadcast(
&AWSClientAuth::AWSCognitoAuthorizationNotifications::OnRequestAWSCredentialsSuccess, clientAuthAWSCrendentials);
}
else
{
AWSClientAuth::AWSCognitoAuthorizationNotificationBus::Broadcast(
&AWSClientAuth::AWSCognitoAuthorizationNotifications::OnRequestAWSCredentialsFail,
"Failed to get AWS credentials");
}
},
true, jobContext);
job->Start();
}
AZStd::string AWSCognitoAuthorizationController::GetAuthenticationProviderId(const ProviderNameEnum& providerName)
{
switch (providerName)
{
case ProviderNameEnum::AWSCognitoIDP:
{
return m_settings->m_cognitoUserPoolId;
}
case ProviderNameEnum::LoginWithAmazon:
{
return m_settings->m_loginWithAmazonId;
}
case ProviderNameEnum::Google:
{
return m_settings->m_googleId;
}
default:
{
return "";
}
}
}
void AWSCognitoAuthorizationController::PersistLoginsAndRefreshAWSCredentials(const AuthenticationTokens& authenticationTokens)
{
// lock to persist logins as the object is shared with Native SDK. Native SDK reads logins and persists identity id and expiry.
AZStd::lock_guard<AZStd::mutex> lock(m_persistentCognitoIdentityProviderMutex);
// Save logins to the shared persistent Cognito identity provider for authenticated authorization.
// Append logins to existing map.
Aws::Map<Aws::String, Aws::Auth::LoginAccessTokens> logins = m_persistentCognitoIdentityProvider->GetLogins();
Aws::Auth::LoginAccessTokens tokens;
tokens.accessToken = authenticationTokens.GetOpenIdToken().c_str();
logins[GetAuthenticationProviderId(authenticationTokens.GetProviderName()).c_str()] = tokens;
m_persistentCognitoIdentityProvider->PersistLogins(logins);
}
void AWSCognitoAuthorizationController::OnPasswordGrantSingleFactorSignInSuccess(const AWSClientAuth::AuthenticationTokens& authenticationTokens)
{
PersistLoginsAndRefreshAWSCredentials(authenticationTokens);
}
void AWSCognitoAuthorizationController::OnPasswordGrantMultiFactorConfirmSignInSuccess(
const AWSClientAuth::AuthenticationTokens& authenticationTokens)
{
PersistLoginsAndRefreshAWSCredentials(authenticationTokens);
}
void AWSCognitoAuthorizationController::OnDeviceCodeGrantConfirmSignInSuccess(
const AWSClientAuth::AuthenticationTokens& authenticationTokens)
{
PersistLoginsAndRefreshAWSCredentials(authenticationTokens);
}
void AWSCognitoAuthorizationController::OnRefreshTokensSuccess(const AWSClientAuth::AuthenticationTokens& authenticationTokens)
{
PersistLoginsAndRefreshAWSCredentials(authenticationTokens);
}
void AWSCognitoAuthorizationController::OnSignOut(const ProviderNameEnum& provideName)
{
// lock to persist logins as the object is shared with Native SDK.
AZStd::lock_guard<AZStd::mutex> lock(m_persistentCognitoIdentityProviderMutex);
m_persistentCognitoIdentityProvider->RemoveLogin(GetAuthenticationProviderId(provideName).c_str());
}
int AWSCognitoAuthorizationController::GetCredentialHandlerOrder() const
{
return AWSCore::CredentialHandlerOrder::COGNITO_IDENITY_POOL_CREDENTIAL_HANDLER;
}
std::shared_ptr<Aws::Auth::AWSCredentialsProvider> AWSCognitoAuthorizationController::GetCredentialsProvider()
{
// If logins are persisted default to using authenticated credentials provide.
// Check authenticated credentials to verify persisted logins are valid.
if (HasPersistedLogins())
{
// lock to protect logins being persisted.
AZStd::lock_guard<AZStd::mutex> lock(m_persistentCognitoIdentityProviderMutex);
if (!m_cognitoCachingCredentialsProvider->GetAWSCredentials().IsEmpty())
{
return m_cognitoCachingCredentialsProvider;
}
}
// lock to protect getting identity id.
AZStd::lock_guard<AZStd::mutex> lock(m_persistentAnonymousCognitoIdentityProviderMutex);
// Check anonymous credentials as they are optional settings in Cognito Identity pool.
if (!m_cognitoCachingAnonymousCredentialsProvider->GetAWSCredentials().IsEmpty())
{
AZ_Warning("AWSCognitoAuthorizationCredentialHandler", true, "No logins found. Using Anonymous credential provider");
return m_cognitoCachingAnonymousCredentialsProvider;
}
return nullptr;
}
} // namespace AWSClientAuth
@@ -0,0 +1,272 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzCore/Jobs/JobFunction.h>
#include <UserManagement/AWSCognitoUserManagementController.h>
#include <AWSClientAuthBus.h>
#include <AWSCoreBus.h>
#include <aws/core/utils/Outcome.h>
#include <aws/core/utils/memory/stl/AWSVector.h>
#include <aws/cognito-idp/model/SignUpRequest.h>
#include <aws/cognito-idp/CognitoIdentityProviderClient.h>
#include <aws/cognito-idp/model/SignUpResult.h>
#include <aws/cognito-idp/model/ConfirmSignUpRequest.h>
#include <aws/cognito-idp/model/ConfirmSignUpResult.h>
#include <aws/cognito-idp/model/ConfirmSignUpRequest.h>
#include <aws/cognito-idp/model/ConfirmSignUpResult.h>
#include <aws/cognito-idp/model/AttributeType.h>
#include <aws/cognito-idp/model/ForgotPasswordRequest.h>
#include <aws/cognito-idp/model/ForgotPasswordResult.h>
#include <aws/cognito-idp/model/ConfirmForgotPasswordRequest.h>
#include <aws/cognito-idp/model/ConfirmForgotPasswordResult.h>
#include <aws/cognito-idp/model/SetUserMFAPreferenceRequest.h>
#include <aws/cognito-idp/model/SetUserMFAPreferenceResult.h>
namespace AWSClientAuth
{
constexpr char COGNITO_USER_POOL[] = "/AWS/CognitoUserPool";
AWSCognitoUserManagementController::AWSCognitoUserManagementController()
{
AZ::Interface<IAWSCognitoUserManagementRequests>::Register(this);
AWSCognitoUserManagementRequestBus::Handler::BusConnect();
m_settings = AZStd::make_unique<AWSCognitoUserManagementSetting>();
}
AWSCognitoUserManagementController::~AWSCognitoUserManagementController()
{
m_settings.reset();
AWSCognitoUserManagementRequestBus::Handler::BusDisconnect();
AZ::Interface<IAWSCognitoUserManagementRequests>::Unregister(this);
}
bool AWSCognitoUserManagementController::Initialize(const AZStd::string& settingsRegistryPath)
{
AZStd::unique_ptr<AZ::SettingsRegistryInterface> settingsRegistry = AZStd::make_unique<AZ::SettingsRegistryImpl>();
if (!settingsRegistry->MergeSettingsFile(settingsRegistryPath, AZ::SettingsRegistryInterface::Format::JsonMergePatch))
{
AZ_Error("AWSCognitoUserManagementController", true, "Failed to merge settings file for path %s", settingsRegistryPath.c_str());
return false;
}
if (!settingsRegistry->GetObject(m_settings.get(), azrtti_typeid(m_settings.get()), COGNITO_USER_POOL))
{
AZ_Error("AWSCognitoUserManagementController", true, "Failed to get settings object for path %s", COGNITO_USER_POOL);
return false;
}
return true;
}
// Call Cognito user pool sign up using email. Confirmation code sent to the email set.
// Refer https://docs.aws.amazon.com/cognito/latest/developerguide/signing-up-users-in-your-app.html
void AWSCognitoUserManagementController::EmailSignUpAsync(const AZStd::string& username, const AZStd::string& password, const AZStd::string& email)
{
std::shared_ptr<Aws::CognitoIdentityProvider::CognitoIdentityProviderClient> cognitoIdentityProviderClient =
AZ::Interface<IAWSClientAuthRequests>::Get()->GetCognitoIDPClient();
AZ::JobContext* jobContext = nullptr;
AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext);
AZ::Job* emailSignUpJob = AZ::CreateJobFunction([this, cognitoIdentityProviderClient, username, password, email]()
{
Aws::CognitoIdentityProvider::Model::SignUpRequest signUpRequest;
signUpRequest.SetClientId(m_settings->m_appClientId.c_str());
signUpRequest.SetUsername(username.c_str());
signUpRequest.SetPassword(password.c_str());
Aws::Vector<Aws::CognitoIdentityProvider::Model::AttributeType> attributes;
Aws::CognitoIdentityProvider::Model::AttributeType emailAttribute;
emailAttribute.SetName("email");
emailAttribute.SetValue(email.c_str());
attributes.push_back(emailAttribute);
signUpRequest.SetUserAttributes(attributes);
Aws::CognitoIdentityProvider::Model::SignUpOutcome signUpOutcome{ cognitoIdentityProviderClient->SignUp(signUpRequest) };
if (signUpOutcome.IsSuccess())
{
Aws::CognitoIdentityProvider::Model::SignUpResult signUpResult{ signUpOutcome.GetResult() };
AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnEmailSignUpSuccess, signUpResult.GetUserSub().c_str());
}
else
{
Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error = signUpOutcome.GetError();
AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnEmailSignUpFail, error.GetMessage().c_str());
}
}, true, jobContext);
emailSignUpJob->Start();
}
void AWSCognitoUserManagementController::PhoneSignUpAsync(const AZStd::string& username, const AZStd::string& password, const AZStd::string& phoneNumber)
{
std::shared_ptr<Aws::CognitoIdentityProvider::CognitoIdentityProviderClient> cognitoIdentityProviderClient =
AZ::Interface<IAWSClientAuthRequests>::Get()->GetCognitoIDPClient();
AZ::JobContext* jobContext = nullptr;
AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext);
AZ::Job* phoneSignUpJob = AZ::CreateJobFunction([this, cognitoIdentityProviderClient, username, password, phoneNumber]()
{
Aws::CognitoIdentityProvider::Model::SignUpRequest signUpRequest;
signUpRequest.SetClientId(m_settings->m_appClientId.c_str());
signUpRequest.SetUsername(username.c_str());
signUpRequest.SetPassword(password.c_str());
Aws::Vector<Aws::CognitoIdentityProvider::Model::AttributeType> attributes;
Aws::CognitoIdentityProvider::Model::AttributeType emailAttribute;
emailAttribute.SetName("phone_number");
emailAttribute.SetValue(phoneNumber.c_str());
attributes.push_back(emailAttribute);
signUpRequest.SetUserAttributes(attributes);
Aws::CognitoIdentityProvider::Model::SignUpOutcome signUpOutcome{ cognitoIdentityProviderClient->SignUp(signUpRequest) };
if (signUpOutcome.IsSuccess())
{
Aws::CognitoIdentityProvider::Model::SignUpResult signUpResult{ signUpOutcome.GetResult() };
AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnPhoneSignUpSuccess, signUpResult.GetUserSub().c_str());
}
else
{
Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error = signUpOutcome.GetError();
AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnPhoneSignUpFail, error.GetMessage().c_str());
}
}, true, jobContext);
phoneSignUpJob->Start();
}
// Call Cognito user pool confirm sign up using code from email/phone.
// Refer https://docs.aws.amazon.com/cognito/latest/developerguide/signing-up-users-in-your-app.html
void AWSCognitoUserManagementController::ConfirmSignUpAsync(const AZStd::string& username, const AZStd::string& confirmationCode)
{
std::shared_ptr<Aws::CognitoIdentityProvider::CognitoIdentityProviderClient> cognitoIdentityProviderClient =
AZ::Interface<IAWSClientAuthRequests>::Get()->GetCognitoIDPClient();
AZ::JobContext* jobContext = nullptr;
AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext);
AZ::Job* confirmSignUpJob = AZ::CreateJobFunction([this, cognitoIdentityProviderClient, username, confirmationCode]()
{
Aws::CognitoIdentityProvider::Model::ConfirmSignUpRequest confirmSignupRequest;
confirmSignupRequest.SetClientId(m_settings->m_appClientId.c_str());
confirmSignupRequest.SetUsername(username.c_str());
confirmSignupRequest.SetConfirmationCode(confirmationCode.c_str());
Aws::CognitoIdentityProvider::Model::ConfirmSignUpOutcome confirmSignupOutcome{ cognitoIdentityProviderClient->ConfirmSignUp(confirmSignupRequest) };
if (confirmSignupOutcome.IsSuccess())
{
AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnConfirmSignUpSuccess);
}
else
{
Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error = confirmSignupOutcome.GetError();
AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnConfirmSignUpFail, error.GetMessage().c_str());
}
}, true, jobContext);
confirmSignUpJob->Start();
}
void AWSCognitoUserManagementController::ForgotPasswordAsync(const AZStd::string& username)
{
std::shared_ptr<Aws::CognitoIdentityProvider::CognitoIdentityProviderClient> cognitoIdentityProviderClient =
AZ::Interface<IAWSClientAuthRequests>::Get()->GetCognitoIDPClient();
AZ::JobContext* jobContext = nullptr;
AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext);
AZ::Job* forgotPasswordJob = AZ::CreateJobFunction([this, cognitoIdentityProviderClient, username]()
{
Aws::CognitoIdentityProvider::Model::ForgotPasswordRequest forgotPasswordRequest;
forgotPasswordRequest.SetClientId(m_settings->m_appClientId.c_str());
forgotPasswordRequest.SetUsername(username.c_str());
Aws::CognitoIdentityProvider::Model::ForgotPasswordOutcome forgotPasswordOutcome{ cognitoIdentityProviderClient->ForgotPassword(forgotPasswordRequest) };
if (forgotPasswordOutcome.IsSuccess())
{
AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnForgotPasswordSuccess);
}
else
{
Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error = forgotPasswordOutcome.GetError();
AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnForgotPasswordFail, error.GetMessage().c_str());
}
}, true, jobContext);
forgotPasswordJob->Start();
}
void AWSCognitoUserManagementController::ConfirmForgotPasswordAsync(const AZStd::string& username, const AZStd::string& confirmationCode, const AZStd::string& newPassword)
{
std::shared_ptr<Aws::CognitoIdentityProvider::CognitoIdentityProviderClient> cognitoIdentityProviderClient =
AZ::Interface<IAWSClientAuthRequests>::Get()->GetCognitoIDPClient();
AZ::JobContext* jobContext = nullptr;
AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext);
AZ::Job* confirmForgotPasswordJob = AZ::CreateJobFunction([this, cognitoIdentityProviderClient, username, confirmationCode, newPassword]()
{
Aws::CognitoIdentityProvider::Model::ConfirmForgotPasswordRequest confirmForgotPasswordRequest;
confirmForgotPasswordRequest.SetClientId(m_settings->m_appClientId.c_str());
confirmForgotPasswordRequest.SetUsername(username.c_str());
confirmForgotPasswordRequest.SetConfirmationCode(confirmationCode.c_str());
confirmForgotPasswordRequest.SetPassword(newPassword.c_str());
Aws::CognitoIdentityProvider::Model::ConfirmForgotPasswordOutcome confirmForgotPasswordOutcome{ cognitoIdentityProviderClient->ConfirmForgotPassword(confirmForgotPasswordRequest) };
if (confirmForgotPasswordOutcome.IsSuccess())
{
AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnConfirmForgotPasswordSuccess);
}
else
{
Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error = confirmForgotPasswordOutcome.GetError();
AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnConfirmForgotPasswordFail, error.GetMessage().c_str());
}
}, true, jobContext);
confirmForgotPasswordJob->Start();
}
void AWSCognitoUserManagementController::EnableMFAAsync(const AZStd::string& accessToken)
{
std::shared_ptr<Aws::CognitoIdentityProvider::CognitoIdentityProviderClient> cognitoIdentityProviderClient =
AZ::Interface<IAWSClientAuthRequests>::Get()->GetCognitoIDPClient();
AZ::JobContext* jobContext = nullptr;
AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext);
AZ::Job* enableMFAJob = AZ::CreateJobFunction([this, cognitoIdentityProviderClient, accessToken]()
{
Aws::CognitoIdentityProvider::Model::SetUserMFAPreferenceRequest confirmForgotPasswordRequest;
Aws::CognitoIdentityProvider::Model::SMSMfaSettingsType settings;
settings.SetEnabled(true);
settings.SetPreferredMfa(true);
confirmForgotPasswordRequest.SetSMSMfaSettings(settings);
confirmForgotPasswordRequest.SetAccessToken(accessToken.c_str());
Aws::CognitoIdentityProvider::Model::SetUserMFAPreferenceOutcome setUserMFAPreferenceOutcome{ cognitoIdentityProviderClient->SetUserMFAPreference(confirmForgotPasswordRequest) };
if (setUserMFAPreferenceOutcome.IsSuccess())
{
AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnEnableMFASuccess);
}
else
{
Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error = setUserMFAPreferenceOutcome.GetError();
AWSCognitoUserManagementNotificationBus::Broadcast(&AWSCognitoUserManagementNotifications::OnEnableMFAFail, error.GetMessage().c_str());
}
}, true, jobContext);
enableMFAJob->Start();
}
} // namespace AWSClientAuth
@@ -0,0 +1,628 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzTest/AzTest.h>
#include <AzTest/Utils.h>
#include <AzFramework/IO/LocalFileIO.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/Memory/PoolAllocator.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzCore/Settings/SettingsRegistry.h>
#include <AzCore/Settings/SettingsRegistryImpl.h>
#include <AzCore/Serialization/Json/RegistrationContext.h>
#include <AzCore/Serialization/Json/JsonSystemComponent.h>
#include <AzCore/Component/ComponentBus.h>
#include <AzCore/Jobs/JobManager.h>
#include <AzCore/Jobs/JobManagerBus.h>
#include <AzCore/Jobs/JobContext.h>
#include <Authentication/AWSCognitoAuthenticationProvider.h>
#include <Authentication/LWAAuthenticationProvider.h>
#include <Authentication/AuthenticationProviderBus.h>
#include <Authorization/AWSCognitoAuthorizationBus.h>
#include <UserManagement/AWSCognitoUserManagementBus.h>
#include <AWSCoreBus.h>
#include <AWSClientAuthBus.h>
#include <AWSNativeSDKInit/AWSNativeSDKInit.h>
#include <HttpRequestor/HttpRequestorBus.h>
#include <aws/core/utils/Outcome.h>
#include <aws/cognito-idp/model/InitiateAuthRequest.h>
#include <aws/cognito-idp/model/InitiateAuthResult.h>
#include <aws/cognito-idp/CognitoIdentityProviderClient.h>
#include <aws/cognito-idp/model/SignUpRequest.h>
#include <aws/cognito-idp/model/SignUpResult.h>
#include <aws/cognito-idp/model/ConfirmSignUpRequest.h>
#include <aws/cognito-idp/model/ConfirmSignUpResult.h>
#include <aws/cognito-idp/model/RespondToAuthChallengeRequest.h>
#include <aws/cognito-idp/model/RespondToAuthChallengeResult.h>
#include <aws/cognito-idp/model/ForgotPasswordResult.h>
#include <aws/cognito-idp/model/ForgotPasswordRequest.h>
#include <aws/cognito-idp/model/ConfirmForgotPasswordRequest.h>
#include <aws/cognito-idp/model/ConfirmForgotPasswordResult.h>
#include <aws/cognito-idp/model/SetUserMFAPreferenceRequest.h>
#include <aws/cognito-idp/model/SetUserMFAPreferenceResult.h>
#include <aws/cognito-identity/CognitoIdentityClient.h>
#include <aws/cognito-identity/model/GetCredentialsForIdentityRequest.h>
#include <aws/cognito-identity/model/GetCredentialsForIdentityResult.h>
#include <aws/cognito-identity/model/GetIdRequest.h>
#include <aws/cognito-identity/model/GetIdResult.h>
namespace AWSClientAuthUnitTest
{
constexpr char TEST_USERNAME[] = "TestUsername";
constexpr char TEST_PASSWORD[] = "TestPassword";
constexpr char TEST_NEW_PASSWORD[] = "TestNewPassword";
constexpr char TEST_CODE[] = "TestCode";
constexpr char TEST_EMAIL[] = "test@test.com";
constexpr char TEST_PHONE[] = "+11234567890";
constexpr char TEST_COGNITO_CLIENTID[] = "TestCognitoClientId";
constexpr char TEST_EXCEPTION[] = "TestException";
constexpr char TEST_SESSION[] = "TestSession";
constexpr char TEST_TOKEN[] = "TestToken";
constexpr char TEST_ACCOUNT_ID[] = "1234567890";
constexpr char TEST_IDENTITY_POOL_ID[] = "TestIdenitityPoolId";
constexpr char TEST_IDENTITY_ID[] = "TestIdenitityId";
constexpr char TEST_ACCESS_TOKEN[] = "TestAccessToken";
constexpr char TEST_REFRESH_TOKEN[] = "TestRefreshToken";
constexpr char TEST_ID_TOKEN[] = "TestIdToken";
constexpr char TEST_ACCESS_KEY_ID[] = "TestAccessKeyId";
constexpr char TEST_SECRET_KEY_ID[] = "TestSecretKeyId";
class HttpRequestorRequestBusMock
: public HttpRequestor::HttpRequestorRequestBus::Handler
{
public:
HttpRequestorRequestBusMock()
{
ON_CALL(*this, AddRequestWithHeadersAndBody(testing::_, testing::_, testing::_, testing::_, testing::_)).WillByDefault(testing::Invoke(this, &HttpRequestorRequestBusMock::AddRequestWithHeadersAndBodyMock));
HttpRequestor::HttpRequestorRequestBus::Handler::BusConnect();
}
virtual ~HttpRequestorRequestBusMock()
{
HttpRequestor::HttpRequestorRequestBus::Handler::BusDisconnect();
}
MOCK_METHOD5(AddRequestWithHeadersAndBody, void(const AZStd::string& URI, Aws::Http::HttpMethod method, const HttpRequestor::Headers& headers, const AZStd::string& body, const HttpRequestor::Callback& callback));
void AddRequestWithHeadersAndBodyError(const AZStd::string& URI, Aws::Http::HttpMethod method, const HttpRequestor::Headers& headers, const AZStd::string& body, const HttpRequestor::Callback& callback)
{
AZ_UNUSED(URI);
AZ_UNUSED(method);
AZ_UNUSED(headers);
AZ_UNUSED(body);
Aws::Utils::Json::JsonValue jsonValue;
jsonValue.WithString("error", "TestError");
Aws::Utils::Json::JsonView jsonView(jsonValue);
Aws::Http::HttpResponseCode code = Aws::Http::HttpResponseCode::INTERNAL_SERVER_ERROR;
callback(jsonView, code);
}
void AddRequest(const AZStd::string& URI, Aws::Http::HttpMethod method, const HttpRequestor::Callback& callback) override
{
AZ_UNUSED(URI);
AZ_UNUSED(method);
AZ_UNUSED(callback);
}
void AddRequestWithHeaders(const AZStd::string& URI, Aws::Http::HttpMethod method, const HttpRequestor::Headers& headers, const HttpRequestor::Callback& callback) override
{
AZ_UNUSED(URI);
AZ_UNUSED(method);
AZ_UNUSED(headers);
AZ_UNUSED(callback);
}
void AddRequestWithHeadersAndBodyMock(const AZStd::string& URI, Aws::Http::HttpMethod method, const HttpRequestor::Headers& headers, const AZStd::string& body, const HttpRequestor::Callback& callback)
{
AZ_UNUSED(URI);
AZ_UNUSED(method);
AZ_UNUSED(headers);
AZ_UNUSED(body);
Aws::Utils::Json::JsonValue jsonValue;
jsonValue.WithString("user_code", "TestCode");
jsonValue.WithString("device_code", "TestDeviceCode");
jsonValue.WithString("verification_uri", "TestVerificationURI");
jsonValue.WithString("access_token", "TestAccessToken");
jsonValue.WithString("refresh_token", "TestRefreshToken");
jsonValue.WithString("id_token", "TestIdToken");
jsonValue.WithString("expires_in", "600");
Aws::Utils::Json::JsonView jsonView(jsonValue);
Aws::Http::HttpResponseCode code = Aws::Http::HttpResponseCode::OK;
callback(jsonView, code);
}
void AddTextRequest(const AZStd::string& URI, Aws::Http::HttpMethod method, const HttpRequestor::TextCallback& callback) override
{
AZ_UNUSED(URI);
AZ_UNUSED(method);
AZ_UNUSED(callback);
}
void AddTextRequestWithHeaders(const AZStd::string& URI, Aws::Http::HttpMethod method, const HttpRequestor::Headers& headers, const HttpRequestor::TextCallback& callback) override
{
AZ_UNUSED(URI);
AZ_UNUSED(method);
AZ_UNUSED(headers);
AZ_UNUSED(callback);
}
void AddTextRequestWithHeadersAndBody(const AZStd::string& URI, Aws::Http::HttpMethod method, const HttpRequestor::Headers& headers, const AZStd::string& body, const HttpRequestor::TextCallback& callback) override
{
AZ_UNUSED(URI);
AZ_UNUSED(method);
AZ_UNUSED(headers);
AZ_UNUSED(body);
AZ_UNUSED(callback);
}
};
class CognitoIdentityProviderClientMock
: public Aws::CognitoIdentityProvider::CognitoIdentityProviderClient
{
public:
CognitoIdentityProviderClientMock() : Aws::CognitoIdentityProvider::CognitoIdentityProviderClient(Aws::Auth::AWSCredentials())
{
ON_CALL(*this, InitiateAuth(testing::_)).WillByDefault(testing::Invoke(this, &CognitoIdentityProviderClientMock::InitiateAuthMock));
ON_CALL(*this, SignUp(testing::_)).WillByDefault(testing::Invoke(this, &CognitoIdentityProviderClientMock::SignUpMock));
ON_CALL(*this, ConfirmSignUp(testing::_)).WillByDefault(testing::Invoke(this, &CognitoIdentityProviderClientMock::ConfirmSignUpMock));
ON_CALL(*this, RespondToAuthChallenge(testing::_)).WillByDefault(testing::Invoke(this, &CognitoIdentityProviderClientMock::RespondToAuthChallengeMock));
ON_CALL(*this, ForgotPassword(testing::_)).WillByDefault(testing::Invoke(this, &CognitoIdentityProviderClientMock::ForgotPasswordMock));
ON_CALL(*this, ConfirmForgotPassword(testing::_)).WillByDefault(testing::Invoke(this, &CognitoIdentityProviderClientMock::ConfirmForgotPasswordMock));
ON_CALL(*this, SetUserMFAPreference(testing::_)).WillByDefault(testing::Invoke(this, &CognitoIdentityProviderClientMock::SetUserMFAPreferenceMock));
}
MOCK_CONST_METHOD1(InitiateAuth
, Aws::CognitoIdentityProvider::Model::InitiateAuthOutcome(const Aws::CognitoIdentityProvider::Model::InitiateAuthRequest& request));
MOCK_CONST_METHOD1(RespondToAuthChallenge
, Aws::CognitoIdentityProvider::Model::RespondToAuthChallengeOutcome(const Aws::CognitoIdentityProvider::Model::RespondToAuthChallengeRequest& request));
MOCK_CONST_METHOD1(SignUp
, Aws::CognitoIdentityProvider::Model::SignUpOutcome(const Aws::CognitoIdentityProvider::Model::SignUpRequest& request));
MOCK_CONST_METHOD1(ConfirmSignUp
, Aws::CognitoIdentityProvider::Model::ConfirmSignUpOutcome(const Aws::CognitoIdentityProvider::Model::ConfirmSignUpRequest& request));
MOCK_CONST_METHOD1(ForgotPassword
, Aws::CognitoIdentityProvider::Model::ForgotPasswordOutcome(const Aws::CognitoIdentityProvider::Model::ForgotPasswordRequest& request));
MOCK_CONST_METHOD1(ConfirmForgotPassword
, Aws::CognitoIdentityProvider::Model::ConfirmForgotPasswordOutcome(const Aws::CognitoIdentityProvider::Model::ConfirmForgotPasswordRequest& request));
MOCK_CONST_METHOD1(SetUserMFAPreference
, Aws::CognitoIdentityProvider::Model::SetUserMFAPreferenceOutcome(const Aws::CognitoIdentityProvider::Model::SetUserMFAPreferenceRequest& request));
Aws::CognitoIdentityProvider::Model::InitiateAuthOutcome InitiateAuthMock(const Aws::CognitoIdentityProvider::Model::InitiateAuthRequest& request)
{
AZ_UNUSED(request);
Aws::CognitoIdentityProvider::Model::AuthenticationResultType authenticationResult;
authenticationResult.SetAccessToken(TEST_ACCESS_TOKEN);
authenticationResult.SetRefreshToken(TEST_REFRESH_TOKEN);
authenticationResult.SetIdToken(TEST_ID_TOKEN);
authenticationResult.SetExpiresIn(5);
Aws::CognitoIdentityProvider::Model::InitiateAuthResult result;
result.SetChallengeName(Aws::CognitoIdentityProvider::Model::ChallengeNameType::NOT_SET);
result.SetAuthenticationResult(authenticationResult);
Aws::CognitoIdentityProvider::Model::InitiateAuthOutcome outcome(result);
return outcome;
}
Aws::CognitoIdentityProvider::Model::SignUpOutcome SignUpMock(const Aws::CognitoIdentityProvider::Model::SignUpRequest& request)
{
AZ_UNUSED(request);
Aws::CognitoIdentityProvider::Model::SignUpResult result;
result.SetUserSub("TestUserUUID");
Aws::CognitoIdentityProvider::Model::SignUpOutcome outcome(result);
return outcome;
}
Aws::CognitoIdentityProvider::Model::RespondToAuthChallengeOutcome RespondToAuthChallengeMock(const Aws::CognitoIdentityProvider::Model::RespondToAuthChallengeRequest& request)
{
AZ_UNUSED(request);
Aws::CognitoIdentityProvider::Model::RespondToAuthChallengeResult result;
Aws::CognitoIdentityProvider::Model::AuthenticationResultType authenticationResult;
authenticationResult.SetAccessToken(TEST_ACCESS_TOKEN);
authenticationResult.SetRefreshToken(TEST_REFRESH_TOKEN);
authenticationResult.SetIdToken(TEST_ID_TOKEN);
authenticationResult.SetExpiresIn(30);
result.SetAuthenticationResult(authenticationResult);
Aws::CognitoIdentityProvider::Model::RespondToAuthChallengeOutcome outcome(result);
return outcome;
}
Aws::CognitoIdentityProvider::Model::ConfirmSignUpOutcome ConfirmSignUpMock(const Aws::CognitoIdentityProvider::Model::ConfirmSignUpRequest& request)
{
AZ_UNUSED(request);
Aws::CognitoIdentityProvider::Model::ConfirmSignUpResult result;
Aws::CognitoIdentityProvider::Model::ConfirmSignUpOutcome outcome(result);
return outcome;
}
Aws::CognitoIdentityProvider::Model::ForgotPasswordOutcome ForgotPasswordMock(const Aws::CognitoIdentityProvider::Model::ForgotPasswordRequest& request)
{
AZ_UNUSED(request);
Aws::CognitoIdentityProvider::Model::ForgotPasswordResult result;
Aws::CognitoIdentityProvider::Model::ForgotPasswordOutcome outcome(result);
return outcome;
}
Aws::CognitoIdentityProvider::Model::ConfirmForgotPasswordOutcome ConfirmForgotPasswordMock(const Aws::CognitoIdentityProvider::Model::ConfirmForgotPasswordRequest& request)
{
AZ_UNUSED(request);
Aws::CognitoIdentityProvider::Model::ConfirmForgotPasswordResult result;
Aws::CognitoIdentityProvider::Model::ConfirmForgotPasswordOutcome outcome(result);
return outcome;
}
Aws::CognitoIdentityProvider::Model::SetUserMFAPreferenceOutcome SetUserMFAPreferenceMock(const Aws::CognitoIdentityProvider::Model::SetUserMFAPreferenceRequest& request)
{
AZ_UNUSED(request);
Aws::CognitoIdentityProvider::Model::SetUserMFAPreferenceResult result;
Aws::CognitoIdentityProvider::Model::SetUserMFAPreferenceOutcome outcome(result);
return outcome;
}
};
class CognitoIdentityClientMock
: public Aws::CognitoIdentity::CognitoIdentityClient
{
public:
CognitoIdentityClientMock()
{
ON_CALL(*this, GetId(testing::_)).WillByDefault(testing::Invoke(this, &CognitoIdentityClientMock::GetIdMock));
ON_CALL(*this, GetCredentialsForIdentity(testing::_)).WillByDefault(testing::Invoke(this, &CognitoIdentityClientMock::GetCredentialsForIdentityMock));
}
MOCK_CONST_METHOD1(GetId
, Aws::CognitoIdentity::Model::GetIdOutcome(const Aws::CognitoIdentity::Model::GetIdRequest& request));
MOCK_CONST_METHOD1(GetCredentialsForIdentity
, Aws::CognitoIdentity::Model::GetCredentialsForIdentityOutcome(const Aws::CognitoIdentity::Model::GetCredentialsForIdentityRequest& request));
Aws::CognitoIdentity::Model::GetIdOutcome GetIdMock(const Aws::CognitoIdentity::Model::GetIdRequest& request)
{
AZ_UNUSED(request);
Aws::CognitoIdentity::Model::GetIdResult result;
result.SetIdentityId(TEST_IDENTITY_ID);
Aws::CognitoIdentity::Model::GetIdOutcome outcome(result);
return outcome;
}
Aws::CognitoIdentity::Model::GetCredentialsForIdentityOutcome GetCredentialsForIdentityMock(const Aws::CognitoIdentity::Model::GetCredentialsForIdentityRequest& request)
{
AZ_UNUSED(request);
Aws::CognitoIdentity::Model::Credentials creds;
creds.SetAccessKeyId(TEST_ACCESS_KEY_ID);
creds.SetSecretKey(TEST_SECRET_KEY_ID);
creds.SetExpiration(Aws::Utils::DateTime(std::chrono::system_clock::now() + std::chrono::seconds(600)));
Aws::CognitoIdentity::Model::GetCredentialsForIdentityResult result;
result.SetIdentityId(TEST_IDENTITY_ID);
result.SetCredentials(creds);
Aws::CognitoIdentity::Model::GetCredentialsForIdentityOutcome outcome(result);
return outcome;
}
};
class AuthenticationProviderMock
: public AWSClientAuth::AuthenticationProviderInterface
{
public:
AuthenticationProviderMock()
{
ON_CALL(*this, Initialize(testing::_)).WillByDefault(testing::Return(true));
}
virtual ~AuthenticationProviderMock() = default;
MOCK_METHOD1(Initialize, bool(AZStd::weak_ptr<AZ::SettingsRegistryInterface> settingsRegistry));
MOCK_METHOD2(PasswordGrantSingleFactorSignInAsync, void(const AZStd::string& username, const AZStd::string& password));
MOCK_METHOD2(PasswordGrantMultiFactorSignInAsync, void(const AZStd::string& username, const AZStd::string& password));
MOCK_METHOD2(PasswordGrantMultiFactorConfirmSignInAsync, void(const AZStd::string& username, const AZStd::string& confirmationCode));
MOCK_METHOD0(DeviceCodeGrantSignInAsync, void());
MOCK_METHOD0(DeviceCodeGrantConfirmSignInAsync, void());
MOCK_METHOD0(RefreshTokensAsync, void());
MOCK_METHOD0(GetAuthenticationTokens, AWSClientAuth::AuthenticationTokens());
MOCK_METHOD0(SignOut, void());
};
class AuthenticationProviderNotificationsBusMock
: public AWSClientAuth::AuthenticationProviderNotificationBus::Handler
{
public:
AuthenticationProviderNotificationsBusMock()
{
AWSClientAuth::AuthenticationProviderNotificationBus::Handler::BusConnect();
}
virtual ~AuthenticationProviderNotificationsBusMock()
{
AWSClientAuth::AuthenticationProviderNotificationBus::Handler::BusDisconnect();
}
MOCK_METHOD1(OnPasswordGrantSingleFactorSignInSuccess, void(const AWSClientAuth::AuthenticationTokens& authenticationToken));
MOCK_METHOD1(OnPasswordGrantSingleFactorSignInFail, void(const AZStd::string& error));
MOCK_METHOD0(OnPasswordGrantMultiFactorSignInSuccess, void());
MOCK_METHOD1(OnPasswordGrantMultiFactorSignInFail, void(const AZStd::string& error));
MOCK_METHOD1(OnPasswordGrantMultiFactorConfirmSignInSuccess, void(const AWSClientAuth::AuthenticationTokens& authenticationToken));
MOCK_METHOD1(OnPasswordGrantMultiFactorConfirmSignInFail, void(const AZStd::string& error));
MOCK_METHOD3(OnDeviceCodeGrantSignInSuccess, void(const AZStd::string& userCode, const AZStd::string& verificationUrl, const int codeExpiresInSeconds));
MOCK_METHOD1(OnDeviceCodeGrantSignInFail, void(const AZStd::string& error));
MOCK_METHOD1(OnDeviceCodeGrantConfirmSignInSuccess, void(const AWSClientAuth::AuthenticationTokens& authenticationToken));
MOCK_METHOD1(OnDeviceCodeGrantConfirmSignInFail, void(const AZStd::string& error));
MOCK_METHOD1(OnRefreshTokensSuccess, void(const AWSClientAuth::AuthenticationTokens& authenticationToken));
MOCK_METHOD1(OnRefreshTokensFail, void(const AZStd::string& error));
MOCK_METHOD1(OnSignOut, void(const AWSClientAuth::ProviderNameEnum& providerName));
};
class AWSCognitoAuthorizationNotificationsBusMock
: public AWSClientAuth::AWSCognitoAuthorizationNotificationBus::Handler
{
public:
AWSCognitoAuthorizationNotificationsBusMock()
{
AWSClientAuth::AWSCognitoAuthorizationNotificationBus::Handler::BusConnect();
}
virtual ~AWSCognitoAuthorizationNotificationsBusMock()
{
AWSClientAuth::AWSCognitoAuthorizationNotificationBus::Handler::BusDisconnect();
}
MOCK_METHOD1(OnRequestAWSCredentialsSuccess, void(const AWSClientAuth::ClientAuthAWSCredentials& awsCredentials));
MOCK_METHOD1(OnRequestAWSCredentialsFail, void(const AZStd::string& error));
};
class AWSCognitoUserManagementNotificationsBusMock
: public AWSClientAuth::AWSCognitoUserManagementNotificationBus::Handler
{
public:
AWSCognitoUserManagementNotificationsBusMock()
{
AWSClientAuth::AWSCognitoUserManagementNotificationBus::Handler::BusConnect();
}
virtual ~AWSCognitoUserManagementNotificationsBusMock()
{
AWSClientAuth::AWSCognitoUserManagementNotificationBus::Handler::BusDisconnect();
}
MOCK_METHOD1(OnEmailSignUpSuccess, void(const AZStd::string& uuid));
MOCK_METHOD1(OnEmailSignUpFail, void(const AZStd::string& error));
MOCK_METHOD1(OnPhoneSignUpSuccess, void(const AZStd::string& uuid));
MOCK_METHOD1(OnPhoneSignUpFail, void(const AZStd::string& error));
MOCK_METHOD0(OnConfirmSignUpSuccess, void());
MOCK_METHOD1(OnConfirmSignUpFail, void(const AZStd::string& error));
MOCK_METHOD0(OnForgotPasswordSuccess, void());
MOCK_METHOD1(OnForgotPasswordFail, void(const AZStd::string& error));
MOCK_METHOD0(OnConfirmForgotPasswordSuccess, void());
MOCK_METHOD1(OnConfirmForgotPasswordFail, void(const AZStd::string& error));
MOCK_METHOD0(OnEnableMFASuccess, void());
MOCK_METHOD1(OnEnableMFAFail, void(const AZStd::string& error));
};
class AWSClientAuthGemAllocatorFixture
: public UnitTest::ScopedAllocatorSetupFixture
, public AZ::ComponentApplicationBus::Handler
, public AWSClientAuth::AWSClientAuthRequestBus::Handler
{
public:
AWSClientAuthGemAllocatorFixture()
{
}
AWSClientAuthGemAllocatorFixture(bool connectClientAuthBus)
{
m_connectClientAuthBus = connectClientAuthBus;
}
virtual ~AWSClientAuthGemAllocatorFixture() = default;
protected:
AZStd::shared_ptr<AZ::SerializeContext> m_serializeContext;
AZStd::unique_ptr<AZ::JsonRegistrationContext> m_registrationContext;
AZStd::shared_ptr<AZ::SettingsRegistryImpl> m_settingsRegistry;
AZStd::unique_ptr<AZStd::string> m_testFolder;
bool m_testFolderCreated = false;
AZStd::unique_ptr<AZ::JobContext> m_jobContext;
AZStd::unique_ptr<AZ::JobCancelGroup> m_jobCancelGroup;
AZStd::unique_ptr<AZ::JobManager> m_jobManager;
std::shared_ptr<CognitoIdentityProviderClientMock> m_cognitoIdentityProviderClientMock;
std::shared_ptr<CognitoIdentityClientMock> m_cognitoIdentityClientMock;
bool m_connectClientAuthBus = true;
AuthenticationProviderNotificationsBusMock m_authenticationProviderNotificationsBusMock;
AWSCognitoAuthorizationNotificationsBusMock m_awsCognitoAuthorizationNotificationsBusMock;
AWSCognitoUserManagementNotificationsBusMock m_awsCognitoUserManagementNotificationsBusMock;
void SetUp() override
{
AZ::AllocatorInstance<AZ::ThreadPoolAllocator>::Create();
AZ::IO::FileIOBase::SetInstance(aznew AZ::IO::LocalFileIO());
m_serializeContext = AZStd::make_unique<AZ::SerializeContext>();
m_registrationContext = AZStd::make_unique<AZ::JsonRegistrationContext>();
AZ::JsonSystemComponent::Reflect(m_registrationContext.get());
m_settingsRegistry = AZStd::make_unique<AZ::SettingsRegistryImpl>();
m_settingsRegistry->SetContext(m_serializeContext.get());
m_settingsRegistry->SetContext(m_registrationContext.get());
AZ::ComponentApplicationBus::Handler::BusConnect();
if (m_connectClientAuthBus)
{
AZ::Interface<IAWSClientAuthRequests>::Register(this);
AWSClientAuth::AWSClientAuthRequestBus::Handler::BusConnect();
}
m_testFolder = AZStd::make_unique<AZStd::string>("AWSClientAuthTest_");
m_testFolder->append(AZ::Uuid::CreateRandom().ToString<AZStd::string>(false, false));
AZ::JobManagerDesc jobManagerDesc;
AZ::JobManagerThreadDesc threadDesc;
m_jobManager.reset(aznew AZ::JobManager(jobManagerDesc));
m_jobCancelGroup.reset(aznew AZ::JobCancelGroup());
jobManagerDesc.m_workerThreads.push_back(threadDesc);
jobManagerDesc.m_workerThreads.push_back(threadDesc);
jobManagerDesc.m_workerThreads.push_back(threadDesc);
m_jobContext.reset(aznew AZ::JobContext(*m_jobManager, *m_jobCancelGroup));
AZ::JobContext::SetGlobalContext(m_jobContext.get());
AWSNativeSDKInit::InitializationManager::InitAwsApi();
m_cognitoIdentityProviderClientMock = std::make_shared<CognitoIdentityProviderClientMock>();
m_cognitoIdentityClientMock = std::make_shared<CognitoIdentityClientMock>();
}
void TearDown() override
{
AZ::JobContext::SetGlobalContext(nullptr);
m_jobContext.reset();
m_jobCancelGroup.reset();
m_jobManager.reset();
m_cognitoIdentityProviderClientMock.reset();
m_cognitoIdentityClientMock.reset();
AWSNativeSDKInit::InitializationManager::Shutdown();
AZ::AllocatorInstance<AZ::ThreadPoolAllocator>::Destroy();
if (m_testFolderCreated)
{
DeleteFolderRecursive(*m_testFolder);
}
m_registrationContext->EnableRemoveReflection();
AZ::JsonSystemComponent::Reflect(m_registrationContext.get());
m_registrationContext->DisableRemoveReflection();
AZ::ComponentApplicationBus::Handler::BusDisconnect();
if (m_connectClientAuthBus)
{
AZ::Interface<IAWSClientAuthRequests>::Unregister(this);
AWSClientAuth::AWSClientAuthRequestBus::Handler::BusDisconnect();
}
m_testFolder.reset();
m_settingsRegistry.reset();
m_serializeContext.reset();
m_registrationContext.reset();
delete AZ::IO::FileIOBase::GetInstance();
AZ::IO::FileIOBase::SetInstance(nullptr);
}
// ComponentApplicationBus overrides. Required by settings registry for json serialization context.
AZ::ComponentApplication* GetApplication() override { return nullptr; }
void RegisterComponentDescriptor(const AZ::ComponentDescriptor*) override { }
void UnregisterComponentDescriptor(const AZ::ComponentDescriptor*) override { }
bool AddEntity(AZ::Entity*) override { return true; }
bool RemoveEntity(AZ::Entity*) override { return true; }
bool DeleteEntity(const AZ::EntityId&) override { return true; }
AZ::Entity* FindEntity(const AZ::EntityId&) override { return nullptr; }
AZ::BehaviorContext* GetBehaviorContext() override { return nullptr; }
const char* GetExecutableFolder() const override { return nullptr; }
const char* GetAppRoot() const override { return nullptr; }
AZ::Debug::DrillerManager* GetDrillerManager() override { return nullptr; }
void EnumerateEntities(const EntityCallback& /*callback*/) override {}
void QueryApplicationType(AZ::ApplicationTypeQuery& /*appType*/) const override {}
AZ::SerializeContext* GetSerializeContext() override
{
return m_serializeContext.get();
}
AZ::JsonRegistrationContext* GetJsonRegistrationContext() override
{
return m_registrationContext.get();
}
// AWSClientAuthBus
std::shared_ptr<Aws::CognitoIdentityProvider::CognitoIdentityProviderClient> GetCognitoIDPClient() override
{
return m_cognitoIdentityProviderClientMock;
}
std::shared_ptr<Aws::CognitoIdentity::CognitoIdentityClient> GetCognitoIdentityClient() override
{
return m_cognitoIdentityClientMock;
}
// TODO Add safety check. Also use pattern to create and remove one file.
static void DeleteFolderRecursive(const AZStd::string& path)
{
auto callback = [&path](const char* filename, bool isFile) -> bool
{
if (isFile)
{
AZStd::string filePath = path;
filePath += '/';
filePath += filename;
AZ::IO::SystemFile::Delete(filePath.c_str());
}
else
{
if (strcmp(filename, ".") != 0 && strcmp(filename, "..") != 0)
{
AZStd::string folderPath = path;
folderPath += '/';
folderPath += filename;
DeleteFolderRecursive(folderPath);
}
}
return true;
};
AZStd::string searchPath = path;
searchPath += "/*";
AZ::IO::SystemFile::FindFiles(searchPath.c_str(), callback);
AZ::IO::SystemFile::DeleteDir(path.c_str());
}
AZStd::string CreateTestFile(AZStd::string_view name, AZStd::string_view content)
{
using namespace AZ::IO;
AZStd::string path = AZStd::string::format("%s/%s/%.*s", m_testFolder->c_str(),
AZ::SettingsRegistryInterface::RegistryFolder, static_cast<int>(name.length()), name.data());
SystemFile file;
if (!file.Open(path.c_str(), SystemFile::OpenMode::SF_OPEN_CREATE | SystemFile::SF_OPEN_CREATE_PATH | SystemFile::SF_OPEN_WRITE_ONLY))
{
AZ_Assert(false, "Unable to open test file for writing: %s", path.c_str());
return path;
}
if (file.Write(content.data(), content.size()) != content.size())
{
AZ_Assert(false, "Unable to write content to test file: %s", path.c_str());
}
m_testFolderCreated = true;
return path;
}
};
}
@@ -0,0 +1,16 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzTest/AzTest.h>
// DO NOT REMOVE. Common place to set the testing hook
AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV);
@@ -0,0 +1,240 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzTest/AzTest.h>
#include <AzTest/Utils.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AWSClientAuthSystemComponent.h>
#include <ResourceMapping/AWSResourceMappingBus.h>
#include <AzCore/Component/Entity.h>
#include <AzFramework/IO/LocalFileIO.h>
#include <AWSClientAuthGemMock.h>
namespace AWSClientAuthUnitTest
{
class AWSClientAuthSystemComponentMock
: public AWSClientAuth::AWSClientAuthSystemComponent
{
public:
using AWSClientAuth::AWSClientAuthSystemComponent::GetCognitoIDPClient;
using AWSClientAuth::AWSClientAuthSystemComponent::GetCognitoIdentityClient;
void InitMock()
{
AWSClientAuth::AWSClientAuthSystemComponent::Init();
}
void ActivateMock()
{
AWSClientAuth::AWSClientAuthSystemComponent::Activate();
}
void DeactivateMock()
{
AWSClientAuth::AWSClientAuthSystemComponent::Deactivate();
}
AWSClientAuthSystemComponentMock()
{
ON_CALL(*this, Init()).WillByDefault(testing::Invoke(this, &AWSClientAuthSystemComponentMock::InitMock));
ON_CALL(*this, Activate()).WillByDefault(testing::Invoke(this, &AWSClientAuthSystemComponentMock::ActivateMock));
ON_CALL(*this, Deactivate()).WillByDefault(testing::Invoke(this, &AWSClientAuthSystemComponentMock::DeactivateMock));
}
MOCK_METHOD0(Init, void());
MOCK_METHOD0(Activate, void());
MOCK_METHOD0(Deactivate, void());
AZStd::vector<AWSClientAuth::ProviderNameEnum> m_enabledProviderNames;
};
class AWSCoreSystemComponentMock
: public AZ::Component
{
public:
AZ_COMPONENT(AWSCoreSystemComponentMock, "{5F48030D-EB59-4820-BC65-69EC7CC6C119}");
static void Reflect(AZ::ReflectContext* context)
{
if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
{
serialize->Class<AWSCoreSystemComponentMock, AZ::Component>()
->Version(0)
;
if (AZ::EditContext* ec = serialize->GetEditContext())
{
ec->Class<AWSCoreSystemComponentMock>("AWSCoreMock", "Adds core support for working with AWS")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System"))
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
;
}
}
}
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{
provided.push_back(AZ_CRC_CE("AWSCoreService"));
}
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
{
AZ_UNUSED(incompatible);
}
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
{
AZ_UNUSED(required);
}
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
{
AZ_UNUSED(dependent);
}
void ActivateMock()
{
AWSCore::AWSCoreNotificationsBus::Broadcast(&AWSCore::AWSCoreNotifications::OnSDKInitialized);
}
AWSCoreSystemComponentMock()
{
ON_CALL(*this, Activate()).WillByDefault(testing::Invoke(this, &AWSCoreSystemComponentMock::ActivateMock));
}
~AWSCoreSystemComponentMock() = default;
MOCK_METHOD0(Init, void());
MOCK_METHOD0(Activate, void());
MOCK_METHOD0(Deactivate, void());
};
}
class AWSResourceMappingRequestBusMock
: public AWSCore::AWSResourceMappingRequestBus::Handler
{
public:
AWSResourceMappingRequestBusMock()
{
AWSCore::AWSResourceMappingRequestBus::Handler::BusConnect();
ON_CALL(*this, GetResourceRegion).WillByDefault(testing::Return("us-east-1"));
}
~AWSResourceMappingRequestBusMock()
{
AWSCore::AWSResourceMappingRequestBus::Handler::BusDisconnect();
}
MOCK_CONST_METHOD0(GetDefaultAccountId, AZStd::string());
MOCK_CONST_METHOD0(GetDefaultRegion, AZStd::string());
MOCK_CONST_METHOD1(GetResourceAccountId, AZStd::string(const AZStd::string& resourceKeyName));
MOCK_CONST_METHOD1(GetResourceNameId, AZStd::string(const AZStd::string& resourceKeyName));
MOCK_CONST_METHOD1(GetResourceRegion, AZStd::string(const AZStd::string& resourceKeyName));
MOCK_CONST_METHOD1(GetResourceType, AZStd::string(const AZStd::string& resourceKeyName));
MOCK_CONST_METHOD1(GetServiceUrlByServiceName, AZStd::string(const AZStd::string& serviceName));
MOCK_CONST_METHOD2(
GetServiceUrlByRESTApiIdAndStage, AZStd::string(const AZStd::string& restApiIdKeyName, const AZStd::string& restApiStageKeyName));
MOCK_METHOD1(ReloadConfigFile, void(bool isReloadingConfigFileName));
};
class AWSClientAuthSystemComponentTest
: public AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture
{
public:
AWSClientAuthSystemComponentTest()
: AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture(false)
{
}
protected:
AZStd::unique_ptr<AZ::ComponentDescriptor> m_componentDescriptor;
AZStd::unique_ptr<AZ::ComponentDescriptor> m_awsCoreComponentDescriptor;
void SetUp() override
{
AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture::SetUp();
m_componentDescriptor.reset(AWSClientAuth::AWSClientAuthSystemComponent::CreateDescriptor());
m_awsCoreComponentDescriptor.reset(AWSClientAuthUnitTest::AWSCoreSystemComponentMock::CreateDescriptor());
m_componentDescriptor->Reflect(m_serializeContext.get());
m_awsCoreComponentDescriptor->Reflect(m_serializeContext.get());
m_entity = aznew AZ::Entity();
m_awsClientAuthSystemsComponent = aznew testing::NiceMock<AWSClientAuthUnitTest::AWSClientAuthSystemComponentMock>();
m_awsCoreSystemsComponent = aznew testing::NiceMock<AWSClientAuthUnitTest::AWSCoreSystemComponentMock>();
m_entity->AddComponent(m_awsCoreSystemsComponent);
m_entity->AddComponent(m_awsClientAuthSystemsComponent);
}
void TearDown() override
{
m_entity->RemoveComponent(m_awsClientAuthSystemsComponent);
m_entity->RemoveComponent(m_awsCoreSystemsComponent);
delete m_awsCoreSystemsComponent;
delete m_awsClientAuthSystemsComponent;
delete m_entity;
m_componentDescriptor.reset();
m_awsCoreComponentDescriptor.reset();
AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture::TearDown();
}
public:
testing::NiceMock<AWSClientAuthUnitTest::AWSClientAuthSystemComponentMock> *m_awsClientAuthSystemsComponent;
testing::NiceMock<AWSClientAuthUnitTest::AWSCoreSystemComponentMock> *m_awsCoreSystemsComponent;
testing::NiceMock<AWSResourceMappingRequestBusMock> m_awsResourceMappingRequestBusMock;
AZ::Entity* m_entity = nullptr;
};
TEST_F(AWSClientAuthSystemComponentTest, ActivateDeactivate_Success)
{
m_awsClientAuthSystemsComponent->m_enabledProviderNames.push_back(AWSClientAuth::ProviderNameEnum::LoginWithAmazon);
m_awsClientAuthSystemsComponent->m_enabledProviderNames.push_back(AWSClientAuth::ProviderNameEnum::AWSCognitoIDP);
testing::Sequence s1, s2;
EXPECT_CALL(*m_awsCoreSystemsComponent, Init()).Times(1).InSequence(s1);
EXPECT_CALL(*m_awsClientAuthSystemsComponent, Init()).Times(1).InSequence(s1);
EXPECT_CALL(*m_awsCoreSystemsComponent, Activate()).Times(1).InSequence(s1);
EXPECT_CALL(m_awsResourceMappingRequestBusMock, GetDefaultRegion()).Times(1).InSequence(s1);
EXPECT_CALL(*m_awsClientAuthSystemsComponent, Activate()).Times(1).InSequence(s1);
EXPECT_CALL(*m_awsClientAuthSystemsComponent, Deactivate()).Times(1).InSequence(s2);
EXPECT_CALL(*m_awsCoreSystemsComponent, Deactivate()).Times(1).InSequence(s2);
// activate component
m_entity->Init();
m_entity->Activate();
// deactivate component
m_entity->Deactivate();
}
TEST_F(AWSClientAuthSystemComponentTest, GetCognitoClients_Success)
{
m_awsClientAuthSystemsComponent->m_enabledProviderNames.push_back(AWSClientAuth::ProviderNameEnum::LoginWithAmazon);
m_awsClientAuthSystemsComponent->m_enabledProviderNames.push_back(AWSClientAuth::ProviderNameEnum::AWSCognitoIDP);
// activate component
m_entity->Init();
m_entity->Activate();
EXPECT_TRUE(AZ::Interface<IAWSClientAuthRequests>::Get()->GetCognitoIdentityClient() != nullptr);
EXPECT_TRUE(AZ::Interface<IAWSClientAuthRequests>::Get()->GetCognitoIDPClient() != nullptr);
// deactivate component
m_entity->Deactivate();
}
@@ -0,0 +1,289 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzTest/AzTest.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <Authentication/AWSCognitoAuthenticationProvider.h>
#include <AWSClientAuthGemMock.h>
#include <aws/core/utils/Outcome.h>
#include <aws/cognito-idp/CognitoIdentityProviderErrors.h>
namespace AWSClientAuthUnitTest
{
class AWSCognitoAuthenticationProviderrLocalMock
: public AWSClientAuth::AWSCognitoAuthenticationProvider
{
public:
using AWSClientAuth::AWSCognitoAuthenticationProvider::m_settings;
};
}
class AWSCognitoAuthenticationProviderTest
: public AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture
, public AWSCore::AWSCoreRequestBus::Handler
{
void SetUp() override
{
AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture::SetUp();
AWSClientAuth::AWSCognitoProviderSetting::Reflect(*m_serializeContext);
AZStd::string path = AZStd::string::format("%s/%s/authenticationProvider.setreg",
m_testFolder->c_str(), AZ::SettingsRegistryInterface::RegistryFolder);
CreateTestFile("authenticationProvider.setreg"
, R"({
"AWS":
{
"CognitoIDP":
{
"AppClientId": "TestCognitoClientId"
}
}
})");
m_settingsRegistry->MergeSettingsFile(path, AZ::SettingsRegistryInterface::Format::JsonMergePatch, {});
m_cognitoAuthenticationProviderMock.Initialize(m_settingsRegistry);
AWSCore::AWSCoreRequestBus::Handler::BusConnect();
}
void TearDown() override
{
AWSCore::AWSCoreRequestBus::Handler::BusDisconnect();
AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture::TearDown();
}
// AWSCore::AWSCoreRequestBus overrides
AZ::JobContext* GetDefaultJobContext() override
{
return m_jobContext.get();
}
// Returns the default client configuration setting to use as a starting point in AWS requests
AWSCore::AwsApiJobConfig* GetDefaultConfig() override
{
return nullptr;
}
public:
AWSClientAuthUnitTest::AWSCognitoAuthenticationProviderrLocalMock m_cognitoAuthenticationProviderMock;
void AssertAuthenticationTokensPopulated()
{
AZ_Assert(
m_cognitoAuthenticationProviderMock.GetAuthenticationTokens().GetAccessToken() ==
AWSClientAuthUnitTest::TEST_ACCESS_TOKEN,
"Access token expected to match");
AZ_Assert(
m_cognitoAuthenticationProviderMock.GetAuthenticationTokens().GetOpenIdToken() ==
AWSClientAuthUnitTest::TEST_ID_TOKEN,
"Id token expected to match");
AZ_Assert(
m_cognitoAuthenticationProviderMock.GetAuthenticationTokens().GetRefreshToken() ==
AWSClientAuthUnitTest::TEST_REFRESH_TOKEN,
"Refresh token expected to match");
AZ_Assert(
m_cognitoAuthenticationProviderMock.GetAuthenticationTokens().GetTokensExpireTimeSeconds() != 0,
"Access token expiry expected to be set");
AZ_Assert(m_cognitoAuthenticationProviderMock.GetAuthenticationTokens().AreTokensValid(), "Tokens expected to be valid");
}
void AssertAuthenticationTokensEmpty()
{
AZ_Assert(
m_cognitoAuthenticationProviderMock.GetAuthenticationTokens().GetAccessToken() == "", "Access token expected to be empty");
AZ_Assert(m_cognitoAuthenticationProviderMock.GetAuthenticationTokens().GetOpenIdToken() == "", "Id token expected to be empty");
AZ_Assert(
m_cognitoAuthenticationProviderMock.GetAuthenticationTokens().GetRefreshToken() == "", "Refresh token expected to be empty");
AZ_Assert(
m_cognitoAuthenticationProviderMock.GetAuthenticationTokens().GetTokensExpireTimeSeconds() == 0,
"Access token expiry expected to be 0");
AZ_Assert(!m_cognitoAuthenticationProviderMock.GetAuthenticationTokens().AreTokensValid(), "Tokens expected to be invalid");
}
};
TEST_F(AWSCognitoAuthenticationProviderTest, Initialize_Success)
{
AWSClientAuthUnitTest::AWSCognitoAuthenticationProviderrLocalMock mock;
ASSERT_TRUE(mock.Initialize(m_settingsRegistry));
ASSERT_EQ(mock.m_settings->m_appClientId, AWSClientAuthUnitTest::TEST_COGNITO_CLIENTID);
}
TEST_F(AWSCognitoAuthenticationProviderTest, PasswordGrantSingleFactorSignInAsync_Success)
{
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, InitiateAuth(testing::_)).Times(1);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnPasswordGrantSingleFactorSignInSuccess(testing::_)).Times(1);
m_cognitoAuthenticationProviderMock.PasswordGrantSingleFactorSignInAsync(AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD);
AssertAuthenticationTokensPopulated();
}
TEST_F(AWSCognitoAuthenticationProviderTest, PasswordGrantSingleFactorSignInAsync_Fail_InitiateAuthError)
{
Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error;
error.SetExceptionName(AWSClientAuthUnitTest::TEST_EXCEPTION);
Aws::CognitoIdentityProvider::Model::InitiateAuthOutcome outcome(error);
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, InitiateAuth(testing::_)).Times(1)
.WillOnce(testing::Return(outcome));
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnPasswordGrantSingleFactorSignInSuccess(testing::_)).Times(0);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnPasswordGrantSingleFactorSignInFail(testing::_)).Times(1);
m_cognitoAuthenticationProviderMock.PasswordGrantSingleFactorSignInAsync(AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD);
AssertAuthenticationTokensEmpty();
}
TEST_F(AWSCognitoAuthenticationProviderTest, PasswordGrantSingleFactorSignInAsync_Fail_IncorrectChallengeTypeError)
{
Aws::CognitoIdentityProvider::Model::InitiateAuthResult result;
result.SetChallengeName(Aws::CognitoIdentityProvider::Model::ChallengeNameType::CUSTOM_CHALLENGE);
Aws::CognitoIdentityProvider::Model::InitiateAuthOutcome outcome(result);
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, InitiateAuth(testing::_)).Times(1)
.WillOnce(testing::Return(outcome));
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnPasswordGrantSingleFactorSignInSuccess(testing::_)).Times(0);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnPasswordGrantSingleFactorSignInFail(testing::_)).Times(1);
m_cognitoAuthenticationProviderMock.PasswordGrantSingleFactorSignInAsync(AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD);
}
TEST_F(AWSCognitoAuthenticationProviderTest, PasswordGrantMultiFactorSignInAsync_Success)
{
Aws::CognitoIdentityProvider::Model::InitiateAuthResult result;
result.SetChallengeName(Aws::CognitoIdentityProvider::Model::ChallengeNameType::SMS_MFA);
result.SetSession(AWSClientAuthUnitTest::TEST_SESSION);
Aws::CognitoIdentityProvider::Model::InitiateAuthOutcome outcome(result);
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, InitiateAuth(testing::_)).Times(1)
.WillOnce(testing::Return(outcome));
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnPasswordGrantMultiFactorSignInSuccess()).Times(1);
m_cognitoAuthenticationProviderMock.PasswordGrantMultiFactorSignInAsync(AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD);
}
TEST_F(AWSCognitoAuthenticationProviderTest, PasswordGrantMultiFactorSignInAsync_Fail_InitiateAuthError)
{
Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error;
error.SetExceptionName(AWSClientAuthUnitTest::TEST_EXCEPTION);
Aws::CognitoIdentityProvider::Model::InitiateAuthOutcome outcome(error);
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, InitiateAuth(testing::_)).Times(1)
.WillOnce(testing::Return(outcome));
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnPasswordGrantMultiFactorSignInSuccess()).Times(0);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnPasswordGrantMultiFactorSignInFail(testing::_)).Times(1);
m_cognitoAuthenticationProviderMock.PasswordGrantMultiFactorSignInAsync(AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD);
}
TEST_F(AWSCognitoAuthenticationProviderTest, PasswordGrantMultiFactorSignInAsync_Fail_IncorrectChallengeTypeError)
{
Aws::CognitoIdentityProvider::Model::InitiateAuthResult result;
result.SetChallengeName(Aws::CognitoIdentityProvider::Model::ChallengeNameType::CUSTOM_CHALLENGE);
Aws::CognitoIdentityProvider::Model::InitiateAuthOutcome outcome(result);
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, InitiateAuth(testing::_)).Times(1)
.WillOnce(testing::Return(outcome));
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnPasswordGrantMultiFactorSignInSuccess()).Times(0);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnPasswordGrantMultiFactorSignInFail(testing::_)).Times(1);
m_cognitoAuthenticationProviderMock.PasswordGrantMultiFactorSignInAsync(AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD);
}
TEST_F(AWSCognitoAuthenticationProviderTest, PasswordGrantMultiFactorConfirmSignInAsync_Success)
{
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, RespondToAuthChallenge(testing::_)).Times(1);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnPasswordGrantMultiFactorConfirmSignInSuccess(testing::_)).Times(1);
m_cognitoAuthenticationProviderMock.PasswordGrantMultiFactorConfirmSignInAsync(AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD);
AssertAuthenticationTokensPopulated();
}
TEST_F(AWSCognitoAuthenticationProviderTest, PasswordGrantMultiFactorConfirmSignInAsync_Fail_RespondToAuthChallengeError)
{
Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error;
error.SetExceptionName(AWSClientAuthUnitTest::TEST_EXCEPTION);
Aws::CognitoIdentityProvider::Model::RespondToAuthChallengeOutcome outcome(error);
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, RespondToAuthChallenge(testing::_)).Times(1)
.WillOnce(testing::Return(outcome));
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnPasswordGrantMultiFactorConfirmSignInSuccess(testing::_)).Times(0);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnPasswordGrantMultiFactorConfirmSignInFail(testing::_)).Times(1);
m_cognitoAuthenticationProviderMock.PasswordGrantMultiFactorConfirmSignInAsync(AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD);
AssertAuthenticationTokensEmpty();
}
TEST_F(AWSCognitoAuthenticationProviderTest, RefreshTokensAsync_Success)
{
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, InitiateAuth(testing::_)).Times(1);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnRefreshTokensSuccess(testing::_)).Times(1);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnRefreshTokensFail(testing::_)).Times(0);
m_cognitoAuthenticationProviderMock.RefreshTokensAsync();
AssertAuthenticationTokensPopulated();
}
TEST_F(AWSCognitoAuthenticationProviderTest, RefreshTokensAsync_Fail_InitiateAuthError)
{
Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error;
error.SetExceptionName(AWSClientAuthUnitTest::TEST_EXCEPTION);
Aws::CognitoIdentityProvider::Model::InitiateAuthOutcome outcome(error);
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, InitiateAuth(testing::_)).Times(1)
.WillOnce(testing::Return(outcome));
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnRefreshTokensSuccess(testing::_)).Times(0);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnRefreshTokensFail(testing::_)).Times(1);
m_cognitoAuthenticationProviderMock.RefreshTokensAsync();
AssertAuthenticationTokensEmpty();
}
TEST_F(AWSCognitoAuthenticationProviderTest, RefreshTokensAsync_Fail_IncorrectChallengeType)
{
Aws::CognitoIdentityProvider::Model::InitiateAuthResult result;
result.SetChallengeName(Aws::CognitoIdentityProvider::Model::ChallengeNameType::CUSTOM_CHALLENGE);
Aws::CognitoIdentityProvider::Model::InitiateAuthOutcome outcome(result);
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, InitiateAuth(testing::_)).Times(1)
.WillOnce(testing::Return(outcome));
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnRefreshTokensSuccess(testing::_)).Times(0);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnRefreshTokensFail(testing::_)).Times(1);
m_cognitoAuthenticationProviderMock.RefreshTokensAsync();
AssertAuthenticationTokensEmpty();
}
TEST_F(AWSCognitoAuthenticationProviderTest, SignOut_Success)
{
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, InitiateAuth(testing::_)).Times(1);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnPasswordGrantSingleFactorSignInSuccess(testing::_)).Times(1);
m_cognitoAuthenticationProviderMock.PasswordGrantSingleFactorSignInAsync(AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD);
AssertAuthenticationTokensPopulated();
m_cognitoAuthenticationProviderMock.SignOut();
AssertAuthenticationTokensEmpty();
}
TEST_F(AWSCognitoAuthenticationProviderTest, Initialize_Fail_EmptyRegistry)
{
AWSClientAuthUnitTest::AWSCognitoAuthenticationProviderrLocalMock mock;
AZStd::shared_ptr<AZ::SettingsRegistryImpl> registry = AZStd::make_shared<AZ::SettingsRegistryImpl>();
registry->SetContext(m_serializeContext.get());
ASSERT_FALSE(mock.Initialize(registry));
ASSERT_EQ(mock.m_settings->m_appClientId, "");
registry.reset();
// Restore
mock.Initialize(m_settingsRegistry);
}
@@ -0,0 +1,294 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzTest/AzTest.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzCore/std/utils.h>
#include <Authentication/AuthenticationProviderManager.h>
#include <Authentication/AWSCognitoAuthenticationProvider.h>
#include <Authentication/LWAAuthenticationProvider.h>
#include <Authentication/AuthenticationTokens.h>
#include <AWSClientAuthGemMock.h>
namespace AWSClientAuthUnitTest
{
class AuthenticationProviderManagerLocalMock
: public AWSClientAuth::AuthenticationProviderManager
{
public:
using AWSClientAuth::AuthenticationProviderManager::m_authenticationProvidersMap;
using AWSClientAuth::AuthenticationProviderManager::Initialize;
using AWSClientAuth::AuthenticationProviderManager::PasswordGrantSingleFactorSignInAsync;
using AWSClientAuth::AuthenticationProviderManager::PasswordGrantMultiFactorSignInAsync;
using AWSClientAuth::AuthenticationProviderManager::PasswordGrantMultiFactorConfirmSignInAsync;
using AWSClientAuth::AuthenticationProviderManager::DeviceCodeGrantSignInAsync;
using AWSClientAuth::AuthenticationProviderManager::DeviceCodeGrantConfirmSignInAsync;
using AWSClientAuth::AuthenticationProviderManager::RefreshTokensAsync;
using AWSClientAuth::AuthenticationProviderManager::GetTokensWithRefreshAsync;
using AWSClientAuth::AuthenticationProviderManager::GetAuthenticationTokens;
using AWSClientAuth::AuthenticationProviderManager::SignOut;
using AWSClientAuth::AuthenticationProviderManager::IsSignedIn;
AZStd::unique_ptr<AWSClientAuth::AuthenticationProviderInterface> CreateAuthenticationProviderObjectMock(const AWSClientAuth::ProviderNameEnum& providerName)
{
auto providerObject = AWSClientAuth::AuthenticationProviderManager::CreateAuthenticationProviderObject(providerName);
providerObject.reset();
return AZStd::make_unique<testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>>();
}
AuthenticationProviderManagerLocalMock()
{
ON_CALL(*this, CreateAuthenticationProviderObject(testing::_)).WillByDefault(
testing::Invoke(this, &AuthenticationProviderManagerLocalMock::CreateAuthenticationProviderObjectMock));
}
MOCK_METHOD1(CreateAuthenticationProviderObject, AZStd::unique_ptr<AWSClientAuth::AuthenticationProviderInterface>(const AWSClientAuth::ProviderNameEnum&));
};
}
class AuthenticationProviderManagerTest
: public AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture
{
protected:
void SetUp() override
{
AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture::SetUp();
AWSClientAuth::AWSCognitoProviderSetting::Reflect(*m_serializeContext);
AWSClientAuth::LWAProviderSetting::Reflect(*m_serializeContext);
AWSClientAuth::GoogleProviderSetting::Reflect(*m_serializeContext);
m_settingspath = AZStd::string::format("%s/%s/authenticationProvider.setreg",
m_testFolder->c_str(), AZ::SettingsRegistryInterface::RegistryFolder);
CreateTestFile("authenticationProvider.setreg"
, R"({
"AWS":
{
"LoginWithAmazon":
{
"AppClientId": "TestLWAClientId",
"GrantType": "device_code",
"Scope": "profile",
"ResponseType": "device_code",
"OAuthCodeURL": "https://api.amazon.com/auth/o2/create/codepair",
"OAuthTokensURL": "https://oauth2.googleapis.com/token"
},
"Google":
{
"AppClientId": "TestGoogleClientId",
"ClientSecret": "123",
"GrantType": "urn:ietf:params:oauth:grant-type:device_code",
"Scope": "profile",
"OAuthCodeURL": "https://oauth2.googleapis.com/device/code",
"OAuthTokensURL": "https://oauth2.googleapis.com/token"
},
"CognitoIDP":
{
"AppClientId": "TestCognitoClientId"
}
}
})");
m_mockController = AZStd::make_unique<testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderManagerLocalMock>>();
}
void TearDown() override
{
m_mockController.reset();
AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture::TearDown();
}
public:
AZStd::unique_ptr<testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderManagerLocalMock>> m_mockController;
AZStd::string m_settingspath;
AZStd::vector<AWSClientAuth::ProviderNameEnum> m_enabledProviderNames {AWSClientAuth::ProviderNameEnum::AWSCognitoIDP,
AWSClientAuth::ProviderNameEnum::LoginWithAmazon, AWSClientAuth::ProviderNameEnum::Google};
};
TEST_F(AuthenticationProviderManagerTest, Initialize_Success)
{
ASSERT_TRUE(m_mockController->Initialize(m_enabledProviderNames, m_settingspath));
ASSERT_TRUE(m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::AWSCognitoIDP] != nullptr);
}
TEST_F(AuthenticationProviderManagerTest, PasswordGrantSingleFactorSignInAsync_Success)
{
m_mockController->Initialize(m_enabledProviderNames, m_settingspath);
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock> *cognitoProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::AWSCognitoIDP].get();
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock> *lwaProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::LoginWithAmazon].get();
EXPECT_CALL(*cognitoProviderMock, PasswordGrantSingleFactorSignInAsync(testing::_, testing::_)).Times(1);
m_mockController->PasswordGrantSingleFactorSignInAsync(AWSClientAuth::ProviderNameEnum::AWSCognitoIDP, AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD);
cognitoProviderMock = nullptr;
}
TEST_F(AuthenticationProviderManagerTest, PasswordGrantSingleFactorSignInAsync_Fail_NonConfiguredProviderError)
{
AZ_TEST_START_TRACE_SUPPRESSION;
m_mockController->PasswordGrantSingleFactorSignInAsync(AWSClientAuth::ProviderNameEnum::Apple, AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD);
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
}
TEST_F(AuthenticationProviderManagerTest, PasswordGrantMultiFactorSignInAsync_Success)
{
m_mockController->Initialize(m_enabledProviderNames, m_settingspath);
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>* cognitoProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::AWSCognitoIDP].get();
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>* lwaProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::LoginWithAmazon].get();
EXPECT_CALL(*cognitoProviderMock, PasswordGrantMultiFactorSignInAsync(testing::_, testing::_)).Times(1);
m_mockController->PasswordGrantMultiFactorSignInAsync(AWSClientAuth::ProviderNameEnum::AWSCognitoIDP, AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD);
EXPECT_CALL(*lwaProviderMock, PasswordGrantMultiFactorSignInAsync(testing::_, testing::_)).Times(1);
m_mockController->PasswordGrantMultiFactorSignInAsync(AWSClientAuth::ProviderNameEnum::LoginWithAmazon, AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD);
cognitoProviderMock = nullptr;
}
TEST_F(AuthenticationProviderManagerTest, PasswordGrantMultiFactorConfirmSignInAsync_Success)
{
m_mockController->Initialize(m_enabledProviderNames, m_settingspath);
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock> *cognitoProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::AWSCognitoIDP].get();
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock> *lwaProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::LoginWithAmazon].get();
EXPECT_CALL(*cognitoProviderMock, PasswordGrantMultiFactorConfirmSignInAsync(testing::_, testing::_)).Times(1);
m_mockController->PasswordGrantMultiFactorConfirmSignInAsync(AWSClientAuth::ProviderNameEnum::AWSCognitoIDP, AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD);
EXPECT_CALL(*lwaProviderMock, PasswordGrantMultiFactorConfirmSignInAsync(testing::_, testing::_)).Times(1);
m_mockController->PasswordGrantMultiFactorConfirmSignInAsync(AWSClientAuth::ProviderNameEnum::LoginWithAmazon, AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD);
cognitoProviderMock = nullptr;
}
TEST_F(AuthenticationProviderManagerTest, DeviceCodeGrantSignInAsync_Success)
{
m_mockController->Initialize(m_enabledProviderNames, m_settingspath);
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>* cognitoProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::AWSCognitoIDP].get();
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>* lwaProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::LoginWithAmazon].get();
EXPECT_CALL(*cognitoProviderMock, DeviceCodeGrantSignInAsync()).Times(1);
m_mockController->DeviceCodeGrantSignInAsync(AWSClientAuth::ProviderNameEnum::AWSCognitoIDP);
EXPECT_CALL(*lwaProviderMock, DeviceCodeGrantSignInAsync()).Times(1);
m_mockController->DeviceCodeGrantSignInAsync(AWSClientAuth::ProviderNameEnum::LoginWithAmazon);
cognitoProviderMock = nullptr;
}
TEST_F(AuthenticationProviderManagerTest, DeviceCodeGrantConfirmSignInAsync_Success)
{
m_mockController->Initialize(m_enabledProviderNames, m_settingspath);
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>* cognitoProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::AWSCognitoIDP].get();
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>* lwaProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::LoginWithAmazon].get();
EXPECT_CALL(*cognitoProviderMock, DeviceCodeGrantConfirmSignInAsync()).Times(1);
m_mockController->DeviceCodeGrantConfirmSignInAsync(AWSClientAuth::ProviderNameEnum::AWSCognitoIDP);
EXPECT_CALL(*lwaProviderMock, DeviceCodeGrantConfirmSignInAsync()).Times(1);
m_mockController->DeviceCodeGrantConfirmSignInAsync(AWSClientAuth::ProviderNameEnum::LoginWithAmazon);
cognitoProviderMock = nullptr;
}
TEST_F(AuthenticationProviderManagerTest, RefreshTokenAsync_Success)
{
m_mockController->Initialize(m_enabledProviderNames, m_settingspath);
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock> *cognitoProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::AWSCognitoIDP].get();
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock> *lwaProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::LoginWithAmazon].get();
EXPECT_CALL(*cognitoProviderMock, RefreshTokensAsync()).Times(1);
m_mockController->RefreshTokensAsync(AWSClientAuth::ProviderNameEnum::AWSCognitoIDP);
EXPECT_CALL(*lwaProviderMock, RefreshTokensAsync()).Times(1);
m_mockController->RefreshTokensAsync(AWSClientAuth::ProviderNameEnum::LoginWithAmazon);
cognitoProviderMock = nullptr;
}
TEST_F(AuthenticationProviderManagerTest, GetTokensWithRefreshAsync_ValidToken_Success)
{
m_mockController->Initialize(m_enabledProviderNames, m_settingspath);
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>* cognitoProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::AWSCognitoIDP].get();
AWSClientAuth::AuthenticationTokens tokens(
AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN,
AWSClientAuth::ProviderNameEnum::AWSCognitoIDP, 600);
EXPECT_CALL(*cognitoProviderMock, GetAuthenticationTokens()).Times(1).WillOnce(testing::Return(tokens));
EXPECT_CALL(*cognitoProviderMock, RefreshTokensAsync()).Times(0);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnRefreshTokensSuccess(testing::_)).Times(1);
m_mockController->GetTokensWithRefreshAsync(AWSClientAuth::ProviderNameEnum::AWSCognitoIDP);
cognitoProviderMock = nullptr;
}
TEST_F(AuthenticationProviderManagerTest, GetTokensWithRefreshAsync_InvalidToken_Success)
{
m_mockController->Initialize(m_enabledProviderNames, m_settingspath);
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>* cognitoProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::AWSCognitoIDP].get();
AWSClientAuth::AuthenticationTokens tokens;
EXPECT_CALL(*cognitoProviderMock, GetAuthenticationTokens()).Times(1).WillOnce(testing::Return(tokens));
EXPECT_CALL(*cognitoProviderMock, RefreshTokensAsync()).Times(1);
m_mockController->GetTokensWithRefreshAsync(AWSClientAuth::ProviderNameEnum::AWSCognitoIDP);
cognitoProviderMock = nullptr;
}
TEST_F(AuthenticationProviderManagerTest, GetTokens_Success)
{
m_mockController->Initialize(m_enabledProviderNames, m_settingspath);
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>* cognitoProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::AWSCognitoIDP].get();
AWSClientAuth::AuthenticationTokens tokens(
AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN,
AWSClientAuth::ProviderNameEnum::AWSCognitoIDP, 60);
EXPECT_CALL(*cognitoProviderMock, GetAuthenticationTokens()).Times(1).WillOnce(testing::Return(tokens));
m_mockController->GetAuthenticationTokens(AWSClientAuth::ProviderNameEnum::AWSCognitoIDP);
cognitoProviderMock = nullptr;
}
TEST_F(AuthenticationProviderManagerTest, IsSignedIn_Success)
{
m_mockController->Initialize(m_enabledProviderNames, m_settingspath);
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>* cognitoProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::AWSCognitoIDP].get();
AWSClientAuth::AuthenticationTokens tokens(
AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN,
AWSClientAuth::ProviderNameEnum::AWSCognitoIDP, 60);
EXPECT_CALL(*cognitoProviderMock, GetAuthenticationTokens()).Times(1).WillOnce(testing::Return(tokens));
m_mockController->IsSignedIn(AWSClientAuth::ProviderNameEnum::AWSCognitoIDP);
cognitoProviderMock = nullptr;
}
TEST_F(AuthenticationProviderManagerTest, SignOut_Success)
{
m_mockController->Initialize(m_enabledProviderNames, m_settingspath);
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>* googleProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::Google].get();
EXPECT_CALL(*googleProviderMock, SignOut()).Times(1);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnSignOut(testing::_)).Times(1);
m_mockController->SignOut(AWSClientAuth::ProviderNameEnum::Google);
googleProviderMock = nullptr;
}
TEST_F(AuthenticationProviderManagerTest, Initialize_Fail_InvalidPath)
{
AZ_TEST_START_TRACE_SUPPRESSION;
ASSERT_FALSE(m_mockController->Initialize(m_enabledProviderNames, ""));
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
}
@@ -0,0 +1,135 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzTest/AzTest.h>
#include <AzCore/Debug/Trace.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <Authentication/GoogleAuthenticationProvider.h>
#include <AWSClientAuthGemMock.h>
namespace AWSClientAuthUnitTest
{
class GoogleAuthenticationProviderLocalMock
: public AWSClientAuth::GoogleAuthenticationProvider
{
public:
using AWSClientAuth::GoogleAuthenticationProvider::m_settings;
};
}
class GoogleAuthenticationProviderTest
: public AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture
{
void SetUp() override
{
AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture::SetUp();
AWSClientAuth::GoogleProviderSetting::Reflect(*m_serializeContext);
AZStd::string path = AZStd::string::format("%s/%s/awsCognitoAuthorization.setreg",
m_testFolder->c_str(), AZ::SettingsRegistryInterface::RegistryFolder);
CreateTestFile("awsCognitoAuthorization.setreg"
, R"({"AWS":
{
"Google":
{
"AppClientId": "TestGoogleClientId",
"ClientSecret": "TestClientSecret",
"GrantType": "urn:ietf:params:oauth:grant-type:device_code",
"Scope": "profile",
"OAuthCodeURL": "https://oauth2.googleapis.com/device/code",
"OAuthTokensURL": "https://oauth2.googleapis.com/token"
}
}
})");
m_settingsRegistry->MergeSettingsFile(path, AZ::SettingsRegistryInterface::Format::JsonMergePatch, {});
m_googleAuthenticationProviderLocalMock.Initialize(m_settingsRegistry);
}
void TearDown() override
{
AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture::TearDown();
}
public:
AWSClientAuthUnitTest::GoogleAuthenticationProviderLocalMock m_googleAuthenticationProviderLocalMock;
AWSClientAuthUnitTest::HttpRequestorRequestBusMock m_httpRequestorRequestBusMock;
};
TEST_F(GoogleAuthenticationProviderTest, Initialize_Success)
{
AWSClientAuthUnitTest::GoogleAuthenticationProviderLocalMock mock;
ASSERT_TRUE(mock.Initialize(m_settingsRegistry));
ASSERT_EQ(mock.m_settings->m_appClientId, "TestGoogleClientId");
}
TEST_F(GoogleAuthenticationProviderTest, DeviceCodeGrantSignInAsync_Success)
{
EXPECT_CALL(m_httpRequestorRequestBusMock, AddRequestWithHeadersAndBody(testing::_, testing::_, testing::_, testing::_, testing::_)).Times(1);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnDeviceCodeGrantSignInSuccess(testing::_, testing::_, testing::_)).Times(1);
m_googleAuthenticationProviderLocalMock.DeviceCodeGrantSignInAsync();
}
TEST_F(GoogleAuthenticationProviderTest, DeviceCodeGrantSignInAsync_Fail_RequestHttpError)
{
EXPECT_CALL(m_httpRequestorRequestBusMock, AddRequestWithHeadersAndBody(testing::_, testing::_, testing::_, testing::_, testing::_)).Times(1)
.WillOnce(testing::Invoke(&m_httpRequestorRequestBusMock, &AWSClientAuthUnitTest::HttpRequestorRequestBusMock::AddRequestWithHeadersAndBodyError));
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnDeviceCodeGrantSignInSuccess(testing::_, testing::_, testing::_)).Times(0);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnDeviceCodeGrantSignInFail(testing::_)).Times(1);
m_googleAuthenticationProviderLocalMock.DeviceCodeGrantSignInAsync();
}
TEST_F(GoogleAuthenticationProviderTest, DeviceCodeGrantConfirmAsync_Success)
{
EXPECT_CALL(m_httpRequestorRequestBusMock, AddRequestWithHeadersAndBody(testing::_, testing::_, testing::_, testing::_, testing::_)).Times(1);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnDeviceCodeGrantConfirmSignInSuccess(testing::_)).Times(1);
m_googleAuthenticationProviderLocalMock.DeviceCodeGrantConfirmSignInAsync();
}
TEST_F(GoogleAuthenticationProviderTest, DeviceCodeGrantConfirmSignInAsync_Fail_RequestHttpError)
{
EXPECT_CALL(m_httpRequestorRequestBusMock, AddRequestWithHeadersAndBody(testing::_, testing::_, testing::_, testing::_, testing::_)).Times(1)
.WillOnce(testing::Invoke(&m_httpRequestorRequestBusMock, &AWSClientAuthUnitTest::HttpRequestorRequestBusMock::AddRequestWithHeadersAndBodyError));
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnDeviceCodeGrantConfirmSignInSuccess(testing::_)).Times(0);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnDeviceCodeGrantConfirmSignInFail(testing::_)).Times(1);
m_googleAuthenticationProviderLocalMock.DeviceCodeGrantConfirmSignInAsync();
}
TEST_F(GoogleAuthenticationProviderTest, RefreshTokensAsync_Success)
{
EXPECT_CALL(m_httpRequestorRequestBusMock, AddRequestWithHeadersAndBody(testing::_, testing::_, testing::_, testing::_, testing::_)).Times(1);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnRefreshTokensSuccess(testing::_)).Times(1);
m_googleAuthenticationProviderLocalMock.RefreshTokensAsync();
}
TEST_F(GoogleAuthenticationProviderTest, RefreshTokensAsync_Fail_RequestHttpError)
{
EXPECT_CALL(m_httpRequestorRequestBusMock, AddRequestWithHeadersAndBody(testing::_, testing::_, testing::_, testing::_, testing::_)).Times(1)
.WillOnce(testing::Invoke(&m_httpRequestorRequestBusMock, &AWSClientAuthUnitTest::HttpRequestorRequestBusMock::AddRequestWithHeadersAndBodyError));
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnRefreshTokensSuccess(testing::_)).Times(0);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnRefreshTokensFail(testing::_)).Times(1);
m_googleAuthenticationProviderLocalMock.RefreshTokensAsync();
}
TEST_F(GoogleAuthenticationProviderTest, Initialize_Fail_EmptyRegistry)
{
AZStd::shared_ptr<AZ::SettingsRegistryImpl> registry = AZStd::make_shared<AZ::SettingsRegistryImpl>();
registry->SetContext(m_serializeContext.get());
AWSClientAuthUnitTest::GoogleAuthenticationProviderLocalMock mock;
ASSERT_FALSE(mock.Initialize(registry));
ASSERT_EQ(mock.m_settings->m_appClientId, "");
registry.reset();
// Restore
mock.Initialize(m_settingsRegistry);
}
@@ -0,0 +1,135 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzTest/AzTest.h>
#include <AzCore/Debug/Trace.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <Authentication/LWAAuthenticationProvider.h>
#include <AWSClientAuthGemMock.h>
namespace AWSClientAuthUnitTest
{
class LWAAuthenticationProviderLocalMock
: public AWSClientAuth::LWAAuthenticationProvider
{
public:
using AWSClientAuth::LWAAuthenticationProvider::m_settings;
};
}
class LWAAuthenticationProviderTest
: public AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture
{
void SetUp() override
{
AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture::SetUp();
AWSClientAuth::LWAProviderSetting::Reflect(*m_serializeContext);
AZStd::string path = AZStd::string::format("%s/%s/awsCognitoAuthorization.setreg",
m_testFolder->c_str(), AZ::SettingsRegistryInterface::RegistryFolder);
CreateTestFile("awsCognitoAuthorization.setreg"
, R"({"AWS":
{
"LoginWithAmazon":
{
"AppClientId": "TestLWAClientId",
"GrantType": "device_code",
"Scope": "profile",
"ResponseType": "device_code",
"OAuthCodeURL": "https://api.amazon.com/auth/o2/create/codepair",
"OAuthTokensURL": "https://oauth2.googleapis.com/token"
}
}
})");
m_settingsRegistry->MergeSettingsFile(path, AZ::SettingsRegistryInterface::Format::JsonMergePatch, {});
m_lwaAuthenticationProviderLocalMock.Initialize(m_settingsRegistry);
}
void TearDown() override
{
AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture::TearDown();
}
public:
AWSClientAuthUnitTest::LWAAuthenticationProviderLocalMock m_lwaAuthenticationProviderLocalMock;
AWSClientAuthUnitTest::HttpRequestorRequestBusMock m_httpRequestorRequestBusMock;
};
TEST_F(LWAAuthenticationProviderTest, Initialize_Success)
{
AWSClientAuthUnitTest::LWAAuthenticationProviderLocalMock mock;
ASSERT_TRUE(mock.Initialize(m_settingsRegistry));
ASSERT_EQ(mock.m_settings->m_appClientId, "TestLWAClientId");
}
TEST_F(LWAAuthenticationProviderTest, DeviceCodeGrantSignInAsync_Success)
{
EXPECT_CALL(m_httpRequestorRequestBusMock, AddRequestWithHeadersAndBody(testing::_, testing::_, testing::_, testing::_, testing::_)).Times(1);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnDeviceCodeGrantSignInSuccess(testing::_, testing::_, testing::_)).Times(1);
m_lwaAuthenticationProviderLocalMock.DeviceCodeGrantSignInAsync();
}
TEST_F(LWAAuthenticationProviderTest, DeviceCodeGrantSignInAsync_RequestHttpError)
{
EXPECT_CALL(m_httpRequestorRequestBusMock, AddRequestWithHeadersAndBody(testing::_, testing::_, testing::_, testing::_, testing::_)).Times(1)
.WillOnce(testing::Invoke(&m_httpRequestorRequestBusMock, &AWSClientAuthUnitTest::HttpRequestorRequestBusMock::AddRequestWithHeadersAndBodyError));
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnDeviceCodeGrantSignInSuccess(testing::_, testing::_, testing::_)).Times(0);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnDeviceCodeGrantSignInFail(testing::_)).Times(1);
m_lwaAuthenticationProviderLocalMock.DeviceCodeGrantSignInAsync();
}
TEST_F(LWAAuthenticationProviderTest, DeviceCodeGrantConfirmSignInAsync_Success)
{
EXPECT_CALL(m_httpRequestorRequestBusMock, AddRequestWithHeadersAndBody(testing::_, testing::_, testing::_, testing::_, testing::_)).Times(1);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnDeviceCodeGrantConfirmSignInSuccess(testing::_)).Times(1);
m_lwaAuthenticationProviderLocalMock.DeviceCodeGrantConfirmSignInAsync();
}
TEST_F(LWAAuthenticationProviderTest, DeviceCodeGrantConfirmSignInAsync_Fail_RequestHttpError)
{
EXPECT_CALL(m_httpRequestorRequestBusMock, AddRequestWithHeadersAndBody(testing::_, testing::_, testing::_, testing::_, testing::_)).Times(1)
.WillOnce(testing::Invoke(&m_httpRequestorRequestBusMock, &AWSClientAuthUnitTest::HttpRequestorRequestBusMock::AddRequestWithHeadersAndBodyError));
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnDeviceCodeGrantConfirmSignInSuccess(testing::_)).Times(0);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnDeviceCodeGrantConfirmSignInFail(testing::_)).Times(1);
m_lwaAuthenticationProviderLocalMock.DeviceCodeGrantConfirmSignInAsync();
}
TEST_F(LWAAuthenticationProviderTest, RefreshTokensAsync_Success)
{
EXPECT_CALL(m_httpRequestorRequestBusMock, AddRequestWithHeadersAndBody(testing::_, testing::_, testing::_, testing::_, testing::_)).Times(1);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnRefreshTokensSuccess(testing::_)).Times(1);
m_lwaAuthenticationProviderLocalMock.RefreshTokensAsync();
}
TEST_F(LWAAuthenticationProviderTest, RefreshTokensAsync_Fail_RequestHttpError)
{
EXPECT_CALL(m_httpRequestorRequestBusMock, AddRequestWithHeadersAndBody(testing::_, testing::_, testing::_, testing::_, testing::_)).Times(1)
.WillOnce(testing::Invoke(&m_httpRequestorRequestBusMock, &AWSClientAuthUnitTest::HttpRequestorRequestBusMock::AddRequestWithHeadersAndBodyError));
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnRefreshTokensSuccess(testing::_)).Times(0);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnRefreshTokensFail(testing::_)).Times(1);
m_lwaAuthenticationProviderLocalMock.RefreshTokensAsync();
}
TEST_F(LWAAuthenticationProviderTest, Initialize_Fail_EmptyRegistry)
{
AZStd::shared_ptr<AZ::SettingsRegistryImpl> registry = AZStd::make_shared<AZ::SettingsRegistryImpl>();
registry->SetContext(m_serializeContext.get());
AWSClientAuthUnitTest::LWAAuthenticationProviderLocalMock mock;
ASSERT_FALSE(mock.Initialize(registry));
ASSERT_EQ(mock.m_settings->m_appClientId, "");
registry.reset();
// Restore
mock.Initialize(m_settingsRegistry);
}
@@ -0,0 +1,75 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzTest/AzTest.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AWSClientAuthGemMock.h>
#include <Authorization/AWSClientAuthPersistentCognitoIdentityProvider.h>
class AWSClientAuthPersistentCognitoIdentityProviderTest : public AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture
{
protected:
void SetUp() override
{
AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture::SetUp();
}
void TearDown() override
{
AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture::TearDown();
}
public:
};
TEST_F(AWSClientAuthPersistentCognitoIdentityProviderTest, Initialize_AndPersisteIdentityId_Success)
{
AWSClientAuth::AWSClientAuthPersistentCognitoIdentityProvider provider;
provider.Initialize(AWSClientAuthUnitTest::TEST_ACCOUNT_ID, AWSClientAuthUnitTest::TEST_IDENTITY_POOL_ID);
ASSERT_TRUE(provider.GetAccountId() == AWSClientAuthUnitTest::TEST_ACCOUNT_ID);
ASSERT_TRUE(provider.GetIdentityPoolId() == AWSClientAuthUnitTest::TEST_IDENTITY_POOL_ID);
provider.PersistIdentityId(AWSClientAuthUnitTest::TEST_IDENTITY_ID);
ASSERT_TRUE(provider.GetIdentityId() == AWSClientAuthUnitTest::TEST_IDENTITY_ID);
}
TEST_F(AWSClientAuthPersistentCognitoIdentityProviderTest, AddRemoveLogins_Success)
{
AWSClientAuth::AWSClientAuthPersistentCognitoIdentityProvider provider;
provider.Initialize(AWSClientAuthUnitTest::TEST_ACCOUNT_ID, AWSClientAuthUnitTest::TEST_IDENTITY_POOL_ID);
ASSERT_TRUE(provider.HasLogins() == false);
Aws::Map<Aws::String, Aws::Auth::LoginAccessTokens> logins;
Aws::Auth::LoginAccessTokens tokens;
tokens.accessToken = "TestToken";
logins.insert(std::pair<Aws::String, Aws::Auth::LoginAccessTokens>("TestLoginKey1", tokens));
logins.insert(std::pair<Aws::String, Aws::Auth::LoginAccessTokens>("TestLoginKey2", tokens));
provider.PersistLogins(logins);
ASSERT_TRUE(provider.HasLogins() == true);
ASSERT_TRUE(provider.GetLogins().size() == 2);
ASSERT_TRUE(provider.GetLogins()["TestLoginKey1"].accessToken == tokens.accessToken);
ASSERT_TRUE(provider.GetLogins()["TestLoginKey2"].accessToken == tokens.accessToken);
provider.RemoveLogin("TestLoginKey1");
ASSERT_TRUE(provider.HasLogins() == true);
ASSERT_TRUE(provider.GetLogins().size() == 1);
ASSERT_TRUE(provider.GetLogins()["TestLoginKey2"].accessToken == tokens.accessToken);
provider.RemoveLogin("TestLoginKey2");
ASSERT_TRUE(provider.HasLogins() == false);
ASSERT_TRUE(provider.GetLogins().size() == 0);
}
@@ -0,0 +1,446 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzTest/AzTest.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AWSClientAuthGemMock.h>
#include <Authorization/AWSCognitoAuthorizationController.h>
#include <Credential/AWSCredentialBus.h>
#include <aws/cognito-identity/CognitoIdentityErrors.h>
namespace AWSClientAuthUnitTest
{
class AWSCognitoAuthorizationControllerTestLocalMock
: public AWSClientAuth::AWSCognitoAuthorizationController
{
public:
using AWSClientAuth::AWSCognitoAuthorizationController::m_settings;
using AWSClientAuth::AWSCognitoAuthorizationController::m_persistentCognitoIdentityProvider;
using AWSClientAuth::AWSCognitoAuthorizationController::m_persistentAnonymousCognitoIdentityProvider;
using AWSClientAuth::AWSCognitoAuthorizationController::m_cognitoCachingCredentialsProvider;
using AWSClientAuth::AWSCognitoAuthorizationController::m_cognitoCachingAnonymousCredentialsProvider;
};
}
class AWSCognitoAuthorizationControllerTest
: public AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture
{
protected:
void SetUp() override
{
AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture::SetUp();
AWSClientAuth::CognitoAuthorizationSettings::Reflect(*m_serializeContext);
m_mockController = AZStd::make_unique<AWSClientAuthUnitTest::AWSCognitoAuthorizationControllerTestLocalMock>();
}
void TearDown() override
{
m_mockController.reset();
AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture::TearDown();
}
public:
AZStd::unique_ptr<AWSClientAuthUnitTest::AWSCognitoAuthorizationControllerTestLocalMock> m_mockController;
};
TEST_F(AWSCognitoAuthorizationControllerTest, Initialize_Success)
{
AZStd::string path = AZStd::string::format("%s/%s/awsCognitoAuthorization.setreg",
m_testFolder->c_str(), AZ::SettingsRegistryInterface::RegistryFolder);
CreateTestFile("awsCognitoAuthorization.setreg"
, R"({
"AWS": {
"CognitoIdentityPool": {
"CognitoUserPoolId": "TestUserPoolId",
"LoginWithAmazonId": "www.amazon.com",
"AWSAccountId": "1234567890",
"IdentityPoolId": "TestIdentityPoolId"
}
}
})");
ASSERT_TRUE(m_mockController->Initialize(path));
ASSERT_TRUE(m_mockController->m_settings->m_cognitoUserPoolId == "TestUserPoolId");
}
TEST_F(AWSCognitoAuthorizationControllerTest, RequestAWSCredentials_WithLogins_Success)
{
AWSClientAuth::AuthenticationTokens tokens(
AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN,
AWSClientAuth::ProviderNameEnum::AWSCognitoIDP, 60);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnPasswordGrantSingleFactorSignInSuccess(testing::_)).Times(1);
AWSClientAuth::AuthenticationProviderNotificationBus::Broadcast(
&AWSClientAuth::AuthenticationProviderNotifications::OnPasswordGrantSingleFactorSignInSuccess, tokens);
AWSClientAuth::AuthenticationTokens tokens1(
AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN,
AWSClientAuth::ProviderNameEnum::Google, 60);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnDeviceCodeGrantConfirmSignInSuccess(testing::_)).Times(1);
AWSClientAuth::AuthenticationProviderNotificationBus::Broadcast(
&AWSClientAuth::AuthenticationProviderNotifications::OnDeviceCodeGrantConfirmSignInSuccess, tokens1);
EXPECT_CALL(*m_cognitoIdentityClientMock, GetId(testing::_)).Times(1);
EXPECT_CALL(*m_cognitoIdentityClientMock, GetCredentialsForIdentity(testing::_)).Times(1);
EXPECT_CALL(m_awsCognitoAuthorizationNotificationsBusMock, OnRequestAWSCredentialsSuccess(testing::_)).Times(1);
m_mockController->RequestAWSCredentialsAsync();
ASSERT_TRUE(m_mockController->GetIdentityId() == AWSClientAuthUnitTest::TEST_IDENTITY_ID);
auto creds = m_mockController->GetCognitoCredentialsProvider()->GetAWSCredentials();
ASSERT_TRUE(creds.GetAWSAccessKeyId() == AWSClientAuthUnitTest::TEST_ACCESS_KEY_ID);
ASSERT_TRUE(creds.GetAWSSecretKey() == AWSClientAuthUnitTest::TEST_SECRET_KEY_ID);
}
TEST_F(AWSCognitoAuthorizationControllerTest, RequestAWSCredentials_WithoutLoginsAnonymous_Success)
{
EXPECT_CALL(*m_cognitoIdentityClientMock, GetId(testing::_)).Times(1);
EXPECT_CALL(m_awsCognitoAuthorizationNotificationsBusMock, OnRequestAWSCredentialsSuccess(testing::_)).Times(1);
EXPECT_CALL(*m_cognitoIdentityClientMock, GetCredentialsForIdentity(testing::_)).Times(1);
m_mockController->RequestAWSCredentialsAsync();
ASSERT_TRUE(m_mockController->GetIdentityId() == AWSClientAuthUnitTest::TEST_IDENTITY_ID);
auto creds = m_mockController->GetAnonymousCognitoCredentialsProvider()->GetAWSCredentials();
ASSERT_TRUE(creds.GetAWSAccessKeyId() == AWSClientAuthUnitTest::TEST_ACCESS_KEY_ID);
ASSERT_TRUE(creds.GetAWSSecretKey() == AWSClientAuthUnitTest::TEST_SECRET_KEY_ID);
}
TEST_F(AWSCognitoAuthorizationControllerTest, MultipleCalls_UsesCacheCredentials_Success)
{
EXPECT_CALL(*m_cognitoIdentityClientMock, GetId(testing::_)).Times(1);
EXPECT_CALL(*m_cognitoIdentityClientMock, GetCredentialsForIdentity(testing::_)).Times(1);
EXPECT_CALL(m_awsCognitoAuthorizationNotificationsBusMock, OnRequestAWSCredentialsSuccess(testing::_)).Times(1);
m_mockController->RequestAWSCredentialsAsync();
ASSERT_TRUE(m_mockController->GetIdentityId() == AWSClientAuthUnitTest::TEST_IDENTITY_ID);
auto creds = m_mockController->GetAnonymousCognitoCredentialsProvider()->GetAWSCredentials();
ASSERT_TRUE(creds.GetAWSAccessKeyId() == AWSClientAuthUnitTest::TEST_ACCESS_KEY_ID);
ASSERT_TRUE(creds.GetAWSSecretKey() == AWSClientAuthUnitTest::TEST_SECRET_KEY_ID);
EXPECT_CALL(*m_cognitoIdentityClientMock, GetId(testing::_)).Times(0);
EXPECT_CALL(*m_cognitoIdentityClientMock, GetCredentialsForIdentity(testing::_)).Times(0);
EXPECT_CALL(m_awsCognitoAuthorizationNotificationsBusMock, OnRequestAWSCredentialsSuccess(testing::_)).Times(1);
m_mockController->RequestAWSCredentialsAsync();
}
TEST_F(AWSCognitoAuthorizationControllerTest, RequestAWSCredentials_Fail_GetIdError)
{
AWSClientAuth::AuthenticationTokens cognitoTokens(
AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN,
AWSClientAuth::ProviderNameEnum::AWSCognitoIDP, 60);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnPasswordGrantSingleFactorSignInSuccess(testing::_)).Times(1);
AWSClientAuth::AuthenticationProviderNotificationBus::Broadcast(
&AWSClientAuth::AuthenticationProviderNotifications::OnPasswordGrantSingleFactorSignInSuccess, cognitoTokens);
ASSERT_TRUE(m_mockController->m_persistentCognitoIdentityProvider->GetLogins().size() == 1);
Aws::Client::AWSError<Aws::CognitoIdentity::CognitoIdentityErrors> error;
error.SetExceptionName(AWSClientAuthUnitTest::TEST_EXCEPTION);
Aws::CognitoIdentity::Model::GetIdOutcome outcome(error);
EXPECT_CALL(*m_cognitoIdentityClientMock, GetId(testing::_)).Times(1).WillOnce(testing::Return(outcome));
EXPECT_CALL(*m_cognitoIdentityClientMock, GetCredentialsForIdentity(testing::_)).Times(0);
EXPECT_CALL(m_awsCognitoAuthorizationNotificationsBusMock, OnRequestAWSCredentialsSuccess(testing::_)).Times(0);
EXPECT_CALL(m_awsCognitoAuthorizationNotificationsBusMock, OnRequestAWSCredentialsFail(testing::_)).Times(1);
m_mockController->RequestAWSCredentialsAsync();
}
TEST_F(AWSCognitoAuthorizationControllerTest, RequestAWSCredentials_Fail_GetCredentialsForIdentityError)
{
AWSClientAuth::AuthenticationTokens cognitoTokens(
AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN,
AWSClientAuth::ProviderNameEnum::AWSCognitoIDP, 60);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnPasswordGrantSingleFactorSignInSuccess(testing::_)).Times(1);
AWSClientAuth::AuthenticationProviderNotificationBus::Broadcast(
&AWSClientAuth::AuthenticationProviderNotifications::OnPasswordGrantSingleFactorSignInSuccess, cognitoTokens);
AWSClientAuth::AuthenticationTokens googleTokens(
AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN,
AWSClientAuth::ProviderNameEnum::Google, 60);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnDeviceCodeGrantConfirmSignInSuccess(testing::_)).Times(1);
AWSClientAuth::AuthenticationProviderNotificationBus::Broadcast(
&AWSClientAuth::AuthenticationProviderNotifications::OnDeviceCodeGrantConfirmSignInSuccess, googleTokens);
ASSERT_TRUE(m_mockController->m_persistentCognitoIdentityProvider->GetLogins().size() == 2);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnDeviceCodeGrantConfirmSignInSuccess(testing::_)).Times(1);
AWSClientAuth::AuthenticationProviderNotificationBus::Broadcast(
&AWSClientAuth::AuthenticationProviderNotifications::OnDeviceCodeGrantConfirmSignInSuccess, googleTokens);
ASSERT_TRUE(m_mockController->m_persistentCognitoIdentityProvider->GetLogins().size() == 2);
Aws::Client::AWSError<Aws::CognitoIdentity::CognitoIdentityErrors> error;
error.SetExceptionName(AWSClientAuthUnitTest::TEST_EXCEPTION);
Aws::CognitoIdentity::Model::GetCredentialsForIdentityOutcome outcome(error);
EXPECT_CALL(*m_cognitoIdentityClientMock, GetId(testing::_)).Times(1);
EXPECT_CALL(*m_cognitoIdentityClientMock, GetCredentialsForIdentity(testing::_)).Times(1).WillOnce(testing::Return(outcome));
EXPECT_CALL(m_awsCognitoAuthorizationNotificationsBusMock, OnRequestAWSCredentialsSuccess(testing::_)).Times(0);
EXPECT_CALL(m_awsCognitoAuthorizationNotificationsBusMock, OnRequestAWSCredentialsFail(testing::_)).Times(1);
m_mockController->RequestAWSCredentialsAsync();
}
TEST_F(AWSCognitoAuthorizationControllerTest, AddRemoveLogins_Succuess)
{
AWSClientAuth::AuthenticationTokens cognitoTokens(
AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN,
AWSClientAuth::ProviderNameEnum::AWSCognitoIDP, 60);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnPasswordGrantSingleFactorSignInSuccess(testing::_)).Times(1);
AWSClientAuth::AuthenticationProviderNotificationBus::Broadcast(
&AWSClientAuth::AuthenticationProviderNotifications::OnPasswordGrantSingleFactorSignInSuccess, cognitoTokens);
ASSERT_TRUE(m_mockController->m_persistentCognitoIdentityProvider->GetLogins().size() == 1);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnPasswordGrantSingleFactorSignInSuccess(testing::_)).Times(1);
AWSClientAuth::AuthenticationProviderNotificationBus::Broadcast(
&AWSClientAuth::AuthenticationProviderNotifications::OnPasswordGrantSingleFactorSignInSuccess, cognitoTokens);
// One entry max for each provider.
ASSERT_TRUE(m_mockController->m_persistentCognitoIdentityProvider->GetLogins().size() == 1);
AWSClientAuth::AuthenticationTokens googleTokens(
AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN,
AWSClientAuth::ProviderNameEnum::Google, 60);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnDeviceCodeGrantConfirmSignInSuccess(testing::_)).Times(1);
AWSClientAuth::AuthenticationProviderNotificationBus::Broadcast(
&AWSClientAuth::AuthenticationProviderNotifications::OnDeviceCodeGrantConfirmSignInSuccess, googleTokens);
ASSERT_TRUE(m_mockController->m_persistentCognitoIdentityProvider->GetLogins().size() == 2);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnDeviceCodeGrantConfirmSignInSuccess(testing::_)).Times(1);
AWSClientAuth::AuthenticationProviderNotificationBus::Broadcast(
&AWSClientAuth::AuthenticationProviderNotifications::OnDeviceCodeGrantConfirmSignInSuccess, googleTokens);
ASSERT_TRUE(m_mockController->m_persistentCognitoIdentityProvider->GetLogins().size() == 2);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnSignOut(testing::_)).Times(1);
AWSClientAuth::AuthenticationProviderNotificationBus::Broadcast(
&AWSClientAuth::AuthenticationProviderNotifications::OnSignOut, AWSClientAuth::ProviderNameEnum::Google);
ASSERT_TRUE(m_mockController->m_persistentCognitoIdentityProvider->GetLogins().size() == 1);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnSignOut(testing::_)).Times(1);
AWSClientAuth::AuthenticationProviderNotificationBus::Broadcast(
&AWSClientAuth::AuthenticationProviderNotifications::OnSignOut, AWSClientAuth::ProviderNameEnum::AWSCognitoIDP);
ASSERT_TRUE(m_mockController->m_persistentCognitoIdentityProvider->GetLogins().size() == 0);
AWSClientAuth::AuthenticationTokens lwaTokens(
AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN,
AWSClientAuth::ProviderNameEnum::LoginWithAmazon, 60);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnPasswordGrantMultiFactorConfirmSignInSuccess(testing::_)).Times(1);
AWSClientAuth::AuthenticationProviderNotificationBus::Broadcast(
&AWSClientAuth::AuthenticationProviderNotifications::OnPasswordGrantMultiFactorConfirmSignInSuccess, lwaTokens);
ASSERT_TRUE(m_mockController->m_persistentCognitoIdentityProvider->GetLogins().size() == 1);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnSignOut(testing::_)).Times(1);
AWSClientAuth::AuthenticationProviderNotificationBus::Broadcast(
&AWSClientAuth::AuthenticationProviderNotifications::OnSignOut, AWSClientAuth::ProviderNameEnum::LoginWithAmazon);
ASSERT_TRUE(m_mockController->m_persistentCognitoIdentityProvider->GetLogins().size() == 0);
}
TEST_F(AWSCognitoAuthorizationControllerTest, ResetAuthenticated_ClearsCachedLoginsAndIdentityId_Success)
{
AWSClientAuth::AuthenticationTokens cognitoTokens(
AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN,
AWSClientAuth::ProviderNameEnum::AWSCognitoIDP, 60);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnPasswordGrantSingleFactorSignInSuccess(testing::_)).Times(1);
AWSClientAuth::AuthenticationProviderNotificationBus::Broadcast(
&AWSClientAuth::AuthenticationProviderNotifications::OnPasswordGrantSingleFactorSignInSuccess, cognitoTokens);
EXPECT_CALL(*m_cognitoIdentityClientMock, GetId(testing::_)).Times(1);
EXPECT_CALL(*m_cognitoIdentityClientMock, GetCredentialsForIdentity(testing::_)).Times(1);
EXPECT_CALL(m_awsCognitoAuthorizationNotificationsBusMock, OnRequestAWSCredentialsSuccess(testing::_)).Times(1);
m_mockController->RequestAWSCredentialsAsync();
ASSERT_TRUE(m_mockController->GetIdentityId() == AWSClientAuthUnitTest::TEST_IDENTITY_ID);
auto creds = m_mockController->GetCognitoCredentialsProvider()->GetAWSCredentials();
ASSERT_TRUE(creds.GetAWSAccessKeyId() == AWSClientAuthUnitTest::TEST_ACCESS_KEY_ID);
ASSERT_TRUE(creds.GetAWSSecretKey() == AWSClientAuthUnitTest::TEST_SECRET_KEY_ID);
m_mockController->Reset();
EXPECT_TRUE(m_mockController->GetIdentityId() == "");
EXPECT_TRUE(m_mockController->m_persistentCognitoIdentityProvider->GetLogins().size() == 0);
EXPECT_CALL(*m_cognitoIdentityClientMock, GetId(testing::_)).Times(1);
EXPECT_CALL(*m_cognitoIdentityClientMock, GetCredentialsForIdentity(testing::_)).Times(1);
EXPECT_CALL(m_awsCognitoAuthorizationNotificationsBusMock, OnRequestAWSCredentialsSuccess(testing::_)).Times(1);
m_mockController->RequestAWSCredentialsAsync();
}
TEST_F(AWSCognitoAuthorizationControllerTest, ResetAnonymous_ClearsCachedLoginsAndIdentityId_Success)
{
EXPECT_CALL(*m_cognitoIdentityClientMock, GetId(testing::_)).Times(1);
EXPECT_CALL(*m_cognitoIdentityClientMock, GetCredentialsForIdentity(testing::_)).Times(1);
EXPECT_CALL(m_awsCognitoAuthorizationNotificationsBusMock, OnRequestAWSCredentialsSuccess(testing::_)).Times(1);
m_mockController->RequestAWSCredentialsAsync();
ASSERT_TRUE(m_mockController->GetIdentityId() == AWSClientAuthUnitTest::TEST_IDENTITY_ID);
auto creds = m_mockController->GetAnonymousCognitoCredentialsProvider()->GetAWSCredentials();
ASSERT_TRUE(creds.GetAWSAccessKeyId() == AWSClientAuthUnitTest::TEST_ACCESS_KEY_ID);
ASSERT_TRUE(creds.GetAWSSecretKey() == AWSClientAuthUnitTest::TEST_SECRET_KEY_ID);
m_mockController->Reset();
EXPECT_TRUE(m_mockController->GetIdentityId() == "");
EXPECT_CALL(*m_cognitoIdentityClientMock, GetId(testing::_)).Times(1);
EXPECT_CALL(*m_cognitoIdentityClientMock, GetCredentialsForIdentity(testing::_)).Times(1);
EXPECT_CALL(m_awsCognitoAuthorizationNotificationsBusMock, OnRequestAWSCredentialsSuccess(testing::_)).Times(1);
m_mockController->RequestAWSCredentialsAsync();
}
TEST_F(AWSCognitoAuthorizationControllerTest, GetCredentialsProvider_ForPersistedLogins_ResultIsAuthenticatedCredentials)
{
AWSClientAuth::AuthenticationTokens cognitoTokens(
AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN,
AWSClientAuth::ProviderNameEnum::AWSCognitoIDP, 60);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnPasswordGrantSingleFactorSignInSuccess(testing::_)).Times(1);
AWSClientAuth::AuthenticationProviderNotificationBus::Broadcast(
&AWSClientAuth::AuthenticationProviderNotifications::OnPasswordGrantSingleFactorSignInSuccess, cognitoTokens);
EXPECT_CALL(*m_cognitoIdentityClientMock, GetId(testing::_)).Times(1);
EXPECT_CALL(*m_cognitoIdentityClientMock, GetCredentialsForIdentity(testing::_)).Times(1);
std::shared_ptr<Aws::Auth::AWSCredentialsProvider> actualCredentialsProvider;
AWSCore::AWSCredentialRequestBus::BroadcastResult(actualCredentialsProvider, &AWSCore::AWSCredentialRequests::GetCredentialsProvider);
EXPECT_TRUE(actualCredentialsProvider == m_mockController->m_cognitoCachingCredentialsProvider);
}
TEST_F(AWSCognitoAuthorizationControllerTest, GetCredentialsProvider_NoPersistedLogins_ResultIsAnonymousCredentials)
{
EXPECT_CALL(*m_cognitoIdentityClientMock, GetId(testing::_)).Times(1);
EXPECT_CALL(*m_cognitoIdentityClientMock, GetCredentialsForIdentity(testing::_)).Times(1);
std::shared_ptr<Aws::Auth::AWSCredentialsProvider> actualCredentialsProvider;
AWSCore::AWSCredentialRequestBus::BroadcastResult(actualCredentialsProvider, &AWSCore::AWSCredentialRequests::GetCredentialsProvider);
EXPECT_TRUE(actualCredentialsProvider == m_mockController->m_cognitoCachingAnonymousCredentialsProvider);
}
TEST_F(AWSCognitoAuthorizationControllerTest, GetCredentialsProvider_NoPersistedLogins_NoAnonymousCredentials_ResultNullPtr)
{
Aws::Client::AWSError<Aws::CognitoIdentity::CognitoIdentityErrors> error;
error.SetExceptionName(AWSClientAuthUnitTest::TEST_EXCEPTION);
Aws::CognitoIdentity::Model::GetIdOutcome outcome(error);
EXPECT_CALL(*m_cognitoIdentityClientMock, GetId(testing::_)).Times(1).WillOnce(testing::Return(outcome));
EXPECT_CALL(*m_cognitoIdentityClientMock, GetCredentialsForIdentity(testing::_)).Times(0);
std::shared_ptr<Aws::Auth::AWSCredentialsProvider> actualCredentialsProvider;
AWSCore::AWSCredentialRequestBus::BroadcastResult(
actualCredentialsProvider, &AWSCore::AWSCredentialRequests::GetCredentialsProvider);
EXPECT_TRUE(actualCredentialsProvider == nullptr);
}
TEST_F(
AWSCognitoAuthorizationControllerTest,
GetCredentialsProvider_OneThreadPersistLogins_SecondThreadGetCredentialsProvider_GetCredentialsSuccess)
{
AZStd::vector<AZStd::thread> testThreads;
AZStd::atomic_bool loginsAdded = false;
AZStd::atomic_int anonymousLogin = 0;
AZStd::atomic_int authenticatedLogin = 0;
testThreads.emplace_back(AZStd::thread([&]() {
AWSClientAuth::AuthenticationTokens cognitoTokens(
AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN,
AWSClientAuth::ProviderNameEnum::AWSCognitoIDP, 60);
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnPasswordGrantSingleFactorSignInSuccess(testing::_)).Times(1);
AWSClientAuth::AuthenticationProviderNotificationBus::Broadcast(
&AWSClientAuth::AuthenticationProviderNotifications::OnPasswordGrantSingleFactorSignInSuccess, cognitoTokens);
loginsAdded = true;
}));
testThreads.emplace_back(AZStd::thread([&]() {
std::shared_ptr<Aws::Auth::AWSCredentialsProvider> actualCredentialsProvider;
EXPECT_CALL(*m_cognitoIdentityClientMock, GetId(testing::_)).Times(1);
EXPECT_CALL(*m_cognitoIdentityClientMock, GetCredentialsForIdentity(testing::_)).Times(1);
AWSCore::AWSCredentialRequestBus::BroadcastResult(
actualCredentialsProvider, &AWSCore::AWSCredentialRequests::GetCredentialsProvider);
if (actualCredentialsProvider == m_mockController->m_cognitoCachingAnonymousCredentialsProvider)
{
anonymousLogin++;
}
else if (actualCredentialsProvider == m_mockController->m_cognitoCachingCredentialsProvider)
{
authenticatedLogin++;
}
EXPECT_TRUE(loginsAdded ? m_mockController->HasPersistedLogins() : true);
EXPECT_TRUE(actualCredentialsProvider != nullptr);
}));
for (auto& testThread : testThreads)
{
testThread.join();
}
testThreads.clear();
AZStd::atomic_bool loginsCleared = false;
testThreads.emplace_back(AZStd::thread([&]() {
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnSignOut(testing::_)).Times(1);
AWSClientAuth::AuthenticationProviderNotificationBus::Broadcast(
&AWSClientAuth::AuthenticationProviderNotifications::OnSignOut, AWSClientAuth::ProviderNameEnum::AWSCognitoIDP);
loginsCleared = true;
}));
testThreads.emplace_back(AZStd::thread([&]() {
std::shared_ptr<Aws::Auth::AWSCredentialsProvider> actualCredentialsProvider;
// Can be 0, 1 depending on the previous thread order.
EXPECT_CALL(*m_cognitoIdentityClientMock, GetId(testing::_)).Times(testing::Between(0, 1));
EXPECT_CALL(*m_cognitoIdentityClientMock, GetCredentialsForIdentity(testing::_)).Times(testing::Between(0, 1));
AWSCore::AWSCredentialRequestBus::BroadcastResult(
actualCredentialsProvider, &AWSCore::AWSCredentialRequests::GetCredentialsProvider);
EXPECT_FALSE(loginsCleared ? m_mockController->HasPersistedLogins() : false);
EXPECT_TRUE(actualCredentialsProvider != nullptr);
if (actualCredentialsProvider == m_mockController->m_cognitoCachingAnonymousCredentialsProvider)
{
anonymousLogin++;
}
else if (actualCredentialsProvider == m_mockController->m_cognitoCachingCredentialsProvider)
{
authenticatedLogin++;
}
EXPECT_TRUE(authenticatedLogin.load() + anonymousLogin.load() == 2);
}));
for (auto& testThread : testThreads)
{
testThread.join();
}
}
TEST_F(AWSCognitoAuthorizationControllerTest, GetCredentialHandlerOrder_Call_AlwaysGetExpectedValue)
{
int order;
AWSCore::AWSCredentialRequestBus::BroadcastResult(order, &AWSCore::AWSCredentialRequests::GetCredentialHandlerOrder);
EXPECT_EQ(order, AWSCore::CredentialHandlerOrder::COGNITO_IDENITY_POOL_CREDENTIAL_HANDLER);
}
TEST_F(AWSCognitoAuthorizationControllerTest, Initialize_Fail_InvalidPath)
{
AZ_TEST_START_TRACE_SUPPRESSION;
ASSERT_FALSE(m_mockController->Initialize(""));
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
}
@@ -0,0 +1,211 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzTest/AzTest.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <UserManagement/AWSCognitoUserManagementController.h>
#include <AWSClientAuthGemMock.h>
#include <aws/cognito-idp/CognitoIdentityProviderErrors.h>
namespace AWSClientAuthUnitTest
{
class AWSCognitoUserManagementControllerLocalMock
: public AWSClientAuth::AWSCognitoUserManagementController
{
public:
using AWSClientAuth::AWSCognitoUserManagementController::m_settings;
};
}
class AWSCognitoUserManagementControllerTest
: public AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture
, public AWSCore::AWSCoreRequestBus::Handler
{
protected:
void SetUp() override
{
AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture::SetUp();
AWSClientAuth::AWSCognitoUserManagementSetting::Reflect(*m_serializeContext);
m_mockController = AZStd::make_unique<AWSClientAuthUnitTest::AWSCognitoUserManagementControllerLocalMock>();
AWSCore::AWSCoreRequestBus::Handler::BusConnect();
}
void TearDown() override
{
AWSCore::AWSCoreRequestBus::Handler::BusDisconnect();
m_mockController.reset();
AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture::TearDown();
}
// AWSCore::AWSCoreRequestBus overrides
AZ::JobContext* GetDefaultJobContext() override
{
return m_jobContext.get();
}
// Returns the default client configuration setting to use as a starting point in AWS requests
AWSCore::AwsApiJobConfig* GetDefaultConfig() override
{
return nullptr;
}
public:
AZStd::unique_ptr<AWSClientAuthUnitTest::AWSCognitoUserManagementControllerLocalMock> m_mockController;
};
TEST_F(AWSCognitoUserManagementControllerTest, Initialize_Success)
{
AZStd::string path = AZStd::string::format("%s/%s/awsCognitoUserManagement.setreg",
m_testFolder->c_str(), AZ::SettingsRegistryInterface::RegistryFolder);
CreateTestFile("awsCognitoUserManagement.setreg"
, R"({"AWS":
{
"CognitoUserPool":
{
"AppClientId": "TestClientId",
"SignUpConfirmationType": "email"
}
}
})");
ASSERT_TRUE(m_mockController->Initialize(path));
ASSERT_EQ(m_mockController->m_settings->m_appClientId, "TestClientId");
}
TEST_F(AWSCognitoUserManagementControllerTest, EmailSignUp_Success)
{
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, SignUp(testing::_)).Times(1);
EXPECT_CALL(m_awsCognitoUserManagementNotificationsBusMock, OnEmailSignUpSuccess(testing::_)).Times(1);
m_mockController->EmailSignUpAsync(AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD, AWSClientAuthUnitTest::TEST_EMAIL);
}
TEST_F(AWSCognitoUserManagementControllerTest, EmailSignUp_Fail_SignUpError)
{
Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error;
error.SetExceptionName(AWSClientAuthUnitTest::TEST_EXCEPTION);
Aws::CognitoIdentityProvider::Model::SignUpOutcome outcome(error);
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, SignUp(testing::_)).Times(1)
.WillOnce(testing::Return(outcome));
EXPECT_CALL(m_awsCognitoUserManagementNotificationsBusMock, OnEmailSignUpSuccess(testing::_)).Times(0);
EXPECT_CALL(m_awsCognitoUserManagementNotificationsBusMock, OnEmailSignUpFail(testing::_)).Times(1);
m_mockController->EmailSignUpAsync(AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD, AWSClientAuthUnitTest::TEST_EMAIL);
}
TEST_F(AWSCognitoUserManagementControllerTest, PhoneSignUp_Success)
{
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, SignUp(testing::_)).Times(1);
EXPECT_CALL(m_awsCognitoUserManagementNotificationsBusMock, OnPhoneSignUpSuccess(testing::_)).Times(1);
m_mockController->PhoneSignUpAsync(AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD, AWSClientAuthUnitTest::TEST_PHONE);
}
TEST_F(AWSCognitoUserManagementControllerTest, PhoneSignUp_Fail_SignUpError)
{
Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error;
error.SetExceptionName(AWSClientAuthUnitTest::TEST_EXCEPTION);
Aws::CognitoIdentityProvider::Model::SignUpOutcome outcome(error);
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, SignUp(testing::_)).Times(1)
.WillOnce(testing::Return(outcome));
EXPECT_CALL(m_awsCognitoUserManagementNotificationsBusMock, OnPhoneSignUpSuccess(testing::_)).Times(0);
EXPECT_CALL(m_awsCognitoUserManagementNotificationsBusMock, OnPhoneSignUpFail(testing::_)).Times(1);
m_mockController->PhoneSignUpAsync(AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD, AWSClientAuthUnitTest::TEST_PHONE);
}
TEST_F(AWSCognitoUserManagementControllerTest, ConfirmSignUp_Success)
{
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, ConfirmSignUp(testing::_)).Times(1);
EXPECT_CALL(m_awsCognitoUserManagementNotificationsBusMock, OnConfirmSignUpSuccess()).Times(1);
m_mockController->ConfirmSignUpAsync(AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_CODE);
}
TEST_F(AWSCognitoUserManagementControllerTest, ConfirmSignUp_Fail_ConfirmSignUpError)
{
Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error;
error.SetExceptionName(AWSClientAuthUnitTest::TEST_EXCEPTION);
Aws::CognitoIdentityProvider::Model::ConfirmSignUpOutcome outcome(error);
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, ConfirmSignUp(testing::_)).Times(1)
.WillOnce(testing::Return(outcome));
EXPECT_CALL(m_awsCognitoUserManagementNotificationsBusMock, OnConfirmSignUpSuccess()).Times(0);
EXPECT_CALL(m_awsCognitoUserManagementNotificationsBusMock, OnConfirmSignUpFail(testing::_)).Times(1);
m_mockController->ConfirmSignUpAsync(AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_CODE);
}
TEST_F(AWSCognitoUserManagementControllerTest, EnableMFA_Success)
{
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, SetUserMFAPreference(testing::_)).Times(1);
EXPECT_CALL(m_awsCognitoUserManagementNotificationsBusMock, OnEnableMFASuccess()).Times(1);
m_mockController->EnableMFAAsync(AWSClientAuthUnitTest::TEST_TOKEN);
}
TEST_F(AWSCognitoUserManagementControllerTest, EnableMFA_Fail_SetUserMFAPreferenceError)
{
Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error;
error.SetExceptionName(AWSClientAuthUnitTest::TEST_EXCEPTION);
Aws::CognitoIdentityProvider::Model::SetUserMFAPreferenceOutcome outcome(error);
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, SetUserMFAPreference(testing::_)).Times(1)
.WillOnce(testing::Return(outcome));
EXPECT_CALL(m_awsCognitoUserManagementNotificationsBusMock, OnEnableMFASuccess()).Times(0);
EXPECT_CALL(m_awsCognitoUserManagementNotificationsBusMock, OnEnableMFAFail(testing::_)).Times(1);
m_mockController->EnableMFAAsync(AWSClientAuthUnitTest::TEST_TOKEN);
}
TEST_F(AWSCognitoUserManagementControllerTest, ForgotPassword_Success)
{
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, ForgotPassword(testing::_)).Times(1);
EXPECT_CALL(m_awsCognitoUserManagementNotificationsBusMock, OnForgotPasswordSuccess()).Times(1);
m_mockController->ForgotPasswordAsync(AWSClientAuthUnitTest::TEST_USERNAME);
}
TEST_F(AWSCognitoUserManagementControllerTest, ForgotPassword_Fail_ForgotPasswordError)
{
Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error;
error.SetExceptionName(AWSClientAuthUnitTest::TEST_EXCEPTION);
Aws::CognitoIdentityProvider::Model::ForgotPasswordOutcome outcome(error);
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, ForgotPassword(testing::_)).Times(1)
.WillOnce(testing::Return(outcome));
EXPECT_CALL(m_awsCognitoUserManagementNotificationsBusMock, OnForgotPasswordSuccess()).Times(0);
EXPECT_CALL(m_awsCognitoUserManagementNotificationsBusMock, OnForgotPasswordFail(testing::_)).Times(1);
m_mockController->ForgotPasswordAsync(AWSClientAuthUnitTest::TEST_USERNAME);
}
TEST_F(AWSCognitoUserManagementControllerTest, ConfirmForgotPassword_Success)
{
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, ConfirmForgotPassword(testing::_)).Times(1);
EXPECT_CALL(m_awsCognitoUserManagementNotificationsBusMock, OnConfirmForgotPasswordSuccess()).Times(1);
m_mockController->ConfirmForgotPasswordAsync(AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_CODE, AWSClientAuthUnitTest::TEST_NEW_PASSWORD);
}
TEST_F(AWSCognitoUserManagementControllerTest, ConfirmForgotPassword_Fail_ConfirmForgotPasswordError)
{
Aws::Client::AWSError<Aws::CognitoIdentityProvider::CognitoIdentityProviderErrors> error;
error.SetExceptionName("TestException");
Aws::CognitoIdentityProvider::Model::ConfirmForgotPasswordOutcome outcome(error);
EXPECT_CALL(*m_cognitoIdentityProviderClientMock, ConfirmForgotPassword(testing::_)).Times(1)
.WillOnce(testing::Return(outcome));
EXPECT_CALL(m_awsCognitoUserManagementNotificationsBusMock, OnConfirmForgotPasswordSuccess()).Times(0);
EXPECT_CALL(m_awsCognitoUserManagementNotificationsBusMock, OnConfirmForgotPasswordFail(testing::_)).Times(1);
m_mockController->ConfirmForgotPasswordAsync(AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_CODE, AWSClientAuthUnitTest::TEST_NEW_PASSWORD);
}
TEST_F(AWSCognitoUserManagementControllerTest, Initialize_Fail_InvalidPath)
{
AZ_TEST_START_TRACE_SUPPRESSION;
ASSERT_FALSE(m_mockController->Initialize(""));
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
}
@@ -0,0 +1,52 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
Include/Public/Authentication/AuthenticationProviderBus.h
Include/Public/Authentication/AuthenticationTokens.h
Include/Public/Authorization/AWSCognitoAuthorizationBus.h
Include/Public/Authorization/ClientAuthAWSCredentials.h
Include/Public/UserManagement/AWSCognitoUserManagementBus.h
Include/Private/AWSClientAuthSystemComponent.h
Include/Private/AWSClientAuthBus.h
Include/Private/Authentication/AuthenticationProviderTypes.h
Include/Private/Authentication/AuthenticationProviderManager.h
Include/Private/Authentication/AuthenticationNotificationBusBehaviorHandler.h
Include/Private/Authorization/AWSCognitoAuthorizationTypes.h
Include/Private/Authorization/AWSCognitoAuthorizationController.h
Include/Private/Authorization/AWSClientAuthPersistentCognitoIdentityProvider.h
Include/Private/Authorization/AWSCognitoAuthorizationNotificationBusBehaviorHandler.h
Include/Private/UserManagement/AWSCognitoUserManagementTypes.h
Include/Private/UserManagement/AWSCognitoUserManagementController.h
Include/Private/UserManagement/UserManagementNotificationBusBehaviorHandler.h
Include/Private/Authentication/AuthenticationProviderInterface.h
Include/Private/Authentication/OAuthConstants.h
Include/Private/Authentication/AWSCognitoAuthenticationProvider.h
Include/Private/Authentication/LWAAuthenticationProvider.h
Include/Private/Authentication/GoogleAuthenticationProvider.h
Source/AWSClientAuthSystemComponent.cpp
Source/Authentication/AuthenticationTokens.cpp
Source/Authentication/AuthenticationProviderInterface.cpp
Source/Authentication/AuthenticationProviderManager.cpp
Source/Authentication/AWSCognitoAuthenticationProvider.cpp
Source/Authentication/LWAAuthenticationProvider.cpp
Source/Authentication/GoogleAuthenticationProvider.cpp
Source/Authorization/AWSCognitoAuthorizationController.cpp
Source/Authorization/AWSClientAuthPersistentCognitoIdentityProvider.cpp
Source/UserManagement/AWSCognitoUserManagementController.cpp
)
@@ -0,0 +1,15 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
Include/Private/AWSClientAuthModule.h
Source/AWSClientAuthModule.cpp
)
@@ -0,0 +1,24 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
Tests/AWSClientAuthGemMock.h
Tests/AWSClientAuthGemTest.cpp
Tests/AWSClientAuthSystemComponentTest.cpp
Tests/Authentication/AuthenticationProviderManagerTest.cpp
Tests/Authentication/AWSCognitoAuthenticationProviderTest.cpp
Tests/Authentication/LWAAuthenticationProviderTest.cpp
Tests/Authentication/GoogleAuthenticationProviderTest.cpp
Tests/Authorization/AWSClientAuthPersistentCognitoIdentityProviderTest.cpp
Tests/Authorization/AWSCognitoAuthorizationControllerTest.cpp
Tests/UserManagement/AWSCognitoUserManagementControllerTest.cpp
)