public function perform() { $hash = Request::getString($_REQUEST['x']); if (!strlen($hash) || base64_decode($hash, true) === false) { $this->req->setResult(['success' => false, 'error' => 'Wrong format of extTokenHash']); return; } $this->appInstance->externalAuthTokens->findByExtTokenHash($hash, function ($result) use($hash) { if ($result) { $this->req->setResult(['success' => false, 'error' => 'This token was already used.']); return; } $ip = $this->req->getIp(); $intToken = Crypt::hash(Daemon::uniqid() . "" . $ip . "" . Crypt::randomString()); $this->appInstance->externalAuthTokens->save(['extTokenHash' => $hash, 'intToken' => $intToken, 'ip' => $ip, 'useragent' => Request::getString($_SERVER['HTTP_USER_AGENT']), 'ctime' => microtime(true), 'status' => 'new'], function ($lastError) use($intToken) { if (!isset($lastError['n']) || $lastError['n'] === 0) { $this->req->setResult(['success' => false, 'errors' => ['code' => 'Sorry, internal error.']]); return; } $type = Request::getString($_REQUEST['type']); if ($type === 'email') { // send email.... } elseif ($type === 'redirect') { $this->req->redirectTo(HTTPClient::buildUrl(['/' . $this->req->locale . '/account/extauth', 'i' => $intToken]), false); } $this->req->setResult(['success' => true, 'intToken' => $intToken]); }); }); }
public function redirect() { if (!$this->checkReferer($this->appInstance->config->domain->value)) { $this->req->setResult(['error' => 'Wrong referer']); return; } $code = Request::getString($_GET['code']); if ($code === '') { Daemon::log('Authentication failed'); $this->req->status(401); $this->req->setResult(['error' => 'Authenticaion failed']); return; } $this->appInstance->httpclient->get($get = ['https://api.vk.com/oauth/access_token', 'client_id' => $this->cmp->config->vk_app_key->value, 'redirect_uri' => HTTPClient::buildUrl([$this->req->getBaseUrl() . '/component/Account/ExternalAuthRedirect/json', 'agent' => 'VK', 'backurl' => $this->getBackurl(true)]), 'client_secret' => $this->cmp->config->vk_app_secret->value, 'code' => $code], function ($conn, $success) use(&$get) { if (!$success) { $this->req->status(400); $this->req->setResult(['error' => 'request declined']); return; } Daemon::log(Debug::dump($get)); Daemon::log(Debug::dump($conn->body)); $response = json_decode(rtrim($conn->body), true); $user_id = isset($response['user_id']) ? (int) $response['user_id'] : 0; $access_token = Request::getString($response['access_token']); if ($user_id === 0 || $access_token === '') { $this->req->status(403); $this->req->setResult(['error' => 'no access token or user id']); return; } $this->appInstance->httpclient->get(['https://api.vk.com/method/users.get', 'uids' => $user_id, 'fields' => 'screen_name', 'access_token' => $access_token], function ($conn, $success) use($user_id) { $response = json_decode($conn->body, true); if (!$success || !is_array($response) || empty($user_id)) { $this->req->redirectTo($this->req->getBaseUrl(), false); $this->req->setResult(['error' => 'Unrecognized response']); return; } $data = []; if (isset($response['screen_name'])) { $data['username'] = Request::getString($response['screen_name']); } $this->req->components->account->acceptUserAuthentication('VK', $user_id, $data, [$this, 'finalRedirect']); }); }); }
/** * @param $url */ public function redirectTo($url, $finish = true, $perm = false) { $e = null; try { $url = HTTPClient::buildUrl($url); if (substr($url, 0, 1) === '/') { $url = $this->getBaseUrl() . $url; } if ($perm) { $this->status(301); $this->header('Location: ' . $url); } else { $this->status(302); $this->header('Cache-Control: no-cache, no-store, must-revalidate'); $this->header('Pragma: no-cache'); $this->header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); $this->header('Location: ' . $url); } } catch (RequestHeadersAlreadySent $e) { } if ($finish) { $this->finish(); } if ($e) { throw $e; } }