request = $request; $this->pdm = new PersistentDataManager(); $this->oAuthClientRepository = new OAuthClientRepository(); } public function isAuthenticationRequired(): bool { return true; } public function auth() { $redirectUri = $this->request->query('redirect_uri'); $clientId = $this->request->query('client_id'); $scope = $this->request->query('scope') ? $this->request->query('scope'): ''; $state = $this->request->query('state'); $nonce = $this->request->query('nonce') ? $this->request->query('nonce'): ''; if (!$clientId || !$redirectUri || !$state) { return new HtmlContent('oauth/oauth_error', ['error' => 'An invalid request was made. Please start authentication again.']); } $client = $this->oAuthClientRepository->getByClientId($clientId); if ($client === null) { return new HtmlContent('oauth/oauth_error', ['error' => 'Client is not authorized.']); } $redirectUriParsed = parse_url($redirectUri); $redirectUriBase = $redirectUriParsed['scheme'] . '://' . $redirectUriParsed['host'] . $redirectUriParsed['path']; $redirectUriQuery = []; if (isset($redirectUriParsed['query'])) { parse_str($redirectUriParsed['query'], $redirectUriQuery); } if (!in_array($redirectUriBase, $client->getRedirectUrisArray())) { return new HtmlContent('oauth/oauth_error', ['error' => 'Redirect URI \'' . $redirectUriBase .'\' is not allowed for this client.']); } /** * @var ?User $user */ $user = $this->request->user(); $code = bin2hex(random_bytes(16)); $accessToken = bin2hex(random_bytes(16)); $token = new OAuthToken(); $token->setNonce($nonce); $token->setScope($scope); $token->setUser($user); $token->setCode($code); $token->setAccessToken($accessToken); $token->setCreatedDate(new DateTime()); $token->setExpiresDate(new DateTime('+5 minutes')); $this->pdm->saveToDb($token); $redirectUriQuery = array_merge($redirectUriQuery, [ 'state' => $state, 'code' => $code ]); $finalRedirectUri = $redirectUriBase . '?' . http_build_query($redirectUriQuery); return new Redirect($finalRedirectUri, IRedirect::TEMPORARY); } }