Skip to content

Permissons

Abdulbasit Rubeya edited this page Aug 3, 2024 · 1 revision

Roles

Flow comes with roles management modules where user can create an unlimited number of roles for the application on the go, To register a new role,

  1. Go to Settings
  2. Head to `access > permissions > create new role
  3. Fill in the details and description of the role

While creating the role you'll also be to select from which roles should the new role clone it's permission from.

Permissions

Flow comes with permissions managements, these permissions are broken down in small granular chunks, which can then be dynamically allocated to user roles which are also created dynamically, So in short with Flow, one can have an app with unlimited user roles and unlimited permission both of which can be created on a go.

Flow categorizes the permissions management into two, Auth Guard (App\Middlewares\Auth) and Granular Permission Handler (App\Middlewares\Handler)

Auth Guard (App\Middlewares\Auth)

As the name suggest the main purpose of this middleware is to check if user is authorized and they're allowed to be where they requesting to be, Unlike granular permission it works directly with user roles and application routes, The authguard is also responsible for handling and authorizing API key if an API based request is made, it by default overides all granualar permissions in case access is forbidden and instantenously destroys the request.

To work with the Auth guard, you'll need to create custom rules which are stored in guard.php inside the app/routes directory and from there you can describe the basic rules for your app.

The defaul content will be as follows

<?php
/*
 |----------------------------------------------------------------------------------
 | The URI Access file
 |----------------------------------------------------------------------------------
 | This handles file access rule for each route
 |
 | @expression {int}    - Integer values
 | @expression {slug}   - Alphanumerical values
 | @expression {any}    - Every character except slashes (/)
 | @expression {wild}   - Every character including slashes
 */

return [
    'auth/login' => [ 'session' => false, 'access' => 'guest'],
    'auth/register' => [ 'session' => false, 'access' => 'guest'],

    'app/{wild}' => [ 'session' => true, 'access' => 'all' ],
    'admin/{wild}' => [ 'session' => true, 'access' => ['admin', 'moderator'] ],
        
    'api/auth/{wild}' => [ 'session' => false, 'access' => 'guest' ],
    'api/{wild}' => [ 'session' =>true, 'access' => 'all' ]
];

A few things to note out

  1. The rules in in the Auth guard are independent from the general routes
  2. A more declarative rule (higher level route) should come before a lower level route, this is to avoid the higher level route being overidden as the rules are being processed sequentially as it is the case with api/{wild} and api/auth/{wild}

Granular Permission (App\Middlewares\Handler)

The granular permissions are used to manage a sub part of the module and they are based on the CRUD permission sytem, i.e a student can view their score but can not add or update it etc

Permission scope

This defines as to how much control does the user have to the data stored in the database, the scopes are classified into 5 levels

Scope Description
ALL Full control of the permission.
i.e The head of school has access to view all teachers and students record
OWNED Control only on the part of the data they own.
i.e The author can view only the blogs they have written
ADDED Control only what's being shared with them or belong to same group.
i.e. The teacher can only add score to only students allocated to them
OWNED Control their record and others who are in their moderation
NONE No access over the permission

Adding a granular permission

  1. Go to settings
  2. Head to `access > permissions > create new permission
  3. Fill in the details of the permission along with scopes of access it has, where as by default all and none are allocated

Using granular permission

NOTE: If using granular permission in a class, make sure you first import the permission handler namespace use App\Middlewares\Handler

Handler middleware offers two static methods can and owns where as

  1. Handler::can()
  • Takes in $module, $permission, mixed $permissionScopes = ['all', 'owned', 'added', 'both'], $userId = null respectively
  • returns objects scope and status
  • The method tell us whether a user has control/access of the feature and if yes what is their scope/level of control they have over that feature
use App\Model\BlogArticles
use App\Middlewares\Handler

class MyClass extends Class
{
    ...

    function listArticles() :void
    {
        // check for permission
        $permission = Handler::can('blog', 'list_articles');
        if(!$permission->status) exit;

        ($permission->scope === 'all') ?
            $articles = BlogArticles::all() :
            $articles = BlogArticles::where('author', auth()->id());

        ...

    }
}
  1. Handler::owns
  • Takes in $scope, bool $ownFunction=false, bool $addFunction = false
  • Returns a boolean
  • Return true if permission scope is all
public function updateArticle($id)
{
    ... # check and handle permission as usual

    $article = BlogArticles::find($id);

    # verify if user owns the article before update
    if(!Handler::owns(
        $scope = $permission->scope,
        $ownFunction = ($article->author === auth()->id())
    ): exit;

    ...
}
  1. To access the Handler class in a view you can use the variable $handler which is loaded by default to the view by the Base Controller