Bernhard Schussek introduced a very good idea of security aware routing:
use sfRouting to verify owner rights...
Here is my implementation :
// in lib/routing/securePropelRoute.class.php
/**
* secureObjectRoute represents a route that is bound to PHP object(s) which are owned by sfUser.
*
* An object route can represent a single object or a list of objects.
*
* @package symfony
* @subpackage routing
* @author Fabien Potencier
* @version SVN: $Id: sfObjectRoute.class.php 15850 2009-02-27 16:48:19Z fabien $
*/
class securePropelRoute extends sfPropelRoute
{
/**
* Constructor.
*
* @param string $pattern The pattern to match
* @param array $defaults An array of default parameter values
* @param array $requirements An array of requirements for parameters (regexes)
* @param array $options An array of options
*
* @see sfRoute
*/
public function __construct($pattern, array $defaults = array(), array $requirements = array(), array $options = array())
{
parent::__construct($pattern, $defaults, $requirements, $options);
}
public function getObjectAuthorizedFor(sfUser $user) {
parent::getObject();
if(!$this->verifyAccess($user)) {
throw new sfError404Exception(sprintf('Unable to find the %s object for sfUser %s with the following parameters "%s").', $this->options['model'], $user, str_replace("\n", '', var_export($this->filterParameters($this->parameters), true))));
}
return $this->object;
}
public function verifyAccess(sfUser $user) {
return true;
}
}
// in lib/routing/securePropelRouteCollection.class.php
/*
* This file is part of the symfony package.
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* securePropelRouteCollection represents a collection of routes bound to Propel objects.
*
* @package symfony
* @subpackage routing
* @author Fabien Potencier
* @version SVN: $Id: sfPropelRouteCollection.class.php 12755 2008-11-08 09:48:03Z fabien $
*/
class securePropelRouteCollection extends sfObjectRouteCollection
{
protected
$routeClass = 'securePropelRoute';
}
An exemple of routing definition in
test:
class: securePropelRouteCollection
options:
model: Test
module: test
prefix_path: test
column: id
with_wildcard_routes: true
Voilà !
The only thing you have to do is to customize the securePropelRoute::verifiyAccess method
to fit your needs, by surcharging it with a secureTestRoute class for example...
Let's see an example for the test route:
// in lib/routing/secureTestRoute.class.php
class secureTestRoute extends securePropelRoute
{
public function verifyAccess(sfUser $user) {
return $this->getObject()->getOwnerId() == $user->getId();
}
}
Then, you have to call
$this->getRoute()->getObjectAuthorizedFor($this->getUser())
in your actions.
But we've forgotten sfObjectRoute::getObjects() .... for the next time :)
