Skip to content

Commit 9919096

Browse files
committed
refactor(router): enhance role-based access control
- Improve readability and maintainability of RBAC logic - Implement single source of truth for top-level route paths - Redirect unauthorized users based on role permissions
1 parent b345cf8 commit 9919096

File tree

1 file changed

+31
-10
lines changed

1 file changed

+31
-10
lines changed

lib/router/router.dart

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,24 +86,45 @@ GoRouter createRouter({
8686

8787
// --- Role-Based Access Control (RBAC) ---
8888
final userRole = context.read<AppBloc>().state.user?.dashboardRole;
89-
final destinationRouteName = state.topRoute?.name;
9089

91-
// Allow navigation if role is not yet determined or route is unknown.
92-
if (userRole == null || destinationRouteName == null) {
90+
// Allow navigation if the user role isn't determined yet.
91+
if (userRole == null) {
9392
return null;
9493
}
9594

96-
final allowedRoutes = routePermissions[userRole];
95+
// A local map to resolve top-level route names to their base paths.
96+
// This is the single source for this mapping within the redirect logic.
97+
const topLevelPaths = {
98+
Routes.overviewName: Routes.overview,
99+
Routes.contentManagementName: Routes.contentManagement,
100+
Routes.userManagementName: Routes.userManagement,
101+
Routes.appConfigurationName: Routes.appConfiguration,
102+
};
97103

98-
// Check if the user is trying to access a route they are not
99-
// permitted to view.
104+
// Get the set of authorized route *names* for the user's role from
105+
// the single source of truth: route_permissions.dart.
106+
final allowedRouteNames = routePermissions[userRole] ?? {};
107+
108+
// Convert the allowed route names into a list of their base paths.
109+
final authorizedPaths = allowedRouteNames
110+
.map((name) => topLevelPaths[name])
111+
.whereType<
112+
String
113+
>() // Filter out any nulls if a name is not in the map.
114+
.toList();
115+
116+
// Check if the destination path starts with any of the authorized base
117+
// paths, or if it's the universally accessible settings page.
100118
final isAuthorized =
101-
allowedRoutes?.contains(destinationRouteName) ?? false;
119+
authorizedPaths.any(
120+
currentLocation.startsWith,
121+
) ||
122+
currentLocation.startsWith(Routes.settings);
102123

103-
// Universally allowed routes like 'settings' are exempt from this check.
104-
if (!isAuthorized && destinationRouteName != Routes.settingsName) {
124+
if (!isAuthorized) {
105125
print(
106-
' Action: Unauthorized access to "$destinationRouteName". '
126+
' Action: Unauthorized access to "$currentLocation" for role '
127+
'$userRole. Authorized base paths: $authorizedPaths. '
107128
'Redirecting to $overviewPath.',
108129
);
109130
// Redirect unauthorized users to the overview page. This is a safe

0 commit comments

Comments
 (0)