Пример #1
0
 protected function setUp()
 {
     $this->_helper = new Magento_Test_Helper_ObjectManager($this);
     $this->_helperData = $this->getMockBuilder('Mage_Webapi_Helper_Data')->disableOriginalConstructor()->setMethods(array('__'))->getMock();
     $this->_helperData->expects($this->any())->method('__')->will($this->returnArgument(0));
     $this->_objectManager = $this->getMockBuilder('Magento_ObjectManager')->disableOriginalConstructor()->setMethods(array('create'))->getMockForAbstractClass();
 }
Пример #2
0
 /**
  * Check permissions on specific resource in ACL.
  *
  * @param string $resource
  * @param string $method
  * @throws Mage_Webapi_Exception
  */
 public function checkResourceAcl($resource, $method)
 {
     $coreAuthorization = $this->_coreAuthorization;
     if (!$coreAuthorization->isAllowed($resource . Mage_Webapi_Model_Acl_Rule::RESOURCE_SEPARATOR . $method) && !$coreAuthorization->isAllowed(Mage_Webapi_Model_Authorization::API_ACL_RESOURCES_ROOT_ID)) {
         throw new Mage_Webapi_Exception($this->_helper->__('Access to resource is forbidden.'), Mage_Webapi_Exception::HTTP_FORBIDDEN);
     }
 }
Пример #3
0
 /**
  * Get renderer for Mime-Type specified in Accept header of request.
  *
  * @return Mage_Webapi_Controller_Response_Rest_RendererInterface
  * @throws Mage_Webapi_Exception
  * @throws LogicException
  */
 public function get()
 {
     $acceptTypes = $this->_request->getAcceptTypes();
     $availableRenderers = (array) $this->_applicationConfig->getNode(self::XML_PATH_WEBAPI_RESPONSE_RENDERS);
     if (!is_array($acceptTypes)) {
         $acceptTypes = array($acceptTypes);
     }
     foreach ($acceptTypes as $acceptType) {
         foreach ($availableRenderers as $rendererConfig) {
             $rendererType = (string) $rendererConfig->type;
             if ($acceptType == $rendererType || $acceptType == current(explode('/', $rendererType)) . '/*' || $acceptType == '*/*') {
                 $rendererClass = (string) $rendererConfig->model;
                 break 2;
             }
         }
     }
     if (!isset($rendererClass)) {
         /** If server does not have renderer for any of the accepted types it SHOULD send 406 (not acceptable). */
         throw new Mage_Webapi_Exception($this->_helper->__('Server cannot understand Accept HTTP header media type.'), Mage_Webapi_Exception::HTTP_NOT_ACCEPTABLE);
     }
     $renderer = $this->_objectManager->get($rendererClass);
     if (!$renderer instanceof Mage_Webapi_Controller_Response_Rest_RendererInterface) {
         throw new LogicException('The renderer must implement "Mage_Webapi_Controller_Response_Rest_RendererInterface".');
     }
     return $renderer;
 }
Пример #4
0
 public function testCheckResourceAclMageWebapiException()
 {
     $this->_coreAuthorization->expects($this->exactly(2))->method('isAllowed')->will($this->returnValue(false));
     $this->_helperMock->expects($this->once())->method('__')->will($this->returnArgument(0));
     $this->setExpectedException('Mage_Webapi_Exception', 'Access to resource is forbidden.');
     $this->_webapiAuthorization->checkResourceAcl('invalidResource', 'invalidMethod');
 }
Пример #5
0
 protected function setUp()
 {
     /** Prepare mocks for SUT constructor. */
     $this->_apiConfigMock = $this->getMockBuilder('Mage_Webapi_Model_Config_Rest')->disableOriginalConstructor()->getMock();
     $interpreterFactory = $this->getMockBuilder('Mage_Webapi_Controller_Request_Rest_Interpreter_Factory')->disableOriginalConstructor()->getMock();
     $this->_helperMock = $this->getMockBuilder('Mage_Webapi_Helper_Data')->disableOriginalConstructor()->setMethods(array('__'))->getMock();
     $this->_helperMock->expects($this->any())->method('__')->will($this->returnArgument(0));
     $this->_routeMock = $this->getMockBuilder('Mage_Webapi_Controller_Router_Route_Rest')->disableOriginalConstructor()->setMethods(array('match'))->getMock();
     $this->_request = new Mage_Webapi_Controller_Request_Rest($interpreterFactory, $this->_helperMock);
     /** Initialize SUT. */
     $this->_router = new Mage_Webapi_Controller_Router_Rest($this->_helperMock, $this->_apiConfigMock);
 }
Пример #6
0
 /**
  * Parse Request body into array of params.
  *
  * @param string $encodedBody Posted content from request.
  * @return array|null Return NULL if content is invalid.
  * @throws InvalidArgumentException
  * @throws Mage_Webapi_Exception If decoding error was encountered.
  */
 public function interpret($encodedBody)
 {
     if (!is_string($encodedBody)) {
         throw new InvalidArgumentException(sprintf('Invalid data type "%s". String is expected.', gettype($encodedBody)));
     }
     try {
         /** @var Mage_Core_Helper_Data $jsonHelper */
         $jsonHelper = $this->_helperFactory->get('Mage_Core_Helper_Data');
         $decodedBody = $jsonHelper->jsonDecode($encodedBody);
     } catch (Zend_Json_Exception $e) {
         if (!$this->_app->isDeveloperMode()) {
             throw new Mage_Webapi_Exception($this->_helper->__('Decoding error.'), Mage_Webapi_Exception::HTTP_BAD_REQUEST);
         } else {
             throw new Mage_Webapi_Exception('Decoding error: ' . PHP_EOL . $e->getMessage() . PHP_EOL . $e->getTraceAsString(), Mage_Webapi_Exception::HTTP_BAD_REQUEST);
         }
     }
     return $decodedBody;
 }
Пример #7
0
 /**
  * Identify versions of resources that should be used for API configuration generation.
  *
  * @return array
  * @throws Mage_Webapi_Exception When GET parameters are invalid
  */
 public function getRequestedResources()
 {
     $wsdlParam = Mage_Webapi_Model_Soap_Server::REQUEST_PARAM_WSDL;
     $resourcesParam = Mage_Webapi_Model_Soap_Server::REQUEST_PARAM_RESOURCES;
     $requestParams = array_keys($this->getParams());
     $allowedParams = array(Mage_Webapi_Controller_Router_Route_Webapi::PARAM_API_TYPE, $wsdlParam, $resourcesParam);
     $notAllowedParameters = array_diff($requestParams, $allowedParams);
     if (count($notAllowedParameters)) {
         $message = $this->_helper->__('Not allowed parameters: %s. ', implode(', ', $notAllowedParameters)) . $this->_helper->__('Please use only "%s" and "%s".', $wsdlParam, $resourcesParam);
         throw new Mage_Webapi_Exception($message, Mage_Webapi_Exception::HTTP_BAD_REQUEST);
     }
     $requestedResources = $this->getParam($resourcesParam);
     if (empty($requestedResources) || !is_array($requestedResources)) {
         $message = $this->_helper->__('Requested resources are missing.');
         throw new Mage_Webapi_Exception($message, Mage_Webapi_Exception::HTTP_BAD_REQUEST);
     }
     return $requestedResources;
 }
Пример #8
0
 /**
  * Authenticate user.
  *
  * @param stdClass $usernameToken WS-Security UsernameToken object
  * @throws Mage_Webapi_Exception If authentication failed
  */
 public function authenticate($usernameToken)
 {
     try {
         $token = $this->_tokenFactory->createFromArray();
         $request = $usernameToken;
         // @codingStandardsIgnoreStart
         $user = $token->authenticate($request->Username, $request->Password, $request->Created, $request->Nonce);
         // @codingStandardsIgnoreEnd
         $this->_roleLocator->setRoleId($user->getRoleId());
     } catch (Mage_Webapi_Model_Soap_Security_UsernameToken_NonceUsedException $e) {
         throw new Mage_Webapi_Exception($this->_helper->__('WS-Security UsernameToken Nonce is already used.'), Mage_Webapi_Exception::HTTP_BAD_REQUEST);
     } catch (Mage_Webapi_Model_Soap_Security_UsernameToken_TimestampRefusedException $e) {
         throw new Mage_Webapi_Exception($this->_helper->__('WS-Security UsernameToken Created timestamp is refused.'), Mage_Webapi_Exception::HTTP_BAD_REQUEST);
     } catch (Mage_Webapi_Model_Soap_Security_UsernameToken_InvalidCredentialException $e) {
         throw new Mage_Webapi_Exception($this->_helper->__('Invalid Username or Password.'), Mage_Webapi_Exception::HTTP_BAD_REQUEST);
     } catch (Mage_Webapi_Model_Soap_Security_UsernameToken_InvalidDateException $e) {
         throw new Mage_Webapi_Exception($this->_helper->__('Invalid UsernameToken Created date.'), Mage_Webapi_Exception::HTTP_BAD_REQUEST);
     }
 }
Пример #9
0
 /**
  * Identify version of requested operation.
  *
  * This method is required when there are two or more resource versions specified in request:
  * http://magento.host/api/soap?wsdl&resources[resource_a]=v1&resources[resource_b]=v2 <br/>
  * In this case it is not obvious what version of requested operation should be used.
  *
  * @param string $operationName
  * @return int
  * @throws Mage_Webapi_Exception
  */
 protected function _getOperationVersion($operationName)
 {
     $requestedResources = $this->_request->getRequestedResources();
     $resourceName = $this->_apiConfig->getResourceNameByOperation($operationName);
     if (!isset($requestedResources[$resourceName])) {
         throw new Mage_Webapi_Exception($this->_helper->__('The version of "%s" operation cannot be identified.', $operationName), Mage_Webapi_Exception::HTTP_NOT_FOUND);
     }
     $version = (int) str_replace('V', '', ucfirst($requestedResources[$resourceName]));
     $this->_apiConfig->validateVersionNumber($version, $resourceName);
     return $version;
 }
Пример #10
0
 /**
  * Check whether current request matches any route of specified method or not. Method version is taken into account.
  *
  * @param Mage_Webapi_Controller_Request_Rest $request
  * @param string $methodName
  * @param string $version
  * @throws Mage_Webapi_Exception In case when request does not match any route of specified method.
  */
 public function checkRoute(Mage_Webapi_Controller_Request_Rest $request, $methodName, $version)
 {
     $resourceName = $request->getResourceName();
     $routes = $this->_apiConfig->getMethodRestRoutes($resourceName, $methodName, $version);
     foreach ($routes as $route) {
         if ($route->match($request)) {
             return;
         }
     }
     throw new Mage_Webapi_Exception($this->_helper->__('Request does not match any route.'), Mage_Webapi_Exception::HTTP_NOT_FOUND);
 }
Пример #11
0
 /**
  * Process API exception.
  *
  * Create report if not in developer mode and render error to send correct API response.
  *
  * @param Exception $exception
  * @param int $httpCode
  * @SuppressWarnings(PHPMD.ExitExpression)
  */
 public function renderException(Exception $exception, $httpCode = self::DEFAULT_ERROR_HTTP_CODE)
 {
     if ($this->_app->isDeveloperMode() || $exception instanceof Mage_Webapi_Exception) {
         $this->render($exception->getMessage(), $exception->getTraceAsString(), $exception->getCode());
     } else {
         $reportId = $this->_logException($exception);
         $this->render($this->_apiHelper->__('Internal Error. Details are available in Magento log file. Report ID: "%s"', $reportId), 'Trace is not available.', $httpCode);
     }
     // TODO: Move die() call to render() method when it will be covered with functional tests.
     die;
 }
Пример #12
0
 /**
  * Test renderException method with turned on Developer mode.
  */
 public function testRenderExecutionInDeveloperMode()
 {
     $this->markTestIncomplete("Think how to replace this test.");
     $_SERVER['HTTP_ACCEPT'] = 'json';
     /** Init base Exception object. */
     $exception = new Exception('Message');
     /** Mock app to return enabled developer mode flag. */
     $this->_appMock->expects($this->any())->method('isDeveloperMode')->will($this->returnValue(true));
     /** Assert jsonEncode will be executed once. */
     $this->_helperMock->expects($this->once())->method('jsonEncode');
     $this->_errorProcessor->renderException($exception);
 }
Пример #13
0
 /**
  * Retrieve proper interpreter for the specified content type.
  *
  * @param string $contentType
  * @return Mage_Webapi_Controller_Request_Rest_InterpreterInterface
  * @throws LogicException|Mage_Webapi_Exception
  */
 public function get($contentType)
 {
     $interpretersMetadata = (array) $this->_applicationConfig->getNode(self::XML_PATH_WEBAPI_REQUEST_INTERPRETERS);
     if (empty($interpretersMetadata) || !is_array($interpretersMetadata)) {
         throw new LogicException('Request interpreter adapter is not set.');
     }
     foreach ($interpretersMetadata as $interpreterMetadata) {
         $interpreterType = (string) $interpreterMetadata->type;
         if ($interpreterType == $contentType) {
             $interpreterClass = (string) $interpreterMetadata->model;
             break;
         }
     }
     if (!isset($interpreterClass) || empty($interpreterClass)) {
         throw new Mage_Webapi_Exception($this->_helper->__('Server cannot understand Content-Type HTTP header media type "%s"', $contentType), Mage_Webapi_Exception::HTTP_BAD_REQUEST);
     }
     $interpreter = $this->_objectManager->get($interpreterClass);
     if (!$interpreter instanceof Mage_Webapi_Controller_Request_Rest_InterpreterInterface) {
         throw new LogicException('The interpreter must implement "Mage_Webapi_Controller_Request_Rest_InterpreterInterface".');
     }
     return $interpreter;
 }
Пример #14
0
 /**
  * Convert XML document into array.
  *
  * @param string $xmlRequestBody XML document
  * @return array Data converted from XML document to array. Root node is excluded from response.
  * @throws InvalidArgumentException In case of invalid argument type.
  * @throws Mage_Webapi_Exception If decoding error occurs.
  */
 public function interpret($xmlRequestBody)
 {
     if (!is_string($xmlRequestBody)) {
         throw new InvalidArgumentException(sprintf('Invalid data type "%s". String is expected.', gettype($xmlRequestBody)));
     }
     /** Disable external entity loading to prevent possible vulnerability */
     $previousLoaderState = libxml_disable_entity_loader(true);
     set_error_handler(array($this, 'handleErrors'));
     $this->_xmlParser->loadXML($xmlRequestBody);
     restore_error_handler();
     libxml_disable_entity_loader($previousLoaderState);
     /** Process errors during XML parsing. */
     if ($this->_errorMessage !== null) {
         if (!$this->_app->isDeveloperMode()) {
             $exceptionMessage = $this->_helper->__('Decoding error.');
         } else {
             $exceptionMessage = 'Decoding Error: ' . $this->_errorMessage;
         }
         throw new Mage_Webapi_Exception($exceptionMessage, Mage_Webapi_Exception::HTTP_BAD_REQUEST);
     }
     $data = $this->_xmlParser->xmlToArray();
     /** Data will always have exactly one element so it is safe to call reset here. */
     return reset($data);
 }
Пример #15
0
 /**
  * Determine current API type using application request (not web API request).
  *
  * @return string
  * @throws Mage_Core_Exception
  * @throws Mage_Webapi_Exception If requested API type is invalid.
  */
 public function determineApiType()
 {
     if (is_null($this->_apiType)) {
         $request = $this->_application->getRequest();
         $apiRoute = $this->_routeFactory->createRoute('Mage_Webapi_Controller_Router_Route_Webapi', Mage_Webapi_Controller_Router_Route_Webapi::getApiRoute());
         if (!($apiTypeMatch = $apiRoute->match($request, true))) {
             throw new Mage_Webapi_Exception($this->_helper->__('Request does not match any API type route.'), Mage_Webapi_Exception::HTTP_BAD_REQUEST);
         }
         $apiType = $apiTypeMatch[Mage_Webapi_Controller_Router_Route_Webapi::PARAM_API_TYPE];
         if (!in_array($apiType, $this->getListOfAvailableApiTypes())) {
             throw new Mage_Webapi_Exception($this->_helper->__('The "%s" API type is not defined.', $apiType), Mage_Webapi_Exception::HTTP_BAD_REQUEST);
         }
         $this->_apiType = $apiType;
     }
     return $this->_apiType;
 }
Пример #16
0
 /**
  * Fetch data from request and prepare it for passing to specified action.
  *
  * @param object $controllerInstance
  * @param string $action
  * @return array
  */
 public function fetchRequestData($controllerInstance, $action)
 {
     $methodReflection = Mage_Webapi_Helper_Data::createMethodReflection($controllerInstance, $action);
     $methodName = $this->_configHelper->getMethodNameWithoutVersionSuffix($methodReflection);
     $bodyParamName = $this->_configHelper->getOperationBodyParamName($methodReflection);
     $requestParams = array_merge($this->_request->getParams(), array($bodyParamName => $this->_getRequestBody($methodName)));
     /** Convert names of ID and Parent ID params in request to those which are used in method interface. */
     $idArgumentName = $this->_configHelper->getOperationIdParamName($methodReflection);
     $parentIdParamName = Mage_Webapi_Controller_Router_Route_Rest::PARAM_PARENT_ID;
     $idParamName = Mage_Webapi_Controller_Router_Route_Rest::PARAM_ID;
     if (isset($requestParams[$parentIdParamName]) && $idArgumentName != $parentIdParamName) {
         $requestParams[$idArgumentName] = $requestParams[$parentIdParamName];
         unset($requestParams[$parentIdParamName]);
     } elseif (isset($requestParams[$idParamName]) && $idArgumentName != $idParamName) {
         $requestParams[$idArgumentName] = $requestParams[$idParamName];
         unset($requestParams[$idParamName]);
     }
     return $this->_apiHelper->prepareMethodParams($controllerInstance, $action, $requestParams, $this->_apiConfig);
 }
Пример #17
0
 protected final function _applyCollectionModifiers(Varien_Data_Collection_Db $collection)
 {
     $pageNumber = $this->getRequest()->getPageNumber();
     if ($pageNumber != abs($pageNumber)) {
         throw new Mage_Webapi_Exception($this->_translationHelper->__("Page number is invalid."), Mage_Webapi_Exception::HTTP_BAD_REQUEST);
     }
     $pageSize = $this->getRequest()->getPageSize();
     if (null == $pageSize) {
         $pageSize = self::PAGE_SIZE_DEFAULT;
     } else {
         if ($pageSize != abs($pageSize) || $pageSize > self::PAGE_SIZE_MAX) {
             throw new Mage_Webapi_Exception($this->_translationHelper->__('The paging limit exceeds the allowed number.'), Mage_Webapi_Exception::HTTP_BAD_REQUEST);
         }
     }
     $orderField = $this->getRequest()->getOrderField();
     if (null !== $orderField) {
         if (!is_string($orderField)) {
             throw new Mage_Webapi_Exception($this->_translationHelper->__('Collection "order" value is invalid.'), Mage_Webapi_Exception::HTTP_BAD_REQUEST);
         }
         $collection->setOrder($orderField, $this->getRequest()->getOrderDirection());
     }
     $collection->setCurPage($pageNumber)->setPageSize($pageSize);
     return $collection;
 }
Пример #18
0
 public function testGenerateRestRoutesInvalidMethod()
 {
     $this->setExpectedException('InvalidArgumentException', '"invalidMethodNameV2" is an invalid API resource method.');
     $this->_model->generateRestRoutes(Mage_Webapi_Helper_Data::createMethodReflection('Vendor_Module_Controller_Webapi_Invalid_Interface', 'invalidMethodNameV2'));
 }
Пример #19
0
 /**
  * Initialize unique fields.
  *
  * @return Mage_Webapi_Model_Resource_Acl_User
  */
 protected function _initUniqueFields()
 {
     $this->_uniqueFields = array(array('field' => 'api_key', 'title' => $this->_helper->__('API Key')));
     return $this;
 }
Пример #20
0
 /**
  * @dataProvider dataProviderForTestPrepareMethodParamsNegative
  * @param string|object $class
  * @param string $methodName
  * @param array $requestData
  * @param string $exceptionClass
  * @param string $exceptionMessage
  */
 public function testPrepareMethodParamsNegative($class, $methodName, $requestData, $exceptionClass, $exceptionMessage)
 {
     $this->setExpectedException($exceptionClass, $exceptionMessage);
     $this->_helper->prepareMethodParams($class, $methodName, $requestData, $this->_getApiConfig());
 }
Пример #21
0
 /**
  * Initialize unique fields.
  *
  * @return Mage_Webapi_Model_Resource_Acl_Role
  */
 protected function _initUniqueFields()
 {
     $this->_uniqueFields = array(array('field' => 'role_name', 'title' => $this->_helper->__('Role Name')));
     return $this;
 }
Пример #22
0
 public function testGetIdParamException()
 {
     $className = 'Vendor_Module_Webapi_Resource_Invalid';
     $this->setExpectedException('LogicException', sprintf('"%s" is not a valid resource class.', $className));
     $this->_helper->getOperationIdParamName(Mage_Webapi_Helper_Data::createMethodReflection($className, 'updateV1'));
 }