Mysql
 sql >> Database >  >> RDS >> Mysql

Yii2 RBAC assegnazioni multiple per ogni utente in base ai gruppi

Ecco una soluzione finale funzionante.

Quindi, un altro giorno, più refactoring.

La mia soluzione finale utilizza la funzione checkAccess nei file di origine DbManager/ManagerInterface, ma ho aggiunto il parametro $assignments da passare. Il problema principale è che ho dovuto creare la mia lista di compiti per il controllo. Assicurati di commentare le righe in cui è impostata la variabile $assignments.

Ecco il mio nuovo modello di accesso:

<?php

namespace app\models;

use Yii;

class Access
{

public function canUser($type, $permissionName, $params = [])
{

    $auth = Yii::$app->authManager;

    switch ($type) {

        case 'group':

        $userID = Yii::$app->user->identity->id;
        $groupID = Yii::$app->options->getOption('user', 'active_group_id');

        $queryAll = GroupAccess::find()
        ->where('user_id = :user_id and group_id = :group_id', [':user_id' => $userID, ':group_id' => $groupID])
        ->asArray()
        ->all();

        $assignments = [];
        foreach ($queryAll as $queryItem) {
            $assignments[$queryItem['item_name']] = [
            'userId' => $queryItem['user_id'],
            'roleName' => $queryItem['item_name'],
            'createdAt' => $queryItem['created_date'],
            ];
        }

        $result = $auth->checkAccess($userID, $permissionName, $assignments, $params);

        return $result;

        break;

        case 'user':

        $userID = Yii::$app->user->identity->id;

        $queryAll = UserAccess::find()
        ->where('user_id = :user_id', [':user_id' => $userID])
        ->asArray()
        ->all();

        $assignments = [];
        foreach ($queryAll as $queryItem) {
            $assignments[$queryItem['item_name']] = [
            'userId' => $queryItem['user_id'],
            'roleName' => $queryItem['item_name'],
            'createdAt' => $queryItem['created_date'],
            ];
        }

        $result = $auth->checkAccess($userID, $permissionName, $assignments, $params);

        return $result;

        break;

    }

}

public function assign($type, $role, $userID = null, $groupID = null)
{

    switch ($type) {

        case 'group':

        // clear existing assigments
        self::revoke('group', $userID, $groupID);

        $groupAccess = new GroupAccess();
        $groupAccess->group_id = $groupID;
        $groupAccess->user_id = $userID;
        $groupAccess->item_name = $role;
        $groupAccess->created_date = time();

        return $groupAccess->save();

        break;

        case 'user':

        // clear existing assignments
        self::revoke('user', $userID);

        $userAccess = new UserAccess();
        $userAccess->user_id = $userID;
        $userAccess->item_name = $role;
        $userAccess->created_date = time();

        return $userAccess->save();

        break;

    }

}

public function revoke($type, $userID, $groupID = null)
{

    switch ($type) {

        case 'group':

        GroupAccess::deleteAll('user_id = :user_id and group_id = :group_id', [':user_id' => $userID, ':group_id' => $groupID]);

        break;

        case 'user':

        UserAccess::deleteAll('user_id = :user_id', [':user_id' => $userID]);

        break;

    }

}

}

Ed ecco la funzione checkAccess modificata in DbManager:

public function checkAccess($userId, $permissionName, $assignments, $params = [])
{
    //$assignments = $this->getAssignments($userId);
    $this->loadFromCache();
    if ($this->items !== null) {
        return $this->checkAccessFromCache($userId, $permissionName, $params, $assignments);
    } else {
        return $this->checkAccessRecursive($userId, $permissionName, $params, $assignments);
    }
}

Ed ecco la funzione checkAccess modificata in ManagerInterface.php:

public function checkAccess($userId, $permissionName, $assignments, $params = []);

Non ho modificato le funzioni $items, checkAccessFromCache e checkAccessRecursive in public da protetto.

Ed ecco il mio modello UserAccess:

<?php

namespace app\models;

use Yii;
use yii\db\ActiveRecord;

 /**
 * This is the model class for table "app_user_access".
 *
 * @property integer $id
 * @property integer $user_id
 * @property string $item_name
 * @property integer $created_date
 *
 * @property AppAuthItem $itemName
 * @property AppUsers $user
 */
class UserAccess extends ActiveRecord
{
/**
 * @inheritdoc
 */
public static function tableName()
{
    return 'app_user_access';
}

/**
 * @inheritdoc
 */
public function rules()
{
    return [
        [['user_id', 'item_name', 'created_date'], 'required'],
        [['user_id', 'created_date'], 'integer'],
        [['item_name'], 'string', 'max' => 64]
    ];
}

/**
 * @inheritdoc
 */
public function attributeLabels()
{
    return [
        'id' => 'ID',
        'user_id' => 'User ID',
        'item_name' => 'Item Name',
        'created_date' => 'Created Date',
    ];
}

/**
 * @return \yii\db\ActiveQuery
 */
public function getItemName()
{
    return $this->hasOne(AppAuthItem::className(), ['name' => 'item_name']);
}

/**
 * @return \yii\db\ActiveQuery
 */
public function getUser()
{
    return $this->hasOne(AppUsers::className(), ['id' => 'user_id']);
}
}

Ed ecco il modello GroupAccess:

<?php

namespace app\models;

use Yii;
use yii\db\ActiveRecord;

 /**
 * This is the model class for table "app_group_access".
 *
 * @property integer $id
 * @property integer $group_id
 * @property integer $user_id
 * @property string $item_name
 * @property integer $created_date
 *
 * @property AppUsers $user
 * @property AppAuthItem $itemName
 * @property AppGroups $group
 */
class GroupAccess extends ActiveRecord
{
/**
 * @inheritdoc
 */
public static function tableName()
{
    return 'app_group_access';
}

/**
 * @inheritdoc
 */
public function rules()
{
    return [
        [['group_id', 'user_id', 'item_name', 'created_date'], 'required'],
        [['group_id', 'user_id', 'created_date'], 'integer'],
        [['item_name'], 'string', 'max' => 64]
    ];
}

/**
 * @inheritdoc
 */
public function attributeLabels()
{
    return [
        'id' => 'ID',
        'group_id' => 'Group ID',
        'user_id' => 'User ID',
        'item_name' => 'Item Name',
        'created_date' => 'Created Date',
    ];
}

/**
 * @return \yii\db\ActiveQuery
 */
public function getUser()
{
    return $this->hasOne(AppUsers::className(), ['id' => 'user_id']);
}

/**
 * @return \yii\db\ActiveQuery
 */
public function getItemName()
{
    return $this->hasOne(AppAuthItem::className(), ['name' => 'item_name']);
}

/**
 * @return \yii\db\ActiveQuery
 */
public function getGroup()
{
    return $this->hasOne(AppGroups::className(), ['id' => 'group_id']);
}
}

E ancora, alcuni esempi utili:

// assign group role
Yii::$app->access->assign('group', 'group_creator', 24, 20);
// assign user role
Yii::$app->access->assign('user', 'app_user', 24);

// revoke group
Yii::$app->access->revoke('group', 22, 18);
// revoke user
Yii::$app->access->revoke('user', 22);

// test user permission
var_dump(Yii::$app->access->canUser('user', 'manage_app_settings'));
// test the group permission
var_dump(Yii::$app->access->canUser('group', 'manage_group_settings'));