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'; } }