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)