diff options
-rw-r--r-- | .gitattributes | 1 | ||||
-rw-r--r-- | .github/mailmap | 13 | ||||
-rw-r--r-- | AUTHORS | 40 | ||||
-rw-r--r-- | COPYING | 28 | ||||
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | application/HttpUtils.php | 2 | ||||
-rw-r--r-- | application/LinkUtils.php | 4 | ||||
-rw-r--r-- | application/Updater.php | 18 | ||||
-rw-r--r-- | application/api/ApiMiddleware.php | 11 | ||||
-rw-r--r-- | index.php | 2 | ||||
-rw-r--r-- | tests/api/ApiMiddlewareTest.php | 29 | ||||
-rw-r--r-- | tpl/default/includes.html | 2 |
12 files changed, 119 insertions, 39 deletions
diff --git a/.gitattributes b/.gitattributes index d753b1db..059fbb18 100644 --- a/.gitattributes +++ b/.gitattributes | |||
@@ -19,6 +19,7 @@ Dockerfile text | |||
19 | 19 | ||
20 | # Exclude from Git archives | 20 | # Exclude from Git archives |
21 | .gitattributes export-ignore | 21 | .gitattributes export-ignore |
22 | .github export-ignore | ||
22 | .gitignore export-ignore | 23 | .gitignore export-ignore |
23 | .travis.yml export-ignore | 24 | .travis.yml export-ignore |
24 | doc/**/*.json export-ignore | 25 | doc/**/*.json export-ignore |
diff --git a/.github/mailmap b/.github/mailmap new file mode 100644 index 00000000..41d91e47 --- /dev/null +++ b/.github/mailmap | |||
@@ -0,0 +1,13 @@ | |||
1 | ArthurHoaro <arthur@hoa.ro> | ||
2 | Florian Eula <eula.florian@gmail.com> feula | ||
3 | Florian Eula <eula.florian@gmail.com> <mr.pikzen@gmail.com> | ||
4 | Nicolas Danelon <hi@nicolasmd.com.ar> nicolasm | ||
5 | Nicolas Danelon <hi@nicolasmd.com.ar> <nda@3818.com.ar> | ||
6 | Nicolas Danelon <hi@nicolasmd.com.ar> <nicolasdanelon@gmail.com> | ||
7 | Nicolas Danelon <hi@nicolasmd.com.ar> <nicolasdanelon@users.noreply.github.com> | ||
8 | Sébastien Sauvage <sebsauvage@sebsauvage.net> | ||
9 | Timo Van Neerden <fire@lehollandaisvolant.net> | ||
10 | Timo Van Neerden <fire@lehollandaisvolant.net> lehollandaisvolant <levoltigeurhollandais@gmail.com> | ||
11 | VirtualTam <virtualtam@flibidi.net> <tamisier.aurelien@gmail.com> | ||
12 | VirtualTam <virtualtam@flibidi.net> <virtualtam+github@flibidi.net> | ||
13 | VirtualTam <virtualtam@flibidi.net> <virtualtam@flibidi.org> | ||
diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 00000000..aa041ae9 --- /dev/null +++ b/AUTHORS | |||
@@ -0,0 +1,40 @@ | |||
1 | 327 ArthurHoaro <arthur@hoa.ro> | ||
2 | 188 VirtualTam <virtualtam@flibidi.net> | ||
3 | 132 nodiscc <nodiscc@gmail.com> | ||
4 | 56 Sébastien Sauvage <sebsauvage@sebsauvage.net> | ||
5 | 15 Florian Eula <eula.florian@gmail.com> | ||
6 | 13 Emilien Klein <emilien@klein.st> | ||
7 | 12 Nicolas Danelon <hi@nicolasmd.com.ar> | ||
8 | 7 Christophe HENRY <christophe.henry@sbgodin.fr> | ||
9 | 4 Alexandre Alapetite <alexandre@alapetite.fr> | ||
10 | 4 David Sferruzza <david.sferruzza@gmail.com> | ||
11 | 3 Teromene <teromene@teromene.fr> | ||
12 | 2 Chris Kuethe <chris.kuethe@gmail.com> | ||
13 | 2 Knah Tsaeb <Knah-Tsaeb@knah-tsaeb.org> | ||
14 | 2 Mathieu Chabanon <git@matchab.fr> | ||
15 | 2 Miloš Jovanović <mjovanovic@gmail.com> | ||
16 | 2 Qwerty <champlywood@free.fr> | ||
17 | 2 Timo Van Neerden <fire@lehollandaisvolant.net> | ||
18 | 2 julienCXX <software@chmodplusx.eu> | ||
19 | 2 kalvn <kalvnthereal@gmail.com> | ||
20 | 1 Adrien Oliva <adrien.oliva@yapbreak.fr> | ||
21 | 1 Alexis J <alexis@effingo.be> | ||
22 | 1 BoboTiG <bobotig@gmail.com> | ||
23 | 1 Bronco <bronco@warriordudimanche.net> | ||
24 | 1 D Low <daniellowtw@gmail.com> | ||
25 | 1 Dimtion <zizou.xena@gmail.com> | ||
26 | 1 Fanch <fanch-github@qth.fr> | ||
27 | 1 Felix Bartels <felix@host-consultants.de> | ||
28 | 1 Felix Kästner <github.com-fpunktk@fpunktk.de> | ||
29 | 1 Florian Voigt <flvoigt@me.com> | ||
30 | 1 Gary Marigliano <gmarigliano93@gmail.com> | ||
31 | 1 Guillaume Virlet <github@virlet.org> | ||
32 | 1 Jonathan Druart <jonathan.druart@gmail.com> | ||
33 | 1 Julien Pivotto <roidelapluie@inuits.eu> | ||
34 | 1 Kevin Canévet <kevin@streamroot.io> | ||
35 | 1 Knah Tsaeb <knah-tsaeb@knah-tsaeb.org> | ||
36 | 1 Lionel Martin <renarddesmers@gmail.com> | ||
37 | 1 Marsup <marsup@gmail.com> | ||
38 | 1 Sbgodin <Sbgodin@users.noreply.github.com> | ||
39 | 1 TsT <tst2005@gmail.com> | ||
40 | 1 dimtion <zizou.xena@gmail.com> | ||
@@ -1,33 +1,7 @@ | |||
1 | Files: * | 1 | Files: * |
2 | License: zlib/libpng | 2 | License: zlib/libpng |
3 | Copyright: (c) 2011-2015 Sébastien SAUVAGE <sebsauvage@sebsauvage.net> | 3 | Copyright: (c) 2011-2015 Sébastien SAUVAGE <sebsauvage@sebsauvage.net> |
4 | (c) 2011-2015 Alexandre Alapetite <alexandre@alapetite.fr> | 4 | (c) 2011-2017 The Shaarli Community, see AUTHORS |
5 | (c) 2011-2015 David Sferruzza <david.sferruzza@gmail.com> | ||
6 | (c) 2011-2015 Christophe HENRY <christophe.henry@sbgodin.fr> | ||
7 | (c) 2011-2015 Mathieu Chabanon <git@matchab.fr> | ||
8 | (c) 2011-2015 BoboTiG <bobotig@gmail.com> | ||
9 | (c) 2011-2015 Bronco <bronco@warriordudimanche.net> | ||
10 | (c) 2011-2015 Emilien Klein <emilien@klein.st> | ||
11 | (c) 2011-2015 Knah Tsaeb <knah-tsaeb@knah-tsaeb.org> | ||
12 | (c) 2011-2015 Lionel Martin <renarddesmers@gmail.com> | ||
13 | (c) 2011-2015 lehollandaisvolant <levoltigeurhollandais@gmail.com> | ||
14 | (c) 2011-2015 timo van neerden <fire@lehollandaisvolant.net> | ||
15 | (c) 2011-2015 nodiscc <nodiscc@gmail.com> | ||
16 | (c) 2011-2015 Florian Eula <mr.pikzen@gmail.com> | ||
17 | (c) 2011-2015 Arthur Hoaro <arthur@hoa.ro> | ||
18 | (c) 2011-2015 Aurélien "VirtualTam" Tamisier <virtualtam@flibidi.net> | ||
19 | (c) 2011-2015 qwertygc <champlywood@free.fr> | ||
20 | (c) 2011-2015 idleman <idleman@idleman.fr> | ||
21 | (c) 2015 Alexis Ju <alexis@effingo.be> | ||
22 | (c) 2015 dimtion <zizou.xena@gmail.com> | ||
23 | (c) 2015 Fanch <fanch-github@qth.fr> | ||
24 | (c) 2015 Guillaume Virlet <github@virlet.org> | ||
25 | (c) 2015 Felix Bartels <felix@host-consultants.de> | ||
26 | (c) 2015 Marsup <marsup@gmail.com> | ||
27 | (c) 2015 Miloš Jovanović <mjovanovic@gmail.com> | ||
28 | (c) 2015 Nicolás Danelón <hola@nicolasdanelon.com.ar> | ||
29 | (c) 2015 TsT <tst2005@gmail.com> | ||
30 | |||
31 | 5 | ||
32 | Files: inc/reset.css | 6 | Files: inc/reset.css |
33 | License: BSD (http://opensource.org/licenses/BSD-3-Clause) | 7 | License: BSD (http://opensource.org/licenses/BSD-3-Clause) |
@@ -169,6 +169,12 @@ clean: | |||
169 | @git clean -df | 169 | @git clean -df |
170 | @rm -rf sandbox | 170 | @rm -rf sandbox |
171 | 171 | ||
172 | ### generate the AUTHORS file from Git commit information | ||
173 | authors: | ||
174 | @cp .github/mailmap .mailmap | ||
175 | @git shortlog -sne > AUTHORS | ||
176 | @rm .mailmap | ||
177 | |||
172 | ### generate Doxygen documentation | 178 | ### generate Doxygen documentation |
173 | doxygen: clean | 179 | doxygen: clean |
174 | @rm -rf doxygen | 180 | @rm -rf doxygen |
@@ -214,4 +220,4 @@ htmlpages: | |||
214 | -o doc/$$base.html $$file; \ | 220 | -o doc/$$base.html $$file; \ |
215 | done; | 221 | done; |
216 | 222 | ||
217 | htmldoc: doc htmlsidebar htmlpages | 223 | htmldoc: authors doc htmlsidebar htmlpages |
diff --git a/application/HttpUtils.php b/application/HttpUtils.php index e8fc1f5d..a81f9056 100644 --- a/application/HttpUtils.php +++ b/application/HttpUtils.php | |||
@@ -122,7 +122,7 @@ function get_http_response($url, $timeout = 30, $maxBytes = 4194304) | |||
122 | $content = substr($response, $headSize); | 122 | $content = substr($response, $headSize); |
123 | $headers = array(); | 123 | $headers = array(); |
124 | foreach (preg_split('~[\r\n]+~', $rawHeadersLastRedir) as $line) { | 124 | foreach (preg_split('~[\r\n]+~', $rawHeadersLastRedir) as $line) { |
125 | if (empty($line) or ctype_space($line)) { | 125 | if (empty($line) || ctype_space($line)) { |
126 | continue; | 126 | continue; |
127 | } | 127 | } |
128 | $splitLine = explode(': ', $line, 2); | 128 | $splitLine = explode(': ', $line, 2); |
diff --git a/application/LinkUtils.php b/application/LinkUtils.php index cf58f808..976474de 100644 --- a/application/LinkUtils.php +++ b/application/LinkUtils.php | |||
@@ -89,7 +89,9 @@ function count_private($links) | |||
89 | { | 89 | { |
90 | $cpt = 0; | 90 | $cpt = 0; |
91 | foreach ($links as $link) { | 91 | foreach ($links as $link) { |
92 | $cpt = $link['private'] == true ? $cpt + 1 : $cpt; | 92 | if ($link['private']) { |
93 | $cpt += 1; | ||
94 | } | ||
93 | } | 95 | } |
94 | 96 | ||
95 | return $cpt; | 97 | return $cpt; |
diff --git a/application/Updater.php b/application/Updater.php index 621c7238..eb03c6d3 100644 --- a/application/Updater.php +++ b/application/Updater.php | |||
@@ -69,7 +69,7 @@ class Updater | |||
69 | return $updatesRan; | 69 | return $updatesRan; |
70 | } | 70 | } |
71 | 71 | ||
72 | if ($this->methods == null) { | 72 | if ($this->methods === null) { |
73 | throw new UpdaterException('Couldn\'t retrieve Updater class methods.'); | 73 | throw new UpdaterException('Couldn\'t retrieve Updater class methods.'); |
74 | } | 74 | } |
75 | 75 | ||
@@ -308,6 +308,22 @@ class Updater | |||
308 | 308 | ||
309 | return true; | 309 | return true; |
310 | } | 310 | } |
311 | |||
312 | /** | ||
313 | * Move the file to inc/user.css to data/user.css. | ||
314 | * | ||
315 | * Note: Due to hardcoded paths, it's not unit testable. But one line of code should be fine. | ||
316 | * | ||
317 | * @return bool true if the update is successful, false otherwise. | ||
318 | */ | ||
319 | public function updateMethodMoveUserCss() | ||
320 | { | ||
321 | if (! is_file('inc/user.css')) { | ||
322 | return true; | ||
323 | } | ||
324 | |||
325 | return rename('inc/user.css', 'data/user.css'); | ||
326 | } | ||
311 | } | 327 | } |
312 | 328 | ||
313 | /** | 329 | /** |
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 | |||
98 | * @throws ApiAuthorizationException The token couldn't be validated. | 98 | * @throws ApiAuthorizationException The token couldn't be validated. |
99 | */ | 99 | */ |
100 | protected function checkToken($request) { | 100 | protected function checkToken($request) { |
101 | $jwt = $request->getHeaderLine('jwt'); | 101 | if (! $request->hasHeader('Authorization')) { |
102 | if (empty($jwt)) { | ||
103 | throw new ApiAuthorizationException('JWT token not provided'); | 102 | throw new ApiAuthorizationException('JWT token not provided'); |
104 | } | 103 | } |
105 | 104 | ||
@@ -107,7 +106,13 @@ class ApiMiddleware | |||
107 | throw new ApiAuthorizationException('Token secret must be set in Shaarli\'s administration'); | 106 | throw new ApiAuthorizationException('Token secret must be set in Shaarli\'s administration'); |
108 | } | 107 | } |
109 | 108 | ||
110 | ApiUtils::validateJwtToken($jwt, $this->conf->get('api.secret')); | 109 | $authorization = $request->getHeaderLine('Authorization'); |
110 | |||
111 | if (! preg_match('/^Bearer (.*)/i', $authorization, $matches)) { | ||
112 | throw new ApiAuthorizationException('Invalid JWT header'); | ||
113 | } | ||
114 | |||
115 | ApiUtils::validateJwtToken($matches[1], $this->conf->get('api.secret')); | ||
111 | } | 116 | } |
112 | 117 | ||
113 | /** | 118 | /** |
@@ -204,7 +204,7 @@ function setup_login_state($conf) | |||
204 | } | 204 | } |
205 | // If session does not exist on server side, or IP address has changed, or session has expired, logout. | 205 | // If session does not exist on server side, or IP address has changed, or session has expired, logout. |
206 | if (empty($_SESSION['uid']) | 206 | if (empty($_SESSION['uid']) |
207 | || ($conf->get('security.session_protection_disabled') == false && $_SESSION['ip'] != allIPs()) | 207 | || ($conf->get('security.session_protection_disabled') === false && $_SESSION['ip'] != allIPs()) |
208 | || time() >= $_SESSION['expires_on']) | 208 | || time() >= $_SESSION['expires_on']) |
209 | { | 209 | { |
210 | logout(); | 210 | logout(); |
diff --git a/tests/api/ApiMiddlewareTest.php b/tests/api/ApiMiddlewareTest.php index 4d4dd9b9..d9753b1d 100644 --- a/tests/api/ApiMiddlewareTest.php +++ b/tests/api/ApiMiddlewareTest.php | |||
@@ -143,7 +143,7 @@ class ApiMiddlewareTest extends \PHPUnit_Framework_TestCase | |||
143 | $env = Environment::mock([ | 143 | $env = Environment::mock([ |
144 | 'REQUEST_METHOD' => 'GET', | 144 | 'REQUEST_METHOD' => 'GET', |
145 | 'REQUEST_URI' => '/echo', | 145 | 'REQUEST_URI' => '/echo', |
146 | 'HTTP_JWT'=> 'jwt', | 146 | 'HTTP_AUTHORIZATION'=> 'Bearer jwt', |
147 | ]); | 147 | ]); |
148 | $request = Request::createFromEnvironment($env); | 148 | $request = Request::createFromEnvironment($env); |
149 | $response = new Response(); | 149 | $response = new Response(); |
@@ -157,7 +157,30 @@ class ApiMiddlewareTest extends \PHPUnit_Framework_TestCase | |||
157 | } | 157 | } |
158 | 158 | ||
159 | /** | 159 | /** |
160 | * Invoke the middleware without an invalid JWT token (debug): | 160 | * Invoke the middleware with an invalid JWT token header |
161 | */ | ||
162 | public function testInvalidJwtAuthHeaderDebug() | ||
163 | { | ||
164 | $this->conf->set('dev.debug', true); | ||
165 | $mw = new ApiMiddleware($this->container); | ||
166 | $env = Environment::mock([ | ||
167 | 'REQUEST_METHOD' => 'GET', | ||
168 | 'REQUEST_URI' => '/echo', | ||
169 | 'HTTP_AUTHORIZATION'=> 'PolarBearer jwt', | ||
170 | ]); | ||
171 | $request = Request::createFromEnvironment($env); | ||
172 | $response = new Response(); | ||
173 | /** @var Response $response */ | ||
174 | $response = $mw($request, $response, null); | ||
175 | |||
176 | $this->assertEquals(401, $response->getStatusCode()); | ||
177 | $body = json_decode((string) $response->getBody()); | ||
178 | $this->assertEquals('Not authorized: Invalid JWT header', $body->message); | ||
179 | $this->assertContains('ApiAuthorizationException', $body->stacktrace); | ||
180 | } | ||
181 | |||
182 | /** | ||
183 | * Invoke the middleware with an invalid JWT token (debug): | ||
161 | * should return a 401 error Unauthorized - with a specific message and a stacktrace. | 184 | * should return a 401 error Unauthorized - with a specific message and a stacktrace. |
162 | * | 185 | * |
163 | * Note: specific JWT errors tests are handled in ApiUtilsTest. | 186 | * Note: specific JWT errors tests are handled in ApiUtilsTest. |
@@ -169,7 +192,7 @@ class ApiMiddlewareTest extends \PHPUnit_Framework_TestCase | |||
169 | $env = Environment::mock([ | 192 | $env = Environment::mock([ |
170 | 'REQUEST_METHOD' => 'GET', | 193 | 'REQUEST_METHOD' => 'GET', |
171 | 'REQUEST_URI' => '/echo', | 194 | 'REQUEST_URI' => '/echo', |
172 | 'HTTP_JWT'=> 'bad jwt', | 195 | 'HTTP_AUTHORIZATION'=> 'Bearer jwt', |
173 | ]); | 196 | ]); |
174 | $request = Request::createFromEnvironment($env); | 197 | $request = Request::createFromEnvironment($env); |
175 | $response = new Response(); | 198 | $response = new Response(); |
diff --git a/tpl/default/includes.html b/tpl/default/includes.html index c3b837f5..17b78b17 100644 --- a/tpl/default/includes.html +++ b/tpl/default/includes.html | |||
@@ -8,7 +8,7 @@ | |||
8 | <link href="images/favicon.ico#" rel="shortcut icon" type="image/x-icon" /> | 8 | <link href="images/favicon.ico#" rel="shortcut icon" type="image/x-icon" /> |
9 | <link type="text/css" rel="stylesheet" href="css/reset.css" /> | 9 | <link type="text/css" rel="stylesheet" href="css/reset.css" /> |
10 | <link type="text/css" rel="stylesheet" href="css/shaarli.css" /> | 10 | <link type="text/css" rel="stylesheet" href="css/shaarli.css" /> |
11 | {if="is_file('inc/user.css')"}<link type="text/css" rel="stylesheet" href="inc/user.css#" />{/if} | 11 | {if="is_file('data/user.css')"}<link type="text/css" rel="stylesheet" href="data/user.css#" />{/if} |
12 | {loop="$plugins_includes.css_files"} | 12 | {loop="$plugins_includes.css_files"} |
13 | <link type="text/css" rel="stylesheet" href="{$value}#"/> | 13 | <link type="text/css" rel="stylesheet" href="{$value}#"/> |
14 | {/loop} | 14 | {/loop} |