Hi,
I am using Yii2 basic. I two tables admin and employee. Both tables have id which is primary key, username, password. I have implemented the scenario where user can login from two different tables. Now I have RBAC implementation. Here I have created four tables which are required for RBAC. Now I have also created rules, permissions and roles in RBAC init(). I have assigned permissions to roles and roles to users.
I have a MultiUser.php model where it checks the instance of user whether it is of admin or employee and on that basis the user logs in.
Following is the MultiUser.php model
<?php
namespace app\models;
use app\models\Employee;
use app\models\Admin;
class MultiUser extends \yii\base\BaseObject implements \yii\web\IdentityInterface
{
/**
* @var \yii\db\BaseActiveRecord
*/
private $_user;
/**
* {@inheritdoc}
*/
public static function findIdentity($id)
{
// $id will be something like "admin-1" or "employee-1"
list($type, $pk) = explode('-', $id);
switch ($type) {
case 'admin':
$model = Admin::findOne($pk);
break;
case 'employee':
$model = Employee::findOne($pk);
break;
}
if (isset($model)) {
return new static(['user' => $model]);
}
}
/**
* {@inheritdoc}
*/
public static function findIdentityByAccessToken($token, $type = null)
{
throw new \yii\base\NotSupportedException();
}
/**
* {@inheritdoc}
*/
public function getId()
{
$prefix = $this->_user instanceof Admin ? 'admin' : 'employee';
return $prefix . '-' . $this->_user->getPrimaryKey();
}
public function getOnlyid()
{
//$prefix = $this->_user instanceof Admin ? 'admin' : 'employee';
return $this->_user->getPrimaryKey();
}
/**
* {@inheritdoc}
*/
public function getAuthKey()
{
$secret = \Yii::$app->request->cookieValidationKey;
return sha1($secret . get_class($this->_user) . $this->_user->getPrimaryKey());
}
public function validateAuthKey($authKey)
{
$secret = Yii::$app->request->cookieValidationKey;
$computedKey = sha1($secret . get_class($this->_user) . $this->_user->getPrimaryKey());
return $authKey === $computedKey;
}
public function setUser(\yii\db\BaseActiveRecord $user)
{
$this->_user = $user;
}
public function getUsername()
{
return $this->_user->username;
}
}
I have a table called groupdetails which has GroupId. employee table has a relation with grouodetails table. meaning One employee has many groupdetails. I created the CRUD for groupdetails. I have also checked for authorization in controller
Following is the Groupdetails controller.
<?php
namespace app\controllers;
use Yii;
use app\models\Groupdetails;
use app\models\GroupdetailsSearch;
use yii\web\UploadedFile;
use yii\web\Controller;
use yii\filters\VerbFilter;
use app\models\FieldofficerRule;
use yii\filters\AccessControl;
use yii\web\NotFoundHttpException;
use yii\web\ForbiddenHttpException;
/**
* GroupdetailsController implements the CRUD actions for Groupdetails model.
*/
class GroupdetailsController extends Controller
{
/**
* {@inheritdoc}
*/
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
];
}
/**
* Lists all Groupdetails models.
* @return mixed
*/
public function actionIndex()
{
$searchModel = new GroupdetailsSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
/**
* Displays a single Groupdetails model.
* @param integer $id
* @return mixed
* @throws NotFoundHttpException if the model cannot be found
*/
public function actionView($id)
{
$model=$this->findModel($id);
$Id=\Yii::$app->user->id;
if(\Yii::$app->user->can('viewGroup',['model'=>$model]))
{
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
else
{
throw new ForbiddenHttpException("You can't view other groups details");
}
}
/**
* Creates a new Groupdetails model.
* If creation is successful, the browser will be redirected to the 'view' page.
* @return mixed
*/
public function actionCreate()
{
if(\Yii::$app->user->can('createGroup'))
{
//$this->layout = 'layoutfile';
$model = new Groupdetails();
if ($model->load(Yii::$app->request->post()) ) {
$model->id=\Yii::$app->user->identity->getOnlyid();
$model->save(false);
return $this->redirect(['view', 'id' => $model->GroupId]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
else
{
throw new ForbiddenHttpException("You have no access to create groups");
}
}
/**
* Updates an existing Groupdetails model.
* If update is successful, the browser will be redirected to the 'view' page.
* @param integer $id
* @return mixed
* @throws NotFoundHttpException if the model cannot be found
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);
if(\Yii::$app->user->can('updateGroup', ['model' => $model]))
{
if ($model->load(Yii::$app->request->post())) {
$model->id=\Yii::$app->user->identity->getOnlyid();
$model->save();
return $this->redirect(['view', 'id' => $model->GroupId]);
}
else {
return $this->render('update', [
'model' => $model,
]);
}
}
else
{
throw new ForbiddenHttpException("You can't update other groups details");
}
}
/**
* Deletes an existing Groupdetails model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* @param integer $id
* @return mixed
* @throws NotFoundHttpException if the model cannot be found
*/
public function actionDelete($id)
{
$model = $this->findModel($id);
if(\Yii::$app->user->can('deleteGroup', ['model' => $model]))
{
$model->delete();
return $this->redirect(['index']);
}
else
{
throw new ForbiddenHttpException("You can't delete other groups details");
}
}
/**
* Finds the Groupdetails model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* @param integer $id
* @return Groupdetails the loaded model
* @throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = Groupdetails::findOne($id)) !== null) {
return $model;
}
throw new NotFoundHttpException('The requested page does not exist.');
}
}
In auth_assignment table I have the following,
Now when the user logs in from admin table and acccess groupdetails he can have access to create, view, update and delete actions.
But now when the user logs in from employee table he can create a record for groupdetails but he cant view, update, delete his groupdetails.
Below is my rule for RBAC
<?php
namespace app\rbac;
use yii\rbac\Rule;
use app\models\Groupdetails;
/**
* Checks if authorID matches user passed via params
*/
class FieldofficerRule extends Rule
{
public $name = 'isfieldofficer';
/**
* @param string|int $user the user ID.
* @param Item $item the role or permission that this rule is associated with
* @param array $params parameters passed to ManagerInterface::checkAccess().
* @return bool a value indicating whether the rule permits the role or permission it is associated with.
*/
public function execute($user, $item, $params)
{
return isset($params['model']) ? $params['model']->id == $user : false;
}
}
How to resolve?