mis a jour gestion d'utilisateur
This commit is contained in:
parent
2f1b40873e
commit
d41936441c
@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:youmazgestion/Views/RoleListPage.dart';
|
||||
import 'package:youmazgestion/Views/historique.dart';
|
||||
import 'package:youmazgestion/Views/addProduct.dart';
|
||||
import 'package:youmazgestion/Views/bilanMois.dart';
|
||||
@ -50,8 +51,21 @@ class CustomDrawer extends StatelessWidget {
|
||||
leading: const Icon(Icons.home),
|
||||
iconColor: Colors.lightBlueAccent,
|
||||
title: const Text("Accueil"),
|
||||
onTap: () {
|
||||
Get.to(const AccueilPage());
|
||||
onTap: () async {
|
||||
bool hasPermission = await userController.hasPermission('view', '/accueil');
|
||||
if (hasPermission) {
|
||||
Get.to(const AccueilPage());
|
||||
} else {
|
||||
Get.snackbar(
|
||||
"Accès refusé",
|
||||
"Vous n'avez pas les droits pour accéder à cette page",
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
icon: const Icon(Icons.error),
|
||||
duration: const Duration(seconds: 3),
|
||||
snackPosition: SnackPosition.TOP,
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
@ -59,7 +73,7 @@ class CustomDrawer extends StatelessWidget {
|
||||
iconColor: Colors.green,
|
||||
title: const Text("Ajouter un utilisateur"),
|
||||
onTap: () async {
|
||||
bool hasPermission = await userController.hasAnyPermission(['create']);
|
||||
bool hasPermission = await userController.hasPermission('create', '/ajouter-utilisateur');
|
||||
if (hasPermission) {
|
||||
Get.to(const RegistrationPage());
|
||||
} else {
|
||||
@ -80,7 +94,7 @@ class CustomDrawer extends StatelessWidget {
|
||||
iconColor: const Color.fromARGB(255, 4, 54, 95),
|
||||
title: const Text("Modifier/Supprimer un utilisateur"),
|
||||
onTap: () async {
|
||||
bool hasPermission = await userController.hasAnyPermission(['update', 'delete']);
|
||||
bool hasPermission = await userController.hasPermission('update', '/modifier-utilisateur');
|
||||
if (hasPermission) {
|
||||
Get.to(const ListUserPage());
|
||||
} else {
|
||||
@ -101,7 +115,7 @@ class CustomDrawer extends StatelessWidget {
|
||||
iconColor: Colors.indigoAccent,
|
||||
title: const Text("Ajouter un produit"),
|
||||
onTap: () async {
|
||||
bool hasPermission = await userController.hasAnyPermission(['create']);
|
||||
bool hasPermission = await userController.hasPermission('create', '/ajouter-produit');
|
||||
if (hasPermission) {
|
||||
Get.to(const AddProductPage());
|
||||
} else {
|
||||
@ -122,7 +136,7 @@ class CustomDrawer extends StatelessWidget {
|
||||
iconColor: Colors.redAccent,
|
||||
title: const Text("Modifier/Supprimer un produit"),
|
||||
onTap: () async {
|
||||
bool hasPermission = await userController.hasAnyPermission(['update', 'delete']);
|
||||
bool hasPermission = await userController.hasPermission('update', '/modifier-produit');
|
||||
if (hasPermission) {
|
||||
Get.to(GestionProduit());
|
||||
} else {
|
||||
@ -142,7 +156,7 @@ class CustomDrawer extends StatelessWidget {
|
||||
leading: const Icon(Icons.bar_chart),
|
||||
title: const Text("Bilan"),
|
||||
onTap: () async {
|
||||
bool hasPermission = await userController.hasAnyPermission(['read']);
|
||||
bool hasPermission = await userController.hasPermission('read', '/bilan');
|
||||
if (hasPermission) {
|
||||
Get.to(const BilanMois());
|
||||
} else {
|
||||
@ -162,12 +176,14 @@ class CustomDrawer extends StatelessWidget {
|
||||
leading: const Icon(Icons.warning_amber),
|
||||
title: const Text("Gérer les rôles"),
|
||||
onTap: () async {
|
||||
bool hasPermission = await userController.hasAnyPermission(['update', 'delete','create']);
|
||||
bool hasPermission = await userController.hasPermission('admin', '/gerer-roles');
|
||||
if (hasPermission) {
|
||||
Get.to(const HandleUserRole());
|
||||
Get.to(const RoleListPage());
|
||||
print("permission accepted");
|
||||
} else {
|
||||
print("permission not accepted for" +userController.username);
|
||||
Get.snackbar(
|
||||
"Accès refusé",
|
||||
"Accès refusé ",
|
||||
"Vous n'avez pas les droits pour gérer les rôles",
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
@ -183,7 +199,7 @@ class CustomDrawer extends StatelessWidget {
|
||||
iconColor: Colors.blueAccent,
|
||||
title: const Text("Gestion de stock"),
|
||||
onTap: () async {
|
||||
bool hasPermission = await userController.hasAnyPermission(['update']);
|
||||
bool hasPermission = await userController.hasPermission('update', '/gestion-stock');
|
||||
if (hasPermission) {
|
||||
Get.to(const GestionStockPage());
|
||||
} else {
|
||||
|
||||
94
lib/Models/menu.dart
Normal file
94
lib/Models/menu.dart
Normal file
@ -0,0 +1,94 @@
|
||||
// Models/menu.dart
|
||||
class Menu {
|
||||
final int? id;
|
||||
final String title;
|
||||
final String icon;
|
||||
final String route;
|
||||
final int orderIndex;
|
||||
final bool isActive;
|
||||
final int? parentId;
|
||||
|
||||
Menu({
|
||||
this.id,
|
||||
required this.title,
|
||||
required this.icon,
|
||||
required this.route,
|
||||
this.orderIndex = 0,
|
||||
this.isActive = true,
|
||||
this.parentId,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'id': id,
|
||||
'title': title,
|
||||
'icon': icon,
|
||||
'route': route,
|
||||
'order_index': orderIndex,
|
||||
'is_active': isActive ? 1 : 0,
|
||||
'parent_id': parentId,
|
||||
};
|
||||
}
|
||||
|
||||
factory Menu.fromMap(Map<String, dynamic> map) {
|
||||
return Menu(
|
||||
id: map['id']?.toInt(),
|
||||
title: map['title'] ?? '',
|
||||
icon: map['icon'] ?? '',
|
||||
route: map['route'] ?? '',
|
||||
orderIndex: map['order_index']?.toInt() ?? 0,
|
||||
isActive: (map['is_active'] ?? 1) == 1,
|
||||
parentId: map['parent_id']?.toInt(),
|
||||
);
|
||||
}
|
||||
|
||||
Menu copyWith({
|
||||
int? id,
|
||||
String? title,
|
||||
String? icon,
|
||||
String? route,
|
||||
int? orderIndex,
|
||||
bool? isActive,
|
||||
int? parentId,
|
||||
}) {
|
||||
return Menu(
|
||||
id: id ?? this.id,
|
||||
title: title ?? this.title,
|
||||
icon: icon ?? this.icon,
|
||||
route: route ?? this.route,
|
||||
orderIndex: orderIndex ?? this.orderIndex,
|
||||
isActive: isActive ?? this.isActive,
|
||||
parentId: parentId ?? this.parentId,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Menu(id: $id, title: $title, icon: $icon, route: $route, orderIndex: $orderIndex, isActive: $isActive, parentId: $parentId)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other is Menu &&
|
||||
other.id == id &&
|
||||
other.title == title &&
|
||||
other.icon == icon &&
|
||||
other.route == route &&
|
||||
other.orderIndex == orderIndex &&
|
||||
other.isActive == isActive &&
|
||||
other.parentId == parentId;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return id.hashCode ^
|
||||
title.hashCode ^
|
||||
icon.hashCode ^
|
||||
route.hashCode ^
|
||||
orderIndex.hashCode ^
|
||||
isActive.hashCode ^
|
||||
parentId.hashCode;
|
||||
}
|
||||
}
|
||||
@ -26,6 +26,7 @@ class AppDatabase {
|
||||
_database = await _initDB('app_database.db');
|
||||
await _createDB(_database, 1);
|
||||
await insertDefaultPermissions();
|
||||
await insertDefaultMenus();
|
||||
await insertDefaultRoles();
|
||||
await insertDefaultSuperAdmin();
|
||||
}
|
||||
@ -36,13 +37,11 @@ class AppDatabase {
|
||||
|
||||
bool dbExists = await File(path).exists();
|
||||
if (!dbExists) {
|
||||
// Optionnel : copier depuis assets si vous avez une DB pré-remplie
|
||||
try {
|
||||
ByteData data = await rootBundle.load('assets/database/$filePath');
|
||||
List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
|
||||
await File(path).writeAsBytes(bytes);
|
||||
} catch (e) {
|
||||
// Si pas de fichier dans assets, on continue avec une DB vide
|
||||
print('Pas de fichier DB dans assets, création d\'une nouvelle DB');
|
||||
}
|
||||
}
|
||||
@ -54,7 +53,6 @@ class AppDatabase {
|
||||
final tables = await db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'");
|
||||
final tableNames = tables.map((row) => row['name'] as String).toList();
|
||||
|
||||
// Table des rôles
|
||||
if (!tableNames.contains('roles')) {
|
||||
await db.execute('''
|
||||
CREATE TABLE roles (
|
||||
@ -65,7 +63,6 @@ class AppDatabase {
|
||||
print("Table 'roles' créée.");
|
||||
}
|
||||
|
||||
// Table des permissions
|
||||
if (!tableNames.contains('permissions')) {
|
||||
await db.execute('''
|
||||
CREATE TABLE permissions (
|
||||
@ -76,7 +73,17 @@ class AppDatabase {
|
||||
print("Table 'permissions' créée.");
|
||||
}
|
||||
|
||||
// Table de liaison role_permissions
|
||||
if (!tableNames.contains('menu')) {
|
||||
await db.execute('''
|
||||
CREATE TABLE menu (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
route TEXT NOT NULL UNIQUE
|
||||
)
|
||||
''');
|
||||
print("Table 'menu' créée.");
|
||||
}
|
||||
|
||||
if (!tableNames.contains('role_permissions')) {
|
||||
await db.execute('''
|
||||
CREATE TABLE role_permissions (
|
||||
@ -90,7 +97,19 @@ class AppDatabase {
|
||||
print("Table 'role_permissions' créée.");
|
||||
}
|
||||
|
||||
// Table des utilisateurs
|
||||
if (!tableNames.contains('menu_permissions')) {
|
||||
await db.execute('''
|
||||
CREATE TABLE menu_permissions (
|
||||
menu_id INTEGER,
|
||||
permission_id INTEGER,
|
||||
PRIMARY KEY (menu_id, permission_id),
|
||||
FOREIGN KEY (menu_id) REFERENCES menu(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (permission_id) REFERENCES permissions(id) ON DELETE CASCADE
|
||||
)
|
||||
''');
|
||||
print("Table 'menu_permissions' créée.");
|
||||
}
|
||||
|
||||
if (!tableNames.contains('users')) {
|
||||
await db.execute('''
|
||||
CREATE TABLE users (
|
||||
@ -106,9 +125,22 @@ class AppDatabase {
|
||||
''');
|
||||
print("Table 'users' créée.");
|
||||
}
|
||||
}
|
||||
if (!tableNames.contains('role_menu_permissions')) {
|
||||
await db.execute('''
|
||||
CREATE TABLE role_menu_permissions (
|
||||
role_id INTEGER,
|
||||
menu_id INTEGER,
|
||||
permission_id INTEGER,
|
||||
PRIMARY KEY (role_id, menu_id, permission_id),
|
||||
FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (menu_id) REFERENCES menu(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (permission_id) REFERENCES permissions(id) ON DELETE CASCADE
|
||||
)
|
||||
''');
|
||||
print("Table 'role_menu_permissions' créée.");
|
||||
}
|
||||
|
||||
// ========== INSERTION DES DONNÉES PAR DÉFAUT ==========
|
||||
}
|
||||
|
||||
Future<void> insertDefaultPermissions() async {
|
||||
final db = await database;
|
||||
@ -123,93 +155,142 @@ class AppDatabase {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> insertDefaultRoles() async {
|
||||
Future<void> insertDefaultMenus() async {
|
||||
final db = await database;
|
||||
final existingRoles = await db.query('roles');
|
||||
|
||||
if (existingRoles.isEmpty) {
|
||||
// Créer le rôle Super Admin
|
||||
int superAdminRoleId = await db.insert('roles', {'designation': 'Super Admin'});
|
||||
|
||||
// Créer d'autres rôles de base
|
||||
int adminRoleId = await db.insert('roles', {'designation': 'Admin'});
|
||||
int userRoleId = await db.insert('roles', {'designation': 'User'});
|
||||
|
||||
// Assigner toutes les permissions au Super Admin
|
||||
final permissions = await db.query('permissions');
|
||||
for (var permission in permissions) {
|
||||
await db.insert('role_permissions', {
|
||||
'role_id': superAdminRoleId,
|
||||
'permission_id': permission['id'],
|
||||
});
|
||||
}
|
||||
|
||||
// Assigner quelques permissions à l'Admin
|
||||
final viewPermission = await db.query('permissions', where: 'name = ?', whereArgs: ['view']);
|
||||
final createPermission = await db.query('permissions', where: 'name = ?', whereArgs: ['create']);
|
||||
final updatePermission = await db.query('permissions', where: 'name = ?', whereArgs: ['update']);
|
||||
|
||||
if (viewPermission.isNotEmpty) {
|
||||
await db.insert('role_permissions', {
|
||||
'role_id': adminRoleId,
|
||||
'permission_id': viewPermission.first['id'],
|
||||
});
|
||||
}
|
||||
if (createPermission.isNotEmpty) {
|
||||
await db.insert('role_permissions', {
|
||||
'role_id': adminRoleId,
|
||||
'permission_id': createPermission.first['id'],
|
||||
});
|
||||
}
|
||||
if (updatePermission.isNotEmpty) {
|
||||
await db.insert('role_permissions', {
|
||||
'role_id': adminRoleId,
|
||||
'permission_id': updatePermission.first['id'],
|
||||
});
|
||||
}
|
||||
|
||||
// Assigner seulement la permission view à User
|
||||
if (viewPermission.isNotEmpty) {
|
||||
await db.insert('role_permissions', {
|
||||
'role_id': userRoleId,
|
||||
'permission_id': viewPermission.first['id'],
|
||||
});
|
||||
}
|
||||
|
||||
print("Rôles par défaut créés et permissions assignées");
|
||||
final existingMenus = await db.query('menu');
|
||||
|
||||
if (existingMenus.isEmpty) {
|
||||
await db.insert('menu', {'name': 'Accueil', 'route': '/accueil'});
|
||||
await db.insert('menu', {'name': 'Ajouter un utilisateur', 'route': '/ajouter-utilisateur'});
|
||||
await db.insert('menu', {'name': 'Modifier/Supprimer un utilisateur', 'route': '/modifier-utilisateur'});
|
||||
await db.insert('menu', {'name': 'Ajouter un produit', 'route': '/ajouter-produit'});
|
||||
await db.insert('menu', {'name': 'Modifier/Supprimer un produit', 'route': '/modifier-produit'});
|
||||
await db.insert('menu', {'name': 'Bilan', 'route': '/bilan'});
|
||||
await db.insert('menu', {'name': 'Gérer les rôles', 'route': '/gerer-roles'});
|
||||
await db.insert('menu', {'name': 'Gestion de stock', 'route': '/gestion-stock'});
|
||||
await db.insert('menu', {'name': 'Historique', 'route': '/historique'});
|
||||
await db.insert('menu', {'name': 'Déconnexion', 'route': '/deconnexion'});
|
||||
print("Menus par défaut insérés");
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> insertDefaultRoles() async {
|
||||
final db = await database;
|
||||
final existingRoles = await db.query('roles');
|
||||
|
||||
if (existingRoles.isEmpty) {
|
||||
int superAdminRoleId = await db.insert('roles', {'designation': 'Super Admin'});
|
||||
int adminRoleId = await db.insert('roles', {'designation': 'Admin'});
|
||||
int userRoleId = await db.insert('roles', {'designation': 'User'});
|
||||
|
||||
final permissions = await db.query('permissions');
|
||||
final menus = await db.query('menu');
|
||||
|
||||
// Assigner toutes les permissions à tous les menus pour le Super Admin
|
||||
for (var menu in menus) {
|
||||
for (var permission in permissions) {
|
||||
await db.insert('role_menu_permissions', {
|
||||
'role_id': superAdminRoleId,
|
||||
'menu_id': menu['id'],
|
||||
'permission_id': permission['id'],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Assigner quelques permissions à l'Admin et à l'User
|
||||
final viewPermission = await db.query('permissions', where: 'name = ?', whereArgs: ['view']);
|
||||
final createPermission = await db.query('permissions', where: 'name = ?', whereArgs: ['create']);
|
||||
final updatePermission = await db.query('permissions', where: 'name = ?', whereArgs: ['update']);
|
||||
|
||||
if (viewPermission.isNotEmpty) {
|
||||
await db.insert('role_menu_permissions', {
|
||||
'role_id': adminRoleId,
|
||||
'menu_id': 1, // Assurez-vous que l'ID du menu est correct
|
||||
'permission_id': viewPermission.first['id'],
|
||||
});
|
||||
await db.insert('role_menu_permissions', {
|
||||
'role_id': userRoleId,
|
||||
'menu_id': 1, // Assurez-vous que l'ID du menu est correct
|
||||
'permission_id': viewPermission.first['id'],
|
||||
});
|
||||
}
|
||||
|
||||
if (createPermission.isNotEmpty) {
|
||||
await db.insert('role_menu_permissions', {
|
||||
'role_id': adminRoleId,
|
||||
'menu_id': 1, // Assurez-vous que l'ID du menu est correct
|
||||
'permission_id': createPermission.first['id'],
|
||||
});
|
||||
}
|
||||
|
||||
if (updatePermission.isNotEmpty) {
|
||||
await db.insert('role_menu_permissions', {
|
||||
'role_id': adminRoleId,
|
||||
'menu_id': 1, // Assurez-vous que l'ID du menu est correct
|
||||
'permission_id': updatePermission.first['id'],
|
||||
});
|
||||
}
|
||||
|
||||
print("Rôles par défaut créés et permissions assignées");
|
||||
} else {
|
||||
// Si les rôles existent déjà, vérifier et ajouter les permissions manquantes pour le Super Admin
|
||||
final superAdminRole = await db.query('roles', where: 'designation = ?', whereArgs: ['Super Admin']);
|
||||
if (superAdminRole.isNotEmpty) {
|
||||
final superAdminRoleId = superAdminRole.first['id'] as int;
|
||||
final permissions = await db.query('permissions');
|
||||
final menus = await db.query('menu');
|
||||
|
||||
// Vérifier et ajouter les permissions manquantes pour le Super Admin
|
||||
for (var menu in menus) {
|
||||
for (var permission in permissions) {
|
||||
final existingPermission = await db.query(
|
||||
'role_menu_permissions',
|
||||
where: 'role_id = ? AND menu_id = ? AND permission_id = ?',
|
||||
whereArgs: [superAdminRoleId, menu['id'], permission['id']],
|
||||
);
|
||||
if (existingPermission.isEmpty) {
|
||||
await db.insert('role_menu_permissions', {
|
||||
'role_id': superAdminRoleId,
|
||||
'menu_id': menu['id'],
|
||||
'permission_id': permission['id'],
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print("Permissions manquantes ajoutées pour le Super Admin");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Future<void> insertDefaultSuperAdmin() async {
|
||||
final db = await database;
|
||||
|
||||
// Vérifier si un super admin existe déjà
|
||||
|
||||
final existingSuperAdmin = await db.rawQuery('''
|
||||
SELECT u.* FROM users u
|
||||
INNER JOIN roles r ON u.role_id = r.id
|
||||
WHERE r.designation = 'Super Admin'
|
||||
''');
|
||||
|
||||
|
||||
if (existingSuperAdmin.isEmpty) {
|
||||
// Récupérer l'ID du rôle Super Admin
|
||||
final superAdminRole = await db.query('roles',
|
||||
where: 'designation = ?',
|
||||
final superAdminRole = await db.query('roles',
|
||||
where: 'designation = ?',
|
||||
whereArgs: ['Super Admin']
|
||||
);
|
||||
|
||||
|
||||
if (superAdminRole.isNotEmpty) {
|
||||
final superAdminRoleId = superAdminRole.first['id'] as int;
|
||||
|
||||
// Créer l'utilisateur Super Admin
|
||||
|
||||
await db.insert('users', {
|
||||
'name': 'Super',
|
||||
'lastname': 'Admin',
|
||||
'email': 'superadmin@youmazgestion.com',
|
||||
'password': 'admin123', // CHANGEZ CE MOT DE PASSE !
|
||||
'password': 'admin123',
|
||||
'username': 'superadmin',
|
||||
'role_id': superAdminRoleId,
|
||||
});
|
||||
|
||||
|
||||
print("Super Admin créé avec succès !");
|
||||
print("Username: superadmin");
|
||||
print("Password: admin123");
|
||||
@ -220,8 +301,6 @@ class AppDatabase {
|
||||
}
|
||||
}
|
||||
|
||||
// ========== GESTION DES UTILISATEURS ==========
|
||||
|
||||
Future<int> createUser(Users user) async {
|
||||
final db = await database;
|
||||
return await db.insert('users', user.toMap());
|
||||
@ -247,7 +326,7 @@ class AppDatabase {
|
||||
final db = await database;
|
||||
final result = await db.rawQuery('''
|
||||
SELECT users.id
|
||||
FROM users
|
||||
FROM users
|
||||
WHERE users.username = ? AND users.password = ?
|
||||
''', [username, password]);
|
||||
return result.isNotEmpty;
|
||||
@ -256,9 +335,9 @@ class AppDatabase {
|
||||
Future<Users> getUser(String username) async {
|
||||
final db = await database;
|
||||
final result = await db.rawQuery('''
|
||||
SELECT users.*, roles.designation as role_name
|
||||
FROM users
|
||||
INNER JOIN roles ON users.role_id = roles.id
|
||||
SELECT users.*, roles.designation as role_name
|
||||
FROM users
|
||||
INNER JOIN roles ON users.role_id = roles.id
|
||||
WHERE users.username = ?
|
||||
''', [username]);
|
||||
|
||||
@ -273,8 +352,8 @@ class AppDatabase {
|
||||
final db = await database;
|
||||
final result = await db.rawQuery('''
|
||||
SELECT users.username, users.id, roles.designation as role_name, roles.id as role_id
|
||||
FROM users
|
||||
INNER JOIN roles ON users.role_id = roles.id
|
||||
FROM users
|
||||
INNER JOIN roles ON users.role_id = roles.id
|
||||
WHERE username = ? AND password = ?
|
||||
''', [username, password]);
|
||||
|
||||
@ -293,16 +372,14 @@ class AppDatabase {
|
||||
Future<List<Users>> getAllUsers() async {
|
||||
final db = await database;
|
||||
final result = await db.rawQuery('''
|
||||
SELECT users.*, roles.designation as role_name
|
||||
FROM users
|
||||
INNER JOIN roles ON users.role_id = roles.id
|
||||
SELECT users.*, roles.designation as role_name
|
||||
FROM users
|
||||
INNER JOIN roles ON users.role_id = roles.id
|
||||
ORDER BY users.id ASC
|
||||
''');
|
||||
return result.map((json) => Users.fromMap(json)).toList();
|
||||
}
|
||||
|
||||
// ========== GESTION DES RÔLES ==========
|
||||
|
||||
Future<int> createRole(Role role) async {
|
||||
final db = await database;
|
||||
return await db.insert('roles', role.toMap());
|
||||
@ -333,8 +410,6 @@ class AppDatabase {
|
||||
);
|
||||
}
|
||||
|
||||
// ========== GESTION DES PERMISSIONS ==========
|
||||
|
||||
Future<List<Permission>> getAllPermissions() async {
|
||||
final db = await database;
|
||||
final result = await db.query('permissions', orderBy: 'name ASC');
|
||||
@ -386,7 +461,22 @@ class AppDatabase {
|
||||
);
|
||||
}
|
||||
|
||||
// ========== MÉTHODES UTILITAIRES POUR LA SÉCURITÉ ==========
|
||||
Future<void> assignMenuPermission(int menuId, int permissionId) async {
|
||||
final db = await database;
|
||||
await db.insert('menu_permissions', {
|
||||
'menu_id': menuId,
|
||||
'permission_id': permissionId,
|
||||
}, conflictAlgorithm: ConflictAlgorithm.ignore);
|
||||
}
|
||||
|
||||
Future<void> removeMenuPermission(int menuId, int permissionId) async {
|
||||
final db = await database;
|
||||
await db.delete(
|
||||
'menu_permissions',
|
||||
where: 'menu_id = ? AND permission_id = ?',
|
||||
whereArgs: [menuId, permissionId],
|
||||
);
|
||||
}
|
||||
|
||||
Future<bool> isSuperAdmin(String username) async {
|
||||
final db = await database;
|
||||
@ -396,20 +486,18 @@ class AppDatabase {
|
||||
INNER JOIN roles r ON u.role_id = r.id
|
||||
WHERE u.username = ? AND r.designation = 'Super Admin'
|
||||
''', [username]);
|
||||
|
||||
|
||||
return (result.first['count'] as int) > 0;
|
||||
}
|
||||
|
||||
Future<void> changePassword(String username, String oldPassword, String newPassword) async {
|
||||
final db = await database;
|
||||
|
||||
// Vérifier l'ancien mot de passe
|
||||
|
||||
final isValidOldPassword = await verifyUser(username, oldPassword);
|
||||
if (!isValidOldPassword) {
|
||||
throw Exception('Ancien mot de passe incorrect');
|
||||
}
|
||||
|
||||
// Changer le mot de passe
|
||||
|
||||
await db.update(
|
||||
'users',
|
||||
{'password': newPassword},
|
||||
@ -418,7 +506,21 @@ class AppDatabase {
|
||||
);
|
||||
}
|
||||
|
||||
// ========== UTILITAIRES ==========
|
||||
Future<bool> hasPermission(String username, String permissionName, String menuRoute) async {
|
||||
final db = await database;
|
||||
final result = await db.rawQuery('''
|
||||
SELECT COUNT(*) as count
|
||||
FROM permissions p
|
||||
JOIN role_menu_permissions rmp ON p.id = rmp.permission_id
|
||||
JOIN roles r ON rmp.role_id = r.id
|
||||
JOIN users u ON u.role_id = r.id
|
||||
JOIN menu m ON m.route = ?
|
||||
WHERE u.username = ? AND p.name = ? AND rmp.menu_id = m.id
|
||||
''', [menuRoute, username, permissionName]);
|
||||
|
||||
return (result.first['count'] as int) > 0;
|
||||
}
|
||||
|
||||
|
||||
Future<void> close() async {
|
||||
if (_database.isOpen) {
|
||||
@ -426,52 +528,75 @@ class AppDatabase {
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> hasPermission(String username, String permissionName) async {
|
||||
final db = await database;
|
||||
final result = await db.rawQuery('''
|
||||
SELECT COUNT(*) as count
|
||||
FROM permissions p
|
||||
JOIN role_permissions rp ON p.id = rp.permission_id
|
||||
JOIN roles r ON rp.role_id = r.id
|
||||
JOIN users u ON u.role_id = r.id
|
||||
WHERE u.username = ? AND p.name = ?
|
||||
''', [username, permissionName]);
|
||||
|
||||
return (result.first['count'] as int) > 0;
|
||||
}
|
||||
|
||||
// ========== MÉTHODE DE DEBUG ==========
|
||||
|
||||
Future<void> printDatabaseInfo() async {
|
||||
final db = await database;
|
||||
|
||||
|
||||
print("=== INFORMATIONS DE LA BASE DE DONNÉES ===");
|
||||
|
||||
// Compter les utilisateurs
|
||||
|
||||
final userCount = await getUserCount();
|
||||
print("Nombre d'utilisateurs: $userCount");
|
||||
|
||||
// Lister tous les utilisateurs
|
||||
|
||||
final users = await getAllUsers();
|
||||
print("Utilisateurs:");
|
||||
for (var user in users) {
|
||||
print(" - ${user.username} (${user.name} ) - Email: ${user.email}");
|
||||
}
|
||||
|
||||
// Lister tous les rôles
|
||||
|
||||
final roles = await getRoles();
|
||||
print("Rôles:");
|
||||
for (var role in roles) {
|
||||
print(" - ${role.designation} (ID: ${role.id})");
|
||||
}
|
||||
|
||||
// Lister toutes les permissions
|
||||
|
||||
final permissions = await getAllPermissions();
|
||||
print("Permissions:");
|
||||
for (var permission in permissions) {
|
||||
print(" - ${permission.name} (ID: ${permission.id})");
|
||||
}
|
||||
|
||||
|
||||
print("=========================================");
|
||||
}
|
||||
|
||||
Future<List<Permission>> getPermissionsForRoleAndMenu(int roleId, int menuId) async {
|
||||
final db = await database;
|
||||
final result = await db.rawQuery('''
|
||||
SELECT p.id, p.name
|
||||
FROM permissions p
|
||||
JOIN role_menu_permissions rmp ON p.id = rmp.permission_id
|
||||
WHERE rmp.role_id = ? AND rmp.menu_id = ?
|
||||
ORDER BY p.name ASC
|
||||
''', [roleId, menuId]);
|
||||
|
||||
return result.map((map) => Permission.fromMap(map)).toList();
|
||||
}
|
||||
// Ajoutez cette méthode temporaire pour supprimer la DB corrompue
|
||||
Future<void> deleteDatabaseFile() async {
|
||||
final documentsDirectory = await getApplicationDocumentsDirectory();
|
||||
final path = join(documentsDirectory.path, 'app_database.db');
|
||||
final file = File(path);
|
||||
if (await file.exists()) {
|
||||
await file.delete();
|
||||
print("Base de données supprimée");
|
||||
}
|
||||
}
|
||||
Future<void> assignRoleMenuPermission(int roleId, int menuId, int permissionId) async {
|
||||
final db = await database;
|
||||
await db.insert('role_menu_permissions', {
|
||||
'role_id': roleId,
|
||||
'menu_id': menuId,
|
||||
'permission_id': permissionId,
|
||||
}, conflictAlgorithm: ConflictAlgorithm.ignore);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Future<void> removeRoleMenuPermission(int roleId, int menuId, int permissionId) async {
|
||||
final db = await database;
|
||||
await db.delete(
|
||||
'role_menu_permissions',
|
||||
where: 'role_id = ? AND menu_id = ? AND permission_id = ?',
|
||||
whereArgs: [roleId, menuId, permissionId],
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
215
lib/Views/RoleListPage.dart
Normal file
215
lib/Views/RoleListPage.dart
Normal file
@ -0,0 +1,215 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:youmazgestion/Components/app_bar.dart';
|
||||
import 'package:youmazgestion/Models/Permission.dart';
|
||||
import 'package:youmazgestion/Services/app_database.dart';
|
||||
import 'package:youmazgestion/Models/role.dart';
|
||||
import 'package:youmazgestion/Views/RolePermissionPage.dart';
|
||||
|
||||
class RoleListPage extends StatefulWidget {
|
||||
const RoleListPage({super.key});
|
||||
|
||||
@override
|
||||
State<RoleListPage> createState() => _RoleListPageState();
|
||||
}
|
||||
|
||||
class _RoleListPageState extends State<RoleListPage> {
|
||||
final db = AppDatabase.instance;
|
||||
final TextEditingController _roleController = TextEditingController();
|
||||
List<Role> roles = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadRoles();
|
||||
}
|
||||
|
||||
Future<void> _loadRoles() async {
|
||||
final roleList = await db.getRoles();
|
||||
setState(() {
|
||||
roles = roleList;
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _addRole() async {
|
||||
String designation = _roleController.text.trim();
|
||||
if (designation.isEmpty) return;
|
||||
|
||||
await db.createRole(Role(designation: designation));
|
||||
_roleController.clear();
|
||||
await _loadRoles();
|
||||
}
|
||||
|
||||
Future<void> _deleteRole(int roleId) async {
|
||||
await db.deleteRole(roleId);
|
||||
await _loadRoles();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: const CustomAppBar(title: "Gestion des rôles"),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
// Section d'ajout de rôle
|
||||
Card(
|
||||
elevation: 4,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
'Ajouter un nouveau rôle',
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _roleController,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Nom du rôle',
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 12, vertical: 12),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
ElevatedButton(
|
||||
onPressed: _addRole,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.blue,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
// padding: const EdgeInsets.symmetric(
|
||||
// horizontal: 20, vertical: 15),
|
||||
),
|
||||
|
||||
),
|
||||
child: const Text('Ajouter'),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
// Liste des rôles existants
|
||||
Expanded(
|
||||
child: Card(
|
||||
elevation: 4,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Liste des rôles',
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Expanded(
|
||||
child: roles.isEmpty
|
||||
? const Center(
|
||||
child: Text('Aucun rôle créé'),
|
||||
)
|
||||
: ListView.builder(
|
||||
itemCount: roles.length,
|
||||
itemBuilder: (context, index) {
|
||||
final role = roles[index];
|
||||
return Card(
|
||||
margin: const EdgeInsets.only(bottom: 8),
|
||||
elevation: 2,
|
||||
child: ListTile(
|
||||
title: Text(role.designation),
|
||||
trailing: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.edit,
|
||||
color: Colors.blue),
|
||||
onPressed: () {
|
||||
_navigateToRolePermissions(
|
||||
context, role);
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.delete,
|
||||
color: Colors.red),
|
||||
onPressed: () {
|
||||
_showDeleteDialog(role);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
onTap: () {
|
||||
_navigateToRolePermissions(
|
||||
context, role);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _navigateToRolePermissions(BuildContext context, Role role) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => RolePermissionsPage(role: role),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showDeleteDialog(Role role) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: const Text('Confirmer la suppression'),
|
||||
content: Text(
|
||||
'Êtes-vous sûr de vouloir supprimer le rôle "${role.designation}" ?'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
child: const Text('Annuler'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
Navigator.of(context).pop();
|
||||
await _deleteRole(role.id!);
|
||||
},
|
||||
child: const Text('Supprimer', style: TextStyle(color: Colors.red)),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
177
lib/Views/RolePermissionPage.dart
Normal file
177
lib/Views/RolePermissionPage.dart
Normal file
@ -0,0 +1,177 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:youmazgestion/Components/app_bar.dart';
|
||||
import 'package:youmazgestion/Models/Permission.dart';
|
||||
import 'package:youmazgestion/Services/app_database.dart';
|
||||
import 'package:youmazgestion/Models/role.dart';
|
||||
|
||||
class RolePermissionsPage extends StatefulWidget {
|
||||
final Role role;
|
||||
|
||||
const RolePermissionsPage({super.key, required this.role});
|
||||
|
||||
@override
|
||||
State<RolePermissionsPage> createState() => _RolePermissionsPageState();
|
||||
}
|
||||
|
||||
class _RolePermissionsPageState extends State<RolePermissionsPage> {
|
||||
final db = AppDatabase.instance;
|
||||
List<Permission> permissions = [];
|
||||
List<Map<String, dynamic>> menus = [];
|
||||
Map<int, Map<String, bool>> menuPermissionsMap = {};
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_initData();
|
||||
}
|
||||
|
||||
Future<void> _initData() async {
|
||||
final perms = await db.getAllPermissions();
|
||||
final menuList = await db.database.then((db) => db.query('menu'));
|
||||
|
||||
Map<int, Map<String, bool>> tempMenuPermissionsMap = {};
|
||||
|
||||
for (var menu in menuList) {
|
||||
final menuId = menu['id'] as int;
|
||||
final menuPerms = await db.getPermissionsForRoleAndMenu(
|
||||
widget.role.id!, menuId);
|
||||
|
||||
tempMenuPermissionsMap[menuId] = {
|
||||
for (var perm in perms)
|
||||
perm.name: menuPerms.any((mp) => mp.name == perm.name)
|
||||
};
|
||||
}
|
||||
|
||||
setState(() {
|
||||
permissions = perms;
|
||||
menus = menuList;
|
||||
menuPermissionsMap = tempMenuPermissionsMap;
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _onPermissionToggle(
|
||||
int menuId, String permission, bool enabled) async {
|
||||
final perm = permissions.firstWhere((p) => p.name == permission);
|
||||
|
||||
if (enabled) {
|
||||
await db.assignRoleMenuPermission(
|
||||
widget.role.id!, menuId, perm.id!);
|
||||
} else {
|
||||
await db.removeRoleMenuPermission(
|
||||
widget.role.id!, menuId, perm.id!);
|
||||
}
|
||||
|
||||
setState(() {
|
||||
menuPermissionsMap[menuId]![permission] = enabled;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(
|
||||
title: "Permissions - ${widget.role.designation}",
|
||||
// showBackButton: true,
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Gestion des permissions pour le rôle: ${widget.role.designation}',
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
const Text(
|
||||
'Sélectionnez les permissions pour chaque menu:',
|
||||
style: TextStyle(fontSize: 14, color: Colors.grey),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
if (permissions.isNotEmpty && menus.isNotEmpty)
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: menus.length,
|
||||
itemBuilder: (context, index) {
|
||||
final menu = menus[index];
|
||||
final menuId = menu['id'] as int;
|
||||
final menuName = menu['name'] as String;
|
||||
|
||||
return Card(
|
||||
margin: const EdgeInsets.only(bottom: 15),
|
||||
elevation: 3,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
menuName,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold, fontSize: 16),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Wrap(
|
||||
spacing: 10,
|
||||
runSpacing: 10,
|
||||
children: permissions.map((perm) {
|
||||
final isChecked = menuPermissionsMap[menuId]?[perm.name] ?? false;
|
||||
return FilterChip(
|
||||
label: perm.name,
|
||||
selected: isChecked,
|
||||
onSelected: (bool value) {
|
||||
_onPermissionToggle(menuId, perm.name, value);
|
||||
},
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
)
|
||||
else
|
||||
const Expanded(
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class FilterChip extends StatelessWidget {
|
||||
final String label;
|
||||
final bool selected;
|
||||
final ValueChanged<bool> onSelected;
|
||||
|
||||
const FilterChip({
|
||||
super.key,
|
||||
required this.label,
|
||||
required this.selected,
|
||||
required this.onSelected,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChoiceChip(
|
||||
label: Text(label),
|
||||
selected: selected,
|
||||
onSelected: onSelected,
|
||||
selectedColor: Colors.blue,
|
||||
labelStyle: TextStyle(
|
||||
color: selected ? Colors.white : Colors.black,
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:youmazgestion/Components/app_bar.dart';
|
||||
import 'package:youmazgestion/Models/Permission.dart';
|
||||
import 'package:youmazgestion/Services/app_database.dart';
|
||||
import 'package:youmazgestion/Models/role.dart';
|
||||
|
||||
@ -13,9 +14,10 @@ class HandleUserRole extends StatefulWidget {
|
||||
class _HandleUserRoleState extends State<HandleUserRole> {
|
||||
final db = AppDatabase.instance;
|
||||
|
||||
List<Map<String, dynamic>> roles = [];
|
||||
List<dynamic> permissions = [];
|
||||
Map<int, Map<String, bool>> rolePermissionsMap = {};
|
||||
List<Role> roles = [];
|
||||
List<Permission> permissions = [];
|
||||
List<Map<String, dynamic>> menus = [];
|
||||
Map<int, Map<int, Map<String, bool>>> roleMenuPermissionsMap = {};
|
||||
|
||||
final TextEditingController _roleController = TextEditingController();
|
||||
|
||||
@ -26,25 +28,32 @@ class _HandleUserRoleState extends State<HandleUserRole> {
|
||||
}
|
||||
|
||||
Future<void> _initData() async {
|
||||
final roleList = await db.database.then((db) => db.query('roles'));
|
||||
final roleList = await db.getRoles();
|
||||
final perms = await db.getAllPermissions();
|
||||
final menuList = await db.database.then((db) => db.query('menu'));
|
||||
|
||||
Map<int, Map<String, bool>> tempRolePermissionsMap = {};
|
||||
Map<int, Map<int, Map<String, bool>>> tempRoleMenuPermissionsMap = {};
|
||||
|
||||
for (var role in roleList) {
|
||||
final roleId = role['id'] as int;
|
||||
final rolePerms = await db.getPermissionsForRole(roleId);
|
||||
final roleId = role.id!;
|
||||
tempRoleMenuPermissionsMap[roleId] = {};
|
||||
|
||||
tempRolePermissionsMap[roleId] = {
|
||||
for (var perm in perms)
|
||||
perm.name: rolePerms.any((rp) => rp.name == perm.name)
|
||||
};
|
||||
for (var menu in menuList) {
|
||||
final menuId = menu['id'] as int;
|
||||
final menuPerms = await db.getPermissionsForRoleAndMenu(roleId, menuId);
|
||||
|
||||
tempRoleMenuPermissionsMap[roleId]![menuId] = {
|
||||
for (var perm in perms)
|
||||
perm.name: menuPerms.any((mp) => mp.name == perm.name)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
setState(() {
|
||||
roles = roleList;
|
||||
permissions = perms;
|
||||
rolePermissionsMap = tempRolePermissionsMap;
|
||||
menus = menuList;
|
||||
roleMenuPermissionsMap = tempRoleMenuPermissionsMap;
|
||||
});
|
||||
}
|
||||
|
||||
@ -57,17 +66,17 @@ class _HandleUserRoleState extends State<HandleUserRole> {
|
||||
await _initData();
|
||||
}
|
||||
|
||||
Future<void> _onPermissionToggle(int roleId, String permission, bool enabled) async {
|
||||
Future<void> _onPermissionToggle(int roleId, int menuId, String permission, bool enabled) async {
|
||||
final perm = permissions.firstWhere((p) => p.name == permission);
|
||||
|
||||
if (enabled) {
|
||||
await db.assignPermission(roleId, perm.id!);
|
||||
await db.assignRoleMenuPermission(roleId, menuId, perm.id!);
|
||||
} else {
|
||||
await db.removePermission(roleId, perm.id!);
|
||||
await db.removeRoleMenuPermission(roleId, menuId, perm.id!);
|
||||
}
|
||||
|
||||
setState(() {
|
||||
rolePermissionsMap[roleId]![permission] = enabled;
|
||||
roleMenuPermissionsMap[roleId]![menuId]![permission] = enabled;
|
||||
});
|
||||
}
|
||||
|
||||
@ -117,7 +126,7 @@ class _HandleUserRoleState extends State<HandleUserRole> {
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
// Tableau des rôles et permissions
|
||||
if (roles.isNotEmpty && permissions.isNotEmpty)
|
||||
if (roles.isNotEmpty && permissions.isNotEmpty && menus.isNotEmpty)
|
||||
Expanded(
|
||||
child: Card(
|
||||
elevation: 6,
|
||||
@ -132,38 +141,51 @@ class _HandleUserRoleState extends State<HandleUserRole> {
|
||||
constraints: BoxConstraints(
|
||||
minWidth: MediaQuery.of(context).size.width - 32,
|
||||
),
|
||||
child: DataTable(
|
||||
columnSpacing: 20,
|
||||
columns: [
|
||||
const DataColumn(
|
||||
label: Text(
|
||||
'Rôles',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
...permissions.map((perm) => DataColumn(
|
||||
label: Text(
|
||||
perm.name,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
)).toList(),
|
||||
],
|
||||
rows: roles.map((role) {
|
||||
final roleId = role['id'] as int;
|
||||
return DataRow(
|
||||
cells: [
|
||||
DataCell(Text(role['designation'] ?? '')),
|
||||
...permissions.map((perm) {
|
||||
final isChecked = rolePermissionsMap[roleId]?[perm.name] ?? false;
|
||||
return DataCell(
|
||||
Checkbox(
|
||||
value: isChecked,
|
||||
onChanged: (bool? value) {
|
||||
_onPermissionToggle(roleId, perm.name, value ?? false);
|
||||
},
|
||||
child: Column(
|
||||
children: menus.map((menu) {
|
||||
final menuId = menu['id'] as int;
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
menu['name'],
|
||||
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
|
||||
),
|
||||
DataTable(
|
||||
columnSpacing: 20,
|
||||
columns: [
|
||||
const DataColumn(
|
||||
label: Text(
|
||||
'Rôles',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
...permissions.map((perm) => DataColumn(
|
||||
label: Text(
|
||||
perm.name,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
)).toList(),
|
||||
],
|
||||
rows: roles.map((role) {
|
||||
final roleId = role.id!;
|
||||
return DataRow(
|
||||
cells: [
|
||||
DataCell(Text(role.designation)),
|
||||
...permissions.map((perm) {
|
||||
final isChecked = roleMenuPermissionsMap[roleId]?[menuId]?[perm.name] ?? false;
|
||||
return DataCell(
|
||||
Checkbox(
|
||||
value: isChecked,
|
||||
onChanged: (bool? value) {
|
||||
_onPermissionToggle(roleId, menuId, perm.name, value ?? false);
|
||||
},
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
],
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
],
|
||||
);
|
||||
}).toList(),
|
||||
@ -176,7 +198,7 @@ class _HandleUserRoleState extends State<HandleUserRole> {
|
||||
else
|
||||
const Expanded(
|
||||
child: Center(
|
||||
child: Text('Aucun rôle ou permission trouvé'),
|
||||
child: Text('Aucun rôle, permission ou menu trouvé'),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@ -129,7 +129,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||
print('ID: ${userCredentials['id']}');
|
||||
|
||||
// Sauvegarder dans le contrôleur
|
||||
userController.setUser(user);
|
||||
// userController.setUser(user);
|
||||
|
||||
// Sauvegarder dans SharedPreferences
|
||||
await saveUser(
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:youmazgestion/Models/users.dart';
|
||||
import 'package:youmazgestion/Services/app_database.dart';
|
||||
|
||||
@ -17,9 +18,33 @@ class UserController extends GetxController {
|
||||
String get lastname => _lastname.value;
|
||||
String get password => _password.value;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
loadUserData(); // Charger les données au démarrage
|
||||
}
|
||||
|
||||
// Charger les données depuis SharedPreferences
|
||||
Future<void> loadUserData() async {
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
_username.value = prefs.getString('username') ?? '';
|
||||
_email.value = prefs.getString('email') ?? '';
|
||||
_role.value = prefs.getString('role') ?? '';
|
||||
_name.value = prefs.getString('name') ?? '';
|
||||
_lastname.value = prefs.getString('lastname') ?? '';
|
||||
|
||||
print("Données chargées - Username: ${_username.value}");
|
||||
print("Role: ${_role.value}");
|
||||
} catch (e) {
|
||||
print('Erreur lors du chargement des données utilisateur: $e');
|
||||
}
|
||||
}
|
||||
|
||||
void setUser(Users user) {
|
||||
_username.value = user.username;
|
||||
print(_username.value);
|
||||
print("username " + _username.value);
|
||||
_email.value = user.email;
|
||||
print(_email.value);
|
||||
_role.value = user.role;
|
||||
@ -30,19 +55,73 @@ class UserController extends GetxController {
|
||||
print(_lastname.value);
|
||||
_password.value = user.password;
|
||||
print(_password.value);
|
||||
|
||||
// Sauvegarder dans SharedPreferences
|
||||
saveUserData();
|
||||
}
|
||||
|
||||
Future<bool> hasPermission(String permissionName) async {
|
||||
// Utilisez votre instance de AppDatabase pour vérifier la permission
|
||||
return await AppDatabase.instance.hasPermission(username, permissionName);
|
||||
}
|
||||
Future<bool> hasAnyPermission(List<String> permissionNames) async {
|
||||
for (String permissionName in permissionNames) {
|
||||
if (await hasPermission(permissionName)) {
|
||||
return true;
|
||||
// Sauvegarder les données dans SharedPreferences
|
||||
Future<void> saveUserData() async {
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
await prefs.setString('username', _username.value);
|
||||
await prefs.setString('email', _email.value);
|
||||
await prefs.setString('role', _role.value);
|
||||
await prefs.setString('name', _name.value);
|
||||
await prefs.setString('lastname', _lastname.value);
|
||||
|
||||
print("Données sauvegardées avec succès");
|
||||
} catch (e) {
|
||||
print('Erreur lors de la sauvegarde des données utilisateur: $e');
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
// Méthode pour vider les données utilisateur
|
||||
Future<void> clearUserData() async {
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
await prefs.remove('username');
|
||||
await prefs.remove('email');
|
||||
await prefs.remove('role');
|
||||
await prefs.remove('name');
|
||||
await prefs.remove('lastname');
|
||||
|
||||
// Vider les variables observables
|
||||
_username.value = '';
|
||||
_email.value = '';
|
||||
_role.value = '';
|
||||
_name.value = '';
|
||||
_lastname.value = '';
|
||||
_password.value = '';
|
||||
|
||||
print("Données utilisateur effacées");
|
||||
} catch (e) {
|
||||
print('Erreur lors de l\'effacement des données utilisateur: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> hasPermission(String permission, String route) async {
|
||||
try {
|
||||
if (_username.value.isEmpty) {
|
||||
print('Username vide, rechargement des données...');
|
||||
await loadUserData();
|
||||
}
|
||||
|
||||
return await AppDatabase.instance.hasPermission(username, permission, route);
|
||||
} catch (e) {
|
||||
print('Erreur vérification permission: $e');
|
||||
return false; // Sécurité : refuser l'accès en cas d'erreur
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> hasAnyPermission(List<String> permissionNames, String menuRoute) async {
|
||||
for (String permissionName in permissionNames) {
|
||||
if (await hasPermission(permissionName, menuRoute)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:youmazgestion/Services/app_database.dart';
|
||||
import 'package:youmazgestion/controller/userController.dart';
|
||||
import 'Services/productDatabase.dart';
|
||||
import 'my_app.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
@ -10,12 +11,14 @@ void main() async {
|
||||
|
||||
try {
|
||||
// Initialiser les bases de données une seule fois
|
||||
// await AppDatabase.instance.deleteDatabaseFile();
|
||||
|
||||
await ProductDatabase.instance.initDatabase();
|
||||
await AppDatabase.instance.initDatabase();
|
||||
|
||||
// Afficher les informations de la base (pour debug)
|
||||
await AppDatabase.instance.printDatabaseInfo();
|
||||
|
||||
Get.put(UserController()); // Ajoute ce code AVANT tout accès au UserController
|
||||
setupLogger();
|
||||
|
||||
runApp(const GetMaterialApp(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user