SAAS application client roles and RBAC


(Eric) #1

Hello guys,

I am building a multi-tenant SAAS application using Yii2 basic template. Everything is going on well but I need ideas or help on how to implement a certain functionality.

My clients register on the frontend as usual users and get a role of “client”. This is saved in the users table and it’s pretty straightforward.

My clients can now register, log in, and see their own data, all that is taken care of pretty well.

Now what I plan to do is to add a functionality whereby these Clients can add their own users into the system. I had wanted to separate these user tables but it got pretty complicated and I abandoned that scenario and now all my users will be lumped in one table, both admins, clients and client users.

Now my question is, how do I go about creating a “sub RBAC” for the Clients? How this will work is as follows:

  1. Client creates own users, creates own roles, own permissions and assigns these own permissions to own users. for example, Client X can have roles of Auditor, Finance Manager, Sales Manager etc, and users Mr A, Mr B, Mr C, Mr D… then Client assigns these users roles and permissions like we would do in a normal Yii2 RBAC scenario
  2. These Client users will then log in like normal users and only do what their permissions allow as pertains to their Client settings.

My initial thinking was just to create some default “permissions” for everyone (clients and their users). e,g payment.list, payment.edit, payment.create, payment.delete etc and then just let the Clients create their own Roles and assign these default permissions accordingly?

Now with that line of thinking, is it possible to make this “sub RBAC” system use other rbac tables, i.e client_auth_items, client_auth_rule and leave the default ones to be only for my admin users?

Or what better architecture can you guys suggest.

Thanks.


(Alexander Makarov) #2

Same RBAC could be used but you have to restrict using certain roles/permissions in the API for UI.


(Eric) #3

One problem comes in whereby Clients put in similar named Roles. There might be conflicts since yii\rbac\Role uses the name field as primary key.

Perhaps the solution here is to extend and create a custom implementation of RBAC.


(Uldisnelsons) #4

Optimal solution is define role as object. Also solved role name translation and logical grouping.

<?php

namespace d3modules\lietvediba\accessRights;

use CompanyRights\components\UserRoleInterface;
use Yii;
use yii2d3\d3persons\accessRights\D3personsUserFullUserRole;

class LietvedibaContractFullUserRole implements UserRoleInterface
{

    public const NAME = 'LietvedibaContractFull';
    public const GROUP_NAME = 'Contracts';

    /**
     * @inheritdoc
     */
    public function getType(): string
    {
        return self::TYPE_COMPANY;
    }

    public function getGroupLabel(): string
    {
        return Yii::t('d3lietvediba', 'Contracts');
    }

    /**
     * @inheritdoc
     */
    public function getLabel(): string
    {
        return Yii::t('d3lietvediba', 'Full');

    }

    /**
     * @inheritdoc
     */
    public function getName(): string
    {
        return self::NAME;
    }

    /**
     * @inheritdoc
     */
    public function getAssigments(): array
    {
        return [];
    }

    private function can(): bool
    {
        return Yii::$app->user->can(D3personsUserFullUserRole::NAME);
    }

    /**
     * @inheritdoc
     */
    public function canAssign(): bool
    {
        return $this->can();
    }

    /**
     * @inheritdoc
     */
    public function canView(): bool
    {
        return $this->can();
    }

    /**
     * @inheritdoc
     */
    public function canRevoke(): bool
    {
        return $this->can();
    }


}