Response validation

@param resource $curl
@param string $response
@throws HttpException
552963
public static function curlValidate($curl, $response = null)
    {
        $json = json_decode($response, true)?: [];
        if (($httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE))
            && !in_array($httpCode, [self::DEFAULT_STATUS_CODE, self::NOT_MODIFIED_STATUS_CODE])
        ) {
            $errorDescription = array_key_exists('description', $json) ? $json['description'] : self::$codes[$httpCode];
            $errorParameters = array_key_exists('parameters', $json) ? $json['parameters'] : [];
            throw new HttpException($errorDescription, $httpCode, null, $errorParameters);
        }
    }
397047
public function processResponse($curlResponse, $curlInfo, $curlError)
    {
        // print "\n" . $curlResponse;
        switch ($curlInfo['http_code']) {
            case '200':
                $responseObject = $this->_XML2Array($curlResponse);
                $ver = "Ver1.0";
                return $responseObject->$ver;
                break;
            case '500':
                $faultString = $this->_XMLFault2String($curlResponse);
                throw new HpsException($faultString);
                break;
            default:
                throw new HpsException('Unexpected response');
                break;
        }
    }
600742
public function execute($response) {

        $ok = $this->check_tool_proxy(null, $response->get_request_data());
        if ($ok) {
            $toolproxy = $this->get_service()->get_tool_proxy();
        } else {
            $toolproxy = null;
            $response->set_code(401);
        }
        $tools = array();

        // Ensure all required elements are present in the Tool Proxy.
        if ($ok) {
            $toolproxyjson = json_decode($response->get_request_data());
            $ok = !empty($toolproxyjson);
            if (!$ok) {
                debugging('Tool proxy is not properly formed JSON');
            } else {
                $ok = isset($toolproxyjson->tool_profile->product_instance->product_info->product_family->vendor->code);
                $ok = $ok && isset($toolproxyjson->security_contract->shared_secret);
                $ok = $ok && isset($toolproxyjson->tool_profile->resource_handler);
                if (!$ok) {
                    debugging('One or more missing elements from tool proxy: vendor code, shared secret or resource handlers');
                }
            }
        }

        // Check all capabilities requested were offered.
        if ($ok) {
            $offeredcapabilities = explode("\n", $toolproxy->capabilityoffered);
            $resources = $toolproxyjson->tool_profile->resource_handler;
            $errors = array();
            foreach ($resources as $resource) {
                if (isset($resource->message)) {
                    foreach ($resource->message as $message) {
                        if (!in_array($message->message_type, $offeredcapabilities)) {
                            $errors[] = $message->message_type;
                        } else if (isset($resource->parameter)) {
                            foreach ($message->parameter as $parameter) {
                                if (isset($parameter->variable) && !in_array($parameter->variable, $offeredcapabilities)) {
                                    $errors[] = $parameter->variable;
                                }
                            }
                        }
                    }
                }
            }
            if (count($errors) > 0) {
                $ok = false;
                debugging('Tool proxy contains capabilities which were not offered: ' . implode(', ', $errors));
            }
        }

        // Check all services requested were offered (only tool services currently supported).
        if ($ok && isset($toolproxyjson->security_contract->tool_service)) {
            $contexts = lti_get_contexts($toolproxyjson);
            $profileservice = lti_get_service_by_name('profile');
            $profileservice->set_tool_proxy($toolproxy);
            $context = $profileservice->get_service_path() . $profileservice->get_resources()[0]->get_path() . '#';
            $offeredservices = explode("\n", $toolproxy->serviceoffered);
            $services = lti_get_services();
            $tpservices = $toolproxyjson->security_contract->tool_service;
            $errors = array();
            foreach ($tpservices as $service) {
                $fqid = lti_get_fqid($contexts, $service->service);
                if (substr($fqid, 0, strlen($context)) !== $context) {
                    $errors[] = $service->service;
                } else {
                    $id = explode('#', $fqid, 2);
                    $aservice = lti_get_service_by_resource_id($services, $id[1]);
                    $classname = explode('\\', get_class($aservice));
                    if (empty($aservice) || !in_array($classname[count($classname) - 1], $offeredservices)) {
                        $errors[] = $service->service;
                    }
                }
            }
            if (count($errors) > 0) {
                $ok = false;
                debugging('Tool proxy contains services which were not offered: ' . implode(', ', $errors));
            }
        }

        // Extract all launchable tools from the resource handlers.
        if ($ok) {
            $resources = $toolproxyjson->tool_profile->resource_handler;
            $messagetypes = [
                'basic-lti-launch-request',
                'ContentItemSelectionRequest',
            ];
            foreach ($resources as $resource) {
                $launchable = false;
                $messages = array();
                $tool = new \stdClass();

                $iconinfo = null;
                if (is_array($resource->icon_info)) {
                    $iconinfo = $resource->icon_info[0];
                } else {
                    $iconinfo = $resource->icon_info;
                }
                if (isset($iconinfo) && isset($iconinfo->default_location) && isset($iconinfo->default_location->path)) {
                    $tool->iconpath = $iconinfo->default_location->path;
                }

                foreach ($resource->message as $message) {
                    if (in_array($message->message_type, $messagetypes)) {
                        $launchable = $launchable || ($message->message_type === 'basic-lti-launch-request');
                        $messages[$message->message_type] = $message;
                    }
                }
                if (!$launchable) {
                    continue;
                }
                $tool->name = $resource->resource_name->default_value;
                $tool->messages = $messages;
                $tools[] = $tool;
            }
            $ok = count($tools) > 0;
            if (!$ok) {
                debugging('No launchable messages found in tool proxy');
            }
        }

        // Add tools and custom parameters.
        if ($ok) {
            $baseurl = '';
            if (isset($toolproxyjson->tool_profile->base_url_choice[0]->default_base_url)) {
                $baseurl = $toolproxyjson->tool_profile->base_url_choice[0]->default_base_url;
            }
            $securebaseurl = '';
            if (isset($toolproxyjson->tool_profile->base_url_choice[0]->secure_base_url)) {
                $securebaseurl = $toolproxyjson->tool_profile->base_url_choice[0]->secure_base_url;
            }
            foreach ($tools as $tool) {
                $messages = $tool->messages;
                $launchrequest = $messages['basic-lti-launch-request'];
                $config = new \stdClass();
                $config->lti_toolurl = "{$baseurl}{$launchrequest->path}";
                $config->lti_typename = $tool->name;
                $config->lti_coursevisible = 1;
                $config->lti_forcessl = 0;
                if (isset($messages['ContentItemSelectionRequest'])) {
                    $contentitemrequest = $messages['ContentItemSelectionRequest'];
                    $config->lti_contentitem = 1;
                    if ($launchrequest->path !== $contentitemrequest->path) {
                        $config->lti_toolurl_ContentItemSelectionRequest = $baseurl . $contentitemrequest->path;
                    }
                    $contentitemcapabilities = implode("\n", $contentitemrequest->enabled_capability);
                    $config->lti_enabledcapability_ContentItemSelectionRequest = $contentitemcapabilities;
                    $contentitemparams = self::lti_extract_parameters($contentitemrequest->parameter);
                    $config->lti_parameter_ContentItemSelectionRequest = $contentitemparams;
                }

                $type = new \stdClass();
                $type->state = LTI_TOOL_STATE_PENDING;
                $type->toolproxyid = $toolproxy->id;
                $type->enabledcapability = implode("\n", $launchrequest->enabled_capability);
                $type->parameter = self::lti_extract_parameters($launchrequest->parameter);

                if (!empty($tool->iconpath)) {
                    $type->icon = "{$baseurl}{$tool->iconpath}";
                    if (!empty($securebaseurl)) {
                        $type->secureicon = "{$securebaseurl}{$tool->iconpath}";
                    }
                }

                $ok = $ok && (lti_add_type($type, $config) !== false);
            }
            if (isset($toolproxyjson->custom)) {
                lti_set_tool_settings($toolproxyjson->custom, $toolproxy->id);
            }
        }

        if (!empty($toolproxy)) {
            if ($ok) {
                // If all went OK accept the tool proxy.
                $toolproxy->state = LTI_TOOL_PROXY_STATE_ACCEPTED;
                $toolproxy->toolproxy = $response->get_request_data();
                $toolproxy->secret = $toolproxyjson->security_contract->shared_secret;
                $toolproxy->vendorcode = $toolproxyjson->tool_profile->product_instance->product_info->product_family->vendor->code;

                $url = $this->get_endpoint();
                $body = <<< EOD
{
  "@context" : "http://purl.imsglobal.org/ctx/lti/v2/ToolProxyId",
  "@type" : "ToolProxy",
  "@id" : "{$url}",
  "tool_proxy_guid" : "{$toolproxy->guid}"
}
EOD;
                $response->set_code(201);
                $response->set_content_type('application/vnd.ims.lti.v2.toolproxy.id+json');
                $response->set_body($body);
            } else {
                // Otherwise reject the tool proxy.
                $toolproxy->state = LTI_TOOL_PROXY_STATE_REJECTED;
                $response->set_code(400);
            }
            lti_update_tool_proxy($toolproxy);
        } else {
            $response->set_code(400);
        }
    }
1060258
public function exec(): Response
    {
        $url = $this->getUrl();

        $ch = curl_init($url);

        foreach ($this->getCurlOptions() as $option => $value) {
            // iterating it so we have all options applied in given order
            curl_setopt($ch, $option, $value);
        }

        $body = curl_exec($ch);

        if (curl_errno($ch)) {
            throw new HttpException(curl_error($ch));
        }

        return new Response($ch, $body, $this);
    }
502320
private function performResponse($response)
    {
        $data = false;
        if ($response instanceof ResponseInterface) {
            $data = json_decode($response->getBody()->getContents());
            $this->getValidationResponse()->validateResponseData($data);
        }

        return $data;
    }
585188
public function execute($response) {
        global $DB;

        $params = $this->parse_template();
        $contextid = $params['context_id'];
        $isget = $response->get_request_method() === self::HTTP_GET;
        if ($isget) {
            $contenttype = $response->get_accept();
        } else {
            $contenttype = $response->get_content_type();
        }
        $container = empty($contenttype) || ($contenttype === $this->formats[0]);
        // We will receive typeid when working with LTI 1.x, if not the we are in LTI 2.
        $typeid = optional_param('type_id', null, PARAM_ALPHANUM);
        if (is_null($typeid)) {
            if (!$this->check_tool_proxy(null, $response->get_request_data())) {
                $response->set_code(403);
                $response->set_reason("Invalid tool proxy specified.");
                return;
            }
        } else {
            switch ($response->get_request_method()) {
                case self::HTTP_GET:
                    if (!$this->check_type($typeid, $contextid, 'LineItem.collection:get', $response->get_request_data())) {
                        $response->set_code(403);
                        $response->set_reason("This resource does not support GET requests.");
                        return;
                    }
                    break;
                case self::HTTP_POST:
                    if (!$this->check_type($typeid, $contextid, 'LineItem.collection:post', $response->get_request_data())) {
                        $response->set_code(403);
                        $response->set_reason("This resource does not support POST requests.");
                        return;
                    }
                    break;
                default:  // Should not be possible.
                    $response->set_code(405);
                    $response->set_reason("Invalid request method specified.");
                    return;
            }
        }
        if (empty($contextid) || !($container ^ ($response->get_request_method() === self::HTTP_POST)) ||
                (!empty($contenttype) && !in_array($contenttype, $this->formats))) {
            $response->set_code(400);
            $response->set_reason("Invalid request made.");
            return;
        }
        if (!$DB->record_exists('course', array('id' => $contextid))) {
            $response->set_code(404);
            $response->set_reason("Not Found: Course $contextid doesn't exist.");
            return;
        }
        switch ($response->get_request_method()) {
            case self::HTTP_GET:
                $resourceid = optional_param('resource_id', null, PARAM_TEXT);
                $ltilinkid = optional_param('lti_link_id', null, PARAM_TEXT);
                $tag = optional_param('tag', null, PARAM_TEXT);
                $limitnum = optional_param('limit', 0, PARAM_INT);
                $limitfrom = optional_param('from', 0, PARAM_INT);
                $itemsandcount = $this->get_service()->get_lineitems($contextid, $resourceid, $ltilinkid, $tag, $limitfrom,
                        $limitnum, $typeid);
                $items = $itemsandcount[1];
                $totalcount = $itemsandcount[0];
                $json = $this->get_json_for_get_request($items, $resourceid, $ltilinkid, $tag, $limitfrom,
                        $limitnum, $totalcount, $typeid, $response);
                $response->set_content_type($this->formats[0]);
                break;
            case self::HTTP_POST:
                try {
                    $json = $this->get_json_for_post_request($response->get_request_data(), $contextid, $typeid);
                    $response->set_code(201);
                    $response->set_content_type($this->formats[1]);
                } catch (\Exception $e) {
                    $response->set_code($e->getCode());
                    $response->set_reason($e->getMessage());
                }
                break;
            default:  // Should not be possible.
                $response->set_code(405);
                $response->set_reason("Invalid request method specified.");
                return;
        }
        $response->set_body($json);
    }
614256
private function checkForOaipmhException(HttpException $httpException)
    {
        try {
            if ($resp = $httpException->getBody()) {
                $this->decodeResponse($resp); // Throw OaipmhException in case of an error
            }
        } catch (MalformedResponseException $e) {
            // There was no valid OAI error in the response, therefore re-throw HttpException
        }

        throw $httpException;
    }
1196666
public function validateRequest(RequestInterface $request, ResponseInterface $response)
    {
        $providerName        = $request->request('provider');
        $providerUserId      = $request->request('provider_user_id');
        $providerAccessToken = $request->request('provider_access_token');

        if (! $providerName || ! $providerUserId || ! $providerAccessToken) {
            $response->setError(
                400,
                'invalid_request',
                'One or more missing parameter: "provider", "provider_user_id" and "provider_access_token" are required'
            );

            return false;
        }

        $provider = isset($this->providers[$providerName]) ? $this->providers[$providerName] : null;

        if (! $provider instanceof ProviderInterface) {
            $response->setError(400, 'invalid_request', 'Unknown provider selected');

            return false;
        }

        try {
            $errorMessage = '';
            if (! $provider->validate($providerUserId, $providerAccessToken, $errorMessage)) {
                $response->setError(401, 'invalid_grant', 'Invalid third party credentials: ' . $errorMessage);

                return false;
            }
        } catch (ClientException $e) {
            $response->setError($e->getCode(), 'provider_client_error', $e->getMessage());

            return false;
        } catch (Exception $e) {
            $response->setError(500, 'provider_error', $e->getMessage());

            return false;
        }

        $token       = $request->request('access_token');
        $accessToken = $token ? $this->accessTokenMapper->findByToken($token) : null;

        if ($accessToken instanceof Entity\AccessToken && $accessToken->isExpired()) {
            $response->setError(401, 'invalid_grant', 'Access token is expired');

            return false;
        }

        $thirdPartyUser = $this->thirdPartyMapper->findByProvider($provider);

        switch (true) {
            // a known user tries to connect with third party credentials owned by another user? issue an error
            case ($accessToken instanceof Entity\AccessToken
                    && $thirdPartyUser instanceof Entity\ThirdParty
                    && $thirdPartyUser->getUser() !== $accessToken->getUser()):
                $response->setError(400, 'invalid_request', 'Another user is already registered with same credentials');

                return false;

            // known third party credentials? update the data and grab the user form it
            case ($thirdPartyUser instanceof Entity\ThirdParty):
                $thirdPartyUser->setData($provider->getUserData());
                $user = $thirdPartyUser->getUser();
                break;

            // valid access token? grab the user form it
            case ($accessToken instanceof Entity\AccessToken):
                $user = $accessToken->getUser();
                break;

            // no third party credentials or access token? it's a new user
            default:
                $userClass = $this->moduleOptions->getUserEntityClassName();
                $user      = new $userClass();
        }

        // in case 3 and 4 we need to connect the user with new third party credentials
        if (! $thirdPartyUser instanceof Entity\ThirdParty) {
            $this->connectUserToThirdParty($user, $provider);
        }

        $this->userMapper->save($user);
        $this->user = $user;

        return true;
    }
135230
private function CheckResponseCode($responseCode, $response)
    {
        if ($responseCode < 200 || $responseCode > 299) {
            if (isset($response) && is_object($response) && isset($response->Message)) {
                $error = new Error();
                $error->Message = $response->Message;
                $error->Errors = property_exists($response, 'Errors')
                    ? $response->Errors
                    : property_exists($response, 'errors') ? $response->errors : null;
                $error->Id = property_exists($response, 'Id') ? $response->Id : null;
                $error->Type = property_exists($response, 'Type') ? $response->Type : null;
                $error->Date = property_exists($response, 'Date') ? $response->Date : null;
                throw new ResponseException($this->_requestUrl, $responseCode, $error);
            } else {
                throw new ResponseException($this->_requestUrl, $responseCode);
            }
        }
    }
990422
protected function processResponse(HTTP_Request2_Response $response)
    {
        if ($this->responseRegex !== '') {
            $this->regexp->setPattern($this->responseRegex);

            if (!$this->regexp->matches($response->getBody())) {
                throw new BuildException('The received response body did not match the given regular expression');
            } else {
                $this->log('The response body matched the provided regex.');
            }
        }

        if ($this->responseCodeRegex !== '') {
            $this->regexp->setPattern($this->responseCodeRegex);

            if (!$this->regexp->matches($response->getStatus())) {
                throw new BuildException('The received response status-code did not match the given regular expression');
            } else {
                $this->log('The response status-code matched the provided regex.');
            }
        }
    }
786460
private function _isValidResponse($response)
    {
        if (is_null($response)) {
            return self::ERROR_EMPTY;
        }

        if (!isset($response->result) or ($response->result != 'error')) {
            return true;
        }

        return $response->message;
    }
643706
protected function processResponse($curlResponse, $curlInfo, $curlError)
    {
        $response = json_decode($curlResponse);

        if (isset($response->error) && is_object($response->error)) {
            throw new HpsException($response->error->message, $response->error->code);
        }
        
        return $response;
    }
1005691
protected function validate_response($response) {

        $response = $this->decode_response($response);

        if (empty($response)) {
            throw new checker_exception('err_response_empty');
        }

        if (empty($response['status']) or $response['status'] !== 'OK') {
            throw new checker_exception('err_response_status', $response['status']);
        }

        if (empty($response['apiver']) or $response['apiver'] !== '1.3') {
            throw new checker_exception('err_response_format_version', $response['apiver']);
        }

        if (empty($response['forbranch']) or $response['forbranch'] !== moodle_major_version(true)) {
            throw new checker_exception('err_response_target_version', $response['forbranch']);
        }
    }
1153798
public function validateResponse(Response $response)
	{
		$xml = simplexml_load_string($response->body);

		if (isset($xml->warnings))
		{
			throw new \DomainException($xml->warnings->info);
		}

		if (isset($xml->error))
		{
			throw new \DomainException($xml->error['info']);
		}

		return $xml;
	}
1278920
protected function validateOpauthResponse($opauth, $response) {
		if(!empty($response['error'])) {
			throw new OpauthValidationException('Oauth provider error', 1, $response['error']);
		}

		// Required components within the response
		$this->requireResponseComponents(
			array('auth', 'timestamp', 'signature'),
			$response
		);

		// More required components within the auth section...
		$this->requireResponseComponents(
			array('provider', 'uid'),
			$response['auth']
		);

		$invalidReason = '';

		/**
		 * @todo: improve this signature check. it's a bit weak.
		 */
		if(!$opauth->validate(
			sha1(print_r($response['auth'], true)),
			$response['timestamp'],
			$response['signature'],
			$invalidReason
		)) {
			throw new OpauthValidationException('Invalid auth response', 3, $invalidReason);
		}
	}
1190869
public static function parseErrorsFromResponse(HttpResponse $response)
    {
        $json = $response->getJsonResult();
        $errorStr = '';
        if (isset($json->errors)
            && is_array($json->errors)
            && !empty($json->errors)
        ) {
            foreach ($json->errors as $stdClassError) {
                if (isset($stdClassError->errors)) {
                    $errorStr .= $stdClassError->errors;
                }
                if (isset($stdClassError->product_id)) {
                    $errorStr .= sprintf('(product #%s)', $stdClassError->product_id);
                }
            }
        }

        return $errorStr;
    }
177417
protected function validateResponse($response)
    {
        if (isset($response->code) && isset($response->message)) {
            if ($response->code == $this->validResponseCode &&
                $response->message == $this->validResponseMessage
            ) {
                // serial keys are valid
                $valid = true;
            } else {
                // serial keys are not valid
                $this->setErrorMessage(\OxidEsales\Eshop\Core\Registry::getLang()->translateString('OLC_ERROR_SERIAL_NOT_VALID'));
                $valid = false;
            }
        } else {
            // validation result is unknown
            throw new \OxidEsales\Eshop\Core\Exception\StandardException('OLC_ERROR_RESPONSE_NOT_VALID');
        }

        return $valid;
    }