Guard Runner

A guardian that protects against unauthorized access to routes and actions, as well as protects data viewing, based on the user's roles.

Features

  • Protect route against not authorized access
  • Verify a permission to perform an action
  • Show or hide an widget based on user's roles.

Installation

Open project's pubspec.yaml and add guard_runner as a dependency

dependencies:
  guard_runner: any

Usage

Setup roles, routes and isAdmin

First of all, it's need to call GuardRunner.setup to load all roles, routes and its respective roles.

import 'package:guard_runner/guard_runner.dart';
...
/// The all allowed roles
final List<String> roles = ['app_first_role', 'app_second_role', 'admin_role'];

/// The routes of app and it's respective roles
final rolesByRoutes = GuardRunnerRouteModelList([
        GuardRunnerRouteModel(routeName: '/', roles: ['*']),
        GuardRunnerRouteModel(
            routeName: '/second-page',
            roles: ['app_first_role', 'app_second_role']),
        GuardRunnerRouteModel(
            routeName: '/third-page', roles: ['app_third_role']),
        GuardRunnerRouteModel(routeName: '/unauthorized-page', roles: ['*'])
      ]);

GuardRunner.setup(
      roles: roles,
      rolesByRoutes: rolesByRoutes,
      isAdminRole: 'admin_role');

Checking if a route has permission to navigate

Warning: It's an example, you can be adapt it to your needs.

import 'package:guard_runner/guard_runner.dart';
...
@override
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      initialRoute: '/',
      onGenerateRoute: (settings) {
        final routeName = settings.name;

        final routes = {
          '/': MyHomePage(title: 'GuardRunner Home Page'),
          '/second-page': SecondPage(),
          '/third-page': ThirdPage(),
          '/unauthorized-page': UnauthorizedPage(),
        };

        if (routes.keys.contains(routeName)) {
          final hasPermission = GuardRunner.hasPermissionFromRoute(routeName!);

          return MaterialPageRoute(
            builder: (context) {
              final toRoute = hasPermission ? routeName : '/unauthorized-page';
              return routes[toRoute]!;
            },
          );
        }

        assert(false, 'Need to implement ${settings.name}');
        return null;
      },
    );
  }
}

In this example, if has permission, then navigate to pushed route, if hasn't permission, then go to UnauthorizedPage.

Verifying permission

To verify if user has permission to execute an action, you can use GuardRunner.hasPermission and/or GuardRunner.hasPermissionFromRoute

import 'package:guard_runner/guard_runner.dart';
...

if (GuardRunner.hasPermission(['app_first_role']) {
    doSomething();
} else {
    doNothing();
}

///
if (GuardRunner.hasPermissionFromRoute('/third-page')) {
    Navigator.of(context).pushNamed('/third-page');
} else {
    Navigator.of(context).pushNamed('/third-page');
}
...

Using GuardRunnerVisibility to show or hide a widget.

GuardRunnerVisibility is a widget that show it's child if has permission and hide if hasn't permission, according to the roles passed as a parameter.

import 'package:guard_runner/guard_runner.dart';
...
GuardRunnerVisibility(
    child: Text('Showing because has permission...'),
    roles: ['app_first_role']),

Passing a wildcard as parameter

If you wish a full access to a route or to show the child of GuardRunnerVisibility, you can pass a wildcard as a parameter.

import 'package:guard_runner/guard_runner.dart';
...

/// Example of using wildcard in a route
GuardRunnerRouteModel(routeName: '/', roles: ['*']),

/// Example of using wildcard with GuardRunnerVisibility
GuardRunnerVisibility(
    child: Text('Showing because has permission...'),
    roles: ['*']),

Setup isAdmin

If you wish give a full access to a user, you can set isAdminRole property when call GuardRunner.setup.

isAdminRole is optional, if defined and it's included in roles list, then full access will be defined.

import 'package:guard_runner/guard_runner.dart';
...
/// The all allowed roles
final List<String> roles = ['app_first_role', 'app_second_role', 'admin_role'];

GuardRunner.setup(
      roles: roles,
      rolesByRoutes: rolesByRoutes,
      isAdminRole: 'admin_role');

Authors

License

APACHE

Libraries

guard_runner