2008-09-10 7 views
21

मैं केकेपीएचपी में एसीएल को लागू करने के लिए संघर्ष कर रहा हूं। cake manual के साथ-साथ कई अन्य ट्यूटोरियल, ब्लॉग पोस्ट इत्यादि में प्रलेखन पढ़ने के बाद, मुझे अरन जॉनसन के उत्कृष्ट ट्यूटोरियल मिले, जिसने कई अंतराल को भरने में मदद की है। उनके उदाहरण दूसरों के साथ संघर्ष करने लगते हैं, हालांकि मैंने कुछ स्थानों पर देखा है - खासकर एआरओ वृक्ष संरचना में वह उपयोग करता है।केकेपीएचपी एसीएल डाटाबेस सेटअप: एआरओ/एसीओ संरचना?

अपने examples में उनके उपयोगकर्ता समूह एक कैस्केडिंग पेड़ के रूप में स्थापित किए जाते हैं, जिसमें सबसे सामान्य उपयोगकर्ता प्रकार पेड़ के शीर्ष पर होता है, और इसके बच्चे प्रत्येक प्रतिबंधित प्रतिबंधित प्रकार के लिए शाखाबद्ध होते हैं। कहीं और मैंने आमतौर पर प्रत्येक उपयोगकर्ता प्रकार को एक सामान्य जेनेरिक उपयोगकर्ता प्रकार के बच्चे के रूप में देखा है।

आप केकेपीएचपी में अपने एआरओ और एसीओ कैसे स्थापित करते हैं? किसी भी और सभी सुझावों की सराहना की!

+0

मैं यहां माइमा() की तलाश कर रहा हूं, जिसे मैंने परिभाषित करने की कोशिश की, लेकिन ऐसा लगता है कि यह पहले से मौजूद है। –

उत्तर

49

केकपीएचपी की अंतर्निर्मित एसीएल प्रणाली वास्तव में शक्तिशाली है, लेकिन वास्तविक कार्यान्वयन विवरण के संदर्भ में खराब तरीके से दस्तावेज किया गया है। एक प्रणाली जिसे हमने कई केकपीएचपी-आधारित परियोजनाओं में कुछ सफलता के साथ उपयोग किया है, निम्नानुसार है।

यह कुछ समूह-स्तरीय एक्सेस सिस्टम का एक संशोधन है जो documented elsewhere रहा है। हमारे सिस्टम के उद्देश्य एक सरल प्रणाली है जहां उपयोगकर्ता समूह-स्तर पर अधिकृत हैं, लेकिन उनके द्वारा बनाए गए आइटमों पर प्रति अतिरिक्त उपयोगकर्ता अधिकार हो सकते हैं, या प्रति उपयोगकर्ता आधार पर। हम aros_acos तालिका में प्रत्येक उपयोगकर्ता (या अधिक विशेष रूप से प्रत्येक एआरओ के लिए) के लिए एक विशिष्ट प्रविष्टि बनाने से बचना चाहते थे।

हमारे पास एक उपयोगकर्ता तालिका है, और एक भूमिका तालिका है।

उपयोगकर्ता

user_id, user_name, role_id

भूमिकाओं

id, role_name

हर पात्र के लिए एआरओ वृक्ष बनाएं (हम आम तौर पर 4 भूमिका है - अनधिकृत अतिथि (आईडी 1), अधिकृत उपयोगकर्ता (आईडी 2), साइट मॉडरेटर (आईडी 3) और प्रशासक (आईडी 4)):

cake acl create aro/Role.1

cake acl create aro 1 Role.2 ... etc ...

इस के बाद, आप इन सभी के लिए उपनाम जोड़ने के लिए, के रूप में केक कमांड लाइन टूल यह ऐसा नहीं करता है एसक्यूएल या phpMyAdmin या इसी तरह का उपयोग करने के लिए है। हम सभी के लिए 'भूमिका- {आईडी}' और 'उपयोगकर्ता- {आईडी}' का उपयोग करते हैं। अब तक तो सामान्य

cake acl create aco 'ROOT' 'MyController' ... etc ...

:

cake acl create aco/'ROOT'

और उसके बाद इस रूट एक के तहत सभी नियंत्रकों के लिए acos बना सकते हैं -

हम तो एक रूट ACO पैदा करते हैं। हम _editown नामक aros_acos तालिका में एक अतिरिक्त फ़ील्ड जोड़ते हैं जिसे हम एसीएल घटक के actionMap में अतिरिक्त क्रिया के रूप में उपयोग कर सकते हैं।

CREATE TABLE IF NOT EXISTS `aros_acos` (
`id` int(11) NOT NULL auto_increment, 
`aro_id` int(11) default NULL, 
`aco_id` int(11) default NULL, 
`_create` int(11) NOT NULL default '0', 
`_read` int(11) NOT NULL default '0', 
`_update` int(11) NOT NULL default '0', 
`_delete` int(11) NOT NULL default '0', 
`_editown` int(11) NOT NULL default '0', 
PRIMARY KEY (`id`), 
KEY `acl` (`aro_id`,`aco_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

हम तो सेटअप प्रमाणीकरण घटक 'crud' विधि है, जो अनुरोध किया नियंत्रक/एक AclComponent :: जांच के खिलाफ कार्रवाई की पुष्टि करता है उपयोग करने के लिए कर सकते हैं()। App_controller में हमारे पास कुछ है:

private function setupAuth() { 
    if(isset($this->Auth)) { 
     .... 
     $this->Auth->authorize = 'crud'; 
     $this->Auth->actionMap = array('index'  => 'read', 
         'add'  => 'create', 
         'edit'  => 'update' 
         'editMine' => 'editown', 
         'view'  => 'read' 
         ... etc ... 
         ); 
     ... etc ... 
    } 
} 

फिर से, यह काफी मानक केकेपीएचपी सामान है।

private function checkAccess() { 
    if(!$user = $this->Auth->user()) { 
     $role_alias = 'Role-1'; 
     $user_alias = null; 
    } else { 
     $role_alias = 'Role-' . $user['User']['role_id']; 
     $user_alias = 'User-' . $user['User']['id']; 
    } 

    // do we have an aro for this user? 
    if($user_alias && ($user_aro = $this->User->Aro->findByAlias($user_alias))) { 
     $aro_alias = $user_alias; 
    } else { 
     $aro_alias = $role_alias; 
    } 

    if ('editown' == $this->Auth->actionMap[$this->action]) { 
     if($this->Acl->check($aro_alias, $this->name, 'editown') and $this->isMine()) { 
      $this->Auth->allow(); 
     } else { 
      $this->Auth->authorize = 'controller'; 
      $this->Auth->deny('*'); 
     } 
    } else { 
     // check this user-level aro for access 
     if($this->Acl->check($aro_alias, $this->name, $this->Auth->actionMap[$this->action])) { 
      $this->Auth->allow(); 
     } else { 
      $this->Auth->authorize = 'controller'; 
      $this->Auth->deny('*'); 
     } 
    } 
} 

setupAuth() और checkAccess() तरीकों AppController 'में कहा जाता है: हम तो एक समूह एआरओ या प्रदर्शन के लिए एआरओ एक उपयोगकर्ता की जाँच करने के लिए कि क्या जांच करने के लिए AppController कि समूह-स्तरीय सामान में कहते हैं में एक checkAccess विधि है एस beforeFilter() कॉलबैक। AppControler में भी isMine विधि है (नीचे देखें) जो केवल जांचता है कि अनुरोधित आइटम का user_id वर्तमान में प्रमाणीकृत उपयोगकर्ता जैसा ही है। मैंने इसे स्पष्टता के लिए छोड़ दिया है।

वास्तव में यह सब कुछ है। इसके बाद आप अनुमति दे सकते हैं/विशेष समूहों विशिष्ट acos तक पहुंच बनाना अस्वीकार -

cake acl grant 'Role-2' 'MyController' 'read'

cake acl grant 'Role-2' 'MyController' 'editown'

cake acl deny 'Role-2' 'MyController' 'update'

cake acl deny 'Role-2' 'MyController' 'delete'

मुझे यकीन है कि आप चित्र प्राप्त कर रहा हूँ।

वैसे भी

, इस उत्तर के रास्ते से अधिक समय तक मैं यह इरादा है, और यह शायद कोई मतलब नहीं करने के लिए अगले है, लेकिन मुझे आशा है कि यह आप के लिए कुछ सहायता प्रदान की ...

- संपादन -

अनुरोध के रूप में, यहां एक संपादित किया गया है (पूरी तरह से स्पष्टता के लिए - हमारे बॉयलरप्लेट कोड में बहुत सी चीजें हैं जो यहां अर्थहीन है) isMine() विधि जो हमारे पास हमारे ऐप कंट्रोलर में है। मैंने बहुत सारी त्रुटियों की जांच भी हटा दी है, लेकिन यह इसका सार है:

function isMine($model=null, $id=null, $usermodel='User', $foreignkey='user_id') { 
    if(empty($model)) { 
     // default model is first item in $this->uses array 
     $model = $this->uses[0]; 
    } 

    if(empty($id)) { 
     if(!empty($this->passedArgs['id'])) { 
     $id = $this->passedArgs['id']; 
     } elseif(!empty($this->passedArgs[0])) { 
      $id = $this->passedArgs[0]; 
     } 
    } 

    if(is_array($id)) { 
     foreach($id as $i) { 
      if(!$this->_isMine($model, $i, $usermodel, $foreignkey)) { 
       return false; 
      } 
     } 

     return true; 
    } 

    return $this->_isMine($model, $id, $usermodel, $foreignkey); 
} 


function _isMine($model, $id, $usermodel='User', $foreignkey='user_id') { 
    $user = Configure::read('curr.loggedinuser'); // this is set in the UsersController on successful login 

    if(isset($this->$model)) { 
     $model = $this->$model; 
    } else { 
     $model = ClassRegistry::init($model); 
    } 

    //read model 
    if(!($record = $model->read(null, $id))) { 
     return false; 
    } 

    //get foreign key 
    if($usermodel == $model->alias) { 
     if($record[$model->alias][$model->primaryKey] == $user['User']['id']) { 
      return true; 
     } 
    } elseif($record[$model->alias][$foreignkey] == $user['User']['id']) { 
     return true; 
    } 

    return false; 
} 
+1

:-) इस तरह के एक महान ट्यूटोरियल के लिए धन्यवाद। यह मुझे भी बचाया .. :-) –

+0

सरल और सबसे लेख – aWebDeveloper

+0

@ दाऊद की तुलना में बेहतर: CakePHP 2.x उपयोग कर रहा हूँ और इस केक एसीएल तरह aco कुछ जोड़ने की कोशिश कर aco नियंत्रकों उपयोगकर्ता तो केक एसीएल बनाने aco उपयोगकर्ता सूचकांक बनाने 1 कमांड चलाने से मुझे त्रुटि मिल जाएगी – anasanjaria