amélioration de la gestion utilisateurs (partie 1)
This commit is contained in:
parent
51c7456ac0
commit
a7ee569fff
98
auth.php
98
auth.php
@ -1,22 +1,64 @@
|
||||
<?php
|
||||
// auth.php
|
||||
session_start();
|
||||
require_once 'Database.php';
|
||||
|
||||
class Auth {
|
||||
private $config;
|
||||
private $db;
|
||||
|
||||
public function __construct() {
|
||||
$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() {
|
||||
if (!isset($_SESSION['auth_time']) || !isset($_SESSION['username'])) {
|
||||
if (!isset($_SESSION['auth_time']) || !isset($_SESSION['user_id'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Vérifier si la session n'a pas expiré
|
||||
$elapsed = time() - $_SESSION['auth_time'];
|
||||
if ($elapsed > $this->config['session_duration']) {
|
||||
if ($elapsed > $this->config['security']['session_duration']) {
|
||||
$this->logout();
|
||||
return false;
|
||||
}
|
||||
@ -24,36 +66,25 @@ class Auth {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function login($username, $password) {
|
||||
if (!isset($this->config['users'][$username])) {
|
||||
public function hasPermission($action) {
|
||||
if (!$this->isAuthenticated()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->config['users'][$username]['password'] === $password) {
|
||||
$_SESSION['auth_time'] = time();
|
||||
$_SESSION['username'] = $username;
|
||||
$_SESSION['user_description'] = $this->config['users'][$username]['description'];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
$role = $_SESSION['role'];
|
||||
return isset($this->config['roles'][$role][$action]) &&
|
||||
$this->config['roles'][$role][$action];
|
||||
}
|
||||
|
||||
public function logout() {
|
||||
if (isset($_SESSION['user_id'])) {
|
||||
$this->db->logActivity($_SESSION['user_id'], 'logout');
|
||||
}
|
||||
session_destroy();
|
||||
}
|
||||
|
||||
public function getCurrentUser() {
|
||||
if ($this->isAuthenticated()) {
|
||||
return [
|
||||
'username' => $_SESSION['username'],
|
||||
'description' => $_SESSION['user_description']
|
||||
];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Point d'entrée API pour l'authentification
|
||||
// Point d'entrée API
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
header('Content-Type: application/json');
|
||||
|
||||
@ -64,15 +95,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
switch ($data['action']) {
|
||||
case 'login':
|
||||
if (isset($data['username']) && isset($data['password'])) {
|
||||
$success = $auth->login($data['username'], $data['password']);
|
||||
if ($success) {
|
||||
$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']);
|
||||
$result = $auth->login($data['username'], $data['password']);
|
||||
echo json_encode($result);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -82,11 +106,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
break;
|
||||
|
||||
case 'check':
|
||||
$isAuthenticated = $auth->isAuthenticated();
|
||||
$user = $isAuthenticated ? $auth->getCurrentUser() : null;
|
||||
echo json_encode([
|
||||
'authenticated' => $isAuthenticated,
|
||||
'user' => $user
|
||||
'authenticated' => $auth->isAuthenticated(),
|
||||
'user' => $auth->isAuthenticated() ? [
|
||||
'username' => $_SESSION['username'],
|
||||
'role' => $_SESSION['role'],
|
||||
'description' => $_SESSION['description']
|
||||
] : null
|
||||
]);
|
||||
break;
|
||||
}
|
||||
|
39
config.php
39
config.php
@ -1,21 +1,36 @@
|
||||
<?php
|
||||
// config.php
|
||||
return [
|
||||
'users' => [
|
||||
'db' => [
|
||||
'path' => __DIR__ . '/database.sqlite'
|
||||
],
|
||||
'security' => [
|
||||
'session_duration' => 3600,
|
||||
'max_login_attempts' => 3,
|
||||
'attempt_window' => 1800 // 30 minutes
|
||||
],
|
||||
'roles' => [
|
||||
'admin' => [
|
||||
'password' => 'votre_mot_de_passe_admin', // À changer !
|
||||
'description' => 'Administrateur'
|
||||
'upload' => true,
|
||||
'download' => true,
|
||||
'delete' => true,
|
||||
'rename' => true,
|
||||
'view_logs' => true
|
||||
],
|
||||
'user1' => [
|
||||
'password' => 'votre_mot_de_passe_user1', // À changer !
|
||||
'description' => 'Utilisateur 1'
|
||||
'user' => [
|
||||
'upload' => true,
|
||||
'download' => true,
|
||||
'delete' => false,
|
||||
'rename' => false,
|
||||
'view_logs' => false
|
||||
],
|
||||
'invite' => [
|
||||
'password' => 'votre_mot_de_passe_invite', // À changer !
|
||||
'description' => 'Invité'
|
||||
'visitor' => [
|
||||
'upload' => false,
|
||||
'download' => true,
|
||||
'delete' => false,
|
||||
'rename' => false,
|
||||
'view_logs' => false
|
||||
]
|
||||
]
|
||||
],
|
||||
'session_duration' => 3600, // Durée de la session en secondes (1 heure)
|
||||
// Vous pouvez ajouter autant d'utilisateurs que nécessaire
|
||||
];
|
||||
?>
|
||||
|
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