273 lines
7.4 KiB
Dart
273 lines
7.4 KiB
Dart
import 'dart:io';
|
|
import 'dart:convert';
|
|
import 'package:path_provider/path_provider.dart';
|
|
import 'package:bcrypt/bcrypt.dart';
|
|
import '../models/user.dart';
|
|
|
|
class UserService {
|
|
static const String _fileName = 'users.json';
|
|
|
|
// Obtenir le fichier JSON
|
|
Future<File> _getUserFile() async {
|
|
final directory = await getApplicationDocumentsDirectory();
|
|
return File('${directory.path}/$_fileName');
|
|
}
|
|
|
|
// Charger tous les utilisateurs
|
|
Future<List<User>> loadUsers() async {
|
|
try {
|
|
final file = await _getUserFile();
|
|
if (!await file.exists()) return [];
|
|
|
|
final contents = await file.readAsString();
|
|
if (contents.isEmpty) return [];
|
|
|
|
final List<dynamic> jsonList = json.decode(contents);
|
|
|
|
return jsonList.map((json) => User.fromMap(json)).toList();
|
|
} catch (e) {
|
|
print('Erreur lors du chargement des utilisateurs: $e');
|
|
return [];
|
|
}
|
|
}
|
|
|
|
// Sauvegarder tous les utilisateurs
|
|
Future<void> saveUsers(List<User> users) async {
|
|
try {
|
|
final file = await _getUserFile();
|
|
final jsonList = users.map((user) => user.toMap()).toList();
|
|
await file.writeAsString(json.encode(jsonList));
|
|
} catch (e) {
|
|
print('Erreur lors de la sauvegarde des utilisateurs: $e');
|
|
throw Exception('Erreur de sauvegarde');
|
|
}
|
|
}
|
|
|
|
// Ajouter un nouvel utilisateur
|
|
Future<bool> addUser(User user) async {
|
|
try {
|
|
final users = await loadUsers();
|
|
|
|
// Vérifier si l'email existe déjà
|
|
if (users.any((u) => u.email.toLowerCase() == user.email.toLowerCase())) {
|
|
return false; // Email déjà utilisé
|
|
}
|
|
|
|
// Générer un ID unique
|
|
final newUser = user.copyWith(
|
|
id: DateTime.now().millisecondsSinceEpoch.toString(),
|
|
);
|
|
|
|
users.add(newUser);
|
|
await saveUsers(users);
|
|
return true;
|
|
} catch (e) {
|
|
print('Erreur lors de l\'ajout de l\'utilisateur: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Authentifier un utilisateur avec bcrypt
|
|
Future<User?> authenticateUser(String email, String password) async {
|
|
try {
|
|
final users = await loadUsers();
|
|
|
|
// Trouver l'utilisateur par email (insensible à la casse)
|
|
User? user;
|
|
try {
|
|
user = users.firstWhere(
|
|
(u) => u.email.toLowerCase() == email.toLowerCase(),
|
|
);
|
|
} catch (e) {
|
|
return null; // Utilisateur non trouvé
|
|
}
|
|
|
|
// Vérifier le mot de passe avec bcrypt
|
|
if (BCrypt.checkpw(password, user.password)) {
|
|
return user;
|
|
}
|
|
|
|
return null; // Mot de passe incorrect
|
|
} catch (e) {
|
|
print('Erreur lors de l\'authentification: $e');
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// Vérifier si un email existe
|
|
Future<bool> emailExists(String email) async {
|
|
try {
|
|
final users = await loadUsers();
|
|
return users.any(
|
|
(user) => user.email.toLowerCase() == email.toLowerCase(),
|
|
);
|
|
} catch (e) {
|
|
print('Erreur lors de la vérification de l\'email: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Obtenir un utilisateur par ID
|
|
Future<User?> getUserById(String id) async {
|
|
try {
|
|
final users = await loadUsers();
|
|
return users.firstWhere((user) => user.id == id);
|
|
} catch (e) {
|
|
print('Utilisateur avec l\'ID $id non trouvé');
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// Obtenir un utilisateur par email
|
|
Future<User?> getUserByEmail(String email) async {
|
|
try {
|
|
final users = await loadUsers();
|
|
return users.firstWhere(
|
|
(user) => user.email.toLowerCase() == email.toLowerCase(),
|
|
);
|
|
} catch (e) {
|
|
print('Utilisateur avec l\'email $email non trouvé');
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// Mettre à jour un utilisateur
|
|
Future<bool> updateUser(User updatedUser) async {
|
|
try {
|
|
final users = await loadUsers();
|
|
final index = users.indexWhere((user) => user.id == updatedUser.id);
|
|
|
|
if (index != -1) {
|
|
users[index] = updatedUser;
|
|
await saveUsers(users);
|
|
return true;
|
|
}
|
|
return false; // Utilisateur non trouvé
|
|
} catch (e) {
|
|
print('Erreur lors de la mise à jour de l\'utilisateur: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Supprimer un utilisateur
|
|
Future<bool> deleteUser(String id) async {
|
|
try {
|
|
final users = await loadUsers();
|
|
final initialLength = users.length;
|
|
users.removeWhere((user) => user.id == id);
|
|
|
|
if (users.length < initialLength) {
|
|
await saveUsers(users);
|
|
return true;
|
|
}
|
|
return false; // Utilisateur non trouvé
|
|
} catch (e) {
|
|
print('Erreur lors de la suppression de l\'utilisateur: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Changer le mot de passe d'un utilisateur
|
|
Future<bool> changePassword(
|
|
String userId,
|
|
String oldPassword,
|
|
String newPassword,
|
|
) async {
|
|
try {
|
|
final users = await loadUsers();
|
|
final userIndex = users.indexWhere((user) => user.id == userId);
|
|
|
|
if (userIndex == -1) return false; // Utilisateur non trouvé
|
|
|
|
final user = users[userIndex];
|
|
|
|
// Vérifier l'ancien mot de passe
|
|
if (!BCrypt.checkpw(oldPassword, user.password)) {
|
|
return false; // Ancien mot de passe incorrect
|
|
}
|
|
|
|
// Hasher le nouveau mot de passe
|
|
final hashedNewPassword = BCrypt.hashpw(newPassword, BCrypt.gensalt());
|
|
|
|
// Mettre à jour l'utilisateur
|
|
users[userIndex] = user.copyWith(password: hashedNewPassword);
|
|
await saveUsers(users);
|
|
|
|
return true;
|
|
} catch (e) {
|
|
print('Erreur lors du changement de mot de passe: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Réinitialiser le mot de passe (pour la fonctionnalité "mot de passe oublié")
|
|
Future<bool> resetPassword(String email, String newPassword) async {
|
|
try {
|
|
final users = await loadUsers();
|
|
final userIndex = users.indexWhere(
|
|
(user) => user.email.toLowerCase() == email.toLowerCase(),
|
|
);
|
|
|
|
if (userIndex == -1) return false; // Utilisateur non trouvé
|
|
|
|
// Hasher le nouveau mot de passe
|
|
final hashedNewPassword = BCrypt.hashpw(newPassword, BCrypt.gensalt());
|
|
|
|
// Mettre à jour l'utilisateur
|
|
users[userIndex] = users[userIndex].copyWith(password: hashedNewPassword);
|
|
await saveUsers(users);
|
|
|
|
return true;
|
|
} catch (e) {
|
|
print('Erreur lors de la réinitialisation du mot de passe: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Obtenir le nombre total d'utilisateurs
|
|
Future<int> getUserCount() async {
|
|
try {
|
|
final users = await loadUsers();
|
|
return users.length;
|
|
} catch (e) {
|
|
print('Erreur lors du comptage des utilisateurs: $e');
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// Vider la base de données (utile pour les tests)
|
|
Future<void> clearAllUsers() async {
|
|
try {
|
|
await saveUsers([]);
|
|
} catch (e) {
|
|
print('Erreur lors du vidage de la base de données: $e');
|
|
}
|
|
}
|
|
|
|
// Méthode pour créer des utilisateurs de test
|
|
Future<void> createTestUsers() async {
|
|
try {
|
|
final testUsers = [
|
|
User(
|
|
nom: 'Dupont',
|
|
prenom: 'Jean',
|
|
email: 'jean.dupont@test.com',
|
|
password: BCrypt.hashpw('password123', BCrypt.gensalt()),
|
|
),
|
|
User(
|
|
nom: 'Martin',
|
|
prenom: 'Marie',
|
|
email: 'marie.martin@test.com',
|
|
password: BCrypt.hashpw('password123', BCrypt.gensalt()),
|
|
),
|
|
];
|
|
|
|
for (final user in testUsers) {
|
|
await addUser(user);
|
|
}
|
|
} catch (e) {
|
|
print('Erreur lors de la création des utilisateurs de test: $e');
|
|
}
|
|
}
|
|
}
|