From 18e6796726d73d7dc90ecdd16c181493941f5487 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Thu, 15 Dec 2016 10:13:00 +0100 Subject: REST API structure using Slim framework * REST API routes are handle by Slim. * Every API controller go through ApiMiddleware which handles security. * First service implemented `/info`, for tests purpose. --- application/api/ApiMiddleware.php | 132 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 application/api/ApiMiddleware.php (limited to 'application/api/ApiMiddleware.php') diff --git a/application/api/ApiMiddleware.php b/application/api/ApiMiddleware.php new file mode 100644 index 00000000..162e88e0 --- /dev/null +++ b/application/api/ApiMiddleware.php @@ -0,0 +1,132 @@ +container = $container; + $this->conf = $this->container->get('conf'); + $this->setLinkDb($this->conf); + } + + /** + * Middleware execution: + * - check the API request + * - execute the controller + * - return the response + * + * @param Request $request Slim request + * @param Response $response Slim response + * @param callable $next Next action + * + * @return Response response. + */ + public function __invoke($request, $response, $next) + { + try { + $this->checkRequest($request); + $response = $next($request, $response); + } catch(ApiException $e) { + $e->setResponse($response); + $e->setDebug($this->conf->get('dev.debug', false)); + $response = $e->getApiResponse(); + } + + return $response; + } + + /** + * Check the request validity (HTTP method, request value, etc.), + * that the API is enabled, and the JWT token validity. + * + * @param Request $request Slim request + * + * @throws ApiAuthorizationException The API is disabled or the token is invalid. + */ + protected function checkRequest($request) + { + if (! $this->conf->get('api.enabled', true)) { + throw new ApiAuthorizationException('API is disabled'); + } + $this->checkToken($request); + } + + /** + * Check that the JWT token is set and valid. + * The API secret setting must be set. + * + * @param Request $request Slim request + * + * @throws ApiAuthorizationException The token couldn't be validated. + */ + protected function checkToken($request) { + $jwt = $request->getHeaderLine('jwt'); + if (empty($jwt)) { + throw new ApiAuthorizationException('JWT token not provided'); + } + + if (empty($this->conf->get('api.secret'))) { + throw new ApiAuthorizationException('Token secret must be set in Shaarli\'s administration'); + } + + ApiUtils::validateJwtToken($jwt, $this->conf->get('api.secret')); + } + + /** + * Instantiate a new LinkDB including private links, + * and load in the Slim container. + * + * FIXME! LinkDB could use a refactoring to avoid this trick. + * + * @param \ConfigManager $conf instance. + */ + protected function setLinkDb($conf) + { + $linkDb = new \LinkDB( + $conf->get('resource.datastore'), + true, + $conf->get('privacy.hide_public_links'), + $conf->get('redirector.url'), + $conf->get('redirector.encode_url') + ); + $this->container['db'] = $linkDb; + } +} -- cgit v1.2.3 From 63ef549749fac9d0e302842f06e7794d1daabc13 Mon Sep 17 00:00:00 2001 From: VirtualTam Date: Sat, 7 Jan 2017 22:23:47 +0100 Subject: API: expect JWT in the Authorization header Relates to https://github.com/shaarli/Shaarli/pull/731 Added: - require the presence of the 'Authorization' header Changed: - use the HTTP Bearer Token authorization schema See: - https://jwt.io/introduction/#how-do-json-web-tokens-work- - https://tools.ietf.org/html/rfc6750 - http://security.stackexchange.com/q/108662 Signed-off-by: VirtualTam --- application/api/ApiMiddleware.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'application/api/ApiMiddleware.php') diff --git a/application/api/ApiMiddleware.php b/application/api/ApiMiddleware.php index 162e88e0..522091ca 100644 --- a/application/api/ApiMiddleware.php +++ b/application/api/ApiMiddleware.php @@ -98,8 +98,7 @@ class ApiMiddleware * @throws ApiAuthorizationException The token couldn't be validated. */ protected function checkToken($request) { - $jwt = $request->getHeaderLine('jwt'); - if (empty($jwt)) { + if (! $request->hasHeader('Authorization')) { throw new ApiAuthorizationException('JWT token not provided'); } @@ -107,7 +106,13 @@ class ApiMiddleware throw new ApiAuthorizationException('Token secret must be set in Shaarli\'s administration'); } - ApiUtils::validateJwtToken($jwt, $this->conf->get('api.secret')); + $authorization = $request->getHeaderLine('Authorization'); + + if (! preg_match('/^Bearer (.*)/i', $authorization, $matches)) { + throw new ApiAuthorizationException('Invalid JWT header'); + } + + ApiUtils::validateJwtToken($matches[1], $this->conf->get('api.secret')); } /** -- cgit v1.2.3 From 3c66e56435359dc678048193e8ee239d06f79b64 Mon Sep 17 00:00:00 2001 From: VirtualTam Date: Fri, 3 Mar 2017 23:06:12 +0100 Subject: application: introduce the Shaarli\Config namespace Namespaces have been introduced with the REST API, and should be generalized to the whole codebase to manage object scope and benefit from autoloading. See: - https://secure.php.net/manual/en/language.namespaces.php - http://www.php-fig.org/psr/psr-4/ Signed-off-by: VirtualTam --- application/api/ApiMiddleware.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'application/api/ApiMiddleware.php') diff --git a/application/api/ApiMiddleware.php b/application/api/ApiMiddleware.php index 522091ca..4120f7a9 100644 --- a/application/api/ApiMiddleware.php +++ b/application/api/ApiMiddleware.php @@ -1,9 +1,9 @@ Date: Sun, 7 May 2017 16:50:20 +0200 Subject: Add history entries for API endpoint CHANGED: datetime is now store as an object in history store file --- application/api/ApiMiddleware.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'application/api/ApiMiddleware.php') diff --git a/application/api/ApiMiddleware.php b/application/api/ApiMiddleware.php index 4120f7a9..ff209393 100644 --- a/application/api/ApiMiddleware.php +++ b/application/api/ApiMiddleware.php @@ -4,6 +4,7 @@ namespace Shaarli\Api; use Shaarli\Api\Exceptions\ApiException; use Shaarli\Api\Exceptions\ApiAuthorizationException; +use Shaarli\Config\ConfigManager; use Slim\Container; use Slim\Http\Request; use Slim\Http\Response; @@ -31,7 +32,7 @@ class ApiMiddleware protected $container; /** - * @var \ConfigManager instance. + * @var ConfigManager instance. */ protected $conf; @@ -121,7 +122,7 @@ class ApiMiddleware * * FIXME! LinkDB could use a refactoring to avoid this trick. * - * @param \ConfigManager $conf instance. + * @param ConfigManager $conf instance. */ protected function setLinkDb($conf) { -- cgit v1.2.3