sql >> データベース >  >> RDS >> Mysql

Yii2RBACグループに基づくユーザーごとの複数の割り当て

    これが実用的な最終解決策です。

    それで、別の日、より多くのリファクタリング。

    私の最終的な解決策は、DbManager / ManagerInterfaceソースファイルのcheckAccess関数を使用しますが、渡される$assignmentsパラメーターを追加しました。主な問題は、チェック用に独自の割り当てリストを作成する必要があることです。 $assignments変数が設定されている行を必ずコメントアウトしてください。

    これが私の新しいアクセスモデルです:

    <?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;
    
        }
    
    }
    
    }
    

    そして、これがDbManagerの変更されたcheckAccess関数です:

    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);
        }
    }
    

    そして、これがManagerInterface.phpの変更されたcheckAccess関数です:

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

    $ items、checkAccessFromCache、およびcheckAccessRecursive関数を保護されたものからpublicに変更しませんでした。

    これが私の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']);
    }
    }
    

    そして、これが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']);
    }
    }
    

    そしてもう一度、いくつかの有用なサンプル:

    // 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'));
    



    1. XAMPPはPHP/MySQLで非常に遅く実行されます

    2. djangoプロジェクトでPostgreSQLをセットアップする

    3. MariaDB 10.0/10.1でのInnoDBパーティションのインポート

    4. 共通テーブル式のINSERTで使用される副選択からデータを返す