Temat: RecordControllBehavior - wersja alpha
Z zalozenia ma sprawdzac uprawnienia do dowolnego rekordu podczas wykonywania operacji CRUD, w chwili obecenj mocno niedorobiony zwlaszcza callback beforeFind... Model w ktorym sprawdzamy uprawnienia uzytkownika musi miec ustawione pole aroId - ktore na chwil obecna jest id uzytkownika dla z tabeli users.
<?php
App::import("Component","Acl");
class RecordControllBehavior extends ModelBehavior
{
private $Acl;
private $Aro;
private $Aco;
public function setup($model,$config){
$this->Acl = new AclComponent();
$this->Aro = $model->getModelObject("Aro");
$this->Aco = $model->getModelObject("Aco");
}
public function beforeFind($model,$queryData) {
if(empty($model->aroId))
return false;
//TODO: uwglednic warunki OR, NOT i IN
if(!empty($queryData['conditions'][$model->primaryKey])):
if($this->Acl->check(array('model' => 'User', 'foreign_key' => $model->aroId), array("model" => $model->name , "foreign_key" => $queryData['conditions'][$model->primaryKey]), "read") !== true)
return false;
else
return $queryData;
endif;
$aco = $this->Aco->find('first', array('conditions' => array('alias' => $model->name), "fields" => array("id", "lft","rght")));
$acos = set::extract($this->Aco->find('all', array('recursive' => -1, 'conditions' => array('lft >=' => $aco['Aco']['lft'], 'rght <=' => $aco['Aco']['rght'], "NOT" =>array("id" => $aco['Aco']['id'])), "fields" =>array("foreign_key"))),"{n}.Aco.foreign_key");
$stack = array();
foreach($acos as $aco)
if($this->Acl->check(array('model' => 'User', 'foreign_key' => $model->aroId),array("model" => $model->name , "foreign_key" => $aco), "read"))
$stack[] = $aco;
$queryData['conditions'][$model->primaryKey] = $stack;
return $queryData;
}
public function beforeSave($model,$options) {
if(empty($model->aroId))
return false;
if(empty($model->data[$model->name][$model->primaryKey])) {
if($this->Acl->check(array('model' => 'User', 'foreign_key' => $model->aroId), $model->name, "create") !== true)
return false;
} else
if($this->Acl->check(array('model' => 'User', 'foreign_key' => $model->aroId), array("model" => $model->name , "foreign_key" => $model->data[$model->name][$model->primaryKey]), "update") !== true)
return false;
return true;
}
public function beforeDelete($model, $cascade) {
if(empty($model->aroId))
return false;
if($this->Acl->check(array('model' => 'User', 'foreign_key' => $model->aroId), array("model" => $model->name , "foreign_key" => $model->id), "delete") !== true)
return false;
return true;
}
}tabele :
CREATE TABLE IF NOT EXISTS `products` (
`id` int(10) NOT NULL auto_increment,
`name` varchar(32) NOT NULL,
`tit` varchar(32) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=12 ;
--
-- Dumping data for table `products`
--
INSERT INTO `products` (`id`, `name`, `tit`) VALUES
(2, 'pr2', ''),
(3, 'pr3', ''),
(4, 'pr4', ''),
(5, 'pr5', ''),
(6, 'pr6', ''),
(7, 'pr7', ''),
(8, 'pr8', ''),
(9, 'pr9', ''),
(10, 'pr10', '');CREATE TABLE IF NOT EXISTS `users` (
`id` int(10) NOT NULL auto_increment,
`name` varchar(32) NOT NULL,
`login` varchar(32) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
--
-- Dumping data for table `users`
--
INSERT INTO `users` (`id`, `name`, `login`) VALUES
(1, 'user1', 'user1'),
(2, 'user2', 'user2'),
(3, 'user3', 'user3'),
(4, 'user4', 'user4'),
(5, 'user5', 'user5'),
(6, 'user6', 'user6');acos ... aros
$aro = new Aro();
$aco = new Aco();
$groups = array(
0 => array(
'alias' => 'Product'
));
foreach($groups as $data)
{
//Remember to call create() when saving in loops...
$aco->create($data);
//Save data
$aco->save();
}
$users = array(
0 => array(
'alias' => 'Product[1]',
'parent_id' => 1,
'model' => 'Product',
'foreign_key' => 1,
),
1 => array(
'alias' => 'Product[2]',
'parent_id' => 1,
'model' => 'Product',
'foreign_key' => 2,
),
2 => array(
'alias' => 'Product[3]',
'parent_id' => 1,
'model' => 'Product',
'foreign_key' => 3,
),
3 => array(
'alias' => 'Product[4]',
'parent_id' => 1,
'model' => 'Product',
'foreign_key' => 4,
),
4 => array(
'alias' => 'Product[5]',
'parent_id' => 1,
'model' => 'Product',
'foreign_key' => 5,
),
5 => array(
'alias' => 'Product[6]',
'parent_id' => 1,
'model' => 'Product',
'foreign_key' => 6,
),
6 => array(
'alias' => 'Product[7]',
'parent_id' => 1,
'model' => 'Product',
'foreign_key' => 7,
),
7 => array(
'alias' => 'Product[8]',
'parent_id' => 1,
'model' => 'Product',
'foreign_key' => 8,
),
8 => array(
'alias' => 'Product[9]',
'parent_id' => 1,
'model' => 'Product',
'foreign_key' => 9,
),
9 => array(
'alias' => 'Product[10]',
'parent_id' => 1,
'model' => 'Product',
'foreign_key' => 10,
),
);
//Iterate and create AROs (as children)
foreach($users as $data)
{
//Remember to call create() when saving in loops...
$aco->create($data);
//Save data
$aco->save();
}
//Here's all of our group info in an array we can iterate through
$groups = array(
0 => array(
'alias' => 'User'
),
1 => array(
'alias' => 'Admin'
),
);
//Iterate and create ARO groups
foreach($groups as $data)
{
//Remember to call create() when saving in loops...
$aro->create($data);
//Save data
$aro->save();
}
$users = array(
0 => array(
'alias' => 'User[1]',
'parent_id' => 1,
'model' => 'User',
'foreign_key' => 1,
),
1 => array(
'alias' => 'User[2]',
'parent_id' => 1,
'model' => 'User',
'foreign_key' => 2,
),
2 => array(
'alias' => 'User[3]',
'parent_id' => 1,
'model' => 'User',
'foreign_key' => 3,
),
3 => array(
'alias' => 'User[4]',
'parent_id' => 1,
'model' => 'User',
'foreign_key' => 4,
),
4 => array(
'alias' => 'User[5]',
'parent_id' => 1,
'model' => 'User',
'foreign_key' => 5,
),
5 => array(
'alias' => 'User[6]',
'parent_id' => 2,
'model' => 'User',
'foreign_key' => 6,
)
);
//Iterate and create AROs (as children)
foreach($users as $data)
{
//Remember to call create() when saving in loops...
$aro->create($data);
//Save data
$aro->save();
}
//Other action logic goes here...
$this->Acl->allow(array('model' => 'User', 'foreign_key' => 1), array('model' => "Product" , "foreign_key" => "1"),array("read"));
$this->Acl->allow(array('model' => 'User', 'foreign_key' => 1), array('model' => "Product" , "foreign_key" => "2"),array("read"));
$this->Acl->allow(array('model' => 'User', 'foreign_key' => 1), array('model' => "Product" , "foreign_key" => "3"),array("read"));
$this->Acl->allow(array('model' => 'User', 'foreign_key' => 1), array('model' => "Product" , "foreign_key" => "4"),array("read"));
$this->Acl->allow(array('model' => 'User', 'foreign_key' => 1), array('model' => "Product" , "foreign_key" => "5"),array("read"));
$this->Acl->allow(array('model' => 'User', 'foreign_key' => 2), array('model' => "Product" , "foreign_key" => "6"),array("read"));
$this->Acl->allow(array('model' => 'User', 'foreign_key' => 2), array('model' => "Product" , "foreign_key" => "7"),array("read"));
$this->Acl->allow(array('model' => 'User', 'foreign_key' => 2), array('model' => "Product" , "foreign_key" => "8"),array("read"));
$this->Acl->allow(array('model' => 'User', 'foreign_key' => 3), array('model' => "Product" , "foreign_key" => "6"),array("read"));
$this->Acl->allow(array('model' => 'User', 'foreign_key' => 3), array('model' => "Product" , "foreign_key" => "7"),array("read"));
$this->Acl->allow(array('model' => 'User', 'foreign_key' => 3), array('model' => "Product" , "foreign_key" => "8"),array("read"));
$this->Acl->allow(array('model' => 'User', 'foreign_key' => 3), array('model' => "Product" , "foreign_key" => "1"),array("read"));
$this->Acl->allow(array('model' => 'User', 'foreign_key' => 3), array('model' => "Product" , "foreign_key" => "2"),array("read"));
$this->Acl->allow(array('model' => 'User', 'foreign_key' => 4), "Product",array("read"));
$this->Acl->allow("Admin", "Product");edit 1:
udalo sie zoptymalizować callback beforeFind, w chwili obecnej niezależnie od ilości liści w drzewie ( rekordów danego modelu) do sprawdzenia uprawnień (łącznie z dziedziczeniem uprawnień z gałęzi) potrzebne są tylko 2 zapytania. Jak będe mieć wenę to behavior będzie skończony dziś.
Ostatnio edytowany przez robal77 (2009-03-25 22:23:46)