Skip to content

Commit 5b009cd

Browse files
authored
Merge pull request #7582 from magento-performance/adobe-ims
CABPI-356: Migration of AdminIms module to magento2ce repo
2 parents fa7009c + 2e19d2e commit 5b009cd

File tree

76 files changed

+5500
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+5500
-1
lines changed
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\AdobeIms\Block\Adminhtml;
9+
10+
use Magento\AdobeImsApi\Api\ConfigProviderInterface;
11+
use Magento\AdobeImsApi\Api\ConfigInterface;
12+
use Magento\AdobeImsApi\Api\UserAuthorizedInterface;
13+
use Magento\AdobeImsApi\Api\UserProfileRepositoryInterface;
14+
use Magento\Authorization\Model\UserContextInterface;
15+
use Magento\Backend\Block\Template;
16+
use Magento\Backend\Block\Template\Context;
17+
use Magento\Framework\Exception\NoSuchEntityException;
18+
use Magento\Framework\Serialize\Serializer\JsonHexTag;
19+
20+
/**
21+
* Provides required data for the Adobe service authentication component
22+
*
23+
* @api
24+
*/
25+
class SignIn extends Template
26+
{
27+
private const DATA_ARGUMENT_KEY_CONFIG_PROVIDERS = 'configProviders';
28+
private const RESPONSE_REGEXP_PATTERN = 'auth\\[code=(success|error);message=(.+)\\]';
29+
private const RESPONSE_CODE_INDEX = 1;
30+
private const RESPONSE_MESSAGE_INDEX = 2;
31+
private const RESPONSE_SUCCESS_CODE = 'success';
32+
private const RESPONSE_ERROR_CODE = 'error';
33+
private const ADOBE_IMS_JS_SIGNIN = 'Magento_AdobeIms/js/signIn';
34+
private const ADOBE_IMS_SIGNIN = 'Magento_AdobeIms/signIn';
35+
private const ADOBE_IMS_USER_PROFILE = 'adobe_ims/user/profile';
36+
private const ADOBE_IMS_USER_LOGOUT = 'adobe_ims/user/logout';
37+
38+
/**
39+
* @var ConfigInterface
40+
*/
41+
private $config;
42+
43+
/**
44+
* @var UserContextInterface
45+
*/
46+
private $userContext;
47+
48+
/**
49+
* @var UserAuthorizedInterface
50+
*/
51+
private $userAuthorized;
52+
53+
/**
54+
* @var UserProfileRepositoryInterface
55+
*/
56+
private $userProfileRepository;
57+
58+
/**
59+
* JsonHexTag Serializer Instance
60+
*
61+
* @var JsonHexTag
62+
*/
63+
private $serializer;
64+
65+
/**
66+
* SignIn constructor.
67+
*
68+
* @param Context $context
69+
* @param ConfigInterface $config
70+
* @param UserContextInterface $userContext
71+
* @param UserAuthorizedInterface $userAuthorized
72+
* @param UserProfileRepositoryInterface $userProfileRepository
73+
* @param JsonHexTag $json
74+
* @param array $data
75+
*/
76+
public function __construct(
77+
Context $context,
78+
ConfigInterface $config,
79+
UserContextInterface $userContext,
80+
UserAuthorizedInterface $userAuthorized,
81+
UserProfileRepositoryInterface $userProfileRepository,
82+
JsonHexTag $json,
83+
array $data = []
84+
) {
85+
$this->config = $config;
86+
$this->userContext = $userContext;
87+
$this->userAuthorized = $userAuthorized;
88+
$this->userProfileRepository = $userProfileRepository;
89+
$this->serializer = $json;
90+
parent::__construct($context, $data);
91+
}
92+
93+
/**
94+
* Get configuration for UI component
95+
*
96+
* @return string
97+
*/
98+
public function getComponentJsonConfig(): string
99+
{
100+
return $this->serializer->serialize(
101+
array_replace_recursive(
102+
$this->getDefaultComponentConfig(),
103+
...$this->getExtendedComponentConfig()
104+
)
105+
);
106+
}
107+
108+
/**
109+
* Get default UI component configuration
110+
*
111+
* @return array
112+
*/
113+
private function getDefaultComponentConfig(): array
114+
{
115+
return [
116+
'component' => self::ADOBE_IMS_JS_SIGNIN,
117+
'template' => self::ADOBE_IMS_SIGNIN,
118+
'profileUrl' => $this->getUrl(self::ADOBE_IMS_USER_PROFILE),
119+
'logoutUrl' => $this->getUrl(self::ADOBE_IMS_USER_LOGOUT),
120+
'user' => $this->getUserData(),
121+
'loginConfig' => [
122+
'url' => $this->config->getAuthUrl(),
123+
'callbackParsingParams' => [
124+
'regexpPattern' => self::RESPONSE_REGEXP_PATTERN,
125+
'codeIndex' => self::RESPONSE_CODE_INDEX,
126+
'messageIndex' => self::RESPONSE_MESSAGE_INDEX,
127+
'successCode' => self::RESPONSE_SUCCESS_CODE,
128+
'errorCode' => self::RESPONSE_ERROR_CODE
129+
]
130+
]
131+
];
132+
}
133+
134+
/**
135+
* Get UI component configuration extension specified in layout configuration for block instance
136+
*
137+
* @return array
138+
*/
139+
private function getExtendedComponentConfig(): array
140+
{
141+
$configProviders = $this->getData(self::DATA_ARGUMENT_KEY_CONFIG_PROVIDERS);
142+
if (empty($configProviders)) {
143+
return [];
144+
}
145+
146+
$configExtensions = [];
147+
foreach ($configProviders as $configProvider) {
148+
if ($configProvider instanceof ConfigProviderInterface) {
149+
$configExtensions[] = $configProvider->get();
150+
}
151+
}
152+
return $configExtensions;
153+
}
154+
155+
/**
156+
* Get user profile information
157+
*
158+
* @return array
159+
*/
160+
private function getUserData(): array
161+
{
162+
if (!$this->userAuthorized->execute()) {
163+
return $this->getDefaultUserData();
164+
}
165+
166+
try {
167+
$userProfile = $this->userProfileRepository->getByUserId((int)$this->userContext->getUserId());
168+
} catch (NoSuchEntityException $exception) {
169+
return $this->getDefaultUserData();
170+
}
171+
172+
return [
173+
'isAuthorized' => true,
174+
'name' => $userProfile->getName(),
175+
'email' => $userProfile->getEmail(),
176+
'image' => $userProfile->getImage(),
177+
];
178+
}
179+
180+
/**
181+
* Get default user data for not authenticated or missing user profile
182+
*
183+
* @return array
184+
*/
185+
private function getDefaultUserData(): array
186+
{
187+
return [
188+
'isAuthorized' => false,
189+
'name' => '',
190+
'email' => '',
191+
'image' => '',
192+
];
193+
}
194+
}
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\AdobeIms\Controller\Adminhtml\OAuth;
10+
11+
use Magento\AdobeImsApi\Api\GetTokenInterface;
12+
use Magento\AdobeImsApi\Api\LogInInterface;
13+
use Magento\Backend\App\Action;
14+
use Magento\Framework\App\Action\HttpGetActionInterface;
15+
use Magento\Framework\Controller\Result\Raw;
16+
use Magento\Framework\Controller\ResultFactory;
17+
use Magento\Framework\Controller\ResultInterface;
18+
use Magento\Framework\Exception\AuthorizationException;
19+
use Magento\Framework\Exception\ConfigurationMismatchException;
20+
use Magento\Framework\Exception\CouldNotSaveException;
21+
use Magento\User\Api\Data\UserInterface;
22+
use Psr\Log\LoggerInterface;
23+
24+
/**
25+
* Callback action for managing user authentication with the Adobe services
26+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
27+
*/
28+
class Callback extends Action implements HttpGetActionInterface
29+
{
30+
/**
31+
* @see _isAllowed()
32+
*/
33+
public const ADMIN_RESOURCE = 'Magento_AdobeIms::login';
34+
35+
/**
36+
* Constants of response
37+
*
38+
* RESPONSE_TEMPLATE - template of response
39+
* RESPONSE_SUCCESS_CODE success code
40+
* RESPONSE_ERROR_CODE error code
41+
*/
42+
private const RESPONSE_TEMPLATE = 'auth[code=%s;message=%s]';
43+
private const RESPONSE_SUCCESS_CODE = 'success';
44+
private const RESPONSE_ERROR_CODE = 'error';
45+
46+
/**
47+
* Constants of request
48+
*
49+
* REQUEST_PARAM_ERROR error
50+
* REQUEST_PARAM_CODE code
51+
*/
52+
private const REQUEST_PARAM_ERROR = 'error';
53+
private const REQUEST_PARAM_CODE = 'code';
54+
55+
/**
56+
* @var GetTokenInterface
57+
*/
58+
private $getToken;
59+
60+
/**
61+
* @var LogInInterface
62+
*/
63+
private $login;
64+
65+
/**
66+
* @var LoggerInterface
67+
*/
68+
private $logger;
69+
70+
/**
71+
* @param Action\Context $context
72+
* @param GetTokenInterface $getToken
73+
* @param LogInInterface $login
74+
* @param LoggerInterface $logger
75+
*/
76+
public function __construct(
77+
Action\Context $context,
78+
GetTokenInterface $getToken,
79+
LogInInterface $login,
80+
LoggerInterface $logger
81+
) {
82+
parent::__construct($context);
83+
84+
$this->getToken = $getToken;
85+
$this->login = $login;
86+
$this->logger = $logger;
87+
}
88+
89+
/**
90+
* @inheritdoc
91+
*/
92+
public function execute(): ResultInterface
93+
{
94+
try {
95+
$this->validateCallbackRequest();
96+
$tokenResponse = $this->getToken->execute(
97+
(string)$this->getRequest()->getParam(self::REQUEST_PARAM_CODE)
98+
);
99+
$this->login->execute((int) $this->getUser()->getId(), $tokenResponse);
100+
101+
$response = sprintf(
102+
self::RESPONSE_TEMPLATE,
103+
self::RESPONSE_SUCCESS_CODE,
104+
__('Authorization was successful')
105+
);
106+
} catch (AuthorizationException $exception) {
107+
$response = sprintf(
108+
self::RESPONSE_TEMPLATE,
109+
self::RESPONSE_ERROR_CODE,
110+
__(
111+
'Login failed. Please check if <a href="%url">the Secret Key</a> is set correctly and try again.',
112+
[
113+
'url' => $this->getUrl(
114+
'adminhtml/system_config/edit',
115+
[
116+
'section' => 'system',
117+
'_fragment' => 'system_adobe_stock_integration-link'
118+
]
119+
)
120+
]
121+
)
122+
);
123+
} catch (ConfigurationMismatchException | CouldNotSaveException $exception) {
124+
$response = sprintf(
125+
self::RESPONSE_TEMPLATE,
126+
self::RESPONSE_ERROR_CODE,
127+
$exception->getMessage()
128+
);
129+
} catch (\Exception $exception) {
130+
$this->logger->critical($exception);
131+
$response = sprintf(
132+
self::RESPONSE_TEMPLATE,
133+
self::RESPONSE_ERROR_CODE,
134+
__('Something went wrong.')
135+
);
136+
}
137+
138+
/** @var Raw $resultRaw */
139+
$resultRaw = $this->resultFactory->create(ResultFactory::TYPE_RAW);
140+
$resultRaw->setContents($response);
141+
142+
return $resultRaw;
143+
}
144+
145+
/**
146+
* Validate callback request from the Adobe OAth service
147+
*
148+
* @throws ConfigurationMismatchException
149+
*/
150+
private function validateCallbackRequest(): void
151+
{
152+
$error = $this->getRequest()->getParam(self::REQUEST_PARAM_ERROR);
153+
if ($error) {
154+
$message = __(
155+
'An error occurred during the callback request from the Adobe service: %error',
156+
['error' => $error]
157+
);
158+
throw new ConfigurationMismatchException($message);
159+
}
160+
}
161+
162+
/**
163+
* Get Authorised User
164+
*
165+
* @return UserInterface
166+
*/
167+
private function getUser(): UserInterface
168+
{
169+
if (!$this->_auth->getUser() instanceof UserInterface) {
170+
throw new \RuntimeException('Auth user object must be an instance of UserInterface');
171+
}
172+
173+
return $this->_auth->getUser();
174+
}
175+
}

0 commit comments

Comments
 (0)