118 lines
3.3 KiB
Dart
118 lines
3.3 KiB
Dart
import '../constants/enums.dart';
|
|
import '../errors/failure.dart';
|
|
import '../network/api_handler.dart';
|
|
|
|
/// Maps UI / route module keys to API permission module codes.
|
|
const Map<String, String> permissionModuleAliases = {
|
|
'master_data': 'MASTERS',
|
|
'masters': 'MASTERS',
|
|
'users': 'USERS',
|
|
'roles': 'ROLES',
|
|
'assets': 'ASSET',
|
|
'asset': 'ASSET',
|
|
'asset_categories': 'ASSET',
|
|
'asset_allocations': 'ASSET',
|
|
'asset_maintenance': 'ASSET',
|
|
'asset_disposal': 'ASSET',
|
|
'vendor': 'VENDOR',
|
|
'vendors': 'VENDOR',
|
|
'purchase_orders': 'PURCHASE_ORDER',
|
|
'purchase_order': 'PURCHASE_ORDER',
|
|
'grn': 'GRN',
|
|
};
|
|
|
|
/// Modules that are always visible in navigation (no API permission key).
|
|
const Set<String> alwaysVisibleMenuModules = {'dashboard'};
|
|
|
|
String normalizePermissionModule(String module) {
|
|
final normalized = module.trim().toLowerCase().replaceAll('-', '_');
|
|
return permissionModuleAliases[normalized] ?? normalized.toUpperCase();
|
|
}
|
|
|
|
List<String> permissionActionAliases(PermissionAction action) {
|
|
return switch (action) {
|
|
PermissionAction.read => const ['read', 'view'],
|
|
PermissionAction.update => const ['update', 'edit'],
|
|
PermissionAction.create => const ['create'],
|
|
PermissionAction.delete => const ['delete'],
|
|
PermissionAction.export => const ['export'],
|
|
PermissionAction.approve => const ['approve'],
|
|
};
|
|
}
|
|
|
|
bool hasPermission({
|
|
required List<String> userPermissions,
|
|
required String module,
|
|
required PermissionAction action,
|
|
}) {
|
|
if (userPermissions.contains('*')) return true;
|
|
|
|
final moduleKey = normalizePermissionModule(module);
|
|
final lowerModule = moduleKey.toLowerCase();
|
|
|
|
for (final actionAlias in permissionActionAliases(action)) {
|
|
final candidates = {
|
|
'$lowerModule.$actionAlias',
|
|
'$lowerModule:$actionAlias',
|
|
'$moduleKey:$actionAlias',
|
|
'$moduleKey:${actionAlias.toUpperCase()}',
|
|
'${module.trim().toUpperCase()}:$actionAlias',
|
|
'${module.trim().toUpperCase()}:${actionAlias.toUpperCase()}',
|
|
};
|
|
|
|
for (final key in candidates) {
|
|
if (userPermissions.contains(key)) return true;
|
|
}
|
|
}
|
|
|
|
final wildcards = {
|
|
'$lowerModule.*',
|
|
'$lowerModule:*',
|
|
'$moduleKey:*',
|
|
'${module.trim().toUpperCase()}:*',
|
|
};
|
|
|
|
for (final key in wildcards) {
|
|
if (userPermissions.contains(key)) return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool canSeeMenuModule({
|
|
required List<String> permissions,
|
|
required String module,
|
|
required UserRole role,
|
|
}) {
|
|
if (alwaysVisibleMenuModules.contains(module)) return true;
|
|
if (isSuperAdmin(role) || permissions.contains('*')) return true;
|
|
|
|
if (module == 'users') {
|
|
return hasPermission(
|
|
userPermissions: permissions,
|
|
module: 'users',
|
|
action: PermissionAction.read,
|
|
) ||
|
|
hasPermission(
|
|
userPermissions: permissions,
|
|
module: 'roles',
|
|
action: PermissionAction.read,
|
|
);
|
|
}
|
|
|
|
return hasPermission(
|
|
userPermissions: permissions,
|
|
module: module,
|
|
action: PermissionAction.read,
|
|
);
|
|
}
|
|
|
|
bool isSuperAdmin(UserRole role) => role == UserRole.superAdmin;
|
|
|
|
bool isAdmin(UserRole role) =>
|
|
role == UserRole.superAdmin || role == UserRole.companyAdmin;
|
|
|
|
String failureMessage(Failure failure) => failure.message;
|
|
|
|
bool isAccessDenied(Failure? failure) => isForbiddenFailure(failure);
|