Skip to content

Commit

Permalink
Merge pull request #7582 from magento-performance/adobe-ims
Browse files Browse the repository at this point in the history
CABPI-356: Migration of AdminIms module to magento2ce repo
  • Loading branch information
andimov authored Apr 28, 2022
2 parents fa7009c + 2e19d2e commit 5b009cd
Show file tree
Hide file tree
Showing 76 changed files with 5,500 additions and 1 deletion.
194 changes: 194 additions & 0 deletions app/code/Magento/AdobeIms/Block/Adminhtml/SignIn.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\AdobeIms\Block\Adminhtml;

use Magento\AdobeImsApi\Api\ConfigProviderInterface;
use Magento\AdobeImsApi\Api\ConfigInterface;
use Magento\AdobeImsApi\Api\UserAuthorizedInterface;
use Magento\AdobeImsApi\Api\UserProfileRepositoryInterface;
use Magento\Authorization\Model\UserContextInterface;
use Magento\Backend\Block\Template;
use Magento\Backend\Block\Template\Context;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Serialize\Serializer\JsonHexTag;

/**
* Provides required data for the Adobe service authentication component
*
* @api
*/
class SignIn extends Template
{
private const DATA_ARGUMENT_KEY_CONFIG_PROVIDERS = 'configProviders';
private const RESPONSE_REGEXP_PATTERN = 'auth\\[code=(success|error);message=(.+)\\]';
private const RESPONSE_CODE_INDEX = 1;
private const RESPONSE_MESSAGE_INDEX = 2;
private const RESPONSE_SUCCESS_CODE = 'success';
private const RESPONSE_ERROR_CODE = 'error';
private const ADOBE_IMS_JS_SIGNIN = 'Magento_AdobeIms/js/signIn';
private const ADOBE_IMS_SIGNIN = 'Magento_AdobeIms/signIn';
private const ADOBE_IMS_USER_PROFILE = 'adobe_ims/user/profile';
private const ADOBE_IMS_USER_LOGOUT = 'adobe_ims/user/logout';

/**
* @var ConfigInterface
*/
private $config;

/**
* @var UserContextInterface
*/
private $userContext;

/**
* @var UserAuthorizedInterface
*/
private $userAuthorized;

/**
* @var UserProfileRepositoryInterface
*/
private $userProfileRepository;

/**
* JsonHexTag Serializer Instance
*
* @var JsonHexTag
*/
private $serializer;

/**
* SignIn constructor.
*
* @param Context $context
* @param ConfigInterface $config
* @param UserContextInterface $userContext
* @param UserAuthorizedInterface $userAuthorized
* @param UserProfileRepositoryInterface $userProfileRepository
* @param JsonHexTag $json
* @param array $data
*/
public function __construct(
Context $context,
ConfigInterface $config,
UserContextInterface $userContext,
UserAuthorizedInterface $userAuthorized,
UserProfileRepositoryInterface $userProfileRepository,
JsonHexTag $json,
array $data = []
) {
$this->config = $config;
$this->userContext = $userContext;
$this->userAuthorized = $userAuthorized;
$this->userProfileRepository = $userProfileRepository;
$this->serializer = $json;
parent::__construct($context, $data);
}

/**
* Get configuration for UI component
*
* @return string
*/
public function getComponentJsonConfig(): string
{
return $this->serializer->serialize(
array_replace_recursive(
$this->getDefaultComponentConfig(),
...$this->getExtendedComponentConfig()
)
);
}

/**
* Get default UI component configuration
*
* @return array
*/
private function getDefaultComponentConfig(): array
{
return [
'component' => self::ADOBE_IMS_JS_SIGNIN,
'template' => self::ADOBE_IMS_SIGNIN,
'profileUrl' => $this->getUrl(self::ADOBE_IMS_USER_PROFILE),
'logoutUrl' => $this->getUrl(self::ADOBE_IMS_USER_LOGOUT),
'user' => $this->getUserData(),
'loginConfig' => [
'url' => $this->config->getAuthUrl(),
'callbackParsingParams' => [
'regexpPattern' => self::RESPONSE_REGEXP_PATTERN,
'codeIndex' => self::RESPONSE_CODE_INDEX,
'messageIndex' => self::RESPONSE_MESSAGE_INDEX,
'successCode' => self::RESPONSE_SUCCESS_CODE,
'errorCode' => self::RESPONSE_ERROR_CODE
]
]
];
}

/**
* Get UI component configuration extension specified in layout configuration for block instance
*
* @return array
*/
private function getExtendedComponentConfig(): array
{
$configProviders = $this->getData(self::DATA_ARGUMENT_KEY_CONFIG_PROVIDERS);
if (empty($configProviders)) {
return [];
}

$configExtensions = [];
foreach ($configProviders as $configProvider) {
if ($configProvider instanceof ConfigProviderInterface) {
$configExtensions[] = $configProvider->get();
}
}
return $configExtensions;
}

/**
* Get user profile information
*
* @return array
*/
private function getUserData(): array
{
if (!$this->userAuthorized->execute()) {
return $this->getDefaultUserData();
}

try {
$userProfile = $this->userProfileRepository->getByUserId((int)$this->userContext->getUserId());
} catch (NoSuchEntityException $exception) {
return $this->getDefaultUserData();
}

return [
'isAuthorized' => true,
'name' => $userProfile->getName(),
'email' => $userProfile->getEmail(),
'image' => $userProfile->getImage(),
];
}

/**
* Get default user data for not authenticated or missing user profile
*
* @return array
*/
private function getDefaultUserData(): array
{
return [
'isAuthorized' => false,
'name' => '',
'email' => '',
'image' => '',
];
}
}
175 changes: 175 additions & 0 deletions app/code/Magento/AdobeIms/Controller/Adminhtml/OAuth/Callback.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

declare(strict_types=1);

namespace Magento\AdobeIms\Controller\Adminhtml\OAuth;

use Magento\AdobeImsApi\Api\GetTokenInterface;
use Magento\AdobeImsApi\Api\LogInInterface;
use Magento\Backend\App\Action;
use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\Controller\Result\Raw;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\Controller\ResultInterface;
use Magento\Framework\Exception\AuthorizationException;
use Magento\Framework\Exception\ConfigurationMismatchException;
use Magento\Framework\Exception\CouldNotSaveException;
use Magento\User\Api\Data\UserInterface;
use Psr\Log\LoggerInterface;

/**
* Callback action for managing user authentication with the Adobe services
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class Callback extends Action implements HttpGetActionInterface
{
/**
* @see _isAllowed()
*/
public const ADMIN_RESOURCE = 'Magento_AdobeIms::login';

/**
* Constants of response
*
* RESPONSE_TEMPLATE - template of response
* RESPONSE_SUCCESS_CODE success code
* RESPONSE_ERROR_CODE error code
*/
private const RESPONSE_TEMPLATE = 'auth[code=%s;message=%s]';
private const RESPONSE_SUCCESS_CODE = 'success';
private const RESPONSE_ERROR_CODE = 'error';

/**
* Constants of request
*
* REQUEST_PARAM_ERROR error
* REQUEST_PARAM_CODE code
*/
private const REQUEST_PARAM_ERROR = 'error';
private const REQUEST_PARAM_CODE = 'code';

/**
* @var GetTokenInterface
*/
private $getToken;

/**
* @var LogInInterface
*/
private $login;

/**
* @var LoggerInterface
*/
private $logger;

/**
* @param Action\Context $context
* @param GetTokenInterface $getToken
* @param LogInInterface $login
* @param LoggerInterface $logger
*/
public function __construct(
Action\Context $context,
GetTokenInterface $getToken,
LogInInterface $login,
LoggerInterface $logger
) {
parent::__construct($context);

$this->getToken = $getToken;
$this->login = $login;
$this->logger = $logger;
}

/**
* @inheritdoc
*/
public function execute(): ResultInterface
{
try {
$this->validateCallbackRequest();
$tokenResponse = $this->getToken->execute(
(string)$this->getRequest()->getParam(self::REQUEST_PARAM_CODE)
);
$this->login->execute((int) $this->getUser()->getId(), $tokenResponse);

$response = sprintf(
self::RESPONSE_TEMPLATE,
self::RESPONSE_SUCCESS_CODE,
__('Authorization was successful')
);
} catch (AuthorizationException $exception) {
$response = sprintf(
self::RESPONSE_TEMPLATE,
self::RESPONSE_ERROR_CODE,
__(
'Login failed. Please check if <a href="%url">the Secret Key</a> is set correctly and try again.',
[
'url' => $this->getUrl(
'adminhtml/system_config/edit',
[
'section' => 'system',
'_fragment' => 'system_adobe_stock_integration-link'
]
)
]
)
);
} catch (ConfigurationMismatchException | CouldNotSaveException $exception) {
$response = sprintf(
self::RESPONSE_TEMPLATE,
self::RESPONSE_ERROR_CODE,
$exception->getMessage()
);
} catch (\Exception $exception) {
$this->logger->critical($exception);
$response = sprintf(
self::RESPONSE_TEMPLATE,
self::RESPONSE_ERROR_CODE,
__('Something went wrong.')
);
}

/** @var Raw $resultRaw */
$resultRaw = $this->resultFactory->create(ResultFactory::TYPE_RAW);
$resultRaw->setContents($response);

return $resultRaw;
}

/**
* Validate callback request from the Adobe OAth service
*
* @throws ConfigurationMismatchException
*/
private function validateCallbackRequest(): void
{
$error = $this->getRequest()->getParam(self::REQUEST_PARAM_ERROR);
if ($error) {
$message = __(
'An error occurred during the callback request from the Adobe service: %error',
['error' => $error]
);
throw new ConfigurationMismatchException($message);
}
}

/**
* Get Authorised User
*
* @return UserInterface
*/
private function getUser(): UserInterface
{
if (!$this->_auth->getUser() instanceof UserInterface) {
throw new \RuntimeException('Auth user object must be an instance of UserInterface');
}

return $this->_auth->getUser();
}
}
Loading

0 comments on commit 5b009cd

Please sign in to comment.