123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- <?php
- /**
- * MageSpecialist
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to info@magespecialist.it so we can send you a copy immediately.
- *
- * @category MSP
- * @package MSP_NoSpam
- * @copyright Copyright (c) 2017 Skeeller srl (http://www.magespecialist.it)
- * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
- */
- namespace MSP\TwoFactorAuth\Model\Provider\Engine\Authy;
- use Magento\Framework\App\Config\ScopeConfigInterface;
- use Magento\Framework\Exception\LocalizedException;
- use Magento\Framework\HTTP\Client\CurlFactory;
- use Magento\Framework\Json\DecoderInterface;
- use Magento\Store\Model\StoreManagerInterface;
- use Magento\User\Api\Data\UserInterface;
- use MSP\TwoFactorAuth\Api\UserConfigManagerInterface;
- use MSP\TwoFactorAuth\Model\Provider\Engine\Authy;
- class OneTouch
- {
- const XML_PATH_ONETOUCH_MESSAGE = 'msp_securitysuite_twofactorauth/authy/onetouch_message';
- /**
- * @var CurlFactory
- */
- private $curlFactory;
- /**
- * @var UserConfigManagerInterface
- */
- private $userConfigManager;
- /**
- * @var StoreManagerInterface
- */
- private $storeManager;
- /**
- * @var Service
- */
- private $service;
- /**
- * @var DecoderInterface
- */
- private $decoder;
- /**
- * @var ScopeConfigInterface
- */
- private $scopeConfig;
- /**
- * OneTouch constructor.
- * @param CurlFactory $curlFactory
- * @param UserConfigManagerInterface $userConfigManager
- * @param DecoderInterface $decoder
- * @param Service $service
- * @param StoreManagerInterface $storeManager
- * @param ScopeConfigInterface $scopeConfig
- */
- public function __construct(
- CurlFactory $curlFactory,
- UserConfigManagerInterface $userConfigManager,
- DecoderInterface $decoder,
- Service $service,
- StoreManagerInterface $storeManager,
- ScopeConfigInterface $scopeConfig
- ) {
- $this->curlFactory = $curlFactory;
- $this->userConfigManager = $userConfigManager;
- $this->storeManager = $storeManager;
- $this->service = $service;
- $this->decoder = $decoder;
- $this->scopeConfig = $scopeConfig;
- }
- /**
- * Request one-touch
- * @param UserInterface $user
- * @return true
- * @throws LocalizedException
- */
- public function request(UserInterface $user)
- {
- $providerInfo = $this->userConfigManager->getProviderConfig($user->getId(), Authy::CODE);
- if (!isset($providerInfo['user'])) {
- throw new LocalizedException(__('Missing user information'));
- }
- $url = $this->service->getOneTouchApiEndpoint('users/' . $providerInfo['user'] . '/approval_requests');
- $curl = $this->curlFactory->create();
- $curl->addHeader('X-Authy-API-Key', $this->service->getApiKey());
- $curl->post($url, [
- 'message' => $this->scopeConfig->getValue(self::XML_PATH_ONETOUCH_MESSAGE),
- 'details[URL]' => $this->storeManager->getStore()->getBaseUrl(),
- 'details[User]' => $user->getUserName(),
- 'details[Email]' => $user->getEmail(),
- 'seconds_to_expire' => 300,
- ]);
- $response = $this->decoder->decode($curl->getBody());
- if ($errorMessage = $this->service->getErrorFromResponse($response)) {
- throw new LocalizedException(__($errorMessage));
- }
- $this->userConfigManager->addProviderConfig($user->getId(), Authy::CODE, [
- 'pending_approval' => $response['approval_request']['uuid'],
- ]);
- return true;
- }
- /**
- * Verify one-touch
- * @param UserInterface $user
- * @return string
- * @throws LocalizedException
- */
- public function verify(UserInterface $user)
- {
- $providerInfo = $this->userConfigManager->getProviderConfig($user->getId(), Authy::CODE);
- if (!isset($providerInfo['user'])) {
- throw new LocalizedException(__('Missing user information'));
- }
- if (!isset($providerInfo['pending_approval'])) {
- throw new LocalizedException(__('No approval requests for this user'));
- }
- $approvalCode = $providerInfo['pending_approval'];
- if (!preg_match('/^\w[\w\-]+\w$/', $approvalCode)) {
- throw new LocalizedException(__('Invalid approval code'));
- }
- $url = $this->service->getOneTouchApiEndpoint('approval_requests/' . $approvalCode);
- $times = 10;
- for ($i=0; $i<$times; $i++) {
- $curl = $this->curlFactory->create();
- $curl->addHeader('X-Authy-API-Key', $this->service->getApiKey());
- $curl->get($url);
- $response = $this->decoder->decode($curl->getBody());
- if ($errorMessage = $this->service->getErrorFromResponse($response)) {
- throw new LocalizedException(__($errorMessage));
- }
- $status = $response['approval_request']['status'];
- if ($status == 'pending') {
- // @codingStandardsIgnoreStart
- sleep(1); // I know... but it is the only option I have here
- // @codingStandardsIgnoreEnd
- continue;
- }
- if ($status == 'approved') {
- return $status;
- }
- return $status;
- }
- return 'retry';
- }
- }
|