Update Authorization Only For The Owner (Author)

Hi Yii!!. Thank you for reading I installed Yum in my app which have a "Project" with a [color="#483D8B"]"project_user"[/color] field, i need to allow the update action only for the [color="#483D8B"]"$project->project_user"[/color] user or the [color="#FF0000"]"Yii::app()->user->isAdmin()"[/color], so, i solved it with:




public function actionUpdate($id)

{

	$model=$this->loadModel($id);

	if(($model->project_user==Yii::app()->user->data()->id)||Yii::app()->user->isAdmin()){

		if(isset($_POST['Projects']))

		{

			$model->attributes=$_POST['Projects'];

			if($model->save())

				$this->redirect(array('view','id'=>$model->id));

		}

		$this->render('update',array(

			'model'=>$model,

		));

	} else {

		throw new CHttpException(404,'Ops! Sorry, page not found');

	}

}



And it works, but my question is if this is the correct way or is better to use accessRules? bizrules? How must i do it? Or where can i find info about it?

Some one told me to use virtual attributes, what i understood is to create a "[color="#FF0000"]getUpdatePermission()[/color]" function in "Project.php" like this:




public function getUpdatePermission(){

    return ($this->project_user==Yii::app()->user->data()->id)||Yii::app()->user->isAdmin();

}



With this i can use it in "ProjectController.php":




public function actionUpdate($id)

{

	$model=$this->loadModel($id);

	if($model->getUpdatePermission()){

		if(isset($_POST['Projects']))

		{

			$model->attributes=$_POST['Projects'];

			if($model->save())

				$this->redirect(array('view','id'=>$model->id));

		}

		$this->render('update',array(

				'model'=>$model,

		));

	} else {

		throw new CHttpException(404,'Ops! Sorry, page not found');

	}

}



And it works too, as expected. But i dont know how to use it in [color="#00BFFF"]"accessRules"[/color], I tried with:




public function accessRules() {

    array('allow', // allow authenticated user to perform 'create' and 'update' actions

    'actions'=>array('update'),

    'expression' => '$model->getUpdatePermission()',

}



Tut got ERROR, as expected.




Fatal error: Call to a member function getUpdatePermission() on a non-object in .... framework\base\CComponent.php(606) : eval()'d code on line 1

#	Time	  Memory	  Function	  Location

15	0.0370	  3169456	  eval( ''return $model->getUpdatePermission();'' )	..\CComponent.php:606



I want to use something like [color="#00BFFF"]"accessRules"[/color] in "YumUserController.php":




public function accessRules() {

		return array(

				array('allow',

					'actions'=>array('index', 'view', 'login'),

					'users'=>array('*'),

					),

				array('allow',

					'actions'=>array('profile', 'logout', 'changepassword', 'passwordexpired', 'delete', 'browse'),

					'users'=>array('@'),

					),

				array('allow',

					'actions'=>array('admin','delete','create','update', 'list', 'assign', 'generateData', 'csv'),

Something like this			'expression' => 'Yii::app()->user->isAdmin()'//Something like this

					),

				array('allow',

					'actions'=>array('create'),

Something like this			'expression' => 'Yii::app()->user->can("user_create")'//Something like this

					),

				array('allow',

					'actions'=>array('admin'),

Something like this			'expression' => 'Yii::app()->user->can("user_admin")' //Something like this

					),

				array('deny',  // deny all other users

						'users'=>array('*'),

						),

				);

	}



Thank you again!

[color="#008000"]- SOLVED -[/color]

in "ProjectsControlles.php"




public function accessRules()

{

	return array(

		array('allow', // allow authenticated user to perform 'update' actions if is the owner

		'actions'=>array('update'),

		'users'=>array('@'),

		'expression' => array($this, 'isOwner'),

		),

	);

}


public function isOwner($user, $rule)

{

	$model = $this->loadModel($_GET['id']);

	return $user->id === $model->project_user;

}



Thanks to [color="#008000"]nsanden [/color]and [color="#008000"]jacksmuts[/color] for their help, an thanks to [color="#008000"]thyseus [/color]for [color="#00BFFF"]Yum[/color]!

So you load the same model 2 times ( on the isOwner and again in the update action) ?

Hi jneto!

Sorry, no, i dont load the same model 2 times, i forgot to say that using the [color="#00BFFF"]"accessRules"[/color] is not necesary to check it in "updateAction", so, in "ProjectsController.php":




public function actionUpdate($id)

{

	$model=$this->loadModel($id);

	if(isset($_POST['Projects']))

	{

	$model->attributes=$_POST['Projects'];

	if($model->save())

		$this->redirect(array('view','id'=>$model->id));

	}

	$this->render('update',array(

		'model'=>$model,

	));

}


public function accessRules()

{

	return array(

		array('allow', // allow authenticated user to perform 'update' actions if is the owner

		'actions'=>array('update'),

		'users'=>array('@'),

		'expression' => array($this, 'isOwner'),

		),

		array('allow', // allow Admin user to perform 'update' actions

		'actions'=>array('update'),

		'expression' => 'Yii::app()->user->isAdmin()'

		),

	);

}


public function isOwner($user, $rule)

{

	$model = $this->loadModel($_GET['id']);

	return $user->id === $model->project_user;

}



PS1: Does any one knows if is posible to merge the two "allow" sentences?

PS2: Does any one knows how to change the post title to [SOLVED]…? Thank you!

but in

isOwner($user, $rule)




  $model = $this->loadModel($_GET['id']);



and in actionUpdate($id)




  $model=$this->loadModel($id);