Yii Framework Forum: Yii::app()->user->checkAccess() does not work - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Yii::app()->user->checkAccess() does not work Chapter 8

#1 User is offline   Crixus 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 4
  • Joined: 27-April 11

Posted 27 April 2011 - 06:36 AM

In chapter 8, when instructed to add something like this into project's view.php
$curuser= Yii::app()->user->getId();
if(Yii::app()->user->checkAccess('createUser',$curuser))
{
	$this->menu[] = array('label'=>'Add user to project', 'url'=>array('adduser', 'id'=>$model->id));
}

It does not work, running var_dump on $curuser returns "false", even when the project listing shows Create user as that of what I am logged in with.
I am confused where the "createUser" should get its value as well... Is it from "AuthAssignment" or maybe from "tbl_project", or maybe some other table?
0

#2 User is offline   EdoFre 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 46
  • Joined: 24-February 11
  • Location:Groningen, The Netherlands

Posted 27 April 2011 - 08:08 AM

I might be horribly wrong as I've not read the book, but it makes sense to me that you don't need to give the id of the user in the checkAcces() method as you're executing it from within the Yii::app()->user.

Have you tried?

if(Yii::app()->user->checkAccess('createUser'))

Moi,
0

#3 User is offline   jefftulsa 

  • Advanced Member
  • Yii
  • Group: Yii Dev Team
  • Posts: 168
  • Joined: 06-October 08
  • Location:Austin, TX

Posted 27 April 2011 - 08:36 PM

Are you referring to the top of page 212? If so, this code does not send in the id of the user as the second parameter, it sends in the project model AR object instance.

the second parameter passed in is:

array('project'=>$model)

0

#4 User is offline   Crixus 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 4
  • Joined: 27-April 11

Posted 28 April 2011 - 01:27 AM

View Postjefftulsa, on 27 April 2011 - 08:36 PM, said:

Are you referring to the top of page 212? If so, this code does not send in the id of the user as the second parameter, it sends in the project model AR object instance.

the second parameter passed in is:

array('project'=>$model)


Sorry, you are correct. However it is still not working, I was probably just testing different methods and forgot about the original parameter.

running var_dump() on Yii::app()->user->checkAccess('createUser',array('project'=>$model)) returns false, while the project details page reports the "Create User" same as I am logged in with.
I am using v1.1.6
0

#5 User is offline   jefftulsa 

  • Advanced Member
  • Yii
  • Group: Yii Dev Team
  • Posts: 168
  • Joined: 06-October 08
  • Location:Austin, TX

Posted 30 April 2011 - 03:16 PM

The 'createUser' parameter is not a user name, it is the name of an authorization item, which is an entry in the AuthItem table. In this case, in order for this to return true, you will need to be logged in as a user who is assigned to the role "owner" in the AuthAssignment table. So, for example, if you are logged in as user 'Crixus' whose user_id is 5, then first of all there will need to be a row in the AuthAssignment table with

itemname: owner
userid: 5

This makes the assignment of the role, "owner" to this user. But since we have our roles defined in the context of specific projects, you will also need to ensure that you are an "owner" of the project you are looking at. This is what the bizrule does. It calls an extra method to see if you are, indeed, an owner of that project. This is the isUserInRole() method in the Project AR class. This checks the table tbl_project_user_role to see if the user is indeed in the role for a specific project. So, if you are looking at project_id = 2, then you would need the following row in this table

project_id: 2
user_id: 5
role: owner

And finally, the reason that the role of "owner" has the permission of "createUser" is due to the mapping in the table AuthItemChild. If you look at that table, you should find a row that establishes the item "createUser" as a child of "owner"

parent: owner
child: createUser

So, in the end, the authorization check

Yii::app()->user->checkAccess('createUser',array('project'=>$model))

Is asking the following question:
"Is the current logged in user assigned the authorization permission item 'createUser'?"

It does a recursive check against the AuthAssignment table to see if 'creatUser' or any of its parents are assigned to the user.
If so, then is will see if there is a bizrule defined in this assignment and execute it, and then return the true or false value returned from executing the bizrule.
0

#6 User is offline   1661design 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 17
  • Joined: 09-May 11
  • Location:New York

Posted 18 May 2011 - 10:41 AM

I just finished the chapter 8 and although quite happy with the overall results, I am a bit uneasy, I sense that I skipped something or that there is a missing part of the whole RBAC equation that I haven't got yet.

Back to the sample, It seem to me that a default project 'owner' assignment should happen automatically on project creation.
And that seems fairly simple to tackle by tapping in the CActiveRecord afterSave() callback and replicating what we did in createUser [guess that code should be in one place only, but for brevity I'm including here].

So I attempted to correct the issue by adding to the project.php model

	/**
	* Adds creator of the project as user and designate as default 'owner'
	*/
	protected function afterSave() {    
		$user = Yii::app()->user;
		$this->associateUserToProject($user->id); 
		$this->associateUserToRole('owner',$user->id);        
		$auth = Yii::app()->AuthManager;   
		if ($auth->getAuthAssignment('owner',$user->id) === null) {
			$bizRule = 'return isset($params["project"]) && $params["project"]->isUserInRole("owner");';
			$auth->assign('owner', $user->id, $bizRule);
		}
	}    


Which solves the problem but uncovered another issue of the "bizrule" being associated in the AuthAssignment with a "role, user_id" pair that will create duplicates in the original verify() function of the ProjectUserForm (easy fixed with the getAuthAssignment check shown above).

My doubt now, is that: although the above changes seem to have solved the assignment within the project context, not sure how the general authorization scheme should work. And I mean, how can I allow/restrict a given user to/for "Create Projects" in the first place.

I'll aprecciate your comments,

Sergio

'Be kind whenever possible. It is always possible" - 14th DL
"Be kind whenever possible. It is always possible." - 14th DL

Mac OS X 10.6.7 - PHP Version 5.3.2 - PHPUnit 3.5.13 - Yii 1.1.7
0

#7 User is offline   windsor 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 63
  • Joined: 04-October 11
  • Location:Tampa, FL

Posted 25 October 2011 - 04:58 PM

[SOLUTION]
I followed all of the advice in this thread, however checkAccess() was still returning false. I had a typo in the validate bizrule. I found it by comparing the code from inside MySQL server to what was submitted via the ProjectUserForm.verify method. I am reproducing my screens below, in case someone else finds it useful.

I am calling it from views/project/view/php like this:

if(Yii::app()->user->checkAccess('createUser',array('project'=>$model)))
{
	$this->menu[]=array('label'=>'Add User to Project', 'url'=>array('adduser','id'=>$model->id));
}


I am logging in to the application as user: Test_User_Four

using this URL:

localhost/trackstar/index.php?r=project/view&id=2

Here is my tbl_user table:

Posted Image



here is my authassignment table:

Posted Image


this is from authItem table

Posted Image



this is from authitemchild

Posted Image



this is from tbl_project_user_role

Posted Image



It looks to me like Test_User_Four is the owner of project 2 and should be able to have access to createUser and see the link

here is my verify() function in ProjectUserForm.php which sets the bizRule

public function verify($atrribute, $params)
	{
		//Review LoginForm.authenticate() for further example.
		
		//only verify if no other input errors present
		if(!$this->hasErrors())
		{
			$user=User::model()->findByAttributes(array('username'=>$this->username));
			if($this->project->isUserInProject($user))
			{
				$this->addError('username', 'This user has already been added to the project.');
				
			}
			else
			{
				$this->project->associateUserToProject($user);
				$this->project->associateUserToRole($this->role, $user->id);
				$auth=Yii::app()->authManager;
				$bizRule='return isset($params["project"]) && params["project"]->isUserInRole("'.$this->role.'");';
				$auth->assign($this->role,$user->id,$bizRule);
				
			}
		}
	}


HERE's THE PROBLEM


$bizRule='return isset($params["project"]) && params["project"]->isUserInRole("'.$this->role.'");';

//params missing a variable identifier $
//should be:

$bizRule='return isset($params["project"]) && $params["project"]->isUserInRole("'.$this->role.'");';




finally, here is the isUserInRole($role) function from the model Project.php

public function isUserinRole($role)
	{
		$sql = "SELECT role FROM tbl_project_user_role WHERE project_id=:projectId AND user_id=:userId AND role=:role";
		$command = Yii::app()->db->createCommand($sql);
		$command->bindValue(":projectId", $this->id, PDO::PARAM_INT);
		$command->bindValue(":userId", Yii::app()->user->getId(), PDO::PARAM_INT);
		$command->bindValue(":role", $role, PDO::PARAM_STR);
		
		return (($command->execute()==1) ? true : false);
	}


Any idea of what I may be doing wrong or what else I can try to make this work?

If you go to your database and inspect the value in the 'bizrule' field in authassignment table you can see the typo more easily:

// this is bad
return isset($params["project"]) && params["project"]->isUserInRole("owner");

//this is good
return isset($params["project"]) && $params["project"]->isUserInRole("owner");



HTH
0

#8 User is offline   bumslayer 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 5
  • Joined: 19-October 11
  • Location:Wherever I may roam.

Posted 27 October 2011 - 12:55 PM

Nice work, windsor for spotting that missing $. You have saved us a lot of money for aspirins :D
0

#9 User is offline   wejder 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 2
  • Joined: 22-November 11

Posted 02 December 2011 - 06:31 PM

hi all,
i thing i had the same problem and couldn't found new link in menu ( [add user to project] ).
now is ok because I insert manually in AuthAssignment one record after read this topic.

insert into AuthAssignment(itemname, userid) values('owner',3)


i'm on site 210 and still wondering how i could miss text about creating this line in this table.

can someone tell me where in book is paragraph about that? :)

maybe the reason is different?

thx :)
0

#10 User is offline   seb7 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 49
  • Joined: 03-April 12

Posted 05 April 2012 - 03:13 AM

Right ! Thanks windsor to point out that prob. Mine was the same, i made a typo in the $bizRule
And more critical i did not made that typo in the unit test so everything seems ok ! I'll now make a copy/paste of that bizRule !
0

#11 User is offline   digitalzombie 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 17
  • Joined: 19-August 10

Posted 18 June 2012 - 01:25 AM

models/ProjectUserForm.php

I had to add:


 64                 $this->project->associateUserToProject($user);
 65                 $this->project->associateUserToRole($this->role,$user->id);
 66                 $auth = Yii::app()->authManager;
 67                 $bizRule='return isset($params["project"]) && $params["project"]->isUserInRole("'.$this->role.'");';
 68                 $auth->assign($this->role,$user->id, $bizRule);
 69               $auth->save();



Added:
$auth->save();


$bizRule wasn't saving.
0

#12 User is offline   ram87 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 13
  • Joined: 12-February 13

Posted 02 March 2013 - 08:32 AM

USERiDENTITY.PHP
public function authenticate()
    {
        $record = RRegister::model()->findByAttributes(array('username'=>$this->username));
        if($record===null)
            $this->errorCode=self::ERROR_USERNAME_INVALID;
        
        else if($record->password!==$this->password)
            $this->errorCode=self::ERROR_PASSWORD_INVALID;
        else
        {
            $this->id=$record->id;
            echo $this->setState('role', $record->role); 
            
            $this->errorCode=self::ERROR_NONE;
        }
        return !$this->errorCode;
    }
 
    public function getId(){
        return $this->id;
    }



MAIN.PHP

'user'=>array(
			// enable cookie-based authentication
			'allowAutoLogin'=>true,
                    //set user role class
                   'class' => 'WebUser',
		),

components/webuser.php
<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
class WebUser extends CWebUser
{
    /**
     * Overrides a Yii method that is used for roles in controllers (accessRules).
     *
     * @param string $operation Name of the operation required (here, a role).
     * @param mixed $params (opt) Parameters for this operation, usually the object to access.
     * @return bool Permission granted?
     */
    public function checkAccess($operation, $params=array())
    {
        if (empty($this->id)) {
            // Not identified => no rights
            return false;
        }
       $role = $this->getState("role");
        if ($role === 'admin') {
            return true; // admin role has access to everything
        }
        // allow access if the operation request is the current user's role
        return ($operation === $role);
    }
}
?>

VIEW FORM:
<div id="mainmenu">
		<?php 
                $user = Yii::app()->user;
                $this->widget('zii.widgets.CMenu',array(
			'items'=>array(
				array('label'=>'Home', 'url'=>array('/site/index')),
				//array('label'=>'About', 'url'=>array('/site/page', 'view'=>'about')),
				//array('label'=>'Contact', 'url'=>array('/site/contact')),
                                array('label'=>'Create Account', 'url'=>array('/RRegister/create'),'visible'=>$user->checkAccess('admin')),
                                array('label'=>'Amount Deposit', 'url'=>array('/RDEposit/create'),'visible'=>$user->checkAccess('staff')),
                                array('label'=>'Amount Transaction', 'url'=>array('/RTransaction/create'),'visible'=>$user->checkAccess('staff')),
                                array('label'=>'Amount Withdraw', 'url'=>array('/RWithdraw/create'),'visible'=>$user->checkAccess('normal')),
				array('label'=>'Login', 'url'=>array('/site/login'), 'visible'=>Yii::app()->user->isGuest),
				array('label'=>'Logout ('.Yii::app()->user->name.')', 'url'=>array('/site/logout'), 'visible'=>!Yii::app()->user->isGuest)
			),
		)); ?>
	</div><!-- mainmenu -->

0

#13 User is offline   Sourabh007 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 5
  • Joined: 23-April 13

Posted 03 May 2013 - 02:10 PM

this code is very useful for authenticate users....
thanks for this suggation

View Postram87, on 02 March 2013 - 08:32 AM, said:

USERiDENTITY.PHP
public function authenticate()
    {
        $record = RRegister::model()->findByAttributes(array('username'=>$this->username));
        if($record===null)
            $this->errorCode=self::ERROR_USERNAME_INVALID;
        
        else if($record->password!==$this->password)
            $this->errorCode=self::ERROR_PASSWORD_INVALID;
        else
        {
            $this->id=$record->id;
            echo $this->setState('role', $record->role); 
            
            $this->errorCode=self::ERROR_NONE;
        }
        return !$this->errorCode;
    }
 
    public function getId(){
        return $this->id;
    }



MAIN.PHP

'user'=>array(
			// enable cookie-based authentication
			'allowAutoLogin'=>true,
                    //set user role class
                   'class' => 'WebUser',
		),

components/webuser.php
<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
class WebUser extends CWebUser
{
    /**
     * Overrides a Yii method that is used for roles in controllers (accessRules).
     *
     * @param string $operation Name of the operation required (here, a role).
     * @param mixed $params (opt) Parameters for this operation, usually the object to access.
     * @return bool Permission granted?
     */
    public function checkAccess($operation, $params=array())
    {
        if (empty($this->id)) {
            // Not identified => no rights
            return false;
        }
       $role = $this->getState("role");
        if ($role === 'admin') {
            return true; // admin role has access to everything
        }
        // allow access if the operation request is the current user's role
        return ($operation === $role);
    }
}
?>

VIEW FORM:
<div id="mainmenu">
		<?php 
                $user = Yii::app()->user;
                $this->widget('zii.widgets.CMenu',array(
			'items'=>array(
				array('label'=>'Home', 'url'=>array('/site/index')),
				//array('label'=>'About', 'url'=>array('/site/page', 'view'=>'about')),
				//array('label'=>'Contact', 'url'=>array('/site/contact')),
                                array('label'=>'Create Account', 'url'=>array('/RRegister/create'),'visible'=>$user->checkAccess('admin')),
                                array('label'=>'Amount Deposit', 'url'=>array('/RDEposit/create'),'visible'=>$user->checkAccess('staff')),
                                array('label'=>'Amount Transaction', 'url'=>array('/RTransaction/create'),'visible'=>$user->checkAccess('staff')),
                                array('label'=>'Amount Withdraw', 'url'=>array('/RWithdraw/create'),'visible'=>$user->checkAccess('normal')),
				array('label'=>'Login', 'url'=>array('/site/login'), 'visible'=>Yii::app()->user->isGuest),
				array('label'=>'Logout ('.Yii::app()->user->name.')', 'url'=>array('/site/logout'), 'visible'=>!Yii::app()->user->isGuest)
			),
		)); ?>
	</div><!-- mainmenu -->


0

#14 User is offline   dhivyahari 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 7
  • Joined: 23-September 13

Posted 22 October 2013 - 04:39 AM

Hi ! good noon...
I have to know how to add rows dynamically using jquery .give ur sugesstion
0

#15 User is offline   KoushikSantra 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 2
  • Joined: 17-August 14

Posted 26 August 2014 - 03:04 PM

View PostEdoFre, on 27 April 2011 - 08:08 AM, said:

I might be horribly wrong as I've not read the book, but it makes sense to me that you don't need to give the id of the user in the checkAcces() method as you're executing it from within the Yii::app()->user.

Have you tried?

if(Yii::app()->user->checkAccess('createUser'))



Sir, I think we can pass id as a secund argument http://www.yiiframew...ckAccess-detail
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users