aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.htaccess4
-rw-r--r--application/api/ApiMiddleware.php10
-rw-r--r--tests/api/ApiMiddlewareTest.php47
3 files changed, 59 insertions, 2 deletions
diff --git a/.htaccess b/.htaccess
index af2dc5a7..25fcfb03 100644
--- a/.htaccess
+++ b/.htaccess
@@ -10,8 +10,12 @@ RewriteRule ^(.git|doxygen|vendor) - [F]
10# fixes JWT token not correctly forwarded on some Apache/FastCGI setups 10# fixes JWT token not correctly forwarded on some Apache/FastCGI setups
11RewriteCond %{HTTP:Authorization} ^(.*) 11RewriteCond %{HTTP:Authorization} ^(.*)
12RewriteRule .* - [e=HTTP_AUTHORIZATION:%1] 12RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
13# Alternative (if the 2 lines above don't work)
14# SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0
13 15
14# REST API 16# REST API
17# Ionos Hosting needs RewriteBase /
18# RewriteBase /
15RewriteCond %{REQUEST_FILENAME} !-f 19RewriteCond %{REQUEST_FILENAME} !-f
16RewriteCond %{REQUEST_FILENAME} !-d 20RewriteCond %{REQUEST_FILENAME} !-d
17RewriteRule ^ index.php [QSA,L] 21RewriteRule ^ index.php [QSA,L]
diff --git a/application/api/ApiMiddleware.php b/application/api/ApiMiddleware.php
index 09ce6445..f5b53b01 100644
--- a/application/api/ApiMiddleware.php
+++ b/application/api/ApiMiddleware.php
@@ -107,7 +107,9 @@ class ApiMiddleware
107 */ 107 */
108 protected function checkToken($request) 108 protected function checkToken($request)
109 { 109 {
110 if (! $request->hasHeader('Authorization')) { 110 if (!$request->hasHeader('Authorization')
111 && !isset($this->container->environment['REDIRECT_HTTP_AUTHORIZATION'])
112 ) {
111 throw new ApiAuthorizationException('JWT token not provided'); 113 throw new ApiAuthorizationException('JWT token not provided');
112 } 114 }
113 115
@@ -115,7 +117,11 @@ class ApiMiddleware
115 throw new ApiAuthorizationException('Token secret must be set in Shaarli\'s administration'); 117 throw new ApiAuthorizationException('Token secret must be set in Shaarli\'s administration');
116 } 118 }
117 119
118 $authorization = $request->getHeaderLine('Authorization'); 120 if (isset($this->container->environment['REDIRECT_HTTP_AUTHORIZATION'])) {
121 $authorization = $this->container->environment['REDIRECT_HTTP_AUTHORIZATION'];
122 } else {
123 $authorization = $request->getHeaderLine('Authorization');
124 }
119 125
120 if (! preg_match('/^Bearer (.*)/i', $authorization, $matches)) { 126 if (! preg_match('/^Bearer (.*)/i', $authorization, $matches)) {
121 throw new ApiAuthorizationException('Invalid JWT header'); 127 throw new ApiAuthorizationException('Invalid JWT header');
diff --git a/tests/api/ApiMiddlewareTest.php b/tests/api/ApiMiddlewareTest.php
index b157e4a7..32031750 100644
--- a/tests/api/ApiMiddlewareTest.php
+++ b/tests/api/ApiMiddlewareTest.php
@@ -67,6 +67,53 @@ class ApiMiddlewareTest extends \PHPUnit\Framework\TestCase
67 } 67 }
68 68
69 /** 69 /**
70 * Invoke the middleware with a valid token
71 */
72 public function testInvokeMiddlewareWithValidToken(): void
73 {
74 $next = function (Request $request, Response $response): Response {
75 return $response;
76 };
77 $mw = new ApiMiddleware($this->container);
78 $env = Environment::mock([
79 'REQUEST_METHOD' => 'GET',
80 'REQUEST_URI' => '/echo',
81 'HTTP_AUTHORIZATION'=> 'Bearer ' . ApiUtilsTest::generateValidJwtToken('NapoleonWasALizard'),
82 ]);
83 $request = Request::createFromEnvironment($env);
84 $response = new Response();
85 /** @var Response $response */
86 $response = $mw($request, $response, $next);
87
88 $this->assertEquals(200, $response->getStatusCode());
89 }
90
91 /**
92 * Invoke the middleware with a valid token
93 * Using specific Apache CGI redirected authorization.
94 */
95 public function testInvokeMiddlewareWithValidTokenFromRedirectedHeader(): void
96 {
97 $next = function (Request $request, Response $response): Response {
98 return $response;
99 };
100
101 $token = 'Bearer ' . ApiUtilsTest::generateValidJwtToken('NapoleonWasALizard');
102 $this->container->environment['REDIRECT_HTTP_AUTHORIZATION'] = $token;
103 $mw = new ApiMiddleware($this->container);
104 $env = Environment::mock([
105 'REQUEST_METHOD' => 'GET',
106 'REQUEST_URI' => '/echo',
107 ]);
108 $request = Request::createFromEnvironment($env);
109 $response = new Response();
110 /** @var Response $response */
111 $response = $mw($request, $response, $next);
112
113 $this->assertEquals(200, $response->getStatusCode());
114 }
115
116 /**
70 * Invoke the middleware with the API disabled: 117 * Invoke the middleware with the API disabled:
71 * should return a 401 error Unauthorized. 118 * should return a 401 error Unauthorized.
72 */ 119 */