/**
  * Validate request
  *
  * @throws AuthorizationException
  * @throws \Magento\Framework\Webapi\Exception
  * @return void
  */
 public function validate()
 {
     $this->checkPermissions();
     $route = $this->router->match($this->request);
     if ($route->isSecure() && !$this->request->isSecure()) {
         throw new \Magento\Framework\Webapi\Exception(__('Operation allowed only in HTTPS'));
     }
 }
 /**
  * Test insecure request for a secure route
  *
  * @expectedException \Magento\Framework\Webapi\Exception
  * @expectedExceptionMessage Operation allowed only in HTTPS
  */
 public function testInSecureRequestOverSecureRoute()
 {
     $this->routeMock->expects($this->any())->method('isSecure')->will($this->returnValue(true));
     $this->routeMock->expects($this->any())->method('getAclResources')->will($this->returnValue(['1']));
     $this->requestMock->expects($this->any())->method('isSecure')->will($this->returnValue(false));
     $this->authorizationMock->expects($this->once())->method('isAllowed')->will($this->returnValue(true));
     $this->requestValidator->validate();
 }
 /**
  * Process filter from the request and apply over response to get the partial results
  *
  * @param array $response
  * @return array partial response array or empty array if invalid filter criteria is provided
  */
 public function filter($response)
 {
     $filter = $this->_request->getParam(self::FILTER_PARAMETER);
     if (!is_string($filter)) {
         return [];
     }
     $filterArray = $this->parse($filter);
     if ($filterArray === null) {
         return [];
     }
     $partialResponse = $this->applyFilter($response, $filterArray);
     return $partialResponse;
 }
Example #4
0
 /**
  * Generate the list of available REST routes. Current HTTP method is taken into account.
  *
  * @param \Magento\Framework\Webapi\Rest\Request $request
  * @return Route[] matched routes
  * @throws \Magento\Framework\Webapi\Exception
  */
 public function getRestRoutes(\Magento\Framework\Webapi\Rest\Request $request)
 {
     $requestHttpMethod = $request->getHttpMethod();
     $servicesRoutes = $this->_config->getServices()[Converter::KEY_ROUTES];
     $routes = [];
     // Return the route on exact match
     if (isset($servicesRoutes[$request->getPathInfo()][$requestHttpMethod])) {
         $methodInfo = $servicesRoutes[$request->getPathInfo()][$requestHttpMethod];
         $routes[] = $this->_createRoute([self::KEY_ROUTE_PATH => $request->getPathInfo(), self::KEY_CLASS => $methodInfo[Converter::KEY_SERVICE][Converter::KEY_SERVICE_CLASS], self::KEY_METHOD => $methodInfo[Converter::KEY_SERVICE][Converter::KEY_SERVICE_METHOD], self::KEY_IS_SECURE => $methodInfo[Converter::KEY_SECURE], self::KEY_ACL_RESOURCES => array_keys($methodInfo[Converter::KEY_ACL_RESOURCES]), self::KEY_PARAMETERS => $methodInfo[Converter::KEY_DATA_PARAMETERS]]);
         return $routes;
     }
     $serviceBaseUrl = $this->_getServiceBaseUrl($request);
     ksort($servicesRoutes, SORT_STRING);
     foreach ($servicesRoutes as $url => $httpMethods) {
         // skip if baseurl is not null and does not match
         if (!$serviceBaseUrl || strpos(trim($url, '/'), trim($serviceBaseUrl, '/')) !== 0) {
             // base url does not match, just skip this service
             continue;
         }
         foreach ($httpMethods as $httpMethod => $methodInfo) {
             if (strtoupper($httpMethod) == strtoupper($requestHttpMethod)) {
                 $aclResources = array_keys($methodInfo[Converter::KEY_ACL_RESOURCES]);
                 $routes[] = $this->_createRoute([self::KEY_ROUTE_PATH => $url, self::KEY_CLASS => $methodInfo[Converter::KEY_SERVICE][Converter::KEY_SERVICE_CLASS], self::KEY_METHOD => $methodInfo[Converter::KEY_SERVICE][Converter::KEY_SERVICE_METHOD], self::KEY_IS_SECURE => $methodInfo[Converter::KEY_SECURE], self::KEY_ACL_RESOURCES => $aclResources, self::KEY_PARAMETERS => $methodInfo[Converter::KEY_DATA_PARAMETERS]]);
             }
         }
     }
     return $routes;
 }
Example #5
0
 /**
  * Handle REST request
  *
  * @param \Magento\Framework\App\RequestInterface $request
  * @return \Magento\Framework\App\ResponseInterface
  */
 public function dispatch(\Magento\Framework\App\RequestInterface $request)
 {
     $path = $this->_pathProcessor->process($request->getPathInfo());
     $this->_request->setPathInfo($path);
     $this->areaList->getArea($this->_appState->getAreaCode())->load(\Magento\Framework\App\Area::PART_TRANSLATE);
     try {
         $this->checkPermissions();
         $route = $this->getCurrentRoute();
         if ($route->isSecure() && !$this->_request->isSecure()) {
             throw new \Magento\Framework\Webapi\Exception(__('Operation allowed only in HTTPS'));
         }
         /** @var array $inputData */
         $inputData = $this->_request->getRequestData();
         $serviceMethodName = $route->getServiceMethod();
         $serviceClassName = $route->getServiceClass();
         $inputData = $this->paramsOverrider->override($inputData, $route->getParameters());
         $inputParams = $this->serviceInputProcessor->process($serviceClassName, $serviceMethodName, $inputData);
         $service = $this->_objectManager->get($serviceClassName);
         /** @var \Magento\Framework\Api\AbstractExtensibleObject $outputData */
         $outputData = call_user_func_array([$service, $serviceMethodName], $inputParams);
         $outputData = $this->serviceOutputProcessor->process($outputData, $serviceClassName, $serviceMethodName);
         if ($this->_request->getParam(FieldsFilter::FILTER_PARAMETER) && is_array($outputData)) {
             $outputData = $this->fieldsFilter->filter($outputData);
         }
         $this->_response->prepareResponse($outputData);
     } catch (\Exception $e) {
         $maskedException = $this->_errorProcessor->maskException($e);
         $this->_response->setException($maskedException);
     }
     return $this->_response;
 }
 /**
  * Find renderer which can render response in requested format.
  *
  * @return string
  * @throws \Magento\Framework\Webapi\Exception
  */
 protected function _getRendererClass()
 {
     $acceptTypes = $this->_request->getAcceptTypes();
     if (!is_array($acceptTypes)) {
         $acceptTypes = [$acceptTypes];
     }
     foreach ($acceptTypes as $acceptType) {
         foreach ($this->_renders as $rendererConfig) {
             $rendererType = $rendererConfig['type'];
             if ($acceptType == $rendererType || $acceptType == current(explode('/', $rendererType)) . '/*' || $acceptType == '*/*') {
                 return $rendererConfig['model'];
             }
         }
     }
     /** If server does not have renderer for any of the accepted types it SHOULD send 406 (not acceptable). */
     throw new \Magento\Framework\Webapi\Exception(new Phrase('Server cannot match any of the given Accept HTTP header media type(s) from the request: "%1" ' . 'with media types from the config of response renderer.', $acceptTypes), 0, \Magento\Framework\Webapi\Exception::HTTP_NOT_ACCEPTABLE);
 }
Example #7
0
 public function testGetMethodAllStoresInvalid()
 {
     $this->_routeMock->expects($this->any())->method('getAclResources')->will($this->returnValue(['1']));
     $this->_authorizationMock->expects($this->any())->method('isAllowed')->will($this->returnValue(true));
     $this->storeMock->expects($this->once())->method('getCode')->willReturn('admin');
     $this->_requestMock->expects($this->once())->method('getMethod')->willReturn('get');
     $this->_restController->dispatch($this->_requestMock);
     $this->assertTrue($this->_responseMock->isException());
     $this->assertSame("Cannot perform GET operation with store code 'all'", $this->_responseMock->getException()[0]->getMessage());
 }
Example #8
0
 /**
  * Validate request
  *
  * @throws AuthorizationException
  * @throws \Magento\Framework\Webapi\Exception
  * @return void
  */
 protected function validateRequest()
 {
     $this->checkPermissions();
     if ($this->getCurrentRoute()->isSecure() && !$this->_request->isSecure()) {
         throw new \Magento\Framework\Webapi\Exception(__('Operation allowed only in HTTPS'));
     }
     if ($this->storeManager->getStore()->getCode() === Store::ADMIN_CODE && strtoupper($this->_request->getMethod()) === RestRequest::HTTP_METHOD_GET) {
         throw new \Magento\Framework\Webapi\Exception(__('Cannot perform GET operation with store code \'all\''));
     }
 }
Example #9
0
 public function testDispatchAllSchemaRequest()
 {
     $params = [\Magento\Framework\Webapi\Request::REQUEST_PARAM_SERVICES => 'all'];
     $this->_requestMock->expects($this->any())->method('getPathInfo')->willReturn(\Magento\Webapi\Controller\Rest::SCHEMA_PATH);
     $this->_requestMock->expects($this->any())->method('getParam')->will($this->returnValueMap([[\Magento\Framework\Webapi\Request::REQUEST_PARAM_SERVICES, null, 'all']]));
     $this->_requestMock->expects($this->any())->method('getParams')->will($this->returnValue($params));
     $this->_requestMock->expects($this->any())->method('getRequestedServices')->will($this->returnValue('all'));
     $schema = 'Some REST schema content';
     $this->swaggerGeneratorMock->expects($this->any())->method('generate')->willReturn($schema);
     $this->swaggerGeneratorMock->expects($this->once())->method('getListOfServices')->willReturn(['listOfServices']);
     $this->_restController->dispatch($this->_requestMock);
     $this->assertEquals($schema, $this->_responseMock->getBody());
 }
Example #10
0
 /**
  * Test insecure request for a secure route
  */
 public function testInSecureRequestOverSecureRoute()
 {
     $this->_serviceMock->expects($this->any())->method(self::SERVICE_METHOD)->will($this->returnValue([]));
     $this->_routeMock->expects($this->any())->method('isSecure')->will($this->returnValue(true));
     $this->_routeMock->expects($this->any())->method('getAclResources')->will($this->returnValue(['1']));
     $this->_requestMock->expects($this->any())->method('isSecure')->will($this->returnValue(false));
     $this->_authorizationMock->expects($this->once())->method('isAllowed')->will($this->returnValue(true));
     // Override default prepareResponse. It should never be called in this case
     $this->_responseMock->expects($this->never())->method('prepareResponse');
     $this->_restController->dispatch($this->_requestMock);
     $this->assertTrue($this->_responseMock->isException());
     $exceptionArray = $this->_responseMock->getException();
     $this->assertEquals('Operation allowed only in HTTPS', $exceptionArray[0]->getMessage());
     $this->assertEquals(\Magento\Framework\Webapi\Exception::HTTP_BAD_REQUEST, $exceptionArray[0]->getHttpCode());
 }
Example #11
0
 /**
  * Test for getContentType() method.
  *
  * @dataProvider providerContentType
  * @param string $contentTypeHeader 'Content-Type' header value
  * @param string $contentType Appropriate content type for header value
  * @param string|boolean $exceptionMessage \Exception message (boolean FALSE if exception is not expected)
  */
 public function testGetContentType($contentTypeHeader, $contentType, $exceptionMessage = false)
 {
     $this->_request->expects($this->once())->method('getHeader')->with('Content-Type')->will($this->returnValue($contentTypeHeader));
     try {
         $this->assertEquals($contentType, $this->_request->getContentType());
     } catch (\Magento\Framework\Exception\InputException $e) {
         if ($exceptionMessage) {
             $this->assertEquals($exceptionMessage, $e->getMessage(), 'Exception message does not match the expected one.');
             return;
         } else {
             $this->fail('Exception is thrown on valid header: ' . $e->getMessage());
         }
     }
     if ($exceptionMessage) {
         $this->fail('Expected exception was not raised.');
     }
 }
 /**
  * Process and resolve input parameters
  *
  * @return array
  * @throws \Magento\Framework\Webapi\Exception
  */
 public function resolve()
 {
     $this->requestValidator->validate();
     $route = $this->getRoute();
     $serviceMethodName = $route->getServiceMethod();
     $serviceClassName = $route->getServiceClass();
     /*
      * Valid only for updates using PUT when passing id value both in URL and body
      */
     if ($this->request->getHttpMethod() == RestRequest::HTTP_METHOD_PUT) {
         $inputData = $this->paramsOverrider->overrideRequestBodyIdWithPathParam($this->request->getParams(), $this->request->getBodyParams(), $serviceClassName, $serviceMethodName);
         $inputData = array_merge($inputData, $this->request->getParams());
     } else {
         $inputData = $this->request->getRequestData();
     }
     $inputData = $this->paramsOverrider->override($inputData, $route->getParameters());
     $inputParams = $this->serviceInputProcessor->process($serviceClassName, $serviceMethodName, $inputData);
     return $inputParams;
 }
 /**
  * @dataProvider invalidFilterDataProvider
  */
 public function testInvalidFilters($invalidFilter)
 {
     $this->requestMock->expects($this->any())->method('getParam')->will($this->returnValue($invalidFilter));
     $filteredResponse = $this->processor->filter($this->sampleResponseValue);
     $this->assertEmpty($filteredResponse);
 }