yiisoft/rbac-cycle-db

Yii RBAC 循环数据库存储

3.0.0 2024-03-07 10:52 UTC

This package is auto-updated.

Last update: 2024-09-22 10:39:21 UTC


README

Yii

Yii RBAC 循环数据库


Latest Stable Version Total Downloads Build status codecov Mutation testing badge static analysis type-coverage

该包提供了为 Cycle Database 存储提供 Yii RBAC 的存储。

详细的构建状态

要求

  • PHP 8.1 或更高版本。
  • 如果与 SQLite 一起使用,最小要求的版本是 3.8.3。
  • 如果与 SQL Server 一起使用,PDO 的最小要求版本为 5.11.1。

安装

可以使用 composer 安装此包

composer require yiisoft/rbac-cycle-db

通用用法

配置数据库连接

配置取决于所选驱动程序。以下是一个 PostgreSQL 的示例

use Cycle\Database\Config\DatabaseConfig;
use Cycle\Database\Config\Postgres\DsnConnectionConfig;
use Cycle\Database\Config\PostgresDriverConfig;
use Cycle\Database\DatabaseManager;

$dbConfig = new DatabaseConfig(
    [
        'default' => 'default',
        'databases' => [
            'default' => ['connection' => 'pgsql'],
        ],
        'connections' => [
            'pgsql' => new PostgresDriverConfig(new DsnConnectionConfig(
                'pgsql:host=127.0.0.1;dbname=yiitest;port=5432',
                'user',
                'password',
            )),
        ],
    ]
);
$databaseManager = new DatabaseManager($dbConfig);
$database = $databaseManager->database();

更全面的示例可以在 Cycle Database 文档 中找到。

处理迁移

此包使用 Cycle Migrations 来管理存储所需的数据库表。总共有三个表(使用 yii_rbac_ 前缀)。

项目存储

  • yii_rbac_item.
  • yii_rbac_item_child.

分配存储

  • yii_rbac_assignment.

配置迁移器和胶囊

use Cycle\Database\DatabaseManager;
use Cycle\Migrations\Capsule;
use Cycle\Migrations\Config\MigrationConfig;
use Cycle\Migrations\FileRepository;
use Cycle\Migrations\Migrator;

$migrationsSubfolders = ['items', 'assignments'];
$directories = array_map(
    static fn (): string => dirname(__DIR__. 2),  "/vendor/yiisoft/rbac-cycle-db/migrations/$subfolder",
    $migrationsSubfolders, 
);
$config = new MigrationConfig([
    'directory' => $directories[0],
    // "vendorDirectories" are specified because the "directory" option doesn't support multiple directories. In the
    // end, it makes no difference because they all will be merged into a single array.
    'vendorDirectories' => $directories[1] ?? [],
    'table' => 'cycle_migration',
    'safe' => true,
]);
/** @var DatabaseManager $databaseManager */
$migrator = new Migrator($config, $databaseManager, new FileRepository($config));
$migrator->configure();

$capsule = new Capsule($databaseManager->database());

有关配置 $databaseManager,请参阅 上一节

由于项目和分配存储完全独立,因此迁移也分开,以防止创建未使用的表。例如,如果您只想使用分配存储,请调整 $migrationsSubfolders 变量如下

$migrationsSubfolders = ['assignments'];

应用迁移

use Cycle\Migrations\Capsule;
use Cycle\Migrations\Migrator;

/**
 * @var Migrator $migrator
 * @var Capsule $capsule 
 */
while ($migrator->run($capsule) !== null) {
    echo "Migration {$migration->getState()->getName()} applied successfully.\n";
}

撤销迁移

use Cycle\Migrations\Capsule;
use Cycle\Migrations\Migrator;

/**
 * @var Migrator $migrator
 * @var Capsule $capsule 
 */
while ($migrator->rollback($capsule) !== null) {
    echo "Migration {$migration->getState()->getName()} reverted successfully.\n";
}

使用存储

存储不打算直接使用。相反,请使用 Yii RBAC 包中的 Manager 使用它们

use Cycle\Database\DatabaseInterface;
use Yiisoft\Rbac\Cycle\AssignmentsStorage;
use Yiisoft\Rbac\Cycle\ItemsStorage;
use Yiisoft\Rbac\Cycle\TransactionalManagerDecorator;
use Yiisoft\Rbac\Manager;
use Yiisoft\Rbac\Permission;
use Yiisoft\Rbac\RuleFactoryInterface;

/** @var DatabaseInterface $database */
$itemsStorage = new ItemsStorage($database);
$assignmentsStorage = new AssignmentsStorage($database);
/** @var RuleFactoryInterface $rulesContainer */
$manager = new TransactionalManagerDecorator(
    new Manager(
        itemsStorage: $itemsStorage, 
        assignmentsStorage: $assignmentsStorage,
        // Requires https://github.com/yiisoft/rbac-rules-container or another compatible factory.
        ruleFactory: $rulesContainer,
    ),
);
$manager->addPermission(new Permission('posts.create'));

注意用装饰器包装管理器——它还提供数据库事务以确保数据完整性。

请注意,没有必要使用两个 DB 存储。结合不同的实现是可能的。一个非常受欢迎的情况是通过 PHP 文件 管理项目,同时将分配存储在数据库中。

更多示例可以在 Yii RBAC 文档中找到。

手动同步存储

由于管理器,存储保持同步,但在某些情况下可能需要手动同步它们。其中之一是使用基于 PHP 文件的存储和 手动编辑 的组合。

假设 PHP 文件用于项目,而数据库用于分配,并且已删除一些项目

return [
    [
        'name' => 'posts.admin',        
        'type' => 'role',        
        'created_at' => 1683707079,
        'updated_at' => 1683707079,
        'children' => [
            'posts.redactor',
            'posts.delete',
            'posts.update.all',
        ],
    ],
-   [
-       'name' => 'posts.redactor',
-       'type' => 'role',        
-       'created_at' => 1683707079,
-       'updated_at' => 1683707079,
-       'children' => [
-           'posts.viewer',
-           'posts.create',
-           'posts.update',
-       ],
-   ],
    [
        'name' => 'posts.viewer',
        'type' => 'role',        
        'created_at' => 1683707079,
        'updated_at' => 1683707079,
        'children' => [
            'posts.view',
        ],
    ],
    [
        'name' => 'posts.view',
        'type' => 'permission',        
        'created_at' => 1683707079,
        'updated_at' => 1683707079,
    ],
    [
        'name' => 'posts.create',
        'type' => 'permission',        
        'created_at' => 1683707079,
        'updated_at' => 1683707079,
    ],
-   [
-       'name' => 'posts.update',
-       'rule_name' => 'is_author',
-       'type' => 'permission',
-       'created_at' => 1683707079,
-       'updated_at' => 1683707079,
-   ],
    [
        'name' => 'posts.delete',        
        'type' => 'permission',        
        'created_at' => 1683707079,
        'updated_at' => 1683707079,
    ],
    [
        'name' => 'posts.update.all',
        'type' => 'permission',        
        'created_at' => 1683707079,
        'updated_at' => 1683707079,
    ],
];

那么其他存储中的相关条目也需要被删除。这可以在迁移中完成

use Cycle\Migrations\Migration;

final class DeletePostUpdateItems extends Migration
{
    private const TABLE_PREFIX = 'yii_rbac_';
    private const ASSIGNMENTS_TABLE = self::TABLE_PREFIX . 'assignment';

    public function up()
    {
        $this
            ->database()
            ->delete()
            ->from(self::ASSIGNMENTS_TABLE)
            ->where('item_name', 'IN', ['posts.redactor', 'posts.update']);
    }

    public function down()
    {
    }
}

文档

如果您需要帮助或有任何问题,可以访问Yii 论坛,那里是一个很好的求助和提问的地方。您也可以查看其他的Yii 社区资源

许可证

Yii RBAC Cycle 数据库是免费软件。它遵循BSD许可证条款发布。有关更多信息,请参阅LICENSE

Yii 软件维护。

支持项目

Open Collective

关注更新

Official website Twitter Telegram Facebook Slack