Skip to content

Commit

Permalink
Merge pull request #373 from magento-api/MAGETWO-43020-Implement-Auth…
Browse files Browse the repository at this point in the history
…orization-For-SOAP-And-REST-Schemas

[API] WSDL Authentication
  • Loading branch information
Korshenko, Oleksii(okorshenko) committed Feb 12, 2016
2 parents 23b962f + 14ee44f commit 5f4871b
Show file tree
Hide file tree
Showing 34 changed files with 392 additions and 280 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
<link src='Magento_Swagger::swagger-ui/js/lang/translator.js' type='text/javascript'/>
<link src='Magento_Swagger::swagger-ui/js/lang/ru.js' type='text/javascript'/>
<link src='Magento_Swagger::swagger-ui/js/lang/en.js' type='text/javascript'/>
<link src='Magento_Swagger::swagger-ui/js/magento-swagger.js' type='text/javascript'/>

<!--Remove require-js assets-->
<remove src="requirejs/require.js"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,84 +17,14 @@
$schemaUrl = rtrim($block->getBaseUrl(), '/') . '/rest/default/schema?services=all';
?>

<!DOCTYPE html>
<script>
$(function () {
var url = window.location.search.match(/url=([^&]+)/);
if (url && url.length > 1) {
url = decodeURIComponent(url[1]);
} else {
url = '<?php /* @escapeNotVerified */ echo $schemaUrl ?>';
}

// Pre load translate...
if(window.SwaggerTranslator) {
window.SwaggerTranslator.translate();
}
window.swaggerUi = new SwaggerUi({
url: url,
dom_id: "swagger-ui-container",
supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'],
onComplete: function(swaggerApi, swaggerUi){
if(typeof initOAuth == "function") {
initOAuth({
clientId: "your-client-id",
clientSecret: "your-client-secret",
realm: "your-realms",
appName: "your-app-name",
scopeSeparator: ","
});
}

if(window.SwaggerTranslator) {
window.SwaggerTranslator.translate();
}

$('pre code').each(function(i, e) {
hljs.highlightBlock(e)
});

addApiKeyAuthorization();
},
onFailure: function(data) {
log("Unable to Load SwaggerUI");
},
docExpansion: "none",
apisSorter: "alpha",
showRequestHeaders: false
});

function addApiKeyAuthorization(){
var key = encodeURIComponent($('#input_apiKey')[0].value);
if(key && key.trim() != "") {
var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("api_key", key, "query");
window.swaggerUi.api.clientAuthorizations.add("api_key", apiKeyAuth);
log("added key " + key);
}
}

$('#input_apiKey').change(addApiKeyAuthorization);

// if you have an apiKey you would like to pre-populate on the page for demonstration purposes...
/*
var apiKey = "myApiKeyXXXX123456789";
$('#input_apiKey').val(apiKey);
*/

window.swaggerUi.load();

function log() {
if ('console' in window) {
console.log.apply(console, arguments);
}
}
});
</script>


<div id='header'>
<div class="swagger-ui-wrap">
<a id="logo" href="http://swagger.io">swagger</a>
<form id='api_selector'>
<input id="input_baseUrl" type="hidden" value="<?php /* @escapeNotVerified */ echo $schemaUrl ?>"/>
<div class='input'><input placeholder="api_key" id="input_apiKey" name="apiKey" type="text"/></div>
<div class='input'><a id="explore" href="#" data-sw-translate>apply</a></div>
</form>
</div>
</div>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
$(function () {
var url = $('#input_baseUrl').val();

// Pre load translate...
if(window.SwaggerTranslator) {
window.SwaggerTranslator.translate();
}
window.swaggerUi = new SwaggerUi({
url: url,
dom_id: "swagger-ui-container",
supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'],
onComplete: function(swaggerApi, swaggerUi){
if(typeof initOAuth == "function") {
initOAuth({
clientId: "your-client-id",
clientSecret: "your-client-secret",
realm: "your-realms",
appName: "your-app-name",
scopeSeparator: ","
});
}

if(window.SwaggerTranslator) {
window.SwaggerTranslator.translate();
}

$('pre code').each(function(i, e) {
hljs.highlightBlock(e)
});

addApiKeyAuthorization();
},
onFailure: function(data) {
log("Unable to Load SwaggerUI");
},
docExpansion: "none",
apisSorter: "alpha",
showRequestHeaders: false
});

function addApiKeyAuthorization(){
var key = encodeURIComponent($('#input_apiKey')[0].value);
if(key && key.trim() != "") {
var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("Authorization", "Bearer " + key, "header");
window.swaggerUi.api.clientAuthorizations.add("apiKeyAuth", apiKeyAuth);
}
}

$('#input_apiKey').change(addApiKeyAuthorization);


window.swaggerUi.load();

function log() {
if ('console' in window) {
console.log.apply(console, arguments);
}
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@
},"22":function(depth0,helpers,partials,data) {
return "";
},"24":function(depth0,helpers,partials,data) {
return " <div class='sandbox_header'>\n <input class='submit' type='hidden' value='Try it out!' data-sw-translate/>\n <a href='#' class='response_hider' style='display:none' data-sw-translate>Hide Response</a>\n <span class='response_throbber' style='display:none'></span>\n </div>\n";
return " <div class='sandbox_header'>\n <input class='submit' type='button' value='Try it out!' data-sw-translate/>\n <a href='#' class='response_hider' style='display:none' data-sw-translate>Hide Response</a>\n <span class='response_throbber' style='display:none'></span>\n </div>\n";
},"26":function(depth0,helpers,partials,data) {
return " <h4 data-sw-translate>Request Headers</h4>\n <div class='block request_headers'></div>\n";
},"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
Expand Down
32 changes: 8 additions & 24 deletions app/code/Magento/Webapi/Controller/Rest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/
namespace Magento\Webapi\Controller;

use Magento\Framework\AuthorizationInterface;
use Magento\Framework\Webapi\Authorization;
use Magento\Framework\Exception\AuthorizationException;
use Magento\Framework\Webapi\ErrorProcessor;
use Magento\Framework\Webapi\Request;
Expand Down Expand Up @@ -52,8 +52,8 @@ class Rest implements \Magento\Framework\App\FrontControllerInterface
/** @var \Magento\Framework\App\State */
protected $_appState;

/** @var AuthorizationInterface */
protected $_authorization;
/** @var Authorization */
protected $authorization;

/** @var ServiceInputProcessor */
protected $serviceInputProcessor;
Expand Down Expand Up @@ -93,7 +93,7 @@ class Rest implements \Magento\Framework\App\FrontControllerInterface
* @param Router $router
* @param \Magento\Framework\ObjectManagerInterface $objectManager
* @param \Magento\Framework\App\State $appState
* @param AuthorizationInterface $authorization
* @param Authorization $authorization
* @param ServiceInputProcessor $serviceInputProcessor
* @param ErrorProcessor $errorProcessor
* @param PathProcessor $pathProcessor
Expand All @@ -113,7 +113,7 @@ public function __construct(
Router $router,
\Magento\Framework\ObjectManagerInterface $objectManager,
\Magento\Framework\App\State $appState,
AuthorizationInterface $authorization,
Authorization $authorization,
ServiceInputProcessor $serviceInputProcessor,
ErrorProcessor $errorProcessor,
PathProcessor $pathProcessor,
Expand All @@ -129,7 +129,7 @@ public function __construct(
$this->_response = $response;
$this->_objectManager = $objectManager;
$this->_appState = $appState;
$this->_authorization = $authorization;
$this->authorization = $authorization;
$this->serviceInputProcessor = $serviceInputProcessor;
$this->_errorProcessor = $errorProcessor;
$this->_pathProcessor = $pathProcessor;
Expand Down Expand Up @@ -198,30 +198,14 @@ protected function getCurrentRoute()
protected function checkPermissions()
{
$route = $this->getCurrentRoute();
if (!$this->isAllowed($route->getAclResources())) {
if (!$this->authorization->isAllowed($route->getAclResources())) {
$params = ['resources' => implode(', ', $route->getAclResources())];
throw new AuthorizationException(
__(AuthorizationException::NOT_AUTHORIZED, $params)
);
}
}

/**
* Check if all ACL resources are allowed to be accessed by current API user.
*
* @param string[] $aclResources
* @return bool
*/
protected function isAllowed($aclResources)
{
foreach ($aclResources as $resource) {
if (!$this->_authorization->isAllowed($resource)) {
return false;
}
}
return true;
}

/**
* Execute schema request
*
Expand All @@ -231,7 +215,7 @@ protected function processSchemaRequest()
{
$requestedServices = $this->_request->getRequestedServices('all');
$requestedServices = $requestedServices == Request::ALL_SERVICES
? array_keys($this->swaggerGenerator->getListOfServices())
? $this->swaggerGenerator->getListOfServices()
: $requestedServices;
$responseBody = $this->swaggerGenerator->generate(
$requestedServices,
Expand Down
20 changes: 0 additions & 20 deletions app/code/Magento/Webapi/Controller/Soap.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
*/
namespace Magento\Webapi\Controller;

use Magento\Framework\Exception\AuthorizationException;
use Magento\Framework\Webapi\ErrorProcessor;
use Magento\Framework\Webapi\Request;
use Magento\Framework\Webapi\Response;
Expand Down Expand Up @@ -171,25 +170,6 @@ protected function _isWsdlListRequest()
return $this->_request->getParam(\Magento\Webapi\Model\Soap\Server::REQUEST_PARAM_LIST_WSDL) !== null;
}

/**
* Parse the Authorization header and return the access token e.g. Authorization: Bearer <access-token>
*
* @return string Access token
* @throws AuthorizationException
*/
protected function _getAccessToken()
{
$headers = array_change_key_case(getallheaders(), CASE_UPPER);
if (isset($headers['AUTHORIZATION'])) {
$token = explode(' ', $headers['AUTHORIZATION']);
if (isset($token[1]) && is_string($token[1])) {
return $token[1];
}
throw new AuthorizationException(__('Authentication header format is invalid.'));
}
throw new AuthorizationException(__('Authentication header is absent.'));
}

/**
* Set body and status code to response using information extracted from provided exception.
*
Expand Down
22 changes: 7 additions & 15 deletions app/code/Magento/Webapi/Controller/Soap/Request/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use Magento\Framework\Api\ExtensibleDataInterface;
use Magento\Framework\Api\MetadataObjectInterface;
use Magento\Framework\Api\SimpleDataObjectConverter;
use Magento\Framework\AuthorizationInterface;
use Magento\Framework\Webapi\Authorization;
use Magento\Framework\Exception\AuthorizationException;
use Magento\Framework\Reflection\DataObjectProcessor;
use Magento\Framework\Webapi\ServiceInputProcessor;
Expand Down Expand Up @@ -38,8 +38,8 @@ class Handler
/** @var SoapConfig */
protected $_apiConfig;

/** @var AuthorizationInterface */
protected $_authorization;
/** @var Authorization */
protected $authorization;

/** @var SimpleDataObjectConverter */
protected $_dataObjectConverter;
Expand All @@ -59,7 +59,7 @@ class Handler
* @param SoapRequest $request
* @param \Magento\Framework\ObjectManagerInterface $objectManager
* @param SoapConfig $apiConfig
* @param AuthorizationInterface $authorization
* @param Authorization $authorization
* @param SimpleDataObjectConverter $dataObjectConverter
* @param ServiceInputProcessor $serviceInputProcessor
* @param DataObjectProcessor $dataObjectProcessor
Expand All @@ -69,7 +69,7 @@ public function __construct(
SoapRequest $request,
\Magento\Framework\ObjectManagerInterface $objectManager,
SoapConfig $apiConfig,
AuthorizationInterface $authorization,
Authorization $authorization,
SimpleDataObjectConverter $dataObjectConverter,
ServiceInputProcessor $serviceInputProcessor,
DataObjectProcessor $dataObjectProcessor,
Expand All @@ -78,7 +78,7 @@ public function __construct(
$this->_request = $request;
$this->_objectManager = $objectManager;
$this->_apiConfig = $apiConfig;
$this->_authorization = $authorization;
$this->authorization = $authorization;
$this->_dataObjectConverter = $dataObjectConverter;
$this->serviceInputProcessor = $serviceInputProcessor;
$this->_dataObjectProcessor = $dataObjectProcessor;
Expand Down Expand Up @@ -107,15 +107,7 @@ public function __call($operation, $arguments)
throw new WebapiException(__("Operation allowed only in HTTPS"));
}

$isAllowed = false;
foreach ($serviceMethodInfo[ServiceMetadata::KEY_ACL_RESOURCES] as $resource) {
if ($this->_authorization->isAllowed($resource)) {
$isAllowed = true;
break;
}
}

if (!$isAllowed) {
if (!$this->authorization->isAllowed($serviceMethodInfo[ServiceMetadata::KEY_ACL_RESOURCES])) {
throw new AuthorizationException(
__(
AuthorizationException::NOT_AUTHORIZED,
Expand Down
Loading

0 comments on commit 5f4871b

Please sign in to comment.