Refresh project and Readme

Adapt vars name for consistency
Add a light CSS design
This commit is contained in:
Crivaledaz 2019-05-02 14:51:50 +02:00
parent 8fddce2fa1
commit 0c1eaf3a31
18 changed files with 293 additions and 196 deletions

View File

@ -1,12 +1,12 @@
<?php <?php
$port = intval(getenv('db_port')) ?: 5432; $db_port = intval(getenv('db_port')) ?: 5432;
$host = getenv('db_host') ?: "127.0.0.1"; $db_host = getenv('db_host') ?: "127.0.0.1";
$name = getenv('db_name') ?: "oauth_db"; $db_name = getenv('db_name') ?: "oauth_db";
$type = getenv('db_type') ?: "pgsql"; $db_type = getenv('db_type') ?: "pgsql";
$username = getenv('db_user') ?: "oauth"; $db_user = getenv('db_user') ?: "oauth";
$password = getenv('db_pass') ?: "oauth_secure-pass"; $db_pass = getenv('db_pass') ?: "oauth_secure-pass";
$dsn = $type . ":dbname=" . $name . ";host=" . $host . ";port=" . $port; $dsn = $type . ":dbname=" . $name . ";host=" . $host . ";port=" . $port;
/* Uncomment the line below to set date.timezone to avoid E.Notice raise by strtotime() (in Pdo.php) /* Uncomment the line below to set date.timezone to avoid E.Notice raise by strtotime() (in Pdo.php)
* If date.timezone is not defined in php.ini or with this function, Mattermost could return a bad token request error * If date.timezone is not defined in php.ini or with this function, Mattermost could return a bad token request error

View File

@ -1,16 +1,16 @@
<?php <?php
// LDAP parameters // LDAP parameters
$hostname = getenv('ldap_host') ?: "ldap://ldap.company.com/"; $ldap_host = getenv('ldap_host') ?: "ldap://ldap.company.com/";
$port = intval(getenv('ldap_port')) ?: 389; $ldap_port = intval(getenv('ldap_port')) ?: 389;
$ldap_version = intval(getenv('ldap_version')) ?: 3; $ldap_version = intval(getenv('ldap_version')) ?: 3;
// Attribute use to identify user on LDAP - ex : uid, mail, sAMAccountName // Attribute use to identify user on LDAP - ex : uid, mail, sAMAccountName
$search_attribute = getenv('ldap_search_attribute') ?: "uid"; $ldap_search_attribute = getenv('ldap_search_attribute') ?: "uid";
// variable use in resource.php // variable use in resource.php
$base = getenv('ldap_base_dn') ?: "ou=People,o=Company"; $ldap_base_dn = getenv('ldap_base_dn') ?: "ou=People,o=Company";
$filter = getenv('ldap_filter') ?: "objectClass=*"; $ldap_filter = getenv('ldap_filter') ?: "objectClass=*";
// ldap service user to allow search in ldap // ldap service user to allow search in ldap
$bind_dn = getenv('ldap_bind_dn') ?: ""; $ldap_bind_dn = getenv('ldap_bind_dn') ?: "";
$bind_pass = getenv('ldap_bind_pass') ?: ""; $ldap_bind_pass = getenv('ldap_bind_pass') ?: "";

View File

@ -1,6 +1,6 @@
The MIT License The MIT License
Copyright (c) 2017 Denis CLAVIER Copyright (c) 2017-2019 Denis CLAVIER
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,13 +1,13 @@
<?php <?php
//Database Server //Database Server
$port = "<%= @db_port %>"; $db_port = "<%= @db_port %>";
$host = "<%= @db_host %>"; $db_host = "<%= @db_host %>";
$name = "<%= @db_name %>"; $db_name = "<%= @db_name %>";
$type = "<%= @db_type %>"; $db_type = "<%= @db_type %>";
$username = "<%= @db_user %>"; $db_user = "<%= @db_user %>";
$password = "<%= @db_pass %>"; $db_pass = "<%= @db_pass %>";
$dsn = $type . ":dbname=" . $name . ";host=" . $host . ";port=" . $port; $dsn = $type . ":dbname=" . $name . ";host=" . $host . ";port=" . $port;
//Set date.timezone to avoid E.Notice raise by strtotime() (in Pdo.php) //Set date.timezone to avoid E.Notice raise by strtotime() (in Pdo.php)
//If date.timezone is not defined, Mattermost will return a bad token request error //If date.timezone is not defined, Mattermost will return a bad token request error

View File

@ -1,17 +1,17 @@
<?php <?php
// LDAP server // LDAP server
$hostname = "<%= @ldap_uri %>"; $ldap_host = "<%= @ldap_uri %>";
$port = <%= @ldap_port %>; $ldap_port = <%= @ldap_port %>;
// Attribute use to identify user on LDAP (used in connexion.php, replace $rdn_suffix) - ex : uid, mail, sAMAccountName // Attribute use to identify user on LDAP (used in connexion.php, replace $rdn_suffix) - ex : uid, mail, sAMAccountName
$search_attribute = "<%= @ldap_attribute %>"; $ldap_search_attribute = "<%= @ldap_attribute %>";
// Base directory name of the LDAP // Base directory name of the LDAP
$base = "<%= @ldap_base %>"; $ldap_base_dn = "<%= @ldap_base %>";
// An optional filter to search in LDAP - ex : objectClass=person // An optional filter to search in LDAP - ex : objectClass=person
$filter = "<%= @ldap_filter %>"; $ldap_filter = "<%= @ldap_filter %>";
// ldap service user to allow search in ldap // ldap service user to allow search in ldap
$bind_dn = "<%= @ldap_bind_dn %>"; $ldap_bind_dn = "<%= @ldap_bind_dn %>";
$bind_pass = "<%= @ldap_bind_pass %>"; $ldap_bind_pass = "<%= @ldap_bind_pass %>";

162
README.md
View File

@ -35,33 +35,35 @@ Obviously, you must have a Mattermost Server installed and be administrator on i
Install required packages : Install required packages :
* For Centos 7, RHEL 7 and Fedora : * For Centos 7, RHEL 7 and Fedora :
``` ```bash
#For PostgreSQL #For PostgreSQL
sudo yum -y --nogpgcheck install httpd php postgresql-server postgresql php-ldap php-pdo php-pgsql git sudo yum -y --nogpgcheck install httpd php postgresql-server postgresql php-ldap php-pdo php-pgsql git
#For MySQL #For MySQL
sudo yum -y --nogpgcheck install httpd php mariadb-server mariadb php-ldap php-pdo php-mysql git sudo yum -y --nogpgcheck install httpd php mariadb-server mariadb php-ldap php-pdo php-mysql git
``` ```
* For Debian, ubuntu, Mint : * For Debian, ubuntu, Mint :
``` ```bash
#For PostgreSQL #For PostgreSQL
sudo apt-get -y install httpd php postgresql-server postgresql php-ldap php-pdo php-pgsql git sudo apt-get -y install httpd php postgresql-server postgresql php-ldap php-pdo php-pgsql git
#For MySQL #For MySQL
sudo apt-get -y install httpd php mariadb-server mariadb php-ldap php-pdo php-mysql git 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 : Setup your SQL server with the following command :
``` ```bash
#For PostgreSQL (create a new database cluster) #For PostgreSQL (create a new database cluster)
sudo postgresql-setup initdb sudo postgresql-setup initdb
#For MySQL (optional configuration for a secure MySQL server) #For MySQL (optional configuration for a secure MySQL server)
sudo mysql_secure_installation 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. 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): Then, start and enable service for Apache and Database (for all distribution using systemd):
``` ```bash
#For PostgreSQL #For PostgreSQL
sudo systemctl start httpd sudo systemctl start httpd
sudo systemctl start postgresql sudo systemctl start postgresql
@ -78,10 +80,9 @@ sudo systemctl enable mariadb
Your system is ready to install and run Mattermost-LDAP module. Your system is ready to install and run Mattermost-LDAP module.
## Install ## Install
Clone (or download and extract) this repository in your /var/www/html (or your httpd root directory) : Clone (or download and extract) this repository in your `/var/www/html` (or your httpd root directory) :
``` ```bash
cd ~ cd ~
git clone https://github.com/crivaledaz/Mattermost-LDAP.git git clone https://github.com/crivaledaz/Mattermost-LDAP.git
cd Mattermost-LDAP cd Mattermost-LDAP
@ -89,137 +90,128 @@ cp -r oauth/ /var/www/html/
``` ```
You need to create a database for the oauth server. For this purpose, you can use the script "init_postgres.sh" or "init_mysql.sh". These scripts try to configure your database automatically, by creating a new user and a new database associated for the oauth server. Scripts also create all tables necessary for the module. If script failed, please report here, and try to configure manually your database by adapting command in scripts. Before running the script you can change the default settings by editing the config_init.sh file and modifying configuration variables. For postgresql, you can copy and paste following lines : You need to create a database for the oauth server. For this purpose, you can use the script "init_postgres.sh" or "init_mysql.sh". These scripts try to configure your database automatically, by creating a new user and a new database associated for the oauth server. Scripts also create all tables necessary for the module. If script failed, please report here, and try to configure manually your database by adapting command in scripts. Before running the script you can change the default settings by editing the config_init.sh file and modifying configuration variables. For postgresql, you can copy and paste following lines :
``` ```bash
nano config_init.sh nano config_init.sh
./init_postgres.sh ./init_postgres.sh
``` ```
This script will automatically create and add a new client in the oauth server, returning a client id and a client secret. You need to keep these two token to configure Mattermost. Please be sure the client secret remained secret. The redirect url in the script must comply with the hostname of your Mattermost server, else Mattermost could not get data from the Oauth server. This script will automatically create and add a new client in the oauth server, returning a client id and a client secret. You need to keep these two token to configure Mattermost. Please be sure the client secret remained secret. The redirect url in the script must comply with the hostname of your Mattermost server, else Mattermost could not get data from the Oauth server.
## Configuration ## 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. 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 : ### Init script parameters
#### oauth_user
Oauth user in the database. This user must have right on the oauth database to store oauth tokens. By default : oauth
#### oauth_pass
Oauth user password in the database. By default, oauth_secure-pass
#### ip
Hostname or IP address of the database. By default : 127.0.0.1
#### port
The port to connect to the database. By default : 5432 (postgres)
#### oauth_db_name
Database name for oauth server. By default : oauth_db
#### client_id
The application ID shared with mattermost. This ID should be a random token. You can use openssl to generate this token (openssl rand -hex 32). By default, this variable contain the openssl command, which use the openssl package. The token will be printed at the end of the script.
#### client_secret
The application secret shared with mattermost. This secret should be a random token. You can use openssl to generate this token (openssl rand -hex 32). By default, this variable contain the openssl command, which use the openssl package. The token will be printed at the end of the script. Secret must be different of the client ID.
#### redirect_uri
The callback address where oauth will send tokens to Mattermost. Normally it should be http://mattermost.company.com/signup/gitlab/complete
#### grant_types
The type of authentification use by Mattermost. It should be "authorization_code".
#### scope
The scope of authentification use by Mattermost. It should be "api".
#### user_id
The username of the user who create the Mattermost client in Oauth. This field has no impact, and could be used as a commentary field. By default this field is empty.
* Mattermost : | Parameter | Description | Default value |
Active Gitlab authentication in system console > Gitlab (or config.json on server) and fill application id and secret with the two token got during install section. For the next fields use this : |---------------|-----------------------------------------------------------------------|-------------------------------------------------------|
| oauth_user | Oauth user in the database. | oauth |
| oauth_pass | Oauth user password in the database. | oauth_secure-pass |
| ip | Hostname or IP address of the database. | 127.0.0.1 |
| port | The port to connect to the database. | 5432 (Postgres) |
| oauth_db_name | Database name for oauth server. | oauth_db |
| client_id | The application ID shared with mattermost. | `openssl rand -hex 32` |
| client_secret | The application secret shared with mattermost. | `openssl rand -hex 32` |
| redirect_uri | The callback address where oauth will send tokens to Mattermost. | http://mattermost.company.com/signup/gitlab/complete |
| grant_types | The type of authentification use by Mattermost. | authorization_code |
| scope | The scope of authentification use by Mattermost. | api |
| user_id | The username of the user who create the Mattermost client in Oauth. | |
Note : The 'oauth_user' must have all privilege on the oauth database to manage oauth tokens.
The 'client_id' and 'client_secret' should be different and random tokens. You can use openssl to generate these tokens (`openssl rand -hex 32`). By default, these variables contain the `openssl` command, which use the openssl package. Tokens will be generated and printed at the end of the script.
The var 'user_id' has no impact, and could be used as a commentary field. By default this field is empty.
### Mattermost
Active Gitlab authentication in `System Console > Gitlab` (or `config.json`) and fill application id and secret with the two tokens got during install section. For the next fields use this :
``` ```
User API Endpoint : http://HOSTNAME/oauth/resource.php User API Endpoint : http://HOSTNAME/oauth/resource.php
Auth Endpoint: http://HOSTNAME/oauth/authorize.php Auth Endpoint: http://HOSTNAME/oauth/authorize.php
Token Endpoint: http://HOSTNAME/oauth/token.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. Since Mattermost 4.9, these fields are disabled in admin panel, so you need to edit directly the configuration file `config.json`.
* Database credentials ### Database credentials
Edit oauth/config_db.php and adapt, with your settings, to set up database in PHP. Edit `oauth/config_db.php` and adapt, with your settings, to set up database in PHP.
#### $host | Parameter | Description | Default value |
Hostname or IP address of the database. (ex : localhost) |------------|----------------------------------------------------------------------|--------------------|
#### $port | db_host | Hostname or IP address of the database server | 127.0.0.1 |
The port of your database to connect. (ex : 5432 for postgres) | db_port | The port of your database to connect | 5432 |
#### $name | db_type | Database type to adapt PDO. Should be pgsql or mysql. | pgsql |
Database name for oauth server. If you use init script make sure to use the same database name. (ex : oauth_db) | db_user | User who manages oauth database | oauth |
#### $type | db_pass | User's password to manage oauth database | oauth_secure-pass |
Database type to adapt PDO to your database server. Should be mysql or pgsql. | db_name | Database name for oauth server | oauth_db |
#### $username
Oauth user in the database. This user must have right on the oauth database to store oauth tokens. If you use init script make sure to use the same database user. (ex : oauth)
#### $password
Oauth user password in the database. If you use init script make sure to use the same database user. (ex : oauth_secure-pass)
* LDAP config If you use the init script, make sure to use the same values for database parameters : 'oauth_user' = 'db_user', 'oauth_pass' = 'db_pass', 'oauth_db_name' = 'db_name'.
Edit oauth/LDAP/config_ldap.php :
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).
#### $hostname Note : The 'db_user' must have all privilege on the oauth database to manage oauth tokens.
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 #14)
#### $search_attribute
The attribute used to identify user on your LDAP. Should be uid, email, cn or sAMAccountName.
#### $base
The base directory name of your LDAP server. (ex : ou=People,o=Company)
#### $filter
Additional filters to search in LDAP (used to get user informations). (ex : objectClass=person)
#### $bind_dn
The LDAP Directory Name of an service account to allow LDAP search. This ption is required if your LDAP is restrictive, else put an empty string (""). (ex : cn=mattermost_ldap,dc=Example,dc=com)
#### $bind_pass
The password associated to the service account to allow LDAP search. This ption is required if your LDAP you provide an bind user, else put an empty string ("").
### LDAP configuration
Edit `oauth/LDAP/config_ldap.php` and adapt prameters with your LDAP configuration :
To try your configuration you can use ldap.php available at the root of this project which use the LDAP library for PHP or you can use ldapsearch command in a shell. | Parameter | Description | Default value |
|-----------------------|-----------------------------------------------------------------------|--------------------------|
| ldap_host | URL or IP to connect LDAP server | ldap://ldap.company.com/ |
| ldap_port | Port used to connect LDAP server | 389 |
| ldap_version | LDAP version or protocol version used by LDAP server | 3 |
| ldap_search_attribute | Attribute used to identify a user on the LDAP | uid |
| ldap_filter | Additional filter for LDAP search | objectClass=* |
| ldap_base_dn | The base directory name of your LDAP server | ou=People,o=Company |
| ldap_bind_dn | The LDAP Directory Name of an service account to allow LDAP search | |
| ldap_bind_pass | The password associated to the service account to allow LDAP search | |
For openLDAP server, the 'ldap_search_attribute' should be `uid`, and for AD server this must be `sAMAccountName`. Nevertheless, 'email' or 'cn' could be used, this depends on your LDAP configuration.
Parameters 'ldap_bind_dn' and 'ldap_bind_pass' are required if your LDAP is restrictive, else put an empty string ("").
Note : 'ldap_version' avoid LDAP blind error with LDAP 3 (issue #14)
To try your configuration you can use `ldap.php` available at the root of this project which use the LDAP library for PHP or you can use `ldapsearch` command in a shell.
Configure LDAP is certainly the most difficult step. Configure LDAP is certainly the most difficult step.
## Usage ## Usage
If you have succeeded previous step you only have to go to the login page of your Mattermost server and click on the Gitlab Button. You will be redirected to a form asking for your LDAP credentials. If your credentials are valid, you will be asked to authorize Oauth to give your information to Mattermost. After authorizing you should be redirected on Mattermost connected with your account. If you have succeeded previous step you only have to go to the login page of your Mattermost server and click on the Gitlab Button. You will be redirected to a form asking for your LDAP credentials. If your credentials are valid, you will be asked to authorize Oauth to give your information to Mattermost. After authorizing you should be redirected on Mattermost connected with your account.
Keep in mind this will create a new account on your Mattermost server with information from LDAP. The process will fail if an existing user already use your LDAP email. To bind a user to the LDAP authentication, sign in mattermost with this user account, go in account settings > security > sign-in method and "switch to using Gitlab SSO". Keep in mind this will create a new account on your Mattermost server with information from LDAP. The process will fail if an existing user already use your LDAP email. To bind an existing user to the LDAP authentication, sign in mattermost with this user account, go in `account settings > security > sign-in method and "switch to using Gitlab SSO"`.
## Limitation ## Limitation
This module has been tested on Centos 7, Fedora and Ubuntu with PostgreSQL and Mattermost Community Edition version 4.1, 4.9 and 5.0.1. Mattermost-LDAP is compliant with Mattermost Team Edition 4.x.x and 5.x.x. This module has been tested on Centos 7, Fedora and Ubuntu with PostgreSQL and Mattermost Community Edition version 4.1, 4.9, 5.0.1 and 5.10. Mattermost-LDAP is compliant with Mattermost Team Edition 4.x.x and 5.x.x.
Others operating systems has not been tested yet but should work fine. Others operating systems has not been tested yet but should work fine.
MySQL has not really been tested so it is possible there is some bugs with. MySQL has not really been tested so it is possible there is some bugs with.
## To do list ## To do list
* Gathering LDAP config * HTTPS support
* Add CSS to make a beautiful interface for Oauth server * Add CSS to make a beautiful interface for Oauth server
* Create an associated Puppet module
* Change Gitlab button * Change Gitlab button
* Security audit * Security audit
## Thanks ## Thanks
I wish to thank my company and my colleagues for their help and support. Also, I thank Brent Shaffer for his Oauth-server-php project and its documentation. I wish to thank CS SI and my colleagues for their help and support. Also, I thank Brent Shaffer for his Oauth-server-php project and its documentation.
## Known issues ## Known issues
* LDAP authentication failed * LDAP authentication failed
Try to restart httpd service. If this persists verify your LDAP configuration or your credentials. Try to restart httpd service. If this persists verify your LDAP configuration or your credentials.
* PHP date timezone error * PHP date timezone error
Edit php.ini to set up date.timezone option and restart httpd service, or use the date_default_timezone_set() function in config_db.php Edit `php.ini` to set up date.timezone option and restart httpd service, or use the `date_default_timezone_set()` function in `config_db.php`
* Token request failed * Token request failed
Try to add a new rule in your firewall (or use iptables -F on both Mattermost server and Oauth server) Try to add a new rule in your firewall (or use `iptables -F` on both Mattermost server and Oauth server)
* .htaccess does not work * .htaccess does not work
Add following lines to your httpd.conf and restart httpd service. Add following lines to your `httpd.conf` and restart httpd service.
``` ```
<Directory "/var/www/html/oauth"> <Directory "/var/www/html/oauth">
AllowOverride All AllowOverride All

View File

@ -16,28 +16,28 @@ class LDAP implements LDAPInterface
/** /**
* LDAP Resource * LDAP Resource
* *
* @param string @hostname * @param string @ldap_host
* Either a hostname or, with OpenLDAP 2.x.x and later, a full LDAP URI * Either a hostname or, with OpenLDAP 2.x.x and later, a full LDAP URI
* @param int @port * @param int @ldap_port
* An optional int to specify ldap server port, by default : 389 * An optional int to specify ldap server port, by default : 389
* @param int @ldap_version * @param int @ldap_version
* An optional int to specify ldap version, by default LDAP V3 protocol is used * An optional int to specify ldap version, by default LDAP V3 protocol is used
* *
* Initiate LDAP connection by creating an associated resource * Initiate LDAP connection by creating an associated resource
*/ */
public function __construct($hostname, $port = 389, $ldap_version = 3) public function __construct($ldap_host, $ldap_port = 389, $ldap_version = 3)
{ {
if (!is_string($hostname)) if (!is_string($ldap_host))
{ {
throw new InvalidArgumentException('First argument to LDAP must be the hostname of a ldap server (string). Ex: ldap//example.com/ '); throw new InvalidArgumentException('First argument to LDAP must be the hostname of a ldap server (string). Ex: ldap//example.com/ ');
} }
if (!is_int($port)) if (!is_int($ldap_port))
{ {
throw new InvalidArgumentException('Second argument to LDAP must be the ldap server port (int). Ex : 389'); throw new InvalidArgumentException('Second argument to LDAP must be the ldap server port (int). Ex : 389');
} }
$ldap = ldap_connect($hostname, $port) $ldap = ldap_connect($ldap_host, $ldap_port)
or die("Unable to connect to the ldap server : $ldaphost ! Please check your configuration."); 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. // Support LDAP V3 since many users have encountered difficulties with LDAP V3.
@ -58,22 +58,22 @@ class LDAP implements LDAPInterface
* A ldap username or email or sAMAccountName * A ldap username or email or sAMAccountName
* @param string @password * @param string @password
* An optional password linked to the user, if not provided an anonymous bind is attempted * An optional password linked to the user, if not provided an anonymous bind is attempted
* @param string @search_attribute * @param string @ldap_search_attribute
* The attribute used on your LDAP to identify user (uid, email, cn, sAMAccountName) * The attribute used on your LDAP to identify user (uid, email, cn, sAMAccountName)
* @param string @filter * @param string @ldap_filter
* An optional filter to search in LDAP (ex : objectClass = person). * An optional filter to search in LDAP (ex : objectClass = person).
* @param string @base_dn * @param string @ldap_base_dn
* The LDAP base DN. * The LDAP base DN.
* @param string @bind_dn * @param string @ldap_bind_dn
* The directory name of a service user to bind before search. Must be a user with read permission on LDAP. * The directory name of a service user to bind before search. Must be a user with read permission on LDAP.
* @param string @bind_pass * @param string @ldap_bind_pass
* The password associated to the service user to bind before search. * The password associated to the service user to bind before search.
* *
* @return * @return
* TRUE if the user is identified and can access to the LDAP server * TRUE if the user is identified and can access to the LDAP server
* and FALSE if it isn't * and FALSE if it isn't
*/ */
public function checkLogin($user, $password = null, $search_attribute, $filter = null, $base_dn,$bind_dn, $bind_pass) { public function checkLogin($user, $password = null, $ldap_search_attribute, $ldap_filter = null, $ldap_base_dn,$ldap_bind_dn, $ldap_bind_pass) {
if (!is_string($user)) if (!is_string($user))
{ {
throw new InvalidArgumentException('First argument to LDAP/checkLogin must be the username or email of a ldap user (string). Ex: jdupont or jdupont@company.com'); throw new InvalidArgumentException('First argument to LDAP/checkLogin must be the username or email of a ldap user (string). Ex: jdupont or jdupont@company.com');
@ -82,31 +82,31 @@ class LDAP implements LDAPInterface
{ {
throw new InvalidArgumentException('Second argument to LDAP/checkLogin must be the password associated to the relative directory name (string).'); throw new InvalidArgumentException('Second argument to LDAP/checkLogin must be the password associated to the relative directory name (string).');
} }
if (!is_string($search_attribute)) if (!is_string($ldap_search_attribute))
{ {
throw new InvalidArgumentException('Third argument to LDAP/checkLogin must be the attribute to identify users (ex : uid, email, sAMAccountName) (string).'); throw new InvalidArgumentException('Third argument to LDAP/checkLogin must be the attribute to identify users (ex : uid, email, sAMAccountName) (string).');
} }
if (!is_string($filter) && $filter != null) if (!is_string($ldap_filter) && $ldap_filter != null)
{ {
throw new InvalidArgumentException('Fourth argument to LDAP/checkLogin must be an optional filter to search in LDAP (string).'); throw new InvalidArgumentException('Fourth argument to LDAP/checkLogin must be an optional filter to search in LDAP (string).');
} }
if (!is_string($base_dn)) if (!is_string($ldap_base_dn))
{ {
throw new InvalidArgumentException('Fifth argument to LDAP/checkLogin must be the ldap base directory name (string). Ex: o=Company'); throw new InvalidArgumentException('Fifth argument to LDAP/checkLogin must be the ldap base directory name (string). Ex: o=Company');
} }
if (!is_string($bind_dn) && $bind_dn != null) if (!is_string($ldap_bind_dn) && $ldap_bind_dn != null)
{ {
throw new InvalidArgumentException('Sixth argument to LDAP/checkLogin must be an optional service account on restrictive LDAP (string).'); throw new InvalidArgumentException('Sixth argument to LDAP/checkLogin must be an optional service account on restrictive LDAP (string).');
} }
if (!is_string($bind_pass) && $bind_pass != null) if (!is_string($ldap_bind_pass) && $ldap_bind_pass != null)
{ {
throw new InvalidArgumentException('Seventh argument to LDAP/checkLogin must be an optional password for the service account on restrictive LDAP (string).'); throw new InvalidArgumentException('Seventh argument to LDAP/checkLogin must be an optional password for the service account on restrictive LDAP (string).');
} }
// If LDAP service account for search is specified, do an ldap_bind with this account // If LDAP service account for search is specified, do an ldap_bind with this account
if ($bind_dn != '' && $bind_dn != null) if ($ldap_bind_dn != '' && $ldap_bind_dn != null)
{ {
$bind_result=ldap_bind($this->ldap_server,$bind_dn,$bind_pass); $bind_result=ldap_bind($this->ldap_server,$ldap_bind_dn,$ldap_bind_pass);
// If authentification failed, throw an exception // If authentification failed, throw an exception
if (!$bind_result) if (!$bind_result)
@ -114,17 +114,17 @@ class LDAP implements LDAPInterface
throw new Exception('An error has occured during ldap_bind execution. Please check parameter of LDAP/checkLogin, and make sure that user provided have read permission on LDAP.'); throw new Exception('An error has occured during ldap_bind execution. Please check parameter of LDAP/checkLogin, and make sure that user provided have read permission on LDAP.');
} }
} }
if ($filter!="" && $filter != null) if ($ldap_filter!="" && $ldap_filter != null)
{ {
$search_filter = '(&(' . $search_attribute . '=' . $user . ')(' . $filter .'))'; $search_filter = '(&(' . $ldap_search_attribute . '=' . $user . ')(' . $ldap_filter .'))';
} }
else else
{ {
$search_filter = $search_attribute . '=' . $user; $search_filter = $ldap_search_attribute . '=' . $user;
} }
$result = ldap_search($this->ldap_server, $base_dn, $search_filter, array(), 0, 1, 500); $result = ldap_search($this->ldap_server, $ldap_base_dn, $search_filter, array(), 0, 1, 500);
if (!$result) if (!$result)
{ {
@ -146,15 +146,15 @@ class LDAP implements LDAPInterface
} }
/** /**
* @param string @base_dn * @param string @ldap_base_dn
* The LDAP base DN. * The LDAP base DN.
* @param string @filter * @param string @ldap_filter
* A filter to get relevant data. Often the user id in ldap (uid or sAMAccountName). * A filter to get relevant data. Often the user id in ldap (uid or sAMAccountName).
* @param string @bind_dn * @param string @ldap_bind_dn
* The directory name of a service user to bind before search. Must be a user with read permission on LDAP. * The directory name of a service user to bind before search. Must be a user with read permission on LDAP.
* @param string @bind_pass * @param string @ldap_bind_pass
* The password associated to the service user to bind before search. * The password associated to the service user to bind before search.
* @param string @search_attribute * @param string @ldap_search_attribute
* The attribute used on your LDAP to identify user (uid, email, cn, sAMAccountName) * The attribute used on your LDAP to identify user (uid, email, cn, sAMAccountName)
* @param string @user * @param string @user
* A ldap username or email or sAMAccountName * A ldap username or email or sAMAccountName
@ -162,27 +162,27 @@ class LDAP implements LDAPInterface
* @return * @return
* An array with the user's mail, complete name and directory 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) { public function getDataForMattermost($ldap_base_dn, $ldap_filter, $ldap_bind_dn, $ldap_bind_pass, $ldap_search_attribute, $user) {
$attribute=array("cn","mail"); $attribute=array("cn","mail");
if (!is_string($base_dn)) if (!is_string($ldap_base_dn))
{ {
throw new InvalidArgumentException('First argument to LDAP/getData must be the ldap base directory name (string). Ex: o=Company'); throw new InvalidArgumentException('First argument to LDAP/getData must be the ldap base directory name (string). Ex: o=Company');
} }
if (!is_string($filter)) if (!is_string($ldap_filter))
{ {
throw new InvalidArgumentException('Second argument to LDAP/getData must be a filter to get relevant data. Often is the user id in ldap (string). Ex : uid=jdupont'); throw new InvalidArgumentException('Second argument to LDAP/getData must be a filter to get relevant data. Often is the user id in ldap (string). Ex : uid=jdupont');
} }
if (!is_string($bind_dn) && $bind_dn != null) if (!is_string($ldap_bind_dn) && $ldap_bind_dn != null)
{ {
throw new InvalidArgumentException('Third argument to LDAP/getData must be an optional service account on restrictive LDAP (string).'); throw new InvalidArgumentException('Third argument to LDAP/getData must be an optional service account on restrictive LDAP (string).');
} }
if (!is_string($bind_pass) && $bind_pass != null) if (!is_string($ldap_bind_pass) && $ldap_bind_pass != null)
{ {
throw new InvalidArgumentException('Fourth argument to LDAP/getData must be an optional password for the service account on restrictive LDAP (string).'); throw new InvalidArgumentException('Fourth argument to LDAP/getData must be an optional password for the service account on restrictive LDAP (string).');
} }
if (!is_string($search_attribute)) if (!is_string($ldap_search_attribute))
{ {
throw new InvalidArgumentException('Fifth argument to LDAP/getData must be the attribute to identify users (ex : uid, email, sAMAccountName) (string).'); throw new InvalidArgumentException('Fifth argument to LDAP/getData must be the attribute to identify users (ex : uid, email, sAMAccountName) (string).');
} }
@ -192,9 +192,9 @@ class LDAP implements LDAPInterface
} }
// If LDAP service account for search is specified, do an ldap_bind with this account // If LDAP service account for search is specified, do an ldap_bind with this account
if ($bind_dn != '' && $bind_dn != null) if ($ldap_bind_dn != '' && $ldap_bind_dn != null)
{ {
$bind_result=ldap_bind($this->ldap_server,$bind_dn,$bind_pass); $bind_result=ldap_bind($this->ldap_server,$ldap_bind_dn,$ldap_bind_pass);
// If authentification failed, throw an exception // If authentification failed, throw an exception
if (!$bind_result) if (!$bind_result)
@ -203,16 +203,16 @@ class LDAP implements LDAPInterface
} }
} }
if ($filter!="" && $filter != null) if ($ldap_filter!="" && $ldap_filter != null)
{ {
$search_filter = '(&(' . $search_attribute . '=' . $user . ')(' . $filter .'))'; $search_filter = '(&(' . $ldap_search_attribute . '=' . $user . ')(' . $ldap_filter .'))';
} }
else else
{ {
$search_filter = $search_attribute . '=' . $user; $search_filter = $ldap_search_attribute . '=' . $user;
} }
$result = ldap_search($this->ldap_server, $base_dn, $search_filter, array(), 0, 1, 500); $result = ldap_search($this->ldap_server, $ldap_base_dn, $search_filter, array(), 0, 1, 500);
if (!$result) if (!$result)
{ {

View File

@ -12,33 +12,33 @@ interface LDAPInterface
* A ldap username or email or sAMAccountName * A ldap username or email or sAMAccountName
* @param string @password * @param string @password
* An optional password linked to the user, if not provided an anonymous bind is attempted * An optional password linked to the user, if not provided an anonymous bind is attempted
* @param string @search_attribute * @param string @ldap_search_attribute
* The attribute used on your LDAP to identify user (uid, email, cn, sAMAccountName) * The attribute used on your LDAP to identify user (uid, email, cn, sAMAccountName)
* @param string @filter * @param string @ldap_filter
* An optional filter to search in LDAP (ex : objectClass = person). * An optional filter to search in LDAP (ex : objectClass = person).
* @param string @base_dn * @param string @ldap_base_dn
* The LDAP base DN. * The LDAP base DN.
* @param string @bind_dn * @param string @ldap_bind_dn
* The directory name of a service user to bind before search. Must be a user with read permission on LDAP. * The directory name of a service user to bind before search. Must be a user with read permission on LDAP.
* @param string @bind_pass * @param string @ldap_bind_pass
* The password associated to the service user to bind before search. * The password associated to the service user to bind before search.
* *
* @return * @return
* TRUE if the user is identified and can access to the LDAP server * TRUE if the user is identified and can access to the LDAP server
* and FALSE if it isn't * and FALSE if it isn't
*/ */
public function checkLogin($user,$password = null,$search_attribute,$filter = null,$base_dn,$bind_dn,$bind_pass); public function checkLogin($user,$password = null,$ldap_search_attribute,$ldap_filter = null,$ldap_base_dn,$ldap_bind_dn,$ldap_bind_pass);
/** /**
* @param string @base_dn * @param string @ldap_base_dn
* The LDAP base DN. * The LDAP base DN.
* @param string @filter * @param string @ldap_filter
* A filter to get relevant data. Often the user id in ldap (uid or sAMAccountName). * A filter to get relevant data. Often the user id in ldap (uid or sAMAccountName).
* @param string @bind_dn * @param string @ldap_bind_dn
* The directory name of a service user to bind before search. Must be a user with read permission on LDAP. * The directory name of a service user to bind before search. Must be a user with read permission on LDAP.
* @param string @bind_pass * @param string @ldap_bind_pass
* The password associated to the service user to bind before search. * The password associated to the service user to bind before search.
* @param string @search_attribute * @param string @ldap_search_attribute
* The attribute used on your LDAP to identify user (uid, email, cn, sAMAccountName) * The attribute used on your LDAP to identify user (uid, email, cn, sAMAccountName)
* @param string @user * @param string @user
* A ldap username or email or sAMAccountName * A ldap username or email or sAMAccountName
@ -46,5 +46,5 @@ interface LDAPInterface
* @return * @return
* An array with the user's mail, complete name and directory 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); public function getDataForMattermost($ldap_base_dn, $ldap_filter, $ldap_bind_dn, $ldap_bind_pass, $ldap_search_attribute, $user);
} }

View File

@ -1,16 +1,16 @@
<?php <?php
// LDAP parameters // LDAP parameters
$hostname = "ldap://company.com/"; $ldap_host = "ldap://company.com/";
$port = 389; $ldap_port = 389;
$ldap_version = 3; $ldap_version = 3;
// Attribute use to identify user on LDAP - ex : uid, mail, sAMAccountName // Attribute use to identify user on LDAP - ex : uid, mail, sAMAccountName
$search_attribute = "uid"; $ldap_search_attribute = "uid";
// variable use in resource.php // variable use in resource.php
$base = "ou=People,o=Company"; $ldap_base_dn = "ou=People,o=Company";
$filter = "objectClass=*"; $ldap_filter = "objectClass=*";
// ldap service user to allow search in ldap // ldap service user to allow search in ldap
$bind_dn = ""; $ldap_bind_dn = "";
$bind_pass = ""; $ldap_bind_pass = "";

View File

@ -45,7 +45,7 @@ if (empty($_POST)) {
<center> <center>
<table background="../images/login.png" border="0" width="729" height="343" cellspacing="1" cellpadding="4"> <table background="images/login.png" border="0" width="729" height="343" cellspacing="1" cellpadding="4">
<tr> <tr>
<td width="40%">&nbsp;</td> <td width="40%">&nbsp;</td>

View File

@ -1,12 +1,12 @@
<?php <?php
$port = 5432; $db_port = 5432;
$host = "localhost"; $db_host = "localhost";
$name = "oauth_db"; $db_name = "oauth_db";
$type = "pgsql"; $db_type = "pgsql";
$username = "oauth"; $db_user = "oauth";
$password = "oauth_secure-pass"; $db_pass = "oauth_secure-pass";
$dsn = $type . ":dbname=" . $name . ";host=" . $host . ";port=" . $port; $dsn = $db_type . ":dbname=" . $db_name . ";host=" . $db_host . ";port=" . $db_port;
/* Uncomment the line below to set date.timezone to avoid E.Notice raise by strtotime() (in Pdo.php) /* Uncomment the line below to set date.timezone to avoid E.Notice raise by strtotime() (in Pdo.php)
* If date.timezone is not defined in php.ini or with this function, Mattermost could return a bad token request error * If date.timezone is not defined in php.ini or with this function, Mattermost could return a bad token request error

View File

@ -37,11 +37,11 @@ else
$password=$_POST['password']; $password=$_POST['password'];
// Open a LDAP connection // Open a LDAP connection
$ldap = new LDAP($hostname,$port,$ldap_version); $ldap = new LDAP($ldap_host,$ldap_port,$ldap_version);
// Check user credential on LDAP // Check user credential on LDAP
try{ try{
$authenticated = $ldap->checkLogin($user,$password,$search_attribute,$filter,$base,$bind_dn,$bind_pass); $authenticated = $ldap->checkLogin($user,$password,$ldap_search_attribute,$ldap_filter,$ldap_base_dn,$ldap_bind_dn,$ldap_bind_pass);
} }
catch (Exception $e) catch (Exception $e)
{ {

Binary file not shown.

After

Width:  |  Height:  |  Size: 977 B

BIN
oauth/images/login.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

@ -5,20 +5,68 @@ session_start();
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<link rel="stylesheet" type="text/css" href="./style.css">
<title>LDAP Connection Interface</title> <title>LDAP Connection Interface</title>
</head> </head>
<body> <body>
<form method="post" action="connexion.php"> <center>
<fieldset> <table background="images/login.png" border="0" width="733" height="348" cellspacing="1" cellpadding="4">
<legend>Connection</legend> <tr>
<p> <td width="40%">&nbsp;</td>
<label for="user">Username :</label><input name="user" type="text" id="user" /><br />
<label for="password">Password :</label><input type="password" name="password" id="password" />
</p>
</fieldset>
<p><input type="submit" value="Connect" /></p> <td width="60%">
</form> <table border="0" width="100%">
<tr>
<td align="center">
<div class="LoginTitle">LDAP Authentification</div>
<form method="post" action="connexion.php">
<table border="0" width="90%" cellpadding="1">
<tr>
<td colspan="2" align="left">
<div class="messageLogin" align="center">
</div>
&nbsp;
</td>
</tr>
<tr>
<td align="left" width="40%" class="LoginUsername">
Username:&nbsp;
</td>
<td width="60%">
<input type="text" name="user" size="25" value="" >
</td>
</tr>
<tr>
<td align="left" width="40%" class="LoginUsername">
Password:&nbsp;
</td>
<td width="60%">
<input type="password" name="password" size="25" value="" >
</td>
</tr>
<tr><td colspan="2">&nbsp;</td></tr>
<tr>
<td colspan="2" align="center"> <input type="submit" class="GreenButton" name="login" value=" Connect " > </td>
</tr>
</table>
</form>
</td>
</tr>
</table>
</td>
</tr>
</table>
</center>
</body> </body>
</html> </html>

View File

@ -27,12 +27,12 @@ $user = $info_oauth["user_id"];
$assoc_id = intval($info_oauth["assoc_id"]); $assoc_id = intval($info_oauth["assoc_id"]);
// Open a LDAP connection // Open a LDAP connection
$ldap = new LDAP($hostname,$port,$ldap_version); $ldap = new LDAP($ldap_host,$ldap_port,$ldap_version);
// Try to get user data on the LDAP // Try to get user data on the LDAP
try try
{ {
$data = $ldap->getDataForMattermost($base,$filter,$bind_dn,$bind_pass,$search_attribute,$user); $data = $ldap->getDataForMattermost($ldap_base_dn,$ldap_filter,$ldap_bind_dn,$ldap_bind_pass,$ldap_search_attribute,$user);
// 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. // 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); $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);

View File

@ -11,7 +11,7 @@ require_once('OAuth2/Autoloader.php');
OAuth2\Autoloader::register(); OAuth2\Autoloader::register();
//$dsn is the Data Source Name for your database, for exmaple "mysql:dbname=my_oauth2_db;host=localhost" //$dsn is the Data Source Name for your database, for exmaple "mysql:dbname=my_oauth2_db;host=localhost"
$storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password)); $storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $db_user, 'password' => $db_pass));
// Pass a storage object or array of storage objects to the OAuth2 server class // Pass a storage object or array of storage objects to the OAuth2 server class
$server = new OAuth2\Server($storage); $server = new OAuth2\Server($storage);

57
oauth/style.css Normal file
View File

@ -0,0 +1,57 @@
html
{
height: 100%;
margin: 0;
}
body {
font-family:"Tahoma","Arial", serif;
font-size:8px;
font-weight: normal;
color: black;
text-decoration:none;
background-color: white;
height: 100%;
margin: 0;
}
.LoginTitle {
color: #000000;
font-family : "Tahoma","Arial", serif;
font-size : 18pt;
font-weight: normal;
}
.LoginUsername {
color: #000000;
font-family : "Tahoma","Arial", serif;
font-size : 14pt;
font-weight: normal;
}
.LoginComment {
color: #000000;
font-family : "Tahoma","Arial", serif;
font-size : 8pt;
font-weight: normal;
}
.GreenButton
{
color: white;
font-family : "Tahoma", "Arial", serif;
font-size : 10pt;
font-weight: normal;
height: 28px;
background: transparent url(images/ButtonGreen.png) repeat-x left top;
border: solid 1px #50B4AE;
font-weight: bold;
}
.messageLogin {
color: Yellow;
font-family : "Tahoma", "Arial", serif;
font-size : 8pt;
font-weight: bold;
}