diff options
-rw-r--r-- | .htaccess | 13 | ||||
-rw-r--r-- | application/ApplicationUtils.php | 3 | ||||
-rw-r--r-- | application/config/ConfigManager.php | 77 | ||||
-rw-r--r-- | application/security/LoginManager.php | 42 | ||||
-rw-r--r-- | application/security/SessionManager.php | 4 | ||||
-rw-r--r-- | index.php | 63 |
6 files changed, 164 insertions, 38 deletions
@@ -6,10 +6,23 @@ RewriteEngine On | |||
6 | # Prevent accessing subdirectories not managed by SCM | 6 | # Prevent accessing subdirectories not managed by SCM |
7 | RewriteRule ^(.git|doxygen|vendor) - [F] | 7 | RewriteRule ^(.git|doxygen|vendor) - [F] |
8 | 8 | ||
9 | RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$ | ||
10 | RewriteRule ^(.*) - [E=BASE:%1] | ||
11 | |||
12 | RewriteCond %{ENV:REDIRECT_BASE} (.+) | ||
13 | RewriteRule .* - [E=BASE:%1] | ||
14 | |||
9 | # Forward the "Authorization" HTTP header | 15 | # Forward the "Authorization" HTTP header |
10 | RewriteCond %{HTTP:Authorization} ^(.*) | 16 | RewriteCond %{HTTP:Authorization} ^(.*) |
11 | RewriteRule .* - [e=HTTP_AUTHORIZATION:%1] | 17 | RewriteRule .* - [e=HTTP_AUTHORIZATION:%1] |
12 | 18 | ||
19 | RewriteCond %{REQUEST_FILENAME} !-f | ||
20 | RewriteCond %{REQUEST_FILENAME} !-d | ||
21 | RewriteRule ^((?!api/)[^/]*)/?(.*)$ $2?%{QUERY_STRING} [E=USERSPACE:$1] | ||
22 | |||
23 | RewriteCond %{ENV:REDIRECT_USERSPACE} (.+) | ||
24 | RewriteRule .* - [E=USERSPACE:%1] | ||
25 | |||
13 | # REST API | 26 | # REST API |
14 | RewriteCond %{REQUEST_FILENAME} !-f | 27 | RewriteCond %{REQUEST_FILENAME} !-f |
15 | RewriteCond %{REQUEST_FILENAME} !-d | 28 | RewriteCond %{REQUEST_FILENAME} !-d |
diff --git a/application/ApplicationUtils.php b/application/ApplicationUtils.php index 911873a0..f21a1ef3 100644 --- a/application/ApplicationUtils.php +++ b/application/ApplicationUtils.php | |||
@@ -191,6 +191,9 @@ class ApplicationUtils | |||
191 | $conf->get('resource.page_cache'), | 191 | $conf->get('resource.page_cache'), |
192 | $conf->get('resource.raintpl_tmp'), | 192 | $conf->get('resource.raintpl_tmp'), |
193 | ) as $path) { | 193 | ) as $path) { |
194 | if (! is_dir($path)) { | ||
195 | mkdir($path, 0755, true); | ||
196 | } | ||
194 | if (! is_readable(realpath($path))) { | 197 | if (! is_readable(realpath($path))) { |
195 | $errors[] = '"'.$path.'" '. t('directory is not readable'); | 198 | $errors[] = '"'.$path.'" '. t('directory is not readable'); |
196 | } | 199 | } |
diff --git a/application/config/ConfigManager.php b/application/config/ConfigManager.php index 32aaea48..99efc156 100644 --- a/application/config/ConfigManager.php +++ b/application/config/ConfigManager.php | |||
@@ -22,6 +22,11 @@ class ConfigManager | |||
22 | public static $DEFAULT_PLUGINS = array('qrcode'); | 22 | public static $DEFAULT_PLUGINS = array('qrcode'); |
23 | 23 | ||
24 | /** | 24 | /** |
25 | * @var string User space. | ||
26 | */ | ||
27 | protected $userSpace; | ||
28 | |||
29 | /** | ||
25 | * @var string Config folder. | 30 | * @var string Config folder. |
26 | */ | 31 | */ |
27 | protected $configFile; | 32 | protected $configFile; |
@@ -41,12 +46,36 @@ class ConfigManager | |||
41 | * | 46 | * |
42 | * @param string $configFile Configuration file path without extension. | 47 | * @param string $configFile Configuration file path without extension. |
43 | */ | 48 | */ |
44 | public function __construct($configFile = 'data/config') | 49 | public function __construct($configFile = null, $userSpace = null) |
45 | { | 50 | { |
46 | $this->configFile = $configFile; | 51 | $this->userSpace = $this->findLDAPUser($userSpace); |
52 | if ($configFile !== null) { | ||
53 | $this->configFile = $configFile; | ||
54 | } else { | ||
55 | $this->configFile = ($this->userSpace === null) ? 'data/config' : 'data/' . $this->userSpace . '/config'; | ||
56 | } | ||
47 | $this->initialize(); | 57 | $this->initialize(); |
48 | } | 58 | } |
49 | 59 | ||
60 | public function findLDAPUser($login, $password = null) { | ||
61 | $connect = ldap_connect(getenv('SHAARLI_LDAP_HOST')); | ||
62 | ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3); | ||
63 | if (!$connect || !ldap_bind($connect, getenv('SHAARLI_LDAP_DN'), getenv('SHAARLI_LDAP_PASSWORD'))) { | ||
64 | return false; | ||
65 | } | ||
66 | |||
67 | $search_query = str_replace('%login%', ldap_escape($login), getenv('SHAARLI_LDAP_FILTER')); | ||
68 | |||
69 | $search = ldap_search($connect, getenv('SHAARLI_LDAP_BASE'), $search_query); | ||
70 | $info = ldap_get_entries($connect, $search); | ||
71 | |||
72 | if (ldap_count_entries($connect, $search) == 1 && (is_null($password) || ldap_bind($connect, $info[0]["dn"], $password))) { | ||
73 | return $login; | ||
74 | } else { | ||
75 | return null; | ||
76 | } | ||
77 | } | ||
78 | |||
50 | /** | 79 | /** |
51 | * Reset the ConfigManager instance. | 80 | * Reset the ConfigManager instance. |
52 | */ | 81 | */ |
@@ -270,6 +299,16 @@ class ConfigManager | |||
270 | } | 299 | } |
271 | 300 | ||
272 | /** | 301 | /** |
302 | * Get the current userspace. | ||
303 | * | ||
304 | * @return mixed User space. | ||
305 | */ | ||
306 | public function getUserSpace() | ||
307 | { | ||
308 | return $this->userSpace; | ||
309 | } | ||
310 | |||
311 | /** | ||
273 | * Recursive function which find asked setting in the loaded config. | 312 | * Recursive function which find asked setting in the loaded config. |
274 | * | 313 | * |
275 | * @param array $settings Ordered array which contains keys to find. | 314 | * @param array $settings Ordered array which contains keys to find. |
@@ -342,19 +381,31 @@ class ConfigManager | |||
342 | */ | 381 | */ |
343 | protected function setDefaultValues() | 382 | protected function setDefaultValues() |
344 | { | 383 | { |
345 | $this->setEmpty('resource.data_dir', 'data'); | 384 | if ($this->userSpace === null) { |
346 | $this->setEmpty('resource.config', 'data/config.php'); | 385 | $data = 'data'; |
347 | $this->setEmpty('resource.datastore', 'data/datastore.php'); | 386 | $tmp = 'tmp'; |
348 | $this->setEmpty('resource.ban_file', 'data/ipbans.php'); | 387 | $cache = 'cache'; |
349 | $this->setEmpty('resource.updates', 'data/updates.txt'); | 388 | $pagecache = 'pagecache'; |
350 | $this->setEmpty('resource.log', 'data/log.txt'); | 389 | } else { |
351 | $this->setEmpty('resource.update_check', 'data/lastupdatecheck.txt'); | 390 | $data = 'data/' . ($this->userSpace); |
352 | $this->setEmpty('resource.history', 'data/history.php'); | 391 | $tmp = 'tmp/' . ($this->userSpace); |
392 | $cache = 'cache/' . ($this->userSpace); | ||
393 | $pagecache = 'pagecache/' . ($this->userSpace); | ||
394 | } | ||
395 | |||
396 | $this->setEmpty('resource.data_dir', $data); | ||
397 | $this->setEmpty('resource.config', $data . '/config.php'); | ||
398 | $this->setEmpty('resource.datastore', $data . '/datastore.php'); | ||
399 | $this->setEmpty('resource.ban_file', $data . '/ipbans.php'); | ||
400 | $this->setEmpty('resource.updates', $data . '/updates.txt'); | ||
401 | $this->setEmpty('resource.log', $data . '/log.txt'); | ||
402 | $this->setEmpty('resource.update_check', $data . '/lastupdatecheck.txt'); | ||
403 | $this->setEmpty('resource.history', $data . '/history.php'); | ||
353 | $this->setEmpty('resource.raintpl_tpl', 'tpl/'); | 404 | $this->setEmpty('resource.raintpl_tpl', 'tpl/'); |
354 | $this->setEmpty('resource.theme', 'default'); | 405 | $this->setEmpty('resource.theme', 'default'); |
355 | $this->setEmpty('resource.raintpl_tmp', 'tmp/'); | 406 | $this->setEmpty('resource.raintpl_tmp', $tmp); |
356 | $this->setEmpty('resource.thumbnails_cache', 'cache'); | 407 | $this->setEmpty('resource.thumbnails_cache', $cache); |
357 | $this->setEmpty('resource.page_cache', 'pagecache'); | 408 | $this->setEmpty('resource.page_cache', $pagecache); |
358 | 409 | ||
359 | $this->setEmpty('security.ban_after', 4); | 410 | $this->setEmpty('security.ban_after', 4); |
360 | $this->setEmpty('security.ban_duration', 1800); | 411 | $this->setEmpty('security.ban_duration', 1800); |
diff --git a/application/security/LoginManager.php b/application/security/LoginManager.php index d6784d6d..bdfaca7b 100644 --- a/application/security/LoginManager.php +++ b/application/security/LoginManager.php | |||
@@ -32,6 +32,9 @@ class LoginManager | |||
32 | /** @var string User sign-in token depending on remote IP and credentials */ | 32 | /** @var string User sign-in token depending on remote IP and credentials */ |
33 | protected $staySignedInToken = ''; | 33 | protected $staySignedInToken = ''; |
34 | 34 | ||
35 | protected $lastErrorReason = ''; | ||
36 | protected $lastErrorIsBanishable = false; | ||
37 | |||
35 | /** | 38 | /** |
36 | * Constructor | 39 | * Constructor |
37 | * | 40 | * |
@@ -83,7 +86,7 @@ class LoginManager | |||
83 | */ | 86 | */ |
84 | public function checkLoginState($cookie, $clientIpId) | 87 | public function checkLoginState($cookie, $clientIpId) |
85 | { | 88 | { |
86 | if (! $this->configManager->exists('credentials.login')) { | 89 | if (! $this->configManager->exists('credentials.login') || (isset($_SESSION['username']) && $_SESSION['username'] && $this->configManager->get('credentials.login') !== $_SESSION['username'])) { |
87 | // Shaarli is not configured yet | 90 | // Shaarli is not configured yet |
88 | $this->isLoggedIn = false; | 91 | $this->isLoggedIn = false; |
89 | return; | 92 | return; |
@@ -133,20 +136,40 @@ class LoginManager | |||
133 | */ | 136 | */ |
134 | public function checkCredentials($remoteIp, $clientIpId, $login, $password) | 137 | public function checkCredentials($remoteIp, $clientIpId, $login, $password) |
135 | { | 138 | { |
136 | $hash = sha1($password . $login . $this->configManager->get('credentials.salt')); | 139 | $this->lastErrorIsBanishable = false; |
140 | |||
141 | if ($this->configManager->getUserSpace() !== null && $this->configManager->getUserSpace() !== $login) { | ||
142 | logm($this->configManager->get('resource.log'), | ||
143 | $remoteIp, | ||
144 | 'Trying to login to wrong user space'); | ||
145 | $this->lastErrorReason = 'You’re trying to access the wrong account.'; | ||
146 | return false; | ||
147 | } | ||
137 | 148 | ||
138 | if ($login != $this->configManager->get('credentials.login') | 149 | logm($this->configManager->get('resource.log'), |
139 | || $hash != $this->configManager->get('credentials.hash') | 150 | $remoteIp, |
140 | ) { | 151 | 'Trying LDAP connection'); |
152 | $result = $this->configManager->findLDAPUser($login, $password); | ||
153 | if ($result === false) { | ||
141 | logm( | 154 | logm( |
142 | $this->configManager->get('resource.log'), | 155 | $this->configManager->get('resource.log'), |
143 | $remoteIp, | 156 | $remoteIp, |
144 | 'Login failed for user ' . $login | 157 | 'Impossible to connect to LDAP' |
145 | ); | 158 | ); |
159 | $this->lastErrorReason = 'Server error.'; | ||
160 | return false; | ||
161 | } else if (is_null($result)) { | ||
162 | logm( | ||
163 | $this->configManager->get('resource.log'), | ||
164 | $remoteIp, | ||
165 | 'Login failed for user ' . $login | ||
166 | ); | ||
167 | $this->lastErrorIsBanishable = true; | ||
168 | $this->lastErrorReason = 'Wrong login/password.'; | ||
146 | return false; | 169 | return false; |
147 | } | 170 | } |
148 | 171 | ||
149 | $this->sessionManager->storeLoginInfo($clientIpId); | 172 | $this->sessionManager->storeLoginInfo($clientIpId, $login); |
150 | logm( | 173 | logm( |
151 | $this->configManager->get('resource.log'), | 174 | $this->configManager->get('resource.log'), |
152 | $remoteIp, | 175 | $remoteIp, |
@@ -187,6 +210,10 @@ class LoginManager | |||
187 | */ | 210 | */ |
188 | public function handleFailedLogin($server) | 211 | public function handleFailedLogin($server) |
189 | { | 212 | { |
213 | if (!$this->lastErrorIsBanishable) { | ||
214 | return $this->lastErrorReason ?: 'Error during login.'; | ||
215 | }; | ||
216 | |||
190 | $ip = $server['REMOTE_ADDR']; | 217 | $ip = $server['REMOTE_ADDR']; |
191 | $trusted = $this->configManager->get('security.trusted_proxies', []); | 218 | $trusted = $this->configManager->get('security.trusted_proxies', []); |
192 | 219 | ||
@@ -215,6 +242,7 @@ class LoginManager | |||
215 | ); | 242 | ); |
216 | } | 243 | } |
217 | $this->writeBanFile(); | 244 | $this->writeBanFile(); |
245 | return $this->lastErrorReason ?: 'Error during login.'; | ||
218 | } | 246 | } |
219 | 247 | ||
220 | /** | 248 | /** |
diff --git a/application/security/SessionManager.php b/application/security/SessionManager.php index b8b8ab8d..5eb4aac5 100644 --- a/application/security/SessionManager.php +++ b/application/security/SessionManager.php | |||
@@ -111,10 +111,10 @@ class SessionManager | |||
111 | * | 111 | * |
112 | * @param string $clientIpId Client IP address identifier | 112 | * @param string $clientIpId Client IP address identifier |
113 | */ | 113 | */ |
114 | public function storeLoginInfo($clientIpId) | 114 | public function storeLoginInfo($clientIpId, $login = null) |
115 | { | 115 | { |
116 | $this->session['ip'] = $clientIpId; | 116 | $this->session['ip'] = $clientIpId; |
117 | $this->session['username'] = $this->conf->get('credentials.login'); | 117 | $this->session['username'] = $login ?: $this->conf->get('credentials.login'); |
118 | $this->extendTimeValidityBy(self::$SHORT_TIMEOUT); | 118 | $this->extendTimeValidityBy(self::$SHORT_TIMEOUT); |
119 | } | 119 | } |
120 | 120 | ||
@@ -121,7 +121,32 @@ if (isset($_COOKIE['shaarli']) && !SessionManager::checkId($_COOKIE['shaarli'])) | |||
121 | $_COOKIE['shaarli'] = session_id(); | 121 | $_COOKIE['shaarli'] = session_id(); |
122 | } | 122 | } |
123 | 123 | ||
124 | $conf = new ConfigManager(); | 124 | $folderBase = getenv("BASE"); |
125 | |||
126 | if (getenv("USERSPACE")) { | ||
127 | if (isset($_GET["do"]) && $_GET["do"] == "login") { | ||
128 | header("Location: $folderBase/?do=login"); | ||
129 | exit; | ||
130 | } | ||
131 | $userspace = preg_replace("/[^-_A-Za-z0-9]/", '', getenv("USERSPACE")); | ||
132 | } else if (isset($_SESSION["username"]) && $_SESSION["username"]) { | ||
133 | header("Location: " . $folderBase . "/" . $_SESSION["username"] . "?"); | ||
134 | exit; | ||
135 | } else if (!isset($_GET["do"]) || $_GET["do"] != "login") { | ||
136 | header("Location: $folderBase/?do=login"); | ||
137 | exit; | ||
138 | } | ||
139 | |||
140 | if (!isset($userspace) && isset($_POST["login"])) { | ||
141 | $userspace = preg_replace("/[^-_A-Za-z0-9]/", '', $_POST["login"]); | ||
142 | error_log("debugImmae: setting userspace from POST: " . $userspace); | ||
143 | } | ||
144 | |||
145 | if (isset($userspace)) { | ||
146 | $conf = new ConfigManager(null, $userspace); | ||
147 | } else { | ||
148 | $conf = new ConfigManager(); | ||
149 | } | ||
125 | $sessionManager = new SessionManager($_SESSION, $conf); | 150 | $sessionManager = new SessionManager($_SESSION, $conf); |
126 | $loginManager = new LoginManager($GLOBALS, $conf, $sessionManager); | 151 | $loginManager = new LoginManager($GLOBALS, $conf, $sessionManager); |
127 | $loginManager->generateStaySignedInToken($_SERVER['REMOTE_ADDR']); | 152 | $loginManager->generateStaySignedInToken($_SERVER['REMOTE_ADDR']); |
@@ -175,7 +200,7 @@ if (! is_file($conf->getConfigFileExt())) { | |||
175 | } | 200 | } |
176 | 201 | ||
177 | // Display the installation form if no existing config is found | 202 | // Display the installation form if no existing config is found |
178 | install($conf, $sessionManager, $loginManager); | 203 | install($conf, $sessionManager, $loginManager, $userspace); |
179 | } | 204 | } |
180 | 205 | ||
181 | $loginManager->checkLoginState($_COOKIE, $clientIpId); | 206 | $loginManager->checkLoginState($_COOKIE, $clientIpId); |
@@ -205,6 +230,7 @@ if (isset($_POST['login'])) { | |||
205 | && $loginManager->checkCredentials($_SERVER['REMOTE_ADDR'], $clientIpId, $_POST['login'], $_POST['password']) | 230 | && $loginManager->checkCredentials($_SERVER['REMOTE_ADDR'], $clientIpId, $_POST['login'], $_POST['password']) |
206 | ) { | 231 | ) { |
207 | $loginManager->handleSuccessfulLogin($_SERVER); | 232 | $loginManager->handleSuccessfulLogin($_SERVER); |
233 | $userspace = $_POST['login']; | ||
208 | 234 | ||
209 | $cookiedir = ''; | 235 | $cookiedir = ''; |
210 | if (dirname($_SERVER['SCRIPT_NAME']) != '/') { | 236 | if (dirname($_SERVER['SCRIPT_NAME']) != '/') { |
@@ -241,25 +267,25 @@ if (isset($_POST['login'])) { | |||
241 | $uri .= '&'.$param.'='.urlencode($_GET[$param]); | 267 | $uri .= '&'.$param.'='.urlencode($_GET[$param]); |
242 | } | 268 | } |
243 | } | 269 | } |
244 | header('Location: '. $uri); | 270 | header('Location: '. $userspace . $uri); |
245 | exit; | 271 | exit; |
246 | } | 272 | } |
247 | 273 | ||
248 | if (isset($_GET['edit_link'])) { | 274 | if (isset($_GET['edit_link'])) { |
249 | header('Location: ?edit_link='. escape($_GET['edit_link'])); | 275 | header('Location: ' . $userspace . '?edit_link='. escape($_GET['edit_link'])); |
250 | exit; | 276 | exit; |
251 | } | 277 | } |
252 | 278 | ||
253 | if (isset($_POST['returnurl'])) { | 279 | if (isset($_POST['returnurl'])) { |
254 | // Prevent loops over login screen. | 280 | // Prevent loops over login screen. |
255 | if (strpos($_POST['returnurl'], 'do=login') === false) { | 281 | if (strpos($_POST['returnurl'], 'do=login') === false) { |
256 | header('Location: '. generateLocation($_POST['returnurl'], $_SERVER['HTTP_HOST'])); | 282 | header('Location: ' . generateLocation($_POST['returnurl'], $_SERVER['HTTP_HOST'])); |
257 | exit; | 283 | exit; |
258 | } | 284 | } |
259 | } | 285 | } |
260 | header('Location: ?'); exit; | 286 | header('Location: '. $userspace . '?'); exit; |
261 | } else { | 287 | } else { |
262 | $loginManager->handleFailedLogin($_SERVER); | 288 | $errorReason = $loginManager->handleFailedLogin($_SERVER); |
263 | $redir = '&username='. urlencode($_POST['login']); | 289 | $redir = '&username='. urlencode($_POST['login']); |
264 | if (isset($_GET['post'])) { | 290 | if (isset($_GET['post'])) { |
265 | $redir .= '&post=' . urlencode($_GET['post']); | 291 | $redir .= '&post=' . urlencode($_GET['post']); |
@@ -270,7 +296,7 @@ if (isset($_POST['login'])) { | |||
270 | } | 296 | } |
271 | } | 297 | } |
272 | // Redirect to login screen. | 298 | // Redirect to login screen. |
273 | echo '<script>alert("'. t("Wrong login/password.") .'");document.location=\'?do=login'.$redir.'\';</script>'; | 299 | echo '<script>alert("'. t($errorReason) .'");document.location=\'?do=login'.$redir.'\';</script>'; |
274 | exit; | 300 | exit; |
275 | } | 301 | } |
276 | } | 302 | } |
@@ -1719,7 +1745,7 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager) | |||
1719 | * @param SessionManager $sessionManager SessionManager instance | 1745 | * @param SessionManager $sessionManager SessionManager instance |
1720 | * @param LoginManager $loginManager LoginManager instance | 1746 | * @param LoginManager $loginManager LoginManager instance |
1721 | */ | 1747 | */ |
1722 | function install($conf, $sessionManager, $loginManager) { | 1748 | function install($conf, $sessionManager, $loginManager, $userspace) { |
1723 | // On free.fr host, make sure the /sessions directory exists, otherwise login will not work. | 1749 | // On free.fr host, make sure the /sessions directory exists, otherwise login will not work. |
1724 | if (endsWith($_SERVER['HTTP_HOST'],'.free.fr') && !is_dir($_SERVER['DOCUMENT_ROOT'].'/sessions')) mkdir($_SERVER['DOCUMENT_ROOT'].'/sessions',0705); | 1750 | if (endsWith($_SERVER['HTTP_HOST'],'.free.fr') && !is_dir($_SERVER['DOCUMENT_ROOT'].'/sessions')) mkdir($_SERVER['DOCUMENT_ROOT'].'/sessions',0705); |
1725 | 1751 | ||
@@ -1755,7 +1781,7 @@ function install($conf, $sessionManager, $loginManager) { | |||
1755 | } | 1781 | } |
1756 | 1782 | ||
1757 | 1783 | ||
1758 | if (!empty($_POST['setlogin']) && !empty($_POST['setpassword'])) | 1784 | if (true) |
1759 | { | 1785 | { |
1760 | $tz = 'UTC'; | 1786 | $tz = 'UTC'; |
1761 | if (!empty($_POST['continent']) && !empty($_POST['city']) | 1787 | if (!empty($_POST['continent']) && !empty($_POST['city']) |
@@ -1764,15 +1790,15 @@ function install($conf, $sessionManager, $loginManager) { | |||
1764 | $tz = $_POST['continent'].'/'.$_POST['city']; | 1790 | $tz = $_POST['continent'].'/'.$_POST['city']; |
1765 | } | 1791 | } |
1766 | $conf->set('general.timezone', $tz); | 1792 | $conf->set('general.timezone', $tz); |
1767 | $login = $_POST['setlogin']; | 1793 | $conf->set('credentials.login', $userspace); |
1768 | $conf->set('credentials.login', $login); | ||
1769 | $salt = sha1(uniqid('', true) .'_'. mt_rand()); | 1794 | $salt = sha1(uniqid('', true) .'_'. mt_rand()); |
1770 | $conf->set('credentials.salt', $salt); | 1795 | $conf->set('credentials.salt', $salt); |
1771 | $conf->set('credentials.hash', sha1($_POST['setpassword'] . $login . $salt)); | 1796 | $hash = sha1(uniqid('', true) .'_'. mt_rand()); |
1797 | $conf->set('credentials.hash', $hash); | ||
1772 | if (!empty($_POST['title'])) { | 1798 | if (!empty($_POST['title'])) { |
1773 | $conf->set('general.title', escape($_POST['title'])); | 1799 | $conf->set('general.title', escape($_POST['title'])); |
1774 | } else { | 1800 | } else { |
1775 | $conf->set('general.title', 'Shared links on '.escape(index_url($_SERVER))); | 1801 | $conf->set('general.title', ucwords(str_replace("_", " ", $userspace))); |
1776 | } | 1802 | } |
1777 | $conf->set('translation.language', escape($_POST['language'])); | 1803 | $conf->set('translation.language', escape($_POST['language'])); |
1778 | $conf->set('updates.check_updates', !empty($_POST['updateCheck'])); | 1804 | $conf->set('updates.check_updates', !empty($_POST['updateCheck'])); |
@@ -1841,7 +1867,12 @@ $container['history'] = $history; | |||
1841 | $app = new \Slim\App($container); | 1867 | $app = new \Slim\App($container); |
1842 | 1868 | ||
1843 | // REST API routes | 1869 | // REST API routes |
1844 | $app->group('/api/v1', function() { | 1870 | if (isset($userspace)) { |
1871 | $mountpoint = '/' . $userspace . '/api/v1'; | ||
1872 | } else { | ||
1873 | $mountpoint = '/api/v1'; | ||
1874 | } | ||
1875 | $app->group($mountpoint, function() { | ||
1845 | $this->get('/info', '\Shaarli\Api\Controllers\Info:getInfo')->setName('getInfo'); | 1876 | $this->get('/info', '\Shaarli\Api\Controllers\Info:getInfo')->setName('getInfo'); |
1846 | $this->get('/links', '\Shaarli\Api\Controllers\Links:getLinks')->setName('getLinks'); | 1877 | $this->get('/links', '\Shaarli\Api\Controllers\Links:getLinks')->setName('getLinks'); |
1847 | $this->get('/links/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:getLink')->setName('getLink'); | 1878 | $this->get('/links/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:getLink')->setName('getLink'); |
@@ -1860,7 +1891,7 @@ $app->group('/api/v1', function() { | |||
1860 | $response = $app->run(true); | 1891 | $response = $app->run(true); |
1861 | // Hack to make Slim and Shaarli router work together: | 1892 | // Hack to make Slim and Shaarli router work together: |
1862 | // If a Slim route isn't found and NOT API call, we call renderPage(). | 1893 | // If a Slim route isn't found and NOT API call, we call renderPage(). |
1863 | if ($response->getStatusCode() == 404 && strpos($_SERVER['REQUEST_URI'], '/api/v1') === false) { | 1894 | if ($response->getStatusCode() == 404 && strpos($_SERVER['REQUEST_URI'], $mountpoint) === false) { |
1864 | // We use UTF-8 for proper international characters handling. | 1895 | // We use UTF-8 for proper international characters handling. |
1865 | header('Content-Type: text/html; charset=utf-8'); | 1896 | header('Content-Type: text/html; charset=utf-8'); |
1866 | renderPage($conf, $pluginManager, $linkDb, $history, $sessionManager, $loginManager); | 1897 | renderPage($conf, $pluginManager, $linkDb, $history, $sessionManager, $loginManager); |