/** * Handle inbound redirect from various services * * @throws DreamFactory\Platform\Exceptions\RestException */ public function actionAuthorize() { Log::debug('Inbound $REQUEST: ' . print_r($_REQUEST, true)); $_state = Storage::defrost(Option::request('state')); $_origin = Option::get($_state, 'origin'); $_apiKey = Option::get($_state, 'api_key'); Log::debug('Inbound state: ' . print_r($_state, true)); if (empty($_origin) || empty($_apiKey)) { Log::error('Invalid request state.'); throw new BadRequestException(); } if ($_apiKey != ($_testKey = sha1($_origin))) { Log::error('API Key mismatch: ' . $_apiKey . ' != ' . $_testKey); throw new ForbiddenException(); } $_code = FilterInput::request('code', null, FILTER_SANITIZE_STRING); if (!empty($_code)) { Log::debug('Inbound code received: ' . $_code . ' from ' . $_state['origin']); } else { if (null === Option::get($_REQUEST, 'access_token')) { Log::error('Inbound request code missing.'); throw new RestException(HttpResponse::BadRequest); } else { Log::debug('Token received. Relaying to origin.'); } } $_redirectUri = Option::get($_state, 'redirect_uri', $_state['origin']); $_redirectUrl = $_redirectUri . (false === strpos($_redirectUri, '?') ? '?' : '&') . \http_build_query($_REQUEST); Log::debug('Proxying request to: ' . $_redirectUrl); header('Location: ' . $_redirectUrl); exit; }
/** * Given an inbound state string, convert to original defrosted state * * @param string $state If not supplied, $_REQUEST['state'] is used. * * @return array */ protected static function _decodeState($state = null) { if (null === ($_state = $state ?: Option::request('state'))) { return array(); } return Storage::defrost($_state); }
/** * Checks the progress of any in-flight OAuth requests * * * @throws \Exception|\OAuthException * @throws \DreamFactory\Oasys\Exceptions\RedirectRequiredException * @return string */ public function checkAuthenticationProgress() { if ($this->_config->getAccessToken()) { $this->_setToken(); return true; } $_state = $this->_config->getState(); $_accessToken = null; $_requestToken = Option::request('oauth_token'); $_tokenSecret = Option::request('oauth_secret', $this->_config->getAccessTokenSecret()); $_verifier = Option::request('oauth_verifier'); try { // No auth yet if (null === $_requestToken) { $_url = $this->_config->getEndpointUrl(EndpointTypes::REQUEST_TOKEN); $_token = $this->getRequestToken($_url); $this->setAccessTokenSecret($_tokenSecret = Option::get($_token, 'oauth_token_secret')); $this->setState(1); // Construct the redirect for authorization $_redirectUrl = $this->getEndpointUrl(EndpointTypes::AUTHORIZE) . '?oauth_token=' . Option::get($_token, 'oauth_token'); if (!empty($this->_redirectProxyUrl)) { $_redirectUrl = $this->_redirectProxyUrl . '?redirect=' . urlencode($_redirectUrl); } $this->_config->setAuthorizeUrl($_redirectUrl); if (Flows::SERVER_SIDE == $this->_config->getFlowType()) { throw new RedirectRequiredException($_redirectUrl); } header('Location: ' . $_redirectUrl); exit; } // Step 2! if (!empty($_requestToken) && !empty($_verifier)) { $this->_client->setToken($_requestToken, $_tokenSecret); $_accessToken = $this->_client->getAccessToken($this->_config->getEndpointUrl(EndpointTypes::ACCESS_TOKEN)); $this->_config->setState($_state = 2); $this->_config->setToken($_accessToken); $this->_config->setAccessToken($_accessToken['oauth_token']); $this->_config->setAccessTokenSecret($_accessToken['oauth_token_secret']); } // Set the token, now ready for action if (2 == $_state) { $this->_setToken(); } } catch (\OAuthException $_ex) { Log::error('OAuth exception: ' . $_ex->getMessage()); throw $_ex; } return true; }
/** * Checks the progress of any in-flight OAuth requests * * @param bool $skipTokenCheck If true, assume there is no token * * @throws NotImplementedException * @throws \DreamFactory\Oasys\Exceptions\RedirectRequiredException * @return string */ public function checkAuthenticationProgress($skipTokenCheck = false) { if (false === $skipTokenCheck && $this->getConfig('access_token')) { return true; } if (GrantTypes::AUTHORIZATION_CODE != $this->getConfig('grant_type')) { throw new NotImplementedException(); } $_code = FilterInput::get(INPUT_GET, 'code'); // No code is present, request one if (empty($_code)) { $_redirectUrl = $this->getAuthorizationUrl(); if (Flows::SERVER_SIDE == $this->getConfig('flow_type')) { throw new RedirectRequiredException($_redirectUrl); } header('Location: ' . $_redirectUrl); exit; } // Figure out where the redirect goes... $_redirectUri = $this->getConfig('redirect_uri'); $_proxyUrl = $this->getConfig('redirect_proxy_url'); if (!empty($_proxyUrl)) { $_redirectUri = $_proxyUrl; } // Got a code, now get a token $_token = $this->requestAccessToken(GrantTypes::AUTHORIZATION_CODE, array('code' => $_code, 'redirect_uri' => $_redirectUri, 'state' => Option::request('state'))); $_info = null; if (isset($_token, $_token['result'])) { if (!is_string($_token['result'])) { $_info = $_token['result']; } else { parse_str($_token['result'], $_info); } $this->_responsePayload = $_info; } if (!is_array($_info) && !is_object($_info) || null !== ($_error = Option::get($_info, 'error'))) { // Error Log::error('Error returned from oauth token request: ' . print_r($_info, true)); $this->_revokeAuthorization(); return false; } return $this->_processReceivedToken($_info); }