私は自分のアプリへのユーザー アクセスを制御するために Yii RBAC を使用しています。これは 3 つの mySql テーブルで構成されています。
authitem
(RBAC ロール アイテム)
authitemchild
(他のロールに属するすべての RBAC ルール)
authitemassignment
(ユーザーへの役割の割り当て)
たとえば、次のようなテーブルがあるとします。
正規品:
| name (pk) |
areaASuperUser
areaACreateOnly
areaAReadOnly
areaAUpdateOnly
areaADeleteOnly
areaBSuperUser
areaBCreateOnly
areaBReadOnly
areaBUpdateOnly
areaBDeleteOnly
オーティテムチャイルド
| parent (pk) | child (pk) |
areaASuperUser areaACreateOnly
areaASuperUser areaAReadOnly
areaASuperUser areaAUpdateOnly
areaASuperUser areaADeleteOnly
areaBSuperUser areaBCreateOnly
areaBSuperUser areaBReadOnly
areaBSuperUser areaBUpdateOnly
areaBSuperUser areaBDeleteOnly
auititemassignment
| itemname (pk) | userid (pk) |
areaASuperUser 1
上記のシナリオでは、ID が 1 のユーザーは、areaA で完全な CRUD アクセス権を持っています。私が必要としているのは、ユーザーがアクセスできないすべてのロールのリストです。また、ユーザーがアクセスできるすべてのロールの子も考慮する必要があります。
ユーザーがアクセスできないすべてのロールを簡単に取得できます。
SELECT DISTINCT `ai`.`name`
FROM `authitem` `ai`
LEFT JOIN `authassignment` `aa`
ON `aa`.`itemname` = `ai`.`name` AND `aa`.`userid` = 1
WHERE `aa`.`itemname` IS NULL
しかし、これは次を返します:
| name |
areaACreateOnly
areaAReadOnly
areaAUpdateOnly
areaADeleteOnly
areaBSuperUser
areaBCreateOnly
areaBReadOnly
areaBUpdateOnly
areaBDeleteOnly
また、すべての areaA* ロールは areaASuperUser の子であるため、それらを返したくありません。
アドバイスや正しい方向へのプッシュは大歓迎です!
*編集:
ありがとう@SuVeRa、あなたの答え:
SELECT DISTINCT `ai`.`name`
FROM `authitem` `ai`
LEFT JOIN `authassignment` `aa`
ON `aa`.`itemname` = `ai`.`name` AND `aa`.`userid` = 1
WHERE
`aa`.`itemname` IS NULL
AND `ai`.`name` NOT IN (
SELECT
`aic`.`child` itemname
FROM `authitemchild` `aic`
JOIN `authassignment` `aa`
ON `aa`.`itemname` = `aic`.`parent`
WHERE `aa`.`userid` = 1
)
上記の例では完全に機能しますが、アプリを拡張して、子供向けの複数のレベルを含めるようにしました。
正規品:
| name (pk) |
areaABSuperUser
areaASuperUser
areaACreateOnly
areaAReadOnly
areaAUpdateOnly
areaADeleteOnly
areaBSuperUser
areaBCreateOnly
areaBReadOnly
areaBUpdateOnly
areaBDeleteOnly
areaCSuperUser
areaCCreateOnly
areaCReadOnly
areaCUpdateOnly
areaCDeleteOnly
オーティテムチャイルド
| parent (pk) | child (pk) |
areaABSuperUser areaASuperUser
areaABSuperUser areaBSuperUser
areaASuperUser areaACreateOnly
areaASuperUser areaAReadOnly
areaASuperUser areaAUpdateOnly
areaASuperUser areaADeleteOnly
areaBSuperUser areaBCreateOnly
areaBSuperUser areaBReadOnly
areaBSuperUser areaBUpdateOnly
areaBSuperUser areaBDeleteOnly
areaCSuperUser areaCCreateOnly
areaCSuperUser areaCReadOnly
areaCSuperUser areaCUpdateOnly
areaCSuperUser areaCDeleteOnly
auititemassignment
| itemname (pk) | userid (pk) |
areaABSuperUser 1
元の答えが返されます。
| name |
areaACreateOnly
areaAReadOnly
areaAUpdateOnly
areaADeleteOnly
areaBCreateOnly
areaBReadOnly
areaBUpdateOnly
areaBDeleteOnly
areaCSuperUser
areaCCreateOnly
areaCReadOnly
areaCUpdateOnly
areaCDeleteOnly
親と子は除外されますが、子の子は除外されません。私が求めている結果 (この 2 番目の例) は次のとおりです。
| name |
areaCSuperUser
areaCCreateOnly
areaCReadOnly
areaCUpdateOnly
areaCDeleteOnly
***編集2:
特に Yii の場合:
私は Yii についてもう少し調べてみました。CAuthManagerには、 hasItemChild()、isAssigned()、getItemChildren()など、必要なデータを取得するのに役立ついくつかの便利なメソッドがあります。