RBAC with defaultRoles

I have been up and down Google and the Yii forums and have yet to figure out my issue so I am hoping someone can help. I have been following along the Agile book (but building my own app) and I have hit some snags implementing RBAC. It was only after searching that I realized I needed to accessRules to define what it allowed and what is denied (the book led me to believe I would add an "if" condition at the beginning of each action method).

I have defined two defaultRoles: guest and authenticated. They each have business rules defining them as guest or not as guest. Guests can read everything, authenticated users can update their own user record, and another “owner” role can create, update, delete anything. When viewing the site as a guest, I can read everything but trying to do anything more redirects me to the login page–as expected. However, whenever I log in I can do all of the other actions (create, update, delete) but I cannot read anything. I thought I had properly defined my authItems to allow guest to read, authenticated to update own user and anything guest has, and owner to anything authenticated has (and by extension guest) and all other create, update, delete actions. I even tried removing the addChild for authenticated role from the “owner” role since by definition, someone with the owner role would be authenticated so they should have both roles. I’m rambling now as I have been searching this for hours and just plain don’t know where to turn. Someone please help! Why can I not read anything when logged in as an owner and what else am I missing to help this make more sense? Thank you for all replies!

main.php




'authManager'=>array(

	'class'=>'CDbAuthManager',

	'connectionID'=>'db',

	'itemTable'=>'{{auth_item}}',

	'assignmentTable'=>'{{auth_assignment}}',

	'itemChildTable'=>'{{auth_item_child}}',

	'defaultRoles'=>array('guest','authenticated'),

),

commands\shell\RbacCommand.php


<?php

class RbacCommand extends CConsoleCommand

{

	/**

	 * Execute the action.

	 * @param array command line parameters specific for the command

	 */

	public function run($args)

	{

		$auth=Yii::app()->authManager;

		

		// remove all operations, roles, child relationships, and assignments

		$auth->clearAll();


		// create operations for User

		$auth->createOperation("readUser","Read existing User");

		$auth->createOperation("adminUser","Manage Users");

		$auth->createOperation("createUser","Create a new User");

		$auth->createOperation("updateUser","Update a User");

		$auth->createOperation("deleteUser","Delete a User");

		$auth->createOperation("updateOwnUser","Update own User"); // needs bizRule

		// create operations for Author

		$auth->createOperation("readAuthor","Read existing Author");

		$auth->createOperation("adminAuthor","Manage Authors");

		$auth->createOperation("createAuthor","Create a new Author");

		$auth->createOperation("updateAuthor","Update an Author");

		$auth->createOperation("deleteAuthor","Delete an Author");

		// create operations for Quote

		$auth->createOperation("readQuote","Read existing Quote");

		$auth->createOperation("adminQuote","Manage Quotes");

		$auth->createOperation("createQuote","Create a new Quote");

		$auth->createOperation("updateQuote","Update a Quote");

		$auth->createOperation("deleteQuote","Delete a Quote");

		// create operations for Drink

		$auth->createOperation("readDrink","Read existing Drink");

		$auth->createOperation("adminDrink","Manage Drinks");

		$auth->createOperation("createDrink","Create a new Drink");

		$auth->createOperation("updateDrink","Update a Drink");

		$auth->createOperation("deleteDrink","Delete a Drink");

		// create operations for Product

		$auth->createOperation("readProduct","Read existing Product");

		$auth->createOperation("adminProduct","Manage Products");

		$auth->createOperation("createProduct","Create a new Product");

		$auth->createOperation("updateProduct","Update an Product");

		$auth->createOperation("deleteProduct","Delete an Product");

		// create operations for Ingredient

		$auth->createOperation("readIngredient","Read existing Ingredient");

		$auth->createOperation("adminIngredient","Manage Ingredients");

		$auth->createOperation("createIngredient","Create a new Ingredient");

		$auth->createOperation("updateIngredient","Update an Ingredient");

		$auth->createOperation("deleteIngredient","Delete an Ingredient");

		// create operations for Unit

		$auth->createOperation("readUnit","Read existing Unit");

		$auth->createOperation("adminUnit","Manage Units");

		$auth->createOperation("createUnit","Create a new Unit");

		$auth->createOperation("updateUnit","Update an Unit");

		$auth->createOperation("deleteUnit","Delete an Unit");

		

		// create guest role and add read operations

		$bizRule="return Yii::app()->user->isGuest;";

		$role=$auth->createRole("guest", "guest user", $bizRule);

		$role->addChild("readAuthor");

		$role->addChild("readQuote");

		$role->addChild("readDrink");

		$role->addChild("readProduct");

		$role->addChild("readIngredient");

		$role->addChild("readUnit");

		

		// create authenticated role and add guest role and update own user permission

		$bizRule="return !Yii::app()->user->isGuest;";

		$role=$auth->createRole("authenticated", "authenticated user", $bizRule);

		$role->addChild("guest");

		$role->addChild("UpdateOwnUser");


		// create owner role and assign all create, update, and delete permissions

		$role=$auth->createRole("owner", "owner user");

		//$role->addChild("authenticated"); // should not be necessary, owner will be authenticated

		$role->addChild("readUser");

		$role->addChild("adminUser");

		$role->addChild("createUser");

		$role->addChild("updateUser");

		$role->addChild("deleteUser");

		$role->addChild("adminQuote");

		$role->addChild("createQuote");

		$role->addChild("updateQuote");

		$role->addChild("deleteQuote");

		$role->addChild("adminAuthor");

		$role->addChild("createAuthor");

		$role->addChild("updateAuthor");

		$role->addChild("deleteAuthor");

		$role->addChild("adminDrink");

		$role->addChild("createDrink");

		$role->addChild("updateDrink");

		$role->addChild("deleteDrink");

		$role->addChild("adminProduct");

		$role->addChild("createProduct");

		$role->addChild("updateProduct");

		$role->addChild("deleteProduct");

		$role->addChild("adminIngredient");

		$role->addChild("createIngredient");

		$role->addChild("updateIngredient");

		$role->addChild("deleteIngredient");

		$role->addChild("adminUnit");

		$role->addChild("createUnit");

		$role->addChild("updateUnit");

		$role->addChild("deleteUnit");


		// assign owner role

		$auth->assign("owner","1");


		// success message

		echo "Authorization hierarchy successfully generated.";

	}

}

AuthorController.php




public function accessRules()

{

	return array(

		array('allow',

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

			'roles'=>array('readAuthor'), // use for listing all authors and viewing 1 author

		),

		array('allow',

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

			'roles'=>array('adminAuthor'), // "manage" page with search

		),

		array('allow',

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

			'roles'=>array('createAuthor'),

		),

		array('allow',

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

			'roles'=>array('updateAuthor'),

		),

		array('allow',

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

			'roles'=>array('deleteAuthor'),

		),

		array('deny',

			'users'=>array('*'), // deny all other action/role combinations

		),

	);

}



I think I’ve narrowed down the problem to the snippet of code below–more specifically the bizRule for the authenticated vs guest default roles. When someone is authenticated, they should inherit the permissions of the guest role, but, because the guest bizRule specifices they must be a guest, it returns false and does not allow the read permissions. Can anyone explain the proper way to implement guest and authenticated default roles with proper inheritance?

Hi,See this issue for more information.I recommend removing the bizrule for the guest role in its entirety. I think this is a flaw in how Yii handles RBAC bizrules but its not me to decide on this :slight_smile: (also, I’m not 100% sure that this is Yii’s flaw. Could be documentation thing and bad inspiration (for me at least) from the default code in RBAM extension) .Good luck with it,Boaz.

Thanks Boaz. At least for me, I think it was a misunderstanding of the documentation regarding default roles found on this page. I took the examples for guest and authenticated default users to be something you would use in tandem when in fact they would not be used together.

Thinking more about the process and your recommendation of removing the bizRule from guest it now makes more sense to me. If every user is assigned the default roles, there needs to be no business logic on the guest user (unless, of course, you had items that guests could perform that authenticated users could not). I have left the authenticated bizRule in place but removed it for guest and everything is working as expected.

I think this is just a result of documentation that lacks real-world scenarios (which are immensely helpful to people like myself).

In any event, the solution (for anyone stumbling across this post) is to have NO bizRules for the guest role, but have the appropriate bizRule for authenticated users.

I wasn’t aware that the official docs use the same business rule for Guest as I was told was a “logic problem created by the user”… . I just added that to the issue report but I doubt it will change anything. Well, at least we have dug to the bottom of this, know where this stems from and have a solution to the problem.