/** * @param IOAuth2Client $client * @param array $input * * @return array * @throws OAuth2ServerException */ protected function grantAccessTokenAuthCode(IOAuth2Client $client, array $input) { if (!$this->storage instanceof IOAuth2GrantCode) { throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_UNSUPPORTED_GRANT_TYPE); } if (!$input["code"]) { throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_INVALID_REQUEST, 'Missing parameter. "code" is required'); } if ($this->getVariable(self::CONFIG_ENFORCE_INPUT_REDIRECT) && !$input["redirect_uri"]) { throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_INVALID_REQUEST, "The redirect URI parameter is required."); } $authCode = $this->storage->getAuthCode($input["code"]); // Check the code exists if ($authCode === null || $client->getPublicId() !== $authCode->getClientId()) { throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_INVALID_GRANT, "Code doesn't exist or is invalid for the client"); } // Validate the redirect URI. If a redirect URI has been provided on input, it must be validated if ($input["redirect_uri"] && !$this->validateRedirectUri($input["redirect_uri"], $authCode->getRedirectUri())) { throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_REDIRECT_URI_MISMATCH, "The redirect URI is missing or do not match"); } if ($authCode->hasExpired()) { throw new OAuth2ServerException(self::HTTP_BAD_REQUEST, self::ERROR_INVALID_GRANT, "The authorization code has expired"); } $this->usedAuthCode = $authCode; return array('scope' => $authCode->getScope(), 'data' => $authCode->getData()); }