This commit is contained in:
Angus B. Grieve-Smith 2020-05-07 18:02:42 -04:00
commit b94872a260
13 changed files with 396 additions and 297 deletions

View File

@ -10,6 +10,9 @@ RUN set -x \
&& docker-php-ext-configure ldap --with-libdir=lib/x86_64-linux-gnu/ \ && docker-php-ext-configure ldap --with-libdir=lib/x86_64-linux-gnu/ \
&& docker-php-ext-install ldap && docker-php-ext-install ldap
# Enable development php.ini config (Solve empty answer from token.php)
RUN ln -s /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini
# Get Mattermost-LDAP project # Get Mattermost-LDAP project
RUN git clone https://github.com/crivaledaz/Mattermost-LDAP.git /opt/Mattermost-LDAP/ RUN git clone https://github.com/crivaledaz/Mattermost-LDAP.git /opt/Mattermost-LDAP/

View File

@ -9,4 +9,5 @@ RUN set -x \
&& docker-php-ext-configure ldap --with-libdir=lib/x86_64-linux-gnu/ \ && docker-php-ext-configure ldap --with-libdir=lib/x86_64-linux-gnu/ \
&& docker-php-ext-install ldap && docker-php-ext-install ldap
# Enable development php.ini config (Solve empty answer from token.php)
RUN ln -s /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini RUN ln -s /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini

View File

@ -8,10 +8,10 @@
# #
# Client ID token. Must be a random hex value. Use `openssl rand -hex 32` to generate a token. # Client ID token. Must be a random hex value. Use `openssl rand -hex 32` to generate a token.
client_id = 123456789abcdef123456789abcdef client_id = "123456789abcdef123456789abcdef"
# Client Secret token. Must be a random hex value. Use `openssl rand -hex 32` to generate a token. # Client Secret token. Must be a random hex value. Use `openssl rand -hex 32` to generate a token.
client_secret = fedcba987654321fedcba987654321 client_secret = "fedcba987654321fedcba987654321"
# Redirect URI use by Oauth server to redirect user after authentifictaion process. Must be the same than as Mattermost give to Oauth server. # Redirect URI use by Oauth server to redirect user after authentifictaion process. Must be the same than as Mattermost give to Oauth server.
redirect_uri = "http://localhost/signup/gitlab/complete" redirect_uri = "http://localhost/signup/gitlab/complete"
@ -30,13 +30,13 @@ user_id = ""
# #
# Username for the PostgreSQL administrator account # Username for the PostgreSQL administrator account
POSTGRES_USER = postgres POSTGRES_USER = "postgres"
# Password for PostgreSQL administrator account # Password for PostgreSQL administrator account
POSTGRES_PASSWORD = rootroot POSTGRES_PASSWORD = "rootroot"
# Method to use for connection to database # Method to use for connection to database
POSTGRES_HOST_AUTH_METHOD = trust POSTGRES_HOST_AUTH_METHOD = "trust"
# Oauth user to connect the database # Oauth user to connect the database
db_user = "oauth" db_user = "oauth"
@ -61,16 +61,16 @@ db_type = "pgsql"
# #
# LDAP host or IP # LDAP host or IP
ldap_host = ldap://ldap.company.com:389/ ldap_host = "ldap://ldap.company.com:389/"
# LDAP port # LDAP port
ldap_port = 389 ldap_port = "389"
# LDAP protocol version # LDAP protocol version
ldap_version = 3 ldap_version = "3"
# Unique identifier for entry in LDAP # Unique identifier for entry in LDAP
ldap_search_attribute = uid ldap_search_attribute = "uid"
# Base DN to search from in LDAP # Base DN to search from in LDAP
ldap_base_dn = "ou=People,o=Company" ldap_base_dn = "ou=People,o=Company"

View File

@ -15,3 +15,8 @@ deny from all
<Files *.png> <Files *.png>
allow from all allow from all
</Files> </Files>
# Only allow access to html files
<Files *.html>
allow from all
</Files>

View File

@ -36,93 +36,67 @@ if (!isset($_SESSION['uid']))
// Check if user has already authorized oauth to share data with Mattermost. In this case, user should exist in 'user' table. // Check if user has already authorized oauth to share data with Mattermost. In this case, user should exist in 'user' table.
if ($server->userExists($_SESSION['uid'])) { if ($server->userExists($_SESSION['uid'])) {
// Bypass authorize form, continue Oauth process. // User had already authorized the client during a previous session.
$server->handleAuthorizeRequest($request, $response, true, $_SESSION['uid']); $is_authorized = true;
} }
// Display an authorization form // Display an authorization form
else if (empty($_POST)) { else if (empty($_POST)) {
exit(' exit('
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="UTF-8" /> <link rel="stylesheet" type="text/css" href="./style.css">
<link rel="stylesheet" type="text/css" href="./style.css"> <title>Mattermost - LDAP Authorization</title>
<title>Authorisation Mattermost</title>
</head>
<body> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css"
integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400" rel="stylesheet">
</head>
<center> <body>
<table background="images/login.png" border="0" width="729" height="343" cellspacing="1" cellpadding="4"> <div id="form-wrapper" style="text-align: center;">
<tr> <div id="form_credentials">
<td width="40%">&nbsp;</td> <h1>LDAP Authentication</h1>
<div id="form_icon">
<td width="60%"> <img src="./images/auth_icon.png" alt="authentication icon" >
<table border="0" width="100%"> </div>
<br>
<tr> <h2>Authorize Mattermost to get the following data:</h2>
<td align="center"> <table>
<div class="LoginTitle">Mattermost desires access to your LDAP data:</div>
<form method="post">
<table border="0" width="90%" cellpadding="1">
<tr> <tr>
<td colspan="2" align="left"> <td>
&nbsp; <strong>Full Name</strong><br/>
<div class="messageLogin" align="center"> &nbsp; <strong>E-mail</strong><br/>
</td>
</div>
&nbsp;
</td>
</tr> </tr>
<tr>
<td align="center" width="100%" class="LoginUsername">
Login as : <b>' . $_SESSION['uid'] . ' </b> <button type="submit" class="link" name="disconnect" value="true" ><span>(not me ?)</span></button>
</td>
</tr>
<tr>
<td align="left" width="100%" class="LoginUsername">
<br/>
Requested Data : <br/>
&nbsp; -> Username,<br/>
&nbsp; -> Full Name,<br/>
&nbsp; -> Email
</td>
</tr>
<tr><td colspan="2">&nbsp;</td></tr>
<tr>
<td colspan="2" align="center"> <input type="submit" class="GreenButton" name="authorized" value="Authorize" >
<input type="submit" class="GreenButton" name="authorized" value="Deny" > </td>
</tr>
</table> </table>
</form> <br/>
Logged as : <strong>' . $_SESSION['uid'] . ' </strong> <button type="submit" class="link" name="disconnect" value="true" ><span>(not me ?)</span></button>
<br/>
<br/>
</td> <form method="POST">
</tr> <input type="submit" value="Authorize" name="authorized" id="input_accept" class="input_field">
</table> <input type="submit" value="Deny" name="authorized" id="input_deny" class="input_field">
</form>
</td> </div>
</tr> </div>
</table> </body>
</center>
</body>
</html> </html>
'); ');
} }
else { else {
// Print the authorization code if the user has authorized your client // Check if user has authorized to share his data with the client
$is_authorized = ($_POST['authorized'] === 'Authorize'); $is_authorized = ($_POST['authorized'] === 'Authorize');
$server->handleAuthorizeRequest($request, $response, $is_authorized, $_SESSION['uid']);
} }
// Print the authorization code if the user has authorized your client
$server->handleAuthorizeRequest($request, $response, $is_authorized,$_SESSION['uid']);
// Authentication process is terminated, session can be destroyed.
$_SESSION=array();
if ($is_authorized) 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

View File

@ -1,70 +0,0 @@
<?php
session_start();
/**
* @author Denis CLAVIER <clavierd at gmail dot com>
*/
// include our LDAP object
require_once __DIR__.'/LDAP/LDAP.php';
require_once __DIR__.'/LDAP/config_ldap.php';
// Verify all fields have been filled
if (empty($_POST['user']) || empty($_POST['password'])) {
echo 'Please fill in your Username and Password<br /><br />';
echo 'Click <a href="./index.php">here</a> to come back to login page';
} else {
// Check received data length (to prevent code injection)
if (strlen($_POST['user']) > 15) {
echo 'Username has incorrect format ... Please try again<br /><br />';
echo 'Click <a href="./index.php">here</a> to come back to login page';
} elseif (strlen($_POST['password']) > 50 || strlen($_POST['password']) <= 7) {
echo 'Password has incorrect format ... Please try again<br /><br />';
echo 'Click <a href="./index.php">here</a> to come back to login page';
} else {
// Remove every html tag and useless space on username (to prevent XSS)
$user=strtolower(strip_tags(htmlspecialchars(trim($_POST['user']))));
$password=$_POST['password'];
// Open a LDAP connection
$ldap = new LDAP($ldap_host, $ldap_port, $ldap_version);
// Check user credential on LDAP
try {
$authenticated = $ldap->checkLogin($user, $password, $ldap_search_attribute, $ldap_filter, $ldap_base_dn, $ldap_bind_dn, $ldap_bind_pass);
} catch (Exception $e) {
if ($e->getCode() == 404) {
$resp = json_encode(
[
"error" => "User not found",
"message" => "$user is not in the group of authorized users."
]
);
} else {
$resp = json_encode(array("error" => "Impossible to get data", "message" => $e->getMessage()));
}
$authenticated = false;
}
// If user is authenticated
if ($authenticated) {
$_SESSION['uid']=$user;
// If user came here with an autorize request, redirect him to the authorize page. Else prompt a simple message.
if (isset($_SESSION['auth_page'])) {
$auth_page=$_SESSION['auth_page'];
header('Location: ' . $auth_page);
exit();
} else {
echo "Congratulation you are authenticated ! <br /><br /> However there is nothing to do here ...";
}
}
// check login on LDAP has failed. Login and password were invalid or LDAP is unreachable
else {
echo "Authentication failed ... Check your username and password.<br />If error persist contact your administrator.<br /><br />";
echo 'Click <a href="./index.php">here</a> to come back to login page';
echo '<br /><br /><br />' . $resp;
}
}
}

41
oauth/form_prompt.html Normal file
View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="./style.css">
<title>LDAP Connection Interface</title>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css"
integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400" rel="stylesheet">
</head>
<body>
<div id="form-wrapper" style="text-align: center;">
<div id="form_credentials">
<h1>LDAP Authentication</h1>
<div id="form_icon_prompt">
<img src="./images/prompt_icon.png" alt="authentication icon" >
</div>
<br>
<form method="POST">
<div class="input_container">
<i class="fas fa-user"></i>
<input placeholder="Username" type="text" name="user" id="field_username" class="input_field">
</div><br>
<div class="input_container">
<i class="fas fa-lock"></i>
<input placeholder="Password" type="password" name="password" id="field_password" class="input_field">
</div><br>
<div class="err_msg">
</div>
<input type="submit" value="Login" name="login" id="input_login" class="input_field">
</form>
</div>
</div>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 977 B

BIN
oauth/images/auth_icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View File

@ -1,72 +1,89 @@
<?php <?php
session_start(); session_start();
?> /**
* @author Denis CLAVIER <clavierd at gmail dot com>
* A modified verion by dimst23
*/
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="./style.css">
<title>LDAP Connection Interface</title>
</head>
<body> // include our LDAP object
<center> require_once __DIR__.'/LDAP/LDAP.php';
<table background="images/login.png" border="0" width="733" height="348" cellspacing="1" cellpadding="4"> require_once __DIR__.'/LDAP/config_ldap.php';
<tr>
<td width="40%">&nbsp;</td>
<td width="60%">
<table border="0" width="100%">
<tr> $prompt_template = new DOMDocument();
<td align="center"> $prompt_template->loadHTMLFile('form_prompt.html');
<div class="LoginTitle">LDAP Authentification</div>
<form method="post" action="connexion.php">
function messageShow($html_template, $message = 'No Msg') {
<table border="0" width="90%" cellpadding="1"> $modification_node = $html_template->getElementsByTagName('div')->item(5);
<tr> $page_fragment = $html_template->createDocumentFragment();
<td colspan="2" align="left"> $page_fragment->appendXML($message);
<div class="messageLogin" align="center"> $modification_node->appendChild($page_fragment);
</div> echo $html_template->saveHTML();
&nbsp; }
</td>
</tr>
<tr> // Verify all fields have been filled
<td align="left" width="40%" class="LoginUsername"> if (empty($_POST['user']) || empty($_POST['password']))
Username:&nbsp; {
</td> if (empty($_POST['user'])) {
<td width="60%"> messageShow($prompt_template, 'Username field can\'t be empty.');
<input type="text" name="user" size="25" value="" > } else {
</td> messageShow($prompt_template, 'Password field can\'t be empty.');
</tr> }
<tr> }
<td align="left" width="40%" class="LoginUsername"> else
Password:&nbsp; {
</td> // Check received data length (to prevent code injection)
<td width="60%"> if (strlen($_POST['user']) > 64)
<input type="password" name="password" size="25" value="" > {
</td> messageShow($prompt_template, 'Username has incorrect format ... Please try again');
</tr> }
<tr><td colspan="2">&nbsp;</td></tr> elseif (strlen($_POST['password']) > 64 || strlen($_POST['password']) <= 7)
<tr> {
<td colspan="2" align="center"> <input type="submit" class="GreenButton" name="login" value=" Connect " > </td> messageShow($prompt_template, 'Password has incorrect format ... Please try again');
</tr> }
else
{
</table> // Remove every html tag and useless space on username (to prevent XSS)
</form> $user=strtolower(strip_tags(htmlspecialchars(trim($_POST['user']))));
$password=$_POST['password'];
</td>
</tr> // Open a LDAP connection
</table> $ldap = new LDAP($ldap_host,$ldap_port,$ldap_version);
</td> // Check user credential on LDAP
</tr> try{
</table> $authenticated = $ldap->checkLogin($user,$password,$ldap_search_attribute,$ldap_filter,$ldap_base_dn,$ldap_bind_dn,$ldap_bind_pass);
</center> }
</body> catch (Exception $e)
</html> {
$authenticated = false;
}
// If user is authenticated
if ($authenticated)
{
$_SESSION['uid']=$user;
// If user came here with an autorize request, redirect him to the authorize page. Else prompt a simple message.
if (isset($_SESSION['auth_page']))
{
$auth_page=$_SESSION['auth_page'];
header('Location: ' . $auth_page);
exit();
}
else
{
messageShow($prompt_template, 'Congratulation you are authenticated ! <br /><br /> However there is nothing to do here ...');
}
}
// check login on LDAP has failed. Login and password were invalid or LDAP is unreachable
else
{
messageShow($prompt_template, 'Authentication failed ... Check your username and password.<br />If the error persists contact your administrator.<br /><br />');
}
}
}

View File

@ -1,84 +1,212 @@
html :root {
{ --input_bg: #E5E5E5;
height: 100%; --input_hover:#eaeaea;
margin: 0; --accept_bg: #1FCC44;
} --accept_hover: #40e263;
--deny_bg: #cc1f1f;
body { --deny_hover: #e24040;
font-family:"Tahoma","Arial", serif; --icon_color:#6b6b6b;
font-size:8px; }
font-weight: normal;
color: black; html {
text-decoration:none; height: 100%;
background-color: white; margin: 0;
height: 100%; }
margin: 0;
} /* Overide browser defaults */
* {
padding: 0;
.LoginTitle { margin: 0;
color: #000000; box-sizing: border-box;
font-family : "Tahoma","Arial", serif; }
font-size : 18pt;
font-weight: normal; /* Style the form wrapper */
} body {
/* Set custom font */
.LoginUsername { font-family: 'Roboto', sans-serif;
color: #000000; margin: auto;
font-family : "Tahoma","Arial", serif; text-align: center;
font-size : 14pt; }
font-weight: normal;
} table {
margin-left: auto;
.LoginComment { margin-right: auto;
color: #000000; font-size: larger;
font-family : "Tahoma","Arial", serif; border: none;
font-size : 8pt; margin-top: 5%;
font-weight: normal; }
}
/* Format the different images*/
.GreenButton #form_icon,
{ #form_icon_prompt {
color: white; display: flex;
font-family : "Tahoma", "Arial", serif; justify-content: center;
font-size : 10pt; align-items: center;
font-weight: normal; margin-top: 5%;
height: 28px; }
background: transparent url(images/ButtonGreen.png) repeat-x left top;
border: solid 1px #50B4AE; #form_icon img {
font-weight: bold; width: 100%;
} max-width: 450px;
}
.messageLogin {
color: Yellow; #form_icon_prompt img {
font-family : "Tahoma", "Arial", serif; width: 50%;
font-size : 8pt; max-width: 350px;
font-weight: bold; }
}
button { /* Style the form_credentials */
overflow: visible; #form_credentials {
width: auto; /* Center the content */
} display: inline-block;
button.link { justify-content: center;
font-family: "Verdana" sans-serif; align-items: center;
font-size: 7pt; position: absolute;
text-align: left; transform: translate(-50%, 25%);
color: blue; }
background: none;
margin: 0; /* Style input fields */
padding: 0; .input_container {
border: none; background-color: var(--input_bg);
cursor: pointer; /* Vertically align icon and text inside the div*/
display: flex;
-moz-user-select: text; align-items: center;
padding-left: 20px;
/* override all your button styles here if there are any others */ }
}
button.link span { .input_container:hover {
text-decoration: underline; background-color: var(--input_hover);
} }
button.link:hover span,
button.link:focus span { .input_container,
color: black; #input_accept,
} #input_deny,
#input_login {
height: 60px;
/* Make the borders more round */
border-radius: 12px;
width: 100%;
}
.input_field {
/* Customize the input tag with lighter font and some padding*/
color: var(--icon_color);
background-color: inherit;
width: 95%;
border: none;
font-size: 1.3rem;
font-weight: 400;
padding-left: 6.5%;
}
.input_field:hover,
.input_field:focus {
/* Remove the outline */
outline: none;
}
#input_accept,
#input_deny,
#input_login {
/* Submit button has a different color and different padding */
background-color: var(--accept_bg);
padding-left: 0;
font-weight: bold;
color: white;
text-transform: capitalize;
text-align: center;
display: inline-block;
margin-top: 25%;
margin-right: 2%;
width: 50%;
}
#input_accept:hover,
#input_deny:hover,
#input_login:hover {
/* Simple color transition on hover */
transition: background-color, 500ms;
cursor: pointer;
}
#input_accept,
#input_deny {
width: 45%;
margin-top: 6%;
}
#input_deny {
background-color: var(--deny_bg);
}
#input_deny:hover {
background-color: var(--deny_hover);
}
/* Format the error messages */
.err_msg {
color: red;
font-weight: bold;
font-size: 110%;
}
/* General page styling */
h1,
span {
text-align: center;
padding-bottom: 2%;
padding-top: 0%;
font-weight: bolder;
font-size: 300%;
}
i {
color: var(--icon_color);
}
/* Make it responsive */
@media screen and (max-width:768px) {
/* Make the layout a single column and add some margin to the wrapper */
#form_wrapper {
grid-template-columns: 1fr;
margin-left: 10px;
margin-right: 10px;
}
/* On small screens we don't display the image */
#form_icon {
display: flex;
}
}
button {
overflow: visible;
width: auto;
}
button.link {
font-family: "Verdana" sans-serif;
font-size: 2pt;
text-align: left;
color: blue;
background: none;
margin: 0;
padding: 0;
border: none;
cursor: pointer;
-moz-user-select: text;
/* override all your button styles here if there are any others */
}
button.link span {
text-decoration: underline;
}
button.link:hover span,
button.link:focus span {
color: black;
}