Closed aavolkoff closed 11 years ago
You can implement this by adding specific callbacks in your models:
<?php
class Robots extends Phalcon\Mvc\Model
{
public function beforeCreate()
{
//Check permissions here if the current user doesn't have permissions to
//create return false
$hasPermission = //...
if ($hasPermission) {
return false;
}
return true;
}
public function beforeUpdate()
{
//Check permissions here if the current user doesn't have permissions
//to update return false
$hasPermission = //...
if ($hasPermission) {
return false;
}
return true;
}
public function beforeDelete()
{
//Check permissions here if the current user doesn't have permissions
//to delete return false
$hasPermission = //...
if ($hasPermission) {
return false;
}
return true;
}
}
You can reuse the login by using a trait in PHP 5.4:
trait ModelRLS {
public function beforeCreate()
{
//...
}
public function beforeUpdate()
{
//...
}
public function beforeDelete()
{
//...
}
}
Or using a BaseClass in PHP 5.3:
class ModelRLS extends Phalcon\Mvc\Model {
public function beforeCreate()
{
//...
}
public function beforeUpdate()
{
//...
}
public function beforeDelete()
{
//...
}
}
Phalcon, thank you for the reply! Sure I did such things already.
But in my previous post I just wanted to tell, that main feature of the RLS is that it works directly in the database.
Advantages:
Now, to restrict the users access to some objects we need to pass PHQL queries to Phalcon (with "Where" statement) or parse and transform all queries in the callbacks of the PHQL?
I can tell you that in the ERP platforms RLS - is the slowest thing. So, if we will produce code in php for the RLS it will works very-very-very slowly.
You can access a database inside a model callback without using models, if you want to avoid the ORM layer:
class Robots \Phalcon\Mvc\Model
{
public function beforeCreate()
{
return MyRLS::getInstance()->hasPermission($this);
}
}
Then you could implement a user component accessing directly the database component or a PDO connection if you want:
<?php
class MyRLS extends Phalcon\DI\Injectable
{
private static $_instance = null;
public static function getInstance()
{
if (!self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}
public function hasPermission($model)
{
$sql = 'SELECT COUNT(*) FROM permissions WHERE ...';
$hasPermission = $this->db->fetchOne($sql);
return $hasPermission[0];
}
}
Also, you can return a custom meta-data according to those fields that the current user are restricted avoiding that the ORM query unnecessary fields:
class Robots \Phalcon\Mvc\Model
{
public function beforeCreate()
{
return MyRLS::getInstance()->hasPermission($this);
}
}
The user-component returns a custom array (http://docs.phalconphp.com/en/latest/reference/models.html#manual-meta-data) with the attributes allowed to the user:
<?php
class MyRLS extends Phalcon\DI\Injectable
{
public function getModelMetaData()
{
if ($this->session->get('user') == 'Peter') {
return array(
//...
);
}
return array(
//...
);
}
}
Additionally caching the user permissions in a fast backend like APC, Redis, Memcached or any other NoSQL database could help you to reduce the need of continuously query the SQL database to check permissions.
I think that the RLS for the ACL is a must.
Code example:
There may be another functions, such as: