From 5afe0736196e78348ae009e7508346f350b8351b Mon Sep 17 00:00:00 2001 From: Denis CLAVIER Date: Sat, 19 May 2018 18:04:13 +0200 Subject: [PATCH] Patch for Mattermost 4.4 -> 4.9 + some bug fix --- README.md | 23 +++++++++++++++---- config_init.sh => config_init.sh.example | 0 ldap.php | 4 ++++ oauth/LDAP/LDAP.php | 18 ++++++++++++--- oauth/LDAP/LDAPInterface.php | 2 +- ...onfig_ldap.php => config_ldap.php.example} | 2 ++ oauth/authorize.php | 21 ++++++----------- .../{config_db.php => config_db.php.example} | 0 oauth/connexion.php | 20 ++++++++++++---- oauth/resource.php | 11 ++++++--- 10 files changed, 71 insertions(+), 30 deletions(-) rename config_init.sh => config_init.sh.example (100%) mode change 100644 => 100755 rename oauth/LDAP/{config_ldap.php => config_ldap.php.example} (89%) rename oauth/{config_db.php => config_db.php.example} (100%) mode change 100644 => 100755 diff --git a/README.md b/README.md index 0ab3db8..573252d 100755 --- a/README.md +++ b/README.md @@ -50,8 +50,17 @@ sudo apt-get -y install httpd php postgresql-server postgresql php-ldap php-pdo #For MySQL sudo apt-get -y install httpd php mariadb-server mariadb php-ldap php-pdo php-mysql git ``` +Setup your SQL server with the following command : +``` +#For PostgreSQL (create a new database cluster) +sudo postgresql-setup initdb -Start and enable service for Apache and Database (for all distribution using systemd): +#For MySQL (optional configuration for a secure MySQL server) +sudo mysql_secure_installation +``` +By default, PostgreSQL does not allow client authentication on the server or a database. So we need to enable it by editing pg_hba.conf file (in /var/lib/pgsql). Open this file and replace 'ident' by 'md5' on the first three lines (local, host 127.0.0.1 and host ::1/128). It's recommended to backup the original file before editing it. + +Then, start and enable service for Apache and Database (for all distribution using systemd): ``` #For PostgreSQL sudo systemctl start httpd @@ -90,6 +99,8 @@ This script will automatically create and add a new client in the oauth server, ## Configuration +Configuration files are provided with examples and default values. Each config file has an ".example" extension, so you need to copy and to rename them without this extension. You can find a detailed description of each parameters available below. + * Init script configuration : #### oauth_user Oauth user in the database. This user must have right on the oauth database to store oauth tokens. By default : oauth @@ -121,7 +132,9 @@ User API Endpoint : http://HOSTNAME/oauth/resource.php Auth Endpoint: http://HOSTNAME/oauth/authorize.php Token Endpoint: http://HOSTNAME/oauth/token.php ``` -Change HOSTNAME by hostname or ip of the server where you have installed Mattermost-LDAP module. +Change HOSTNAME by hostname or ip of the server where you have installed Mattermost-LDAP module. + +In Mattermost 4.9, these fields are disable in admin panel, so you need to edit directly the configuration file config.json. * Database credentials Edit oauth/config_db.php and adapt, with your settings, to set up database in PHP. @@ -141,7 +154,7 @@ Oauth user password in the database. If you use init script make sure to use the * LDAP config Edit oauth/LDAP/config_ldap.php : -1. Provide your ldap address and port. +1. Provide your ldap address, port and version. 2. Change the base directory name ($base) and the filter ($filter) to comply with your LDAP configuration. 3. Change the user ID attribute ($ldap_attribute) to comply with your LDAP configuration (uid, sAMAccountName, email, cn ..). 4. If necessary, you can provide a LDAP account to allow search in LDAP (only restrictive LDAP). @@ -150,6 +163,8 @@ Edit oauth/LDAP/config_ldap.php : Your LDAP hostname or LDAP IP, to connect to the LDAP server. #### $port Your LDAP port, to connect to the LDAP server. By default : 389. +#### $ldap_version +Your LDAP version, or protocol version used by your server. By default : 3. This parameter avoid LDAP blind error with LDAP 3 (issue ) #### $search_attribute The attribute used to identify user on your LDAP. Should be uid, email, cn or sAMAccountName. #### $base @@ -174,7 +189,7 @@ Keep in mind this will create a new account on your Mattermost server with infor ## Limitation -This module has been tested on Centos 7, Fedora and Ubuntu with PostgreSQL. +This module has been tested on Centos 7, Fedora and Ubuntu with PostgreSQL and Mattermost Community Edition version 4.1 and 4.9. Others operating systems has not been tested yet but should work fine. diff --git a/config_init.sh b/config_init.sh.example old mode 100644 new mode 100755 similarity index 100% rename from config_init.sh rename to config_init.sh.example diff --git a/ldap.php b/ldap.php index 14c81db..b949be4 100644 --- a/ldap.php +++ b/ldap.php @@ -7,6 +7,9 @@ error_reporting(E_ALL); //Ldap adress and port $hostname = "ldap://company.com:389"; +//LDAP version +$ldap_version = 3; + //Unique identifier of user on LDAP $uid = "username"; $email = "username@company.com"; @@ -25,6 +28,7 @@ $base = "ou=People,o=Company"; echo "

LDAP : Test Center

"; echo "Attempting to connect LDAP server ...
"; $ldap=ldap_connect($hostname); +ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, $ldap_version); if ($ldap) { echo "Successful connection !
"; diff --git a/oauth/LDAP/LDAP.php b/oauth/LDAP/LDAP.php index f1e3fbc..3adf148 100755 --- a/oauth/LDAP/LDAP.php +++ b/oauth/LDAP/LDAP.php @@ -19,11 +19,13 @@ class LDAP implements LDAPInterface * @param string @hostname * Either a hostname or, with OpenLDAP 2.x.x and later, a full LDAP URI * @param int @port - * An optional int to specify ldap server port + * An optional int to specify ldap server port, by default : 389 + * @param int @ldap_version + * An optional int to specify ldap version, by default LDAP V3 protocol is used * * Initiate LDAP connection by creating an associated resource */ - public function __construct($hostname, $port = 389) + public function __construct($hostname, $port = 389, $ldap_version = 3) { if (!is_string($hostname)) { @@ -38,6 +40,16 @@ class LDAP implements LDAPInterface $ldap = ldap_connect($hostname, $port) or die("Unable to connect to the ldap server : $ldaphost ! Please check your configuration."); + // Support LDAP V3 since many users have encountered difficulties with LDAP V3. + if (is_int($ldap_version) && $ldap_version <= 3 && $ldap_version > 0) + { + ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, $ldap_version); + } + else + { + throw new InvalidArgumentException('Third argument to LDAP must be the ldap version (int). Ex : 3'); + } + $this->ldap_server = $ldap; } @@ -148,7 +160,7 @@ class LDAP implements LDAPInterface * A ldap username or email or sAMAccountName * * @return - * An array with the user's mail and complete name. + * An array with the user's mail, complete name and directory name. */ public function getDataForMattermost($base_dn, $filter, $bind_dn, $bind_pass, $search_attribute, $user) { diff --git a/oauth/LDAP/LDAPInterface.php b/oauth/LDAP/LDAPInterface.php index 7b96d97..f050989 100755 --- a/oauth/LDAP/LDAPInterface.php +++ b/oauth/LDAP/LDAPInterface.php @@ -44,7 +44,7 @@ interface LDAPInterface * A ldap username or email or sAMAccountName * * @return - * An array with the user's mail and complete name. + * An array with the user's mail, complete name and directory name. */ public function getDataForMattermost($base_dn, $filter, $bind_dn, $bind_pass, $search_attribute, $user); } diff --git a/oauth/LDAP/config_ldap.php b/oauth/LDAP/config_ldap.php.example similarity index 89% rename from oauth/LDAP/config_ldap.php rename to oauth/LDAP/config_ldap.php.example index 99be6b6..47cd54e 100755 --- a/oauth/LDAP/config_ldap.php +++ b/oauth/LDAP/config_ldap.php.example @@ -1,6 +1,8 @@ -
Mattermost souhaite accéder à vos données LDAP :
+
Mattermost desires access to your LDAP data:
@@ -71,16 +71,16 @@ if (empty($_POST)) { - Connecté en tant que : ' . $_SESSION['uid'] . ' + Login as : ' . $_SESSION['uid'] . '
- Données souhaitées :
-   -> Identifiant,
-   -> Nom complet,
+ Requested Data :
+   -> Username,
+   -> Full Name,
  -> Email @@ -115,18 +115,11 @@ $server->handleAuthorizeRequest($request, $response, $is_authorized,$_SESSION['u if ($is_authorized) { - // this is only here so that you get to see your code in the cURL request. Otherwise, we'd redirect back to the client + // This is only here so that you get to see your code in the cURL request. Otherwise, we'd redirect back to the client $code = substr($response->getHttpHeader('Location'), strpos($response->getHttpHeader('Location'), 'code=')+5, 40); header('Location: ' . $response->getHttpHeader('Location')); exit(); } // Send message in case of error -$response->send(); - -/* -
- - -
-*/ +$response->send(); \ No newline at end of file diff --git a/oauth/config_db.php b/oauth/config_db.php.example old mode 100644 new mode 100755 similarity index 100% rename from oauth/config_db.php rename to oauth/config_db.php.example diff --git a/oauth/connexion.php b/oauth/connexion.php index 2e7649d..e16ed87 100644 --- a/oauth/connexion.php +++ b/oauth/connexion.php @@ -12,7 +12,7 @@ require_once __DIR__.'/LDAP/config_ldap.php'; // Verify all fields have been filled if (empty($_POST['user']) || empty($_POST['password'])) { - echo 'You must fill each field

'; + echo 'Please fill in your Username and Password

'; echo 'Click here to come back to login page'; } else @@ -20,12 +20,12 @@ else // Check received data length (to prevent code injection) if (strlen($_POST['user']) > 15) { - echo 'Strange username ... Please try again

'; + echo 'Username has incorrect format ... Please try again

'; echo 'Click here to come back to login page'; } elseif (strlen($_POST['password']) > 50 || strlen($_POST['password']) <= 7) { - echo 'Strange password ... Please try again

'; + echo 'Password has incorrect format ... Please try again

'; echo 'Click here to come back to login page'; } else @@ -37,10 +37,20 @@ else $password=$_POST['password']; // Open a LDAP connection - $ldap = new LDAP($hostname,$port); + $ldap = new LDAP($hostname,$port,$ldap_version); // Check user credential on LDAP - if ($ldap->checkLogin($user,$password,$search_attribute,$filter,$base,$bind_dn,$bind_pass)) + try{ + $authenticated = $ldap->checkLogin($user,$password,$search_attribute,$filter,$base,$bind_dn,$bind_pass); + } + catch (Exception $e) + { + echo json_encode(array("error" => "Impossible to get data", "message" => $e->getMessage())); + $authenticated = false; + } + + // If user is authenticated + if ($authenticated) { $_SESSION['uid']=$user; diff --git a/oauth/resource.php b/oauth/resource.php index 54d9646..02b4671 100755 --- a/oauth/resource.php +++ b/oauth/resource.php @@ -19,7 +19,7 @@ if (!$server->verifyResourceRequest(OAuth2\Request::createFromGlobals())) { } // set default error message -$resp = array("error" => "Unknow error", "message" => "An unknown error has occured, please report this bug"); +$resp = array("error" => "Unknown error", "message" => "An unknown error has occured, please report this bug"); // get information on user associated to the token $info_oauth = $server->getAccessTokenData(OAuth2\Request::createFromGlobals()); @@ -27,13 +27,18 @@ $user = $info_oauth["user_id"]; $assoc_id = $info_oauth["assoc_id"]; // Open a LDAP connection -$ldap = new LDAP($hostname,$port); +$ldap = new LDAP($hostname,$port,$ldap_version); // Try to get user data on the LDAP try { $data = $ldap->getDataForMattermost($base,$filter,$bind_dn,$bind_pass,$search_attribute,$user); - $resp = array("name" => $data['cn'],"username" => $user,"id" => $assoc_id,"state" => "active","email" => $data['mail']); + + // Here is the patch for Mattermost 4.4 and older. Gitlab has changed the JSON output of oauth service. Many data are not used by Mattermost, but there is a stack error if we delete them. That's the reason why date and many parameters are null or empty. + $resp = array("id" => $assoc_id,"name" => $data['cn'],"username" => $user,"state" => "active","avatar_url" => "","web_url" => "","created_at" => "0000-00-00T00:00:00.000Z","bio" => null,"location" => null,"skype" => "","linkedin" => "","twitter" => "","website_url" => "","organization" => null,"last_sign_in_at" => "0000-00-00T00:00:00.000Z","confirmed_at" => "0000-00-00T00:00:00.000Z","last_activity_on" => null,"email" => $data['mail'],"theme_id" => 1,"color_scheme_id" => 1,"projects_limit" => 100000,"current_sign_in_at" => "0000-00-00T00:00:00.000Z","identities" => array(array("provider" => "ldapmain","extern_uid" => $data['dn'])),"can_create_group" => true,"can_create_project" => true,"two_factor_enabled" => false,"external" => false,"shared_runners_minutes_limit" => null); + + // Below is the old version, still consistent with Mattermost before version 4.4 + // $resp = array("name" => $data['cn'],"username" => $user,"id" => $assoc_id,"state" => "active","email" => $data['mail']); } catch (Exception $e) {