Integrating latest 47acbe8
This commit is contained in:
@@ -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
|
||||
+48
@@ -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
|
||||
+101
@@ -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
|
||||
+67
@@ -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
|
||||
+58
@@ -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
|
||||
+48
@@ -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
|
||||
+71
@@ -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
|
||||
+39
@@ -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
|
||||
+42
@@ -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
|
||||
+50
@@ -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
|
||||
+93
@@ -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
|
||||
+90
@@ -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();
|
||||
}
|
||||
+289
@@ -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);
|
||||
}
|
||||
+75
@@ -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);
|
||||
}
|
||||
+446
@@ -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);
|
||||
}
|
||||
+211
@@ -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
|
||||
)
|
||||
Reference in New Issue
Block a user