Jump to content
Larry Ullman's Book Forums

Please Explain Routing Rules Precisely !


Ziggi
 Share

Recommended Posts

You first need to define the problem before you look for a solution. Generic help is hard to give you. Write down all functionality you need to implement such a solution before you start coding.

 

It could for example be something like this:

1. Not authenticated users cannot view static pages.

2. User X could be allowed to watch page X, Y, Z, but not A, B or C. Should we do this using a white list or blacklist approach? The solution selected should be the simplest. If a user more often than not are ALLOWED to view a page, a blacklist might make sense. If only some of the X number of pages is available, do a whitelist approach.

3. Page E, F and G requires a certain access level. How do we solve this?

 

From there on, we can start to define some generic rules.

- If a user is not logged in, he is denied

- We must check a blacklist/whitelist for allowed pages

- We must check access levels

 

This is a stupid example. I don't know what you need to implement here. However, you SHOULD use such an approach to define your problem. With a clear definition, everything is much more simple. It's also much more simple to help you that way. As a bonus, when a problem is clearly defined, you more often realize how you can actually solve the problem yourself.

Link to comment
Share on other sites

As I am talking about simple site, Iwouldlike to keep all access rules in Controller.php - common for entire website.

 

So, there can be something like:

 

array(
'allow',
'actions'=>array('about'),
'users'=>array('*'),
),
array(
'allow',
'actions'=>array('help'),
'users'=>array('@'),
),
array(
'deny',
'users'=>array('*'),
),

 

as you can see, according these rules everybody can access (static) page 'About' but only registered users can access (also static) page 'Help'. Of course, in general sense you may have more specific rules for particular static pages (including IP rules).

 

But in my implementation all pages are served through 'missingAction' handler and none of these rules is applied!

 

Consequently, I would like to evaluate these rules in explicit manner - preferably 'parsing' all respective data ($user,$controller,$action,$ip,$verb) through CAccessRule 'isUserAllowed' public method to get authoritative feedback from the filter.

 

But I do not know what is the right way to access CAccessControlFilter...

Link to comment
Share on other sites

Well,

 

I've got it!

 

Presuming these are global access rules defined in components/Controller.php:

 

 public function accessRules(){
 return array(
	 array( // these pages are accessible by all (AJAX captcha is included here)
		 'allow',
		 'actions'=>array('index', 'about'),
		 'users'=>array('*'),
	 ),
	 array( // these pages are for non-logged-in users only
		 'allow',
		 'actions'=>array(''),
		 'users'=>array('?'),
	 ),
	 array( // these pages are for loged-in users only
		 'allow',
		 'actions'=>array('manage', 'help'),
		 'users'=>array('@'),
	 ),
	 array( // black access to everything what was not explicite allowed
		 'deny',
		 'users'=>array('*'),
	 ),
 );
}

 

Presuming both 'about' and 'help' pages are static ones, I define the following StaticController to handle static pages:

 

<?php

class StaticController extends Controller
{
private $akcja;

public function getAkcja()
{
 return $this->akcja;
}

/**
 * This is the action to handle external exceptions.
 */
public function actionerror()
{
 if($error=Yii::app()->errorHandler->error)
 {
	 if(Yii::app()->request->isAjaxRequest)
		 echo $error['message'];
	 else
		 $this->render('error', $error);
 }
}

/**
 * This is the action to render static files as missing actions.
 */
public function missingAction($akcja){
 $this->akcja = $akcja;
 $views = $this->getViewPath();
 if(file_exists($views . "/" . $akcja . ".php")){
	 $this->checkAccess(Yii::app()->user, $akcja);
	 $this->render($akcja);
 }else{
	 throw new CHttpException(404,'Page not found!');
 }
}

public function checkAccess($user, $akcja)
{
 include_once(Yii::getFrameworkPath() . '/web/auth/CAccessControlFilter.php');
 $fa = new FakeAction($akcja);
 $fc = CFilterChain::create($this, $fa, $this->filters());
 $acf = new CAccessControlFilter();
 $acf->filter($fc);

}
}

class FakeAction
{
public function __construct($id)
{
 $this->id = $id;
}

public function getId()
{
 return $this->id;
}

public function runWithParams($param){
 return true;
}
}

 

This code contains minimalistic 'FakeAction' class. This class is used to generate a "dummy action" object what has only two methods neccessary to pass through the rest of the pipe. This is used to create filterChain object what is then supplied as an argument of the 'filter' method of AccessControlFilter object. In case of success (user is allowed to use given action) - ACFilter runs a supplied 'dummy' action what effectively does nothing and the process goes back to the 'missingAction' handler what renders the respective view. In case of failure (user is disallowed to use given action), ACFilter throws appropriate exception and access is effectively denied.

 

Consequently, as ecpected "About' page is availabe to anybody while 'Help" page is only accessible by registered users. The access controll for static pages is now driven in the same manner as for dynamic ones, so we maintain convention consistency.

 

I hope that could be helpful for the Yii community.

 

Rgs,

  • Upvote 1
Link to comment
Share on other sites

 Share

×
×
  • Create New...