amélioration de la gestion utilisateurs (partie 1)
This commit is contained in:
parent
51c7456ac0
commit
a7ee569fff
100
auth.php
100
auth.php
@ -1,22 +1,64 @@
|
|||||||
<?php
|
<?php
|
||||||
// auth.php
|
// auth.php
|
||||||
session_start();
|
session_start();
|
||||||
|
require_once 'Database.php';
|
||||||
|
|
||||||
class Auth {
|
class Auth {
|
||||||
private $config;
|
private $config;
|
||||||
|
private $db;
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
$this->config = require 'config.php';
|
$this->config = require 'config.php';
|
||||||
|
$this->db = Database::getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function login($username, $password) {
|
||||||
|
// Vérifier les tentatives de connexion
|
||||||
|
$attempts = $this->db->checkLoginAttempts($username);
|
||||||
|
if ($attempts >= $this->config['security']['max_login_attempts']) {
|
||||||
|
return ['success' => false, 'error' => 'too_many_attempts'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt = $this->db->prepare('
|
||||||
|
SELECT id, username, password_hash, role, description
|
||||||
|
FROM users
|
||||||
|
WHERE username = :username
|
||||||
|
');
|
||||||
|
|
||||||
|
$stmt->bindValue(':username', $username, SQLITE3_TEXT);
|
||||||
|
$result = $stmt->execute();
|
||||||
|
$user = $result->fetchArray(SQLITE3_ASSOC);
|
||||||
|
|
||||||
|
// Enregistrer la tentative
|
||||||
|
$this->db->logLoginAttempt($username);
|
||||||
|
|
||||||
|
if ($user && password_verify($password, $user['password_hash'])) {
|
||||||
|
$_SESSION['auth_time'] = time();
|
||||||
|
$_SESSION['user_id'] = $user['id'];
|
||||||
|
$_SESSION['username'] = $user['username'];
|
||||||
|
$_SESSION['role'] = $user['role'];
|
||||||
|
$_SESSION['description'] = $user['description'];
|
||||||
|
|
||||||
|
// Log de connexion réussie
|
||||||
|
$this->db->logActivity($user['id'], 'login');
|
||||||
|
|
||||||
|
return ['success' => true, 'user' => [
|
||||||
|
'username' => $user['username'],
|
||||||
|
'role' => $user['role'],
|
||||||
|
'description' => $user['description']
|
||||||
|
]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ['success' => false, 'error' => 'invalid_credentials'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isAuthenticated() {
|
public function isAuthenticated() {
|
||||||
if (!isset($_SESSION['auth_time']) || !isset($_SESSION['username'])) {
|
if (!isset($_SESSION['auth_time']) || !isset($_SESSION['user_id'])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vérifier si la session n'a pas expiré
|
|
||||||
$elapsed = time() - $_SESSION['auth_time'];
|
$elapsed = time() - $_SESSION['auth_time'];
|
||||||
if ($elapsed > $this->config['session_duration']) {
|
if ($elapsed > $this->config['security']['session_duration']) {
|
||||||
$this->logout();
|
$this->logout();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -24,36 +66,25 @@ class Auth {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function login($username, $password) {
|
public function hasPermission($action) {
|
||||||
if (!isset($this->config['users'][$username])) {
|
if (!$this->isAuthenticated()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->config['users'][$username]['password'] === $password) {
|
$role = $_SESSION['role'];
|
||||||
$_SESSION['auth_time'] = time();
|
return isset($this->config['roles'][$role][$action]) &&
|
||||||
$_SESSION['username'] = $username;
|
$this->config['roles'][$role][$action];
|
||||||
$_SESSION['user_description'] = $this->config['users'][$username]['description'];
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function logout() {
|
public function logout() {
|
||||||
session_destroy();
|
if (isset($_SESSION['user_id'])) {
|
||||||
}
|
$this->db->logActivity($_SESSION['user_id'], 'logout');
|
||||||
|
|
||||||
public function getCurrentUser() {
|
|
||||||
if ($this->isAuthenticated()) {
|
|
||||||
return [
|
|
||||||
'username' => $_SESSION['username'],
|
|
||||||
'description' => $_SESSION['user_description']
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
return null;
|
session_destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Point d'entrée API pour l'authentification
|
// Point d'entrée API
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
header('Content-Type: application/json');
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
@ -64,15 +95,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
switch ($data['action']) {
|
switch ($data['action']) {
|
||||||
case 'login':
|
case 'login':
|
||||||
if (isset($data['username']) && isset($data['password'])) {
|
if (isset($data['username']) && isset($data['password'])) {
|
||||||
$success = $auth->login($data['username'], $data['password']);
|
$result = $auth->login($data['username'], $data['password']);
|
||||||
if ($success) {
|
echo json_encode($result);
|
||||||
$user = $auth->getCurrentUser();
|
|
||||||
echo json_encode(['success' => true, 'user' => $user]);
|
|
||||||
} else {
|
|
||||||
echo json_encode(['success' => false, 'error' => 'Identifiants incorrects']);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
echo json_encode(['success' => false, 'error' => 'Identifiants manquants']);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -82,11 +106,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'check':
|
case 'check':
|
||||||
$isAuthenticated = $auth->isAuthenticated();
|
|
||||||
$user = $isAuthenticated ? $auth->getCurrentUser() : null;
|
|
||||||
echo json_encode([
|
echo json_encode([
|
||||||
'authenticated' => $isAuthenticated,
|
'authenticated' => $auth->isAuthenticated(),
|
||||||
'user' => $user
|
'user' => $auth->isAuthenticated() ? [
|
||||||
|
'username' => $_SESSION['username'],
|
||||||
|
'role' => $_SESSION['role'],
|
||||||
|
'description' => $_SESSION['description']
|
||||||
|
] : null
|
||||||
]);
|
]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
45
config.php
45
config.php
@ -1,21 +1,36 @@
|
|||||||
<?php
|
<?php
|
||||||
// config.php
|
// config.php
|
||||||
return [
|
return [
|
||||||
'users' => [
|
'db' => [
|
||||||
'admin' => [
|
'path' => __DIR__ . '/database.sqlite'
|
||||||
'password' => 'votre_mot_de_passe_admin', // À changer !
|
|
||||||
'description' => 'Administrateur'
|
|
||||||
],
|
|
||||||
'user1' => [
|
|
||||||
'password' => 'votre_mot_de_passe_user1', // À changer !
|
|
||||||
'description' => 'Utilisateur 1'
|
|
||||||
],
|
|
||||||
'invite' => [
|
|
||||||
'password' => 'votre_mot_de_passe_invite', // À changer !
|
|
||||||
'description' => 'Invité'
|
|
||||||
]
|
|
||||||
],
|
],
|
||||||
'session_duration' => 3600, // Durée de la session en secondes (1 heure)
|
'security' => [
|
||||||
// Vous pouvez ajouter autant d'utilisateurs que nécessaire
|
'session_duration' => 3600,
|
||||||
|
'max_login_attempts' => 3,
|
||||||
|
'attempt_window' => 1800 // 30 minutes
|
||||||
|
],
|
||||||
|
'roles' => [
|
||||||
|
'admin' => [
|
||||||
|
'upload' => true,
|
||||||
|
'download' => true,
|
||||||
|
'delete' => true,
|
||||||
|
'rename' => true,
|
||||||
|
'view_logs' => true
|
||||||
|
],
|
||||||
|
'user' => [
|
||||||
|
'upload' => true,
|
||||||
|
'download' => true,
|
||||||
|
'delete' => false,
|
||||||
|
'rename' => false,
|
||||||
|
'view_logs' => false
|
||||||
|
],
|
||||||
|
'visitor' => [
|
||||||
|
'upload' => false,
|
||||||
|
'download' => true,
|
||||||
|
'delete' => false,
|
||||||
|
'rename' => false,
|
||||||
|
'view_logs' => false
|
||||||
|
]
|
||||||
|
]
|
||||||
];
|
];
|
||||||
?>
|
?>
|
||||||
|
111
database.php
Normal file
111
database.php
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
<?php
|
||||||
|
// Database.php
|
||||||
|
class Database {
|
||||||
|
private $db;
|
||||||
|
private static $instance = null;
|
||||||
|
|
||||||
|
private function __construct() {
|
||||||
|
$config = require 'config.php';
|
||||||
|
$this->db = new SQLite3($config['db']['path']);
|
||||||
|
$this->db->enableExceptions(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getInstance() {
|
||||||
|
if (self::$instance === null) {
|
||||||
|
self::$instance = new self();
|
||||||
|
}
|
||||||
|
return self::$instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function logActivity($userId, $actionType, $details = '') {
|
||||||
|
$stmt = $this->db->prepare('
|
||||||
|
INSERT INTO activity_logs (user_id, action_type, details, ip_address)
|
||||||
|
VALUES (:user_id, :action_type, :details, :ip)
|
||||||
|
');
|
||||||
|
|
||||||
|
$stmt->bindValue(':user_id', $userId, SQLITE3_INTEGER);
|
||||||
|
$stmt->bindValue(':action_type', $actionType, SQLITE3_TEXT);
|
||||||
|
$stmt->bindValue(':details', $details, SQLITE3_TEXT);
|
||||||
|
$stmt->bindValue(':ip', $_SERVER['REMOTE_ADDR'], SQLITE3_TEXT);
|
||||||
|
|
||||||
|
return $stmt->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getActivityLogs($filters = []) {
|
||||||
|
$query = '
|
||||||
|
SELECT
|
||||||
|
al.*,
|
||||||
|
u.username,
|
||||||
|
u.role
|
||||||
|
FROM activity_logs al
|
||||||
|
LEFT JOIN users u ON al.user_id = u.id
|
||||||
|
WHERE 1=1
|
||||||
|
';
|
||||||
|
|
||||||
|
$params = [];
|
||||||
|
|
||||||
|
if (!empty($filters['action_type'])) {
|
||||||
|
$query .= ' AND action_type = :action_type';
|
||||||
|
$params[':action_type'] = $filters['action_type'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($filters['date_from'])) {
|
||||||
|
$query .= ' AND created_at >= :date_from';
|
||||||
|
$params[':date_from'] = $filters['date_from'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($filters['date_to'])) {
|
||||||
|
$query .= ' AND created_at <= :date_to';
|
||||||
|
$params[':date_to'] = $filters['date_to'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$query .= ' ORDER BY created_at ' .
|
||||||
|
(!empty($filters['order']) && $filters['order'] === 'asc' ? 'ASC' : 'DESC');
|
||||||
|
|
||||||
|
$stmt = $this->db->prepare($query);
|
||||||
|
|
||||||
|
foreach ($params as $key => $value) {
|
||||||
|
$stmt->bindValue($key, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $stmt->execute();
|
||||||
|
$logs = [];
|
||||||
|
|
||||||
|
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
$logs[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $logs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function checkLoginAttempts($username) {
|
||||||
|
$config = require 'config.php';
|
||||||
|
$window = $config['security']['attempt_window'];
|
||||||
|
|
||||||
|
$stmt = $this->db->prepare('
|
||||||
|
SELECT COUNT(*) as attempts
|
||||||
|
FROM login_attempts
|
||||||
|
WHERE username = :username
|
||||||
|
AND attempt_time > datetime("now", "-' . $window . ' seconds")
|
||||||
|
');
|
||||||
|
|
||||||
|
$stmt->bindValue(':username', $username, SQLITE3_TEXT);
|
||||||
|
$result = $stmt->execute();
|
||||||
|
$row = $result->fetchArray();
|
||||||
|
|
||||||
|
return $row['attempts'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function logLoginAttempt($username) {
|
||||||
|
$stmt = $this->db->prepare('
|
||||||
|
INSERT INTO login_attempts (username, ip_address)
|
||||||
|
VALUES (:username, :ip)
|
||||||
|
');
|
||||||
|
|
||||||
|
$stmt->bindValue(':username', $username, SQLITE3_TEXT);
|
||||||
|
$stmt->bindValue(':ip', $_SERVER['REMOTE_ADDR'], SQLITE3_TEXT);
|
||||||
|
|
||||||
|
return $stmt->execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
30
database.sql
Normal file
30
database.sql
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
-- schema.sql
|
||||||
|
CREATE TABLE users (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
username VARCHAR(50) UNIQUE NOT NULL,
|
||||||
|
password_hash VARCHAR(255) NOT NULL,
|
||||||
|
role VARCHAR(20) NOT NULL CHECK (role IN ('admin', 'user', 'visitor')),
|
||||||
|
description TEXT,
|
||||||
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE login_attempts (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
ip_address VARCHAR(45) NOT NULL,
|
||||||
|
attempt_time DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
username VARCHAR(50)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE activity_logs (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
user_id INTEGER,
|
||||||
|
action_type VARCHAR(20) NOT NULL CHECK (action_type IN ('login', 'logout', 'upload', 'download', 'delete', 'rename')),
|
||||||
|
details TEXT,
|
||||||
|
ip_address VARCHAR(45),
|
||||||
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Insertion d'un utilisateur admin par défaut (mot de passe: admin123)
|
||||||
|
INSERT INTO users (username, password_hash, role, description)
|
||||||
|
VALUES ('admin', '$2y$10$YourHashedPasswordHere', 'admin', 'Administrateur principal');
|
Loading…
x
Reference in New Issue
Block a user