Hier is een werkende definitieve oplossing.
Dus, een andere dag, meer refactoring.
Mijn uiteindelijke oplossing gebruikt de checkAccess-functie in de DbManager/ManagerInterface-bronbestanden, maar ik heb de parameter $assignments toegevoegd die moet worden doorgegeven. Het belangrijkste probleem is dat ik mijn eigen opdrachtenlijst moest maken om te controleren. Zorg ervoor dat je commentaar geeft op de regels waar de $assignments-variabele is ingesteld.
Dit is mijn nieuwe toegangsmodel:
<?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;
}
}
}
En hier is de aangepaste checkAccess-functie 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);
}
}
En hier is de aangepaste checkAccess-functie in ManagerInterface.php:
public function checkAccess($userId, $permissionName, $assignments, $params = []);
Ik heb de functies $items, checkAccessFromCache en checkAccessRecursive niet gewijzigd in public from protected.
En hier is mijn UserAccess-model:
<?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']);
}
}
En hier is het GroupAccess-model:
<?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']);
}
}
En nogmaals, enkele bruikbare voorbeelden:
// 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'));