Compare commits
8 Commits
96a62cef3b
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| ff6cd38c8d | |||
| 9e21bdc135 | |||
| 513b7563b6 | |||
| 1521d8dec2 | |||
| 2a2a96a7b4 | |||
| 4ebfd046de | |||
| 45b9cc7dfa | |||
| db2079e0b3 |
31
README.md
31
README.md
@@ -0,0 +1,31 @@
|
|||||||
|
# PHP LDAP
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### AD
|
||||||
|
|
||||||
|
Par défaut, l'application se connecte au serveur AD à l'adresse `woodywood.local`
|
||||||
|
|
||||||
|
### Base de données
|
||||||
|
|
||||||
|
Par défaut, l'application se connecte à la base de données locale
|
||||||
|
avec l'utilisateur `root` et le mot de passe `4321`
|
||||||
|
|
||||||
|
|
||||||
|
## Captures d'écran
|
||||||
|
|
||||||
|
Page d'authentification :
|
||||||
|
|
||||||
|
[[screenshots/auth.png]]
|
||||||
|
|
||||||
|
Page d'erreur :
|
||||||
|
|
||||||
|
[[screenshots/error.png]]
|
||||||
|
|
||||||
|
Page utilisateur :
|
||||||
|
|
||||||
|
[[screenshots/success.png]]
|
||||||
|
|
||||||
|
Page admin (en se connectant avec l'utilisateur Administrateur):
|
||||||
|
|
||||||
|
[[screenshots/admin.png]]
|
||||||
22
css/dataTables.css
Normal file
22
css/dataTables.css
Normal file
File diff suppressed because one or more lines are too long
15
db_test.php
15
db_test.php
@@ -1,15 +0,0 @@
|
|||||||
<?php
|
|
||||||
$host = 'localhost'; // ou l'adresse IP du serveur MariaDB
|
|
||||||
$dbname = 'mysql'; // nom de votre base de donn<6E>es
|
|
||||||
$username = 'root'; // nom d'utilisateur MariaDB
|
|
||||||
$password = '4321'; // mot de passe pour l'utilisateur
|
|
||||||
try {
|
|
||||||
// Cr<43>ation d'une instance PDO pour la connexion <20> la base de donn<6E>es
|
|
||||||
$pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
|
|
||||||
// Configuration du mode d'erreur de PDO pour les exceptions
|
|
||||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
||||||
echo "Connexion réussie <20> MariaDB avec PDO!";
|
|
||||||
} catch (PDOException $e) {
|
|
||||||
echo "<EFBFBD>chec de la connexion : " . $e->getMessage();
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
30
index.php
30
index.php
@@ -1,3 +1,27 @@
|
|||||||
<?php
|
<?php
|
||||||
phpinfo();
|
|
||||||
?>
|
if (!isset($_POST["domain"]) || !isset($_POST["user"]) || !isset($_POST["password"])) {
|
||||||
|
require_once "templates/login_form.html";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$domain = rtrim($_POST["domain"]);
|
||||||
|
$user = rtrim($_POST["user"]);
|
||||||
|
$password = rtrim($_POST["password"]);
|
||||||
|
|
||||||
|
require_once "src/ldap.php";
|
||||||
|
|
||||||
|
$result = LdapIsConnected($domain, $user, $password, []);
|
||||||
|
|
||||||
|
if (!$result) {
|
||||||
|
require_once "templates/login_failed.html";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once "view/View.php";
|
||||||
|
|
||||||
|
$info = LdapGetUserInfo($user);
|
||||||
|
|
||||||
|
$body = PrintLoginInfo($info);
|
||||||
|
|
||||||
|
require_once "templates/login_success.html.php";
|
||||||
|
|||||||
36
js/datatables.min.js
vendored
Normal file
36
js/datatables.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
245
lang/fr.json
Normal file
245
lang/fr.json
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
{
|
||||||
|
"emptyTable": "Aucune donnée disponible dans le tableau",
|
||||||
|
"loadingRecords": "Chargement...",
|
||||||
|
"processing": "Traitement...",
|
||||||
|
"select": {
|
||||||
|
"rows": {
|
||||||
|
"_": "%d lignes sélectionnées",
|
||||||
|
"1": "1 ligne sélectionnée"
|
||||||
|
},
|
||||||
|
"cells": {
|
||||||
|
"1": "1 cellule sélectionnée",
|
||||||
|
"_": "%d cellules sélectionnées"
|
||||||
|
},
|
||||||
|
"columns": {
|
||||||
|
"1": "1 colonne sélectionnée",
|
||||||
|
"_": "%d colonnes sélectionnées"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoFill": {
|
||||||
|
"cancel": "Annuler",
|
||||||
|
"fill": "Remplir toutes les cellules avec <i>%d<\/i>",
|
||||||
|
"fillHorizontal": "Remplir les cellules horizontalement",
|
||||||
|
"fillVertical": "Remplir les cellules verticalement"
|
||||||
|
},
|
||||||
|
"searchBuilder": {
|
||||||
|
"conditions": {
|
||||||
|
"date": {
|
||||||
|
"after": "Après le",
|
||||||
|
"before": "Avant le",
|
||||||
|
"between": "Entre",
|
||||||
|
"empty": "Vide",
|
||||||
|
"not": "Différent de",
|
||||||
|
"notBetween": "Pas entre",
|
||||||
|
"notEmpty": "Non vide",
|
||||||
|
"equals": "Égal à"
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"between": "Entre",
|
||||||
|
"empty": "Vide",
|
||||||
|
"gt": "Supérieur à",
|
||||||
|
"gte": "Supérieur ou égal à",
|
||||||
|
"lt": "Inférieur à",
|
||||||
|
"lte": "Inférieur ou égal à",
|
||||||
|
"not": "Différent de",
|
||||||
|
"notBetween": "Pas entre",
|
||||||
|
"notEmpty": "Non vide",
|
||||||
|
"equals": "Égal à"
|
||||||
|
},
|
||||||
|
"string": {
|
||||||
|
"contains": "Contient",
|
||||||
|
"empty": "Vide",
|
||||||
|
"endsWith": "Se termine par",
|
||||||
|
"not": "Différent de",
|
||||||
|
"notEmpty": "Non vide",
|
||||||
|
"startsWith": "Commence par",
|
||||||
|
"equals": "Égal à",
|
||||||
|
"notContains": "Ne contient pas",
|
||||||
|
"notEndsWith": "Ne termine pas par",
|
||||||
|
"notStartsWith": "Ne commence pas par"
|
||||||
|
},
|
||||||
|
"array": {
|
||||||
|
"empty": "Vide",
|
||||||
|
"contains": "Contient",
|
||||||
|
"not": "Différent de",
|
||||||
|
"notEmpty": "Non vide",
|
||||||
|
"without": "Sans",
|
||||||
|
"equals": "Égal à"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"add": "Ajouter une condition",
|
||||||
|
"button": {
|
||||||
|
"0": "Recherche avancée",
|
||||||
|
"_": "Recherche avancée (%d)"
|
||||||
|
},
|
||||||
|
"clearAll": "Effacer tout",
|
||||||
|
"condition": "Condition",
|
||||||
|
"data": "Donnée",
|
||||||
|
"deleteTitle": "Supprimer la règle de filtrage",
|
||||||
|
"logicAnd": "Et",
|
||||||
|
"logicOr": "Ou",
|
||||||
|
"title": {
|
||||||
|
"0": "Recherche avancée",
|
||||||
|
"_": "Recherche avancée (%d)"
|
||||||
|
},
|
||||||
|
"value": "Valeur",
|
||||||
|
"leftTitle": "Désindenter le critère",
|
||||||
|
"rightTitle": "Indenter le critère"
|
||||||
|
},
|
||||||
|
"searchPanes": {
|
||||||
|
"clearMessage": "Effacer tout",
|
||||||
|
"count": "{total}",
|
||||||
|
"title": "Filtres actifs - %d",
|
||||||
|
"collapse": {
|
||||||
|
"0": "Volet de recherche",
|
||||||
|
"_": "Volet de recherche (%d)"
|
||||||
|
},
|
||||||
|
"countFiltered": "{shown} ({total})",
|
||||||
|
"emptyPanes": "Pas de volet de recherche",
|
||||||
|
"loadMessage": "Chargement du volet de recherche...",
|
||||||
|
"collapseMessage": "Réduire tout",
|
||||||
|
"showMessage": "Montrer tout"
|
||||||
|
},
|
||||||
|
"buttons": {
|
||||||
|
"collection": "Collection",
|
||||||
|
"colvis": "Visibilité colonnes",
|
||||||
|
"colvisRestore": "Rétablir visibilité",
|
||||||
|
"copy": "Copier",
|
||||||
|
"copySuccess": {
|
||||||
|
"1": "1 ligne copiée dans le presse-papier",
|
||||||
|
"_": "%d lignes copiées dans le presse-papier"
|
||||||
|
},
|
||||||
|
"copyTitle": "Copier dans le presse-papier",
|
||||||
|
"csv": "CSV",
|
||||||
|
"excel": "Excel",
|
||||||
|
"pageLength": {
|
||||||
|
"-1": "Afficher toutes les lignes",
|
||||||
|
"_": "Afficher %d lignes",
|
||||||
|
"1": "Afficher 1 ligne"
|
||||||
|
},
|
||||||
|
"pdf": "PDF",
|
||||||
|
"print": "Imprimer",
|
||||||
|
"copyKeys": "Appuyez sur ctrl ou u2318 + C pour copier les données du tableau dans votre presse-papier.",
|
||||||
|
"createState": "Créer un état",
|
||||||
|
"removeAllStates": "Supprimer tous les états",
|
||||||
|
"removeState": "Supprimer",
|
||||||
|
"renameState": "Renommer",
|
||||||
|
"savedStates": "États sauvegardés",
|
||||||
|
"stateRestore": "État %d",
|
||||||
|
"updateState": "Mettre à jour"
|
||||||
|
},
|
||||||
|
"decimal": ",",
|
||||||
|
"datetime": {
|
||||||
|
"previous": "Précédent",
|
||||||
|
"next": "Suivant",
|
||||||
|
"hours": "Heures",
|
||||||
|
"minutes": "Minutes",
|
||||||
|
"seconds": "Secondes",
|
||||||
|
"unknown": "-",
|
||||||
|
"amPm": [
|
||||||
|
"am",
|
||||||
|
"pm"
|
||||||
|
],
|
||||||
|
"months": {
|
||||||
|
"0": "Janvier",
|
||||||
|
"2": "Mars",
|
||||||
|
"3": "Avril",
|
||||||
|
"4": "Mai",
|
||||||
|
"5": "Juin",
|
||||||
|
"6": "Juillet",
|
||||||
|
"8": "Septembre",
|
||||||
|
"9": "Octobre",
|
||||||
|
"10": "Novembre",
|
||||||
|
"1": "Février",
|
||||||
|
"11": "Décembre",
|
||||||
|
"7": "Août"
|
||||||
|
},
|
||||||
|
"weekdays": [
|
||||||
|
"Dim",
|
||||||
|
"Lun",
|
||||||
|
"Mar",
|
||||||
|
"Mer",
|
||||||
|
"Jeu",
|
||||||
|
"Ven",
|
||||||
|
"Sam"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"editor": {
|
||||||
|
"close": "Fermer",
|
||||||
|
"create": {
|
||||||
|
"title": "Créer une nouvelle entrée",
|
||||||
|
"button": "Nouveau",
|
||||||
|
"submit": "Créer"
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"button": "Editer",
|
||||||
|
"title": "Editer Entrée",
|
||||||
|
"submit": "Mettre à jour"
|
||||||
|
},
|
||||||
|
"remove": {
|
||||||
|
"button": "Supprimer",
|
||||||
|
"title": "Supprimer",
|
||||||
|
"submit": "Supprimer",
|
||||||
|
"confirm": {
|
||||||
|
"_": "Êtes-vous sûr de vouloir supprimer %d lignes ?",
|
||||||
|
"1": "Êtes-vous sûr de vouloir supprimer 1 ligne ?"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"multi": {
|
||||||
|
"title": "Valeurs multiples",
|
||||||
|
"info": "Les éléments sélectionnés contiennent différentes valeurs pour cette entrée. Pour modifier et définir tous les éléments de cette entrée à la même valeur, cliquez ou tapez ici, sinon ils conserveront leurs valeurs individuelles.",
|
||||||
|
"restore": "Annuler les modifications",
|
||||||
|
"noMulti": "Ce champ peut être modifié individuellement, mais ne fait pas partie d'un groupe. "
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"system": "Une erreur système s'est produite (<a target=\"\\\" rel=\"nofollow\" href=\"\\\">Plus d'information<\/a>)."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stateRestore": {
|
||||||
|
"removeSubmit": "Supprimer",
|
||||||
|
"creationModal": {
|
||||||
|
"button": "Créer",
|
||||||
|
"order": "Tri",
|
||||||
|
"paging": "Pagination",
|
||||||
|
"scroller": "Position du défilement",
|
||||||
|
"search": "Recherche",
|
||||||
|
"select": "Sélection",
|
||||||
|
"columns": {
|
||||||
|
"search": "Recherche par colonne",
|
||||||
|
"visible": "Visibilité des colonnes"
|
||||||
|
},
|
||||||
|
"name": "Nom :",
|
||||||
|
"searchBuilder": "Recherche avancée",
|
||||||
|
"title": "Créer un nouvel état",
|
||||||
|
"toggleLabel": "Inclus :"
|
||||||
|
},
|
||||||
|
"renameButton": "Renommer",
|
||||||
|
"duplicateError": "Il existe déjà un état avec ce nom.",
|
||||||
|
"emptyError": "Le nom ne peut pas être vide.",
|
||||||
|
"emptyStates": "Aucun état sauvegardé",
|
||||||
|
"removeConfirm": "Voulez vous vraiment supprimer %s ?",
|
||||||
|
"removeError": "Échec de la suppression de l'état.",
|
||||||
|
"removeJoiner": "et",
|
||||||
|
"removeTitle": "Supprimer l'état",
|
||||||
|
"renameLabel": "Nouveau nom pour %s :",
|
||||||
|
"renameTitle": "Renommer l'état"
|
||||||
|
},
|
||||||
|
"info": "Affichage de _START_ à _END_ sur _TOTAL_ entrées",
|
||||||
|
"infoEmpty": "Affichage de 0 à 0 sur 0 entrées",
|
||||||
|
"infoFiltered": "(filtrées depuis un total de _MAX_ entrées)",
|
||||||
|
"lengthMenu": "Afficher _MENU_ entrées",
|
||||||
|
"paginate": {
|
||||||
|
"first": "Première",
|
||||||
|
"last": "Dernière",
|
||||||
|
"next": "Suivante",
|
||||||
|
"previous": "Précédente"
|
||||||
|
},
|
||||||
|
"zeroRecords": "Aucune entrée correspondante trouvée",
|
||||||
|
"aria": {
|
||||||
|
"sortAscending": " : activer pour trier la colonne par ordre croissant",
|
||||||
|
"sortDescending": " : activer pour trier la colonne par ordre décroissant"
|
||||||
|
},
|
||||||
|
"infoThousands": " ",
|
||||||
|
"search": "Rechercher :",
|
||||||
|
"thousands": " "
|
||||||
|
}
|
||||||
33
login.php
33
login.php
@@ -1,33 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
if (!isset($_POST["domain"]) || !isset($_POST["user"]) || !isset($_POST["password"])) {
|
|
||||||
require_once "templates/login_form.html";
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$domain = rtrim($_POST["domain"]);
|
|
||||||
$user = rtrim($_POST["user"]);
|
|
||||||
$password = rtrim($_POST["password"]);
|
|
||||||
|
|
||||||
require_once "ldap.php";
|
|
||||||
|
|
||||||
$result = LdapConnect($domain, $user, $password, []);
|
|
||||||
|
|
||||||
ldap_parse_result($handle, $result, $error_code, $matched_dn, $error_message, $referrals, $controls);
|
|
||||||
|
|
||||||
|
|
||||||
if ($error_code != 0) {
|
|
||||||
require_once "templates/login_failed.html";
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once "view/View.php";
|
|
||||||
|
|
||||||
$info = LdapGetUserInfo($user);
|
|
||||||
|
|
||||||
$body = PrintLoginInfo($info);
|
|
||||||
|
|
||||||
require_once "templates/login_success.html.php";
|
|
||||||
|
|
||||||
// TODO: style
|
|
||||||
// TODO: Mettre les tentatives dans la db
|
|
||||||
BIN
screenshots/admin.png
Normal file
BIN
screenshots/admin.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 138 KiB |
BIN
screenshots/auth.png
Normal file
BIN
screenshots/auth.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
BIN
screenshots/error.png
Normal file
BIN
screenshots/error.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
screenshots/success.png
Normal file
BIN
screenshots/success.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
83
src/database.php
Normal file
83
src/database.php
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$table_name = "authentification_attempts";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connexion à la base de données
|
||||||
|
*/
|
||||||
|
function GetDbConnection(): ?PDO
|
||||||
|
{
|
||||||
|
$host = 'localhost';
|
||||||
|
$dbname = 'ldap';
|
||||||
|
$username = 'root';
|
||||||
|
$password = '4321';
|
||||||
|
try {
|
||||||
|
// Création d'une instance PDO pour la connexion à la base de données
|
||||||
|
$pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
|
||||||
|
// Configuration du mode d'erreur de PDO pour les exceptions
|
||||||
|
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
return $pdo;
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
echo "Échec de la connexion : " . $e->getMessage();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
class AuthAttempt
|
||||||
|
{
|
||||||
|
public string $username;
|
||||||
|
public string $status;
|
||||||
|
public string $timestamp;
|
||||||
|
public string $ip_address;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
string $username,
|
||||||
|
string $status,
|
||||||
|
string $ip_address,
|
||||||
|
string $timestamp = "",
|
||||||
|
) {
|
||||||
|
$this->username = $username;
|
||||||
|
$this->status = $status;
|
||||||
|
$this->ip_address = $ip_address;
|
||||||
|
$this->timestamp = $timestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ajoute une entrée dans la table des tentatives de connexion
|
||||||
|
*/
|
||||||
|
function InsertLine(AuthAttempt $attempt)
|
||||||
|
{
|
||||||
|
global $table_name;
|
||||||
|
$pdo = GetDbConnection();
|
||||||
|
|
||||||
|
$query = $pdo->prepare("INSERT INTO $table_name(`username`, `status`, `ip_address`) VALUES (:user, :status, :ip);");
|
||||||
|
|
||||||
|
$query->bindValue(":user", $attempt->username, PDO::PARAM_STR);
|
||||||
|
$query->bindValue(":status", $attempt->status, PDO::PARAM_STR);
|
||||||
|
$query->bindValue(":ip", $attempt->ip_address, PDO::PARAM_STR);
|
||||||
|
|
||||||
|
$query->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Récupère toutes les lignes de tentative de connexion
|
||||||
|
*/
|
||||||
|
function GetLines() : array {
|
||||||
|
global $table_name;
|
||||||
|
$pdo = GetDbConnection();
|
||||||
|
|
||||||
|
$query = $pdo->prepare("SELECT * FROM $table_name;");
|
||||||
|
|
||||||
|
$query->execute();
|
||||||
|
|
||||||
|
$lines = $query->fetchAll(\PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
$result = [];
|
||||||
|
|
||||||
|
foreach($lines as $line) {
|
||||||
|
array_push($result, new AuthAttempt($line["username"], $line["status"], $line["ip_address"], $line["timestamp"]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
@@ -1,8 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
// Cette ligne permet d'autoriser les certificats auto-signés
|
||||||
|
putenv('LDAPTLS_REQCERT=never');
|
||||||
|
|
||||||
|
require_once "database.php";
|
||||||
|
|
||||||
$ldap_domain_name = "woodywood";
|
$ldap_domain_name = "woodywood";
|
||||||
|
|
||||||
$handle = ldap_connect("ldap://$ldap_domain_name.local");
|
$handle = ldap_connect("ldaps://$ldap_domain_name.local");
|
||||||
ldap_set_option($handle, LDAP_OPT_PROTOCOL_VERSION, 3);
|
ldap_set_option($handle, LDAP_OPT_PROTOCOL_VERSION, 3);
|
||||||
ldap_set_option($handle, LDAP_OPT_REFERRALS, 0);
|
ldap_set_option($handle, LDAP_OPT_REFERRALS, 0);
|
||||||
|
|
||||||
@@ -18,26 +23,38 @@ class UserInfo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function LdapConnect(string $domain, string $username, string $password, ?array $controls): LDAP\Result|false
|
/**
|
||||||
|
* Connexion avec des identifiants
|
||||||
|
*/
|
||||||
|
function LdapConnect(string $domain, string $username, string $password): LDAP\Result|false
|
||||||
{
|
{
|
||||||
global $handle;
|
global $handle;
|
||||||
$bind = ldap_bind_ext($handle, $username . '@' . $domain, $password, $controls);
|
$bind = ldap_bind_ext($handle, $username . '@' . $domain, $password);
|
||||||
LogConnection();
|
|
||||||
return $bind;
|
return $bind;
|
||||||
}
|
}
|
||||||
|
|
||||||
function LogConnection() {}
|
/**
|
||||||
|
* Se connecte à l'AD et vérifie la validité des identifiants
|
||||||
function LdapConnectAndBind()
|
*/
|
||||||
{
|
function LdapIsConnected(string $domain, string $username, string $password) : bool {
|
||||||
global $ldap_domain_name;
|
global $handle;
|
||||||
$ldap_instance = ldap_connect("ldap://$ldap_domain_name.local");
|
$result = LdapConnect($domain, $username, $password);
|
||||||
ldap_set_option($ldap_instance, LDAP_OPT_PROTOCOL_VERSION, 3);
|
ldap_parse_result($handle, $result, $error_code, $matched_dn, $error_message, $referrals, $controls);
|
||||||
ldap_set_option($ldap_instance, LDAP_OPT_REFERRALS, 0);
|
$success = $error_code == 0;
|
||||||
ldap_bind($ldap_instance, "Administrateur@woodywood", "3AFISE+25");
|
LogConnection($username, $success);
|
||||||
return $ldap_instance;
|
return $success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enregistre la tentative de connexion dans la base de données
|
||||||
|
*/
|
||||||
|
function LogConnection(string $username, bool $success) {
|
||||||
|
InsertLine(new AuthAttempt($username, $success ? "success" : "failure", $_SERVER['REMOTE_ADDR']));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne les informations d'un utilisateur
|
||||||
|
*/
|
||||||
function LdapGetUserInfo(string $user): ?UserInfo
|
function LdapGetUserInfo(string $user): ?UserInfo
|
||||||
{
|
{
|
||||||
global $handle;
|
global $handle;
|
||||||
@@ -56,12 +73,18 @@ function LdapGetUserInfo(string $user): ?UserInfo
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Permet de retourner les valeur dans une chaîne de caractère de type dn
|
||||||
|
*/
|
||||||
function GetValue(string $dnStr, string $key): array
|
function GetValue(string $dnStr, string $key): array
|
||||||
{
|
{
|
||||||
preg_match_all("/$key=([^,]+)/", $dnStr, $matches);
|
preg_match_all("/$key=([^,]+)/", $dnStr, $matches);
|
||||||
return isset($matches[1]) ? $matches[1] : [];
|
return isset($matches[1]) ? $matches[1] : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne tous les objets du type spécifié dans l'ou souhaitée et filtre le résultat
|
||||||
|
*/
|
||||||
function LdapGetObjectsInOU(string $ou, string $objectType, string $field): array
|
function LdapGetObjectsInOU(string $ou, string $objectType, string $field): array
|
||||||
{
|
{
|
||||||
global $ldap_domain_name;
|
global $ldap_domain_name;
|
||||||
@@ -95,11 +118,17 @@ function LdapGetObjectsInOU(string $ou, string $objectType, string $field): arra
|
|||||||
return $object_values;
|
return $object_values;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne la liste des utilisateurs d'une OU
|
||||||
|
*/
|
||||||
function LdapGetUsersInOU(string $ou): array
|
function LdapGetUsersInOU(string $ou): array
|
||||||
{
|
{
|
||||||
return LdapGetObjectsInOU($ou, "user", "CN");
|
return LdapGetObjectsInOU($ou, "user", "CN");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne la liste des groupes d'une OU
|
||||||
|
*/
|
||||||
function LdapGetGroupsInOU(string $ou): array
|
function LdapGetGroupsInOU(string $ou): array
|
||||||
{
|
{
|
||||||
return LdapGetObjectsInOU($ou, "group", "CN");
|
return LdapGetObjectsInOU($ou, "group", "CN");
|
||||||
@@ -6,6 +6,8 @@
|
|||||||
<!-- Bootstrap CSS -->
|
<!-- Bootstrap CSS -->
|
||||||
<link rel="stylesheet" href="../css/index.css">
|
<link rel="stylesheet" href="../css/index.css">
|
||||||
<link rel="stylesheet" href="../css/main.css">
|
<link rel="stylesheet" href="../css/main.css">
|
||||||
|
<!-- Datatables CSS -->
|
||||||
|
<link rel="stylesheet" href="../css/dataTables.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<?php
|
<?php
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
$admin_account = "Administrateur";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Affiche les éléments d'une liste
|
||||||
|
*/
|
||||||
function PrintListFirsts(string $title, array $liste): string
|
function PrintListFirsts(string $title, array $liste): string
|
||||||
{
|
{
|
||||||
$result = '<div class="list-group-item"><h5>' . $title . '</h5>';
|
$result = '<div class="list-group-item"><h5>' . $title . '</h5>';
|
||||||
@@ -11,9 +16,16 @@ function PrintListFirsts(string $title, array $liste): string
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Affiche les informations de l'utilisateur
|
||||||
|
*/
|
||||||
function PrintLoginInfo($info)
|
function PrintLoginInfo($info)
|
||||||
{
|
{
|
||||||
|
global $admin_account;
|
||||||
$body = '<h2 class="text-center pt-3">Bienvenue ' . $info->fullName . " !</h2>";
|
$body = '<h2 class="text-center pt-3">Bienvenue ' . $info->fullName . " !</h2>";
|
||||||
|
if ($info->fullName == $admin_account) {
|
||||||
|
return $body .= PrintAdminInterface();
|
||||||
|
}
|
||||||
$body .= '<div class="list-group ">';
|
$body .= '<div class="list-group ">';
|
||||||
foreach ($info->ous as $ou) {
|
foreach ($info->ous as $ou) {
|
||||||
$body .= '<div class="list-group-item"><h3>' . $ou . "</h3>";
|
$body .= '<div class="list-group-item"><h3>' . $ou . "</h3>";
|
||||||
@@ -22,8 +34,54 @@ function PrintLoginInfo($info)
|
|||||||
$body .= PrintListFirsts("Groupes", LdapGetGroupsInOU($ou));
|
$body .= PrintListFirsts("Groupes", LdapGetGroupsInOU($ou));
|
||||||
$body .= "</div>";
|
$body .= "</div>";
|
||||||
$body .= "</div>";
|
$body .= "</div>";
|
||||||
|
|
||||||
}
|
}
|
||||||
$body .= "</div>";
|
$body .= "</div>";
|
||||||
return $body;
|
return $body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne la chaîne traduite de l'état d'une tentative de connexion
|
||||||
|
*/
|
||||||
|
function translateSuccess(string $success) {
|
||||||
|
return $success == "success" ? "Succès" : "Échec";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Affiche l'interface administrateur
|
||||||
|
*/
|
||||||
|
function PrintAdminInterface(): string
|
||||||
|
{
|
||||||
|
$auth_attempts = GetLines();
|
||||||
|
$body = '<h5 class="text-center">Historique des connexions</h5>';
|
||||||
|
$body .= '<table id="attempts" class="table table-striped table-bordered">
|
||||||
|
<thead class="thead-light">
|
||||||
|
<tr>
|
||||||
|
<th scope="col">Utilisateur</th>
|
||||||
|
<th scope="col">Status</th>
|
||||||
|
<th scope="col">Date</th>
|
||||||
|
<th scope="col">Adresse IP</th>
|
||||||
|
</tr>
|
||||||
|
</thead>';
|
||||||
|
foreach ($auth_attempts as $attempt) {
|
||||||
|
$body .= '<tr>';
|
||||||
|
$body .= '<td>' . $attempt->username . '</td>';
|
||||||
|
$body .= '<td>' . translateSuccess($attempt->status) . '</td>';
|
||||||
|
$body .= '<td>' . $attempt->timestamp . '</td>';
|
||||||
|
$body .= '<td>' . $attempt->ip_address . '</td>';
|
||||||
|
$body .= '</tr>';
|
||||||
|
}
|
||||||
|
$body .= "</table>";
|
||||||
|
$body .= '
|
||||||
|
<script src="/js/datatables.min.js"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
let table = new DataTable("#attempts", {
|
||||||
|
language: {
|
||||||
|
url: "/lang/fr.json",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
';
|
||||||
|
return $body;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user