Restricting a user from updating his own post

Basically, I’m trying to restrict a user to update posts that only he has made. I’ve gone through the forums to find the simplest way to achieve that, and for the most part I’ve succeeded.

So far, whenever I go to index.php/r=story/update&id=7, if the users ID matches the ID on record it allows them to update the post; otherwise they’re hit with a 403.

However, the problem arises when I go to view all the stories (index.php/r=story/index). It hits me with an Undefined Index: id. I assume it’s because on the index page, there is no ID to get from. Does anyone have a better solution to solve this? I’ve looked at RBAC but I felt that it was too much for what I was trying to achieve; Unless, I’m mistaken.

Here’s the code I’m working with:


public function accessRules()

	{

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

		return array(

			...

			array('allow',

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

           		 'expression' => '(Yii::app()->user->id) =='.$userid,

                  		),

			...

		);

	}

yes, you’re right about the index not containing the GET id. For this reason, I would do the validation in the actionUpdate method. I.e. not in the access rules. You could also write a filter.




    public function actionUpdate($id)

    {

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


        $userId = Yii::app()->user->id;


        if ($model->user_id != $userId)

        {

            // throw exception here.

        }


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

        {

            ...



Cheers,

Matt

I haven’t done a lot yet with accessRules, but I think you could just use


'expression' => '(Yii::app()->user->id) == $this->loadModel($_GET["id"])->user_id',

so the $this->loadModel($_GET[“id”])->user_id is only evaluated under the condition ‘actions’=>array(‘update’).

Yes, that should work - not tested though. As should this; don’t forget to deny from all below it.




array(

	'allow',

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

	'users'=>array(Yii::app()->user->name),

	'expression' => '(Yii::app()->user->id == ($_GET["id"]))',

),



Doing the validation in a controller/filter allows for a more flexible option to redirect, log, scorn the user. If you just need to block and show a 403, use the previous solutions.

Matt

Thanks guys, went with the actionUpdate method and it worked without a hitch.

Here is working code for updating own user record :)


	public function accessRules()

	{


		return array(

			array('allow',  // allow admin to perform 'index' and 'view' actions

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

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

			),

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

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

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

				'users'=>array(Yii::app()->user->name),

			        'expression' => '(Yii::app()->user->id == ($_GET["id"]))',

			),

			array('allow', // allow admin user to perform 'admin' 'create' and 'delete' actions

				'actions'=>array('admin','delete','create','update'),

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

			),

			array('deny',  // deny all users

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

			),

		);

	}