Ask your Symfony questions! Pay money and get answers fast! (more info)

Row level security enforcement Symfony

  • SOLVED

Does anyone know of a plugin that allows row-level security enforcement? In other words, I have a table called "import businesses" and some of the rows in this table have a security clearance level of "assistant_editor" whereas other rows in the table have a security clearance level of "editor", and the assistant_editors can not edit or delete or see the rows marked for "editors"?

Answers (2)

2010-11-13

Nate Flink answers:

The way I have implemented this is in projects is by adding a "credential" column that can also be a foreign key to the sf guard permissions mechanism.

That way any rows that need clearance can either be linked to a group or a specific permission.

This assumes your using sf guard.

2010-11-14

Florian Klein answers:

Hi,

As said in the [[LINK href="http://www.symfony-project.org/reference/1_4/en/06-Admin-Generator#chapter_06_sub_credentials"]]Symfony reference book[[/LINK]],

<em>Credentials

Actions in the admin generator (on the list and on the forms) can be hidden, based on the user credentials using the credential option (see below). However, even if the link or button does not appear, the actions must still be properly secured from illicit access. The credential management in the admin generator only takes care of the display.

The credential option can also be used to hide columns on the list page.</em>

You can add credentials constraints to avoid the display of edit / delete actions at row level.

But controller actions are still responsive.
You can then use the symfony routing [[LINK href="http://www.symfony-project.org/reference/1_4/en/10-Routing#chapter_10_sub_model_methods"]]configuration[[/LINK]] to customize the method used to retrieve the object at the routing level, by injecting the sfUser in the routing logic.


If you're working with Doctrine:


// in apps/frontend/config/frontendConfiguration.class.php
public function configure()
{
$this->getEventDispatcher()->connect('context.load_factories', array($this, 'listenToLoadFactoriesEvent'));
}

public function listenToLoadFactoriesEvent(sfEvent $event)
{
Doctrine::getTable('ImportBusinesses')->setSfUser($event->getSubject()->getUser());
}


Then in your lib/model/doctrine/ImportBusinessesTable.class.php:

protected $sf_user;

public function getSfUser()
{
return $this->sf_user;
}

public function setSfUser(sfUser $user = null)
{
$this->sf_user = $sf_user;
}

public function getObjectByUserCredentialQuery(Doctrine_query $query)
{
if($this->getSfUser()->hasCredential('assistant_editor')) {
$query->andWhere($query->getRootAlias().'.credential = ?', 'assistant_editor');
}

return $query;
}



You still just have to configure your routes to use this new method:
in your apps/frontend/config/routing.yml:

my_doctrine_route:
method_for_query: getObjectByUserCredentialQuery



You'll maybe to modify this example code, it's just a POC.

Florian.