]> git.immae.eu Git - perso/Immae/Config/Nix.git/blobdiff - overlays/shaarli/shaarli_ldap.patch
Squash changes containing private information
[perso/Immae/Config/Nix.git] / overlays / shaarli / shaarli_ldap.patch
diff --git a/overlays/shaarli/shaarli_ldap.patch b/overlays/shaarli/shaarli_ldap.patch
deleted file mode 100644 (file)
index e66a54f..0000000
+++ /dev/null
@@ -1,425 +0,0 @@
-commit a19c24edc1057bd411821f9e3e7d1d309d38b1bb
-Author: Ismaël Bouya <ismael.bouya@normalesup.org>
-Date:   Sun Feb 3 20:58:18 2019 +0100
-
-    Add ldap connection
-
-diff --git a/.htaccess b/.htaccess
-index 4c00427..5acd708 100644
---- a/.htaccess
-+++ b/.htaccess
-@@ -6,10 +6,23 @@ RewriteEngine On
- # Prevent accessing subdirectories not managed by SCM
- RewriteRule ^(.git|doxygen|vendor) - [F]
-+RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
-+RewriteRule ^(.*) - [E=BASE:%1]
-+
-+RewriteCond %{ENV:REDIRECT_BASE} (.+)
-+RewriteRule .* - [E=BASE:%1]
-+
- # Forward the "Authorization" HTTP header
- RewriteCond %{HTTP:Authorization} ^(.*)
- RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
-+RewriteCond %{REQUEST_FILENAME} !-f
-+RewriteCond %{REQUEST_FILENAME} !-d
-+RewriteRule ^((?!api/)[^/]*)/?(.*)$ $2?%{QUERY_STRING} [E=USERSPACE:$1]
-+
-+RewriteCond %{ENV:REDIRECT_USERSPACE} (.+)
-+RewriteRule .* - [E=USERSPACE:%1]
-+
- # REST API
- RewriteCond %{REQUEST_FILENAME} !-f
- RewriteCond %{REQUEST_FILENAME} !-d
-diff --git a/application/ApplicationUtils.php b/application/ApplicationUtils.php
-index 911873a..f21a1ef 100644
---- a/application/ApplicationUtils.php
-+++ b/application/ApplicationUtils.php
-@@ -191,6 +191,9 @@ public static function checkResourcePermissions($conf)
-             $conf->get('resource.page_cache'),
-             $conf->get('resource.raintpl_tmp'),
-         ) as $path) {
-+            if (! is_dir($path)) {
-+                mkdir($path, 0755, true);
-+            }
-             if (! is_readable(realpath($path))) {
-                 $errors[] = '"'.$path.'" '. t('directory is not readable');
-             }
-diff --git a/application/config/ConfigManager.php b/application/config/ConfigManager.php
-index 32aaea4..99efc15 100644
---- a/application/config/ConfigManager.php
-+++ b/application/config/ConfigManager.php
-@@ -21,6 +21,11 @@ class ConfigManager
-     public static $DEFAULT_PLUGINS = array('qrcode');
-+    /**
-+     * @var string User space.
-+     */
-+    protected $userSpace;
-+
-     /**
-      * @var string Config folder.
-      */
-@@ -41,12 +46,36 @@ class ConfigManager
-      *
-      * @param string $configFile Configuration file path without extension.
-      */
--    public function __construct($configFile = 'data/config')
-+    public function __construct($configFile = null, $userSpace = null)
-     {
--        $this->configFile = $configFile;
-+        $this->userSpace = $this->findLDAPUser($userSpace);
-+        if ($configFile !== null) {
-+            $this->configFile = $configFile;
-+        } else {
-+            $this->configFile = ($this->userSpace === null) ? 'data/config' : 'data/' . $this->userSpace . '/config';
-+        }
-         $this->initialize();
-     }
-+    public function findLDAPUser($login, $password = null) {
-+        $connect = ldap_connect(getenv('SHAARLI_LDAP_HOST'));
-+        ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3);
-+        if (!$connect || !ldap_bind($connect, getenv('SHAARLI_LDAP_DN'), getenv('SHAARLI_LDAP_PASSWORD'))) {
-+            return false;
-+        }
-+
-+        $search_query = str_replace('%login%', ldap_escape($login), getenv('SHAARLI_LDAP_FILTER'));
-+
-+        $search = ldap_search($connect, getenv('SHAARLI_LDAP_BASE'), $search_query);
-+        $info = ldap_get_entries($connect, $search);
-+
-+        if (ldap_count_entries($connect, $search) == 1 && (is_null($password) || ldap_bind($connect, $info[0]["dn"], $password))) {
-+            return $login;
-+        } else {
-+            return null;
-+        }
-+    }
-+
-     /**
-      * Reset the ConfigManager instance.
-      */
-@@ -269,6 +298,16 @@ public function getConfigFileExt()
-         return $this->configFile . $this->configIO->getExtension();
-     }
-+    /**
-+     * Get the current userspace.
-+     *
-+     * @return mixed User space.
-+     */
-+    public function getUserSpace()
-+    {
-+      return $this->userSpace;
-+    }
-+
-     /**
-      * Recursive function which find asked setting in the loaded config.
-      *
-@@ -342,19 +381,31 @@ protected static function removeConfig($settings, &$conf)
-      */
-     protected function setDefaultValues()
-     {
--        $this->setEmpty('resource.data_dir', 'data');
--        $this->setEmpty('resource.config', 'data/config.php');
--        $this->setEmpty('resource.datastore', 'data/datastore.php');
--        $this->setEmpty('resource.ban_file', 'data/ipbans.php');
--        $this->setEmpty('resource.updates', 'data/updates.txt');
--        $this->setEmpty('resource.log', 'data/log.txt');
--        $this->setEmpty('resource.update_check', 'data/lastupdatecheck.txt');
--        $this->setEmpty('resource.history', 'data/history.php');
-+        if ($this->userSpace === null) {
-+          $data = 'data';
-+          $tmp  = 'tmp';
-+          $cache = 'cache';
-+          $pagecache = 'pagecache';
-+        } else {
-+          $data = 'data/' . ($this->userSpace);
-+          $tmp  = 'tmp/' . ($this->userSpace);
-+          $cache = 'cache/' . ($this->userSpace);
-+          $pagecache = 'pagecache/' . ($this->userSpace);
-+        }
-+
-+        $this->setEmpty('resource.data_dir', $data);
-+        $this->setEmpty('resource.config', $data . '/config.php');
-+        $this->setEmpty('resource.datastore', $data . '/datastore.php');
-+        $this->setEmpty('resource.ban_file', $data . '/ipbans.php');
-+        $this->setEmpty('resource.updates', $data . '/updates.txt');
-+        $this->setEmpty('resource.log', $data . '/log.txt');
-+        $this->setEmpty('resource.update_check', $data . '/lastupdatecheck.txt');
-+        $this->setEmpty('resource.history', $data . '/history.php');
-         $this->setEmpty('resource.raintpl_tpl', 'tpl/');
-         $this->setEmpty('resource.theme', 'default');
--        $this->setEmpty('resource.raintpl_tmp', 'tmp/');
--        $this->setEmpty('resource.thumbnails_cache', 'cache');
--        $this->setEmpty('resource.page_cache', 'pagecache');
-+        $this->setEmpty('resource.raintpl_tmp', $tmp);
-+        $this->setEmpty('resource.thumbnails_cache', $cache);
-+        $this->setEmpty('resource.page_cache', $pagecache);
-         $this->setEmpty('security.ban_after', 4);
-         $this->setEmpty('security.ban_duration', 1800);
-diff --git a/application/security/LoginManager.php b/application/security/LoginManager.php
-index d6784d6..bdfaca7 100644
---- a/application/security/LoginManager.php
-+++ b/application/security/LoginManager.php
-@@ -32,6 +32,9 @@ class LoginManager
-     /** @var string User sign-in token depending on remote IP and credentials */
-     protected $staySignedInToken = '';
-+    protected $lastErrorReason = '';
-+    protected $lastErrorIsBanishable = false;
-+
-     /**
-      * Constructor
-      *
-@@ -83,7 +86,7 @@ public function getStaySignedInToken()
-      */
-     public function checkLoginState($cookie, $clientIpId)
-     {
--        if (! $this->configManager->exists('credentials.login')) {
-+        if (! $this->configManager->exists('credentials.login') || (isset($_SESSION['username']) && $_SESSION['username'] && $this->configManager->get('credentials.login') !== $_SESSION['username'])) {
-             // Shaarli is not configured yet
-             $this->isLoggedIn = false;
-             return;
-@@ -133,20 +136,40 @@ public function isLoggedIn()
-      */
-     public function checkCredentials($remoteIp, $clientIpId, $login, $password)
-     {
--        $hash = sha1($password . $login . $this->configManager->get('credentials.salt'));
-+        $this->lastErrorIsBanishable = false;
-+
-+        if ($this->configManager->getUserSpace() !== null && $this->configManager->getUserSpace() !== $login) {
-+          logm($this->configManager->get('resource.log'),
-+               $remoteIp,
-+               'Trying to login to wrong user space');
-+          $this->lastErrorReason = 'You’re trying to access the wrong account.';
-+          return false;
-+        }
--        if ($login != $this->configManager->get('credentials.login')
--            || $hash != $this->configManager->get('credentials.hash')
--        ) {
-+        logm($this->configManager->get('resource.log'),
-+             $remoteIp,
-+             'Trying LDAP connection');
-+        $result = $this->configManager->findLDAPUser($login, $password);
-+        if ($result === false) {
-             logm(
-                 $this->configManager->get('resource.log'),
-                 $remoteIp,
--                'Login failed for user ' . $login
-+                'Impossible to connect to LDAP'
-             );
-+            $this->lastErrorReason = 'Server error.';
-+            return false;
-+        } else if (is_null($result)) {
-+            logm(
-+              $this->configManager->get('resource.log'),
-+              $remoteIp,
-+              'Login failed for user ' . $login
-+            );
-+            $this->lastErrorIsBanishable = true;
-+            $this->lastErrorReason = 'Wrong login/password.';
-             return false;
-         }
--        $this->sessionManager->storeLoginInfo($clientIpId);
-+        $this->sessionManager->storeLoginInfo($clientIpId, $login);
-         logm(
-             $this->configManager->get('resource.log'),
-             $remoteIp,
-@@ -187,6 +210,10 @@ protected function writeBanFile()
-      */
-     public function handleFailedLogin($server)
-     {
-+        if (!$this->lastErrorIsBanishable) {
-+          return $this->lastErrorReason ?: 'Error during login.';
-+        };
-+
-         $ip = $server['REMOTE_ADDR'];
-         $trusted = $this->configManager->get('security.trusted_proxies', []);
-@@ -215,6 +242,7 @@ public function handleFailedLogin($server)
-             );
-         }
-         $this->writeBanFile();
-+        return $this->lastErrorReason ?: 'Error during login.';
-     }
-     /**
-diff --git a/application/security/SessionManager.php b/application/security/SessionManager.php
-index b8b8ab8..5eb4aac 100644
---- a/application/security/SessionManager.php
-+++ b/application/security/SessionManager.php
-@@ -111,10 +111,10 @@ public static function checkId($sessionId)
-      *
-      * @param string $clientIpId Client IP address identifier
-      */
--    public function storeLoginInfo($clientIpId)
-+    public function storeLoginInfo($clientIpId, $login = null)
-     {
-         $this->session['ip'] = $clientIpId;
--        $this->session['username'] = $this->conf->get('credentials.login');
-+        $this->session['username'] = $login ?: $this->conf->get('credentials.login');
-         $this->extendTimeValidityBy(self::$SHORT_TIMEOUT);
-     }
-diff --git a/index.php b/index.php
-index 4b86a3e..58ae2dd 100644
---- a/index.php
-+++ b/index.php
-@@ -121,7 +121,32 @@
-     $_COOKIE['shaarli'] = session_id();
- }
--$conf = new ConfigManager();
-+$folderBase = getenv("BASE");
-+
-+if (getenv("USERSPACE")) {
-+    if (isset($_GET["do"]) && $_GET["do"] == "login") {
-+        header("Location: $folderBase/?do=login");
-+        exit;
-+    }
-+    $userspace = preg_replace("/[^-_A-Za-z0-9]/", '', getenv("USERSPACE"));
-+} else if (isset($_SESSION["username"]) && $_SESSION["username"]) {
-+    header("Location: " . $folderBase . "/" . $_SESSION["username"] . "?");
-+    exit;
-+} else if (!isset($_GET["do"]) || $_GET["do"] != "login") {
-+    header("Location: $folderBase/?do=login");
-+    exit;
-+}
-+
-+if (!isset($userspace) && isset($_POST["login"])) {
-+    $userspace = preg_replace("/[^-_A-Za-z0-9]/", '', $_POST["login"]);
-+    error_log("debugImmae: setting userspace from POST: " . $userspace);
-+}
-+
-+if (isset($userspace)) {
-+  $conf = new ConfigManager(null, $userspace);
-+} else {
-+  $conf = new ConfigManager();
-+}
- $sessionManager = new SessionManager($_SESSION, $conf);
- $loginManager = new LoginManager($GLOBALS, $conf, $sessionManager);
- $loginManager->generateStaySignedInToken($_SERVER['REMOTE_ADDR']);
-@@ -175,7 +200,7 @@
-     }
-     // Display the installation form if no existing config is found
--    install($conf, $sessionManager, $loginManager);
-+    install($conf, $sessionManager, $loginManager, $userspace);
- }
- $loginManager->checkLoginState($_COOKIE, $clientIpId);
-@@ -205,6 +230,7 @@ function isLoggedIn()
-         && $loginManager->checkCredentials($_SERVER['REMOTE_ADDR'], $clientIpId, $_POST['login'], $_POST['password'])
-     ) {
-         $loginManager->handleSuccessfulLogin($_SERVER);
-+        $userspace = $_POST['login'];
-         $cookiedir = '';
-         if (dirname($_SERVER['SCRIPT_NAME']) != '/') {
-@@ -241,25 +267,25 @@ function isLoggedIn()
-                     $uri .= '&'.$param.'='.urlencode($_GET[$param]);
-                 }
-             }
--            header('Location: '. $uri);
-+            header('Location: '. $userspace . $uri);
-             exit;
-         }
-         if (isset($_GET['edit_link'])) {
--            header('Location: ?edit_link='. escape($_GET['edit_link']));
-+            header('Location: ' . $userspace . '?edit_link='. escape($_GET['edit_link']));
-             exit;
-         }
-         if (isset($_POST['returnurl'])) {
-             // Prevent loops over login screen.
-             if (strpos($_POST['returnurl'], 'do=login') === false) {
--                header('Location: '. generateLocation($_POST['returnurl'], $_SERVER['HTTP_HOST']));
-+                header('Location: ' . generateLocation($_POST['returnurl'], $_SERVER['HTTP_HOST']));
-                 exit;
-             }
-         }
--        header('Location: ?'); exit;
-+        header('Location: '. $userspace . '?'); exit;
-     } else {
--        $loginManager->handleFailedLogin($_SERVER);
-+        $errorReason = $loginManager->handleFailedLogin($_SERVER);
-         $redir = '&username='. urlencode($_POST['login']);
-         if (isset($_GET['post'])) {
-             $redir .= '&post=' . urlencode($_GET['post']);
-@@ -270,7 +296,7 @@ function isLoggedIn()
-             }
-         }
-         // Redirect to login screen.
--        echo '<script>alert("'. t("Wrong login/password.") .'");document.location=\'?do=login'.$redir.'\';</script>';
-+        echo '<script>alert("'. t($errorReason) .'");document.location=\'?do=login'.$redir.'\';</script>';
-         exit;
-     }
- }
-@@ -1719,7 +1745,7 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager)
-  * @param SessionManager $sessionManager SessionManager instance
-  * @param LoginManager   $loginManager   LoginManager instance
-  */
--function install($conf, $sessionManager, $loginManager) {
-+function install($conf, $sessionManager, $loginManager, $userspace) {
-     // On free.fr host, make sure the /sessions directory exists, otherwise login will not work.
-     if (endsWith($_SERVER['HTTP_HOST'],'.free.fr') && !is_dir($_SERVER['DOCUMENT_ROOT'].'/sessions')) mkdir($_SERVER['DOCUMENT_ROOT'].'/sessions',0705);
-@@ -1755,7 +1781,7 @@ function install($conf, $sessionManager, $loginManager) {
-     }
--    if (!empty($_POST['setlogin']) && !empty($_POST['setpassword']))
-+    if (true)
-     {
-         $tz = 'UTC';
-         if (!empty($_POST['continent']) && !empty($_POST['city'])
-@@ -1764,15 +1790,15 @@ function install($conf, $sessionManager, $loginManager) {
-             $tz = $_POST['continent'].'/'.$_POST['city'];
-         }
-         $conf->set('general.timezone', $tz);
--        $login = $_POST['setlogin'];
--        $conf->set('credentials.login', $login);
-+        $conf->set('credentials.login', $userspace);
-         $salt = sha1(uniqid('', true) .'_'. mt_rand());
-         $conf->set('credentials.salt', $salt);
--        $conf->set('credentials.hash', sha1($_POST['setpassword'] . $login . $salt));
-+        $hash = sha1(uniqid('', true) .'_'. mt_rand());
-+        $conf->set('credentials.hash', $hash);
-         if (!empty($_POST['title'])) {
-             $conf->set('general.title', escape($_POST['title']));
-         } else {
--            $conf->set('general.title', 'Shared links on '.escape(index_url($_SERVER)));
-+            $conf->set('general.title', ucwords(str_replace("_", " ", $userspace)));
-         }
-         $conf->set('translation.language', escape($_POST['language']));
-         $conf->set('updates.check_updates', !empty($_POST['updateCheck']));
-@@ -1841,7 +1867,12 @@ function install($conf, $sessionManager, $loginManager) {
- $app = new \Slim\App($container);
- // REST API routes
--$app->group('/api/v1', function() {
-+if (isset($userspace)) {
-+  $mountpoint = '/' . $userspace . '/api/v1';
-+} else {
-+  $mountpoint = '/api/v1';
-+}
-+$app->group($mountpoint, function() {
-     $this->get('/info', '\Shaarli\Api\Controllers\Info:getInfo')->setName('getInfo');
-     $this->get('/links', '\Shaarli\Api\Controllers\Links:getLinks')->setName('getLinks');
-     $this->get('/links/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:getLink')->setName('getLink');
-@@ -1860,7 +1891,7 @@ function install($conf, $sessionManager, $loginManager) {
- $response = $app->run(true);
- // Hack to make Slim and Shaarli router work together:
- // If a Slim route isn't found and NOT API call, we call renderPage().
--if ($response->getStatusCode() == 404 && strpos($_SERVER['REQUEST_URI'], '/api/v1') === false) {
-+if ($response->getStatusCode() == 404 && strpos($_SERVER['REQUEST_URI'], $mountpoint) === false) {
-     // We use UTF-8 for proper international characters handling.
-     header('Content-Type: text/html; charset=utf-8');
-     renderPage($conf, $pluginManager, $linkDb, $history, $sessionManager, $loginManager);