aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.gitattributes1
-rw-r--r--.github/mailmap13
-rw-r--r--AUTHORS40
-rw-r--r--COPYING28
-rw-r--r--Makefile8
-rw-r--r--application/HttpUtils.php2
-rw-r--r--application/LinkUtils.php4
-rw-r--r--application/Updater.php18
-rw-r--r--application/api/ApiMiddleware.php11
-rw-r--r--index.php2
-rw-r--r--tests/api/ApiMiddlewareTest.php29
-rw-r--r--tpl/default/includes.html2
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
24doc/**/*.json export-ignore 25doc/**/*.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 @@
1ArthurHoaro <arthur@hoa.ro>
2Florian Eula <eula.florian@gmail.com> feula
3Florian Eula <eula.florian@gmail.com> <mr.pikzen@gmail.com>
4Nicolas Danelon <hi@nicolasmd.com.ar> nicolasm
5Nicolas Danelon <hi@nicolasmd.com.ar> <nda@3818.com.ar>
6Nicolas Danelon <hi@nicolasmd.com.ar> <nicolasdanelon@gmail.com>
7Nicolas Danelon <hi@nicolasmd.com.ar> <nicolasdanelon@users.noreply.github.com>
8Sébastien Sauvage <sebsauvage@sebsauvage.net>
9Timo Van Neerden <fire@lehollandaisvolant.net>
10Timo Van Neerden <fire@lehollandaisvolant.net> lehollandaisvolant <levoltigeurhollandais@gmail.com>
11VirtualTam <virtualtam@flibidi.net> <tamisier.aurelien@gmail.com>
12VirtualTam <virtualtam@flibidi.net> <virtualtam+github@flibidi.net>
13VirtualTam <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>
diff --git a/COPYING b/COPYING
index 547ea570..4bbdf2b3 100644
--- a/COPYING
+++ b/COPYING
@@ -1,33 +1,7 @@
1Files: * 1Files: *
2License: zlib/libpng 2License: zlib/libpng
3Copyright: (c) 2011-2015 Sébastien SAUVAGE <sebsauvage@sebsauvage.net> 3Copyright: (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
32Files: inc/reset.css 6Files: inc/reset.css
33License: BSD (http://opensource.org/licenses/BSD-3-Clause) 7License: BSD (http://opensource.org/licenses/BSD-3-Clause)
diff --git a/Makefile b/Makefile
index 60aec9a0..f3065b77 100644
--- a/Makefile
+++ b/Makefile
@@ -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
173authors:
174 @cp .github/mailmap .mailmap
175 @git shortlog -sne > AUTHORS
176 @rm .mailmap
177
172### generate Doxygen documentation 178### generate Doxygen documentation
173doxygen: clean 179doxygen: 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
217htmldoc: doc htmlsidebar htmlpages 223htmldoc: 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 /**
diff --git a/index.php b/index.php
index e553d1dd..a54dfb1d 100644
--- a/index.php
+++ b/index.php
@@ -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}