CakePHP Plugin ACL を利用する - 3
Plugin ACLを入れていきます。
7.Plugin ACLの導入をする。
・ダウンロードしたalaxos_acl_1.0.7.zipを解凍してaclフォルダを app/plugins に入れる。
・app/config/core.php の88行目の
のコメントを外す。
・app/config/routes.php に
を追加する。
・app/plugins/acl/config/bootstrap.php のソースをコピーして、app/config/bootstrap.php に貼り付ける
・app/config/bootstrap.phpに
とあるが
に変更する
8.アクセスして確認する。
これで何の問題もなく表示されるはずです!
あとは、ユーザー、グループ、ページ、メソッドが追加、削除されたときに
admin/aclにアクセスすればPluginACLが教えてくれます。
アクセスしたときにチェックしてくれるのが良いですね。
CakePHP Plugin ACL を利用する - 2
続き
4.UserとGroupの登録をする。
ユーザーの登録。グループIDは1に自動でなる。
5.ACLの初期設定をする。
<?php
function build_acl() {
if (!Configure::read('debug')) {
return $this->_stop();
}
$log = array();
$aco =& $this->Acl->Aco;
$root = $aco->node('controllers');
if (!$root) {
$aco->create(array('parent_id' => null, 'model' => null, 'alias' => 'controllers'));
$root = $aco->save();
$root['Aco']['id'] = $aco->id;
$log[] = 'Created Aco node for controllers';
} else {
$root = $root[0];
}
App::import('Core', 'File');
$Controllers = Configure::listObjects('controller');
$appIndex = array_search('App', $Controllers);
if ($appIndex !== false ) {
unset($Controllers[$appIndex]);
}
$baseMethods = get_class_methods('Controller');
$baseMethods[] = 'buildAcl';
$Plugins = $this->_getPluginControllerNames();
$Controllers = array_merge($Controllers, $Plugins);
// look at each controller in app/controllers
foreach ($Controllers as $ctrlName) {
$methods = $this->_getClassMethods($this->_getPluginControllerPath($ctrlName));
// Do all Plugins First
if ($this->_isPlugin($ctrlName)){
$pluginNode = $aco->node('controllers/'.$this->_getPluginName($ctrlName));
if (!$pluginNode) {
$aco->create(array('parent_id' => $root['Aco']['id'], 'model' => null, 'alias' => $this->_getPluginName($ctrlName)));
$pluginNode = $aco->save();
$pluginNode['Aco']['id'] = $aco->id;
$log[] = 'Created Aco node for ' . $this->_getPluginName($ctrlName) . ' Plugin';
}
}
// find / make controller node
$controllerNode = $aco->node('controllers/'.$ctrlName);
if (!$controllerNode) {
if ($this->_isPlugin($ctrlName)){
$pluginNode = $aco->node('controllers/' . $this->_getPluginName($ctrlName));
$aco->create(array('parent_id' => $pluginNode['0']['Aco']['id'], 'model' => null, 'alias' => $this->_getPluginControllerName($ctrlName)));
$controllerNode = $aco->save();
$controllerNode['Aco']['id'] = $aco->id;
$log[] = 'Created Aco node for ' . $this->_getPluginControllerName($ctrlName) . ' ' . $this->_getPluginName($ctrlName) . ' Plugin Controller';
} else {
$aco->create(array('parent_id' => $root['Aco']['id'], 'model' => null, 'alias' => $ctrlName));
$controllerNode = $aco->save();
$controllerNode['Aco']['id'] = $aco->id;
$log[] = 'Created Aco node for ' . $ctrlName;
}
} else {
$controllerNode = $controllerNode[0];
}
//clean the methods. to remove those in Controller and private actions.
foreach ($methods as $k => $method) {
if (strpos($method, '_', 0) === 0) {
unset($methods[$k]);
continue;
}
if (in_array($method, $baseMethods)) {
unset($methods[$k]);
continue;
}
$methodNode = $aco->node('controllers/'.$ctrlName.'/'.$method);
if (!$methodNode) {
$aco->create(array('parent_id' => $controllerNode['Aco']['id'], 'model' => null, 'alias' => $method));
$methodNode = $aco->save();
$log[] = 'Created Aco node for '. $method;
}
}
}
if(count($log)>0) {
debug($log);
}
}
function _getClassMethods($ctrlName = null) {
App::import('Controller', $ctrlName);
if (strlen(strstr($ctrlName, '.')) > 0) {
// plugin's controller
$num = strpos($ctrlName, '.');
$ctrlName = substr($ctrlName, $num+1);
}
$ctrlclass = $ctrlName . 'Controller';
return get_class_methods($ctrlclass);
}
function _isPlugin($ctrlName = null) {
$arr = String::tokenize($ctrlName, '/');
if (count($arr) > 1) {
return true;
} else {
return false;
}
}
function _getPluginControllerPath($ctrlName = null) {
$arr = String::tokenize($ctrlName, '/');
if (count($arr) == 2) {
return $arr[0] . '.' . $arr[1];
} else {
return $arr[0];
}
}
function _getPluginName($ctrlName = null) {
$arr = String::tokenize($ctrlName, '/');
if (count($arr) == 2) {
return $arr[0];
} else {
return false;
}
}
function _getPluginControllerName($ctrlName = null) {
$arr = String::tokenize($ctrlName, '/');
if (count($arr) == 2) {
return $arr[1];
} else {
return false;
}
}
/**
* Get the names of the plugin controllers ...
*
* This function will get an array of the plugin controller names, and
* also makes sure the controllers are available for us to get the
* method names by doing an App::import for each plugin controller.
*
* @return array of plugin names.
*
*/
function _getPluginControllerNames() {
App::import('Core', 'File', 'Folder');
$paths = Configure::getInstance();
$folder =& new Folder();
$folder->cd(APP . 'plugins');
// Get the list of plugins
$Plugins = $folder->read();
$Plugins = $Plugins[0];
$arr = array();
// Loop through the plugins
foreach($Plugins as $pluginName) {
// Change directory to the plugin
$didCD = $folder->cd(APP . 'plugins'. DS . $pluginName . DS . 'controllers');
// Get a list of the files that have a file name that ends
// with controller.php
$files = $folder->findRecursive('.*_controller\.php');
// Loop through the controllers we found in the plugins directory
foreach($files as $fileName) {
// Get the base file name
$file = basename($fileName);
// Get the controller name
$file = Inflector::camelize(substr($file, 0, strlen($file)-strlen('_controller.php')));
if (!preg_match('/^'. Inflector::humanize($pluginName). 'App/', $file)) {
if (!App::import('Controller', $pluginName.'.'.$file)) {
debug('Error importing '.$file.' for plugin '.$pluginName);
} else {
/// Now prepend the Plugin name ...
// This is required to allow us to fetch the method names.
$arr[] = Inflector::humanize($pluginName) . "/" . $file;
}
}
}
}
return $arr;
}
↓グループデータのidが1は全てアクセスできるという意味。
<?php
function initDB() {
$group =& $this->User->Group;
// 管理者グループには全てを許可する
$group->id = 1;
$this->Acl->allow($group, 'controllers');
}
・users_controller.phpとgroups_controller.phpの初期導入時の許可アクションの設定を無効にする。
<?php
//$this->Auth->allowedActions = array('*');
・initDBのメソッドを削除する。
・build_aclのメソッドを削除する。
6.認証とアクセス許可の確認をする。
アクセスするとログイン画面に飛ばされるはず。
ログイン画面で登録したユーザでログインする。
ユーザ一覧画面が見れたらOK。
これでこれから作る、アクセス制御設定ページもアクセスできる。
これでAUTHとACLの土台が出来上がった。
次が本題のPlugin ACLの導入。
CakePHP Plugin ACL を利用する - 1
http://www.alaxos.net/blaxos/pages/view/download_plugin_acl
アクセス制御をしたいと思い探したらありました。
使った感じはとてもわかりやすく操作性が最高に良いです。
AJAXで通信しているようでグループごと、ユーザーごとにページ、アクションが細かく制御できます。
制御盤みたいな感じでON/OFFをサクッと切替えれるのが良いですね。
これを使うためにはAUTHとACLの土台が出来ていないとだめです。
誰にでも出来る手順を作りました。何回も手順を確認したんで間違いないと思います。
まずはCakePHPでAuthコンポーネントを組み込み、ログイン機能を作る。
・ログインしたらユーザー一覧が閲覧できる。
・未ログインならユーザー一覧が閲覧できない。
まずはこれだけ。
1.環境
・CakePHP1.3.11
・PHP5.3.6
2.DBの作成
このまま貼り付けて実行。(俺はInnoDBになってるよ、使いたいほうで。)↓
CREATE TABLE IF NOT EXISTS `acos` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`parent_id` int(10) DEFAULT NULL,
`model` varchar(255) COLLATE utf8_unicode_ci DEFAULT '',
`foreign_key` int(10) unsigned DEFAULT NULL,
`alias` varchar(255) COLLATE utf8_unicode_ci DEFAULT '',
`lft` int(10) DEFAULT NULL,
`rght` int(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ;
--
-- テーブルの構造 `aros`
--
CREATE TABLE IF NOT EXISTS `aros` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`parent_id` int(10) DEFAULT NULL,
`model` varchar(255) COLLATE utf8_unicode_ci DEFAULT '',
`foreign_key` int(10) unsigned DEFAULT NULL,
`alias` varchar(255) COLLATE utf8_unicode_ci DEFAULT '',
`lft` int(10) DEFAULT NULL,
`rght` int(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ;
--
-- テーブルの構造 `aros_acos`
--
CREATE TABLE IF NOT EXISTS `aros_acos` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`aro_id` int(10) unsigned NOT NULL,
`aco_id` int(10) unsigned NOT NULL,
`_create` char(2) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`_read` char(2) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`_update` char(2) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`_delete` char(2) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ;
--
-- テーブルの構造 `cake_sessions`
--
CREATE TABLE IF NOT EXISTS `cake_sessions` (
`id` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`data` text COLLATE utf8_unicode_ci NOT NULL,
`expires` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--
-- テーブルの構造 `groups`
--
CREATE TABLE IF NOT EXISTS `groups` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ;
--
-- テーブルの構造 `users`
--
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`password` char(40) COLLATE utf8_unicode_ci NOT NULL,
`group_id` int(11) NOT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ;
3.AppControllerの作成
<?php
class AppController extends Controller {
public $components = array('Acl','Session','Auth','RequestHandler');
/*************************************************************************************
*Method : beforeFilter
*Process:
*************************************************************************************/
function beforeFilter() {
// AuthComponent の設定
$this->Auth->actionPath = 'controllers/';
$this->Auth->authorize = 'actions';
$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
$this->Auth->logoutRedirect = array('controller' => 'users', 'action' => 'login');
$this->Auth->loginRedirect = array('controller' => 'users', 'action' => 'index');
}
}
?>
4.UserとGroupのページを作る。
<?php
class UsersController extends AppController {
public $name = 'Users';
/*************************************************************************************
*Method : beforeFilter
*************************************************************************************/
function beforeFilter() {
parent::beforeFilter();
//初期導入用
$this->Auth->allowedActions = array('*');
}
/*************************************************************************************
*Method : index
*************************************************************************************/
function index() {
$this->loadModel('User');
$this->set('users', $this->User->find('all'));
}
/*************************************************************************************
*Method : login
*************************************************************************************/
function login(){
}
/*************************************************************************************
*Method : logout
*************************************************************************************/
function logout(){
$this->redirect($this->Auth->logout());
}
/*************************************************************************************
*Method : add
*************************************************************************************/
function add(){
if(!empty($this->data)){
if($this->data){
$this->User->create();
$this->User->save($this->data);
$this->redirect(array('action' => 'login'));
}
}
$this->set('datas', $this->User->find('all'));
}
}
?>
<?php
class User extends AppModel{
public $name = 'User';
public $useTable = 'users';
public $belongsTo = array('Group' => array('className' => 'Group'
,'foreignKey' => 'group_id'));
public $actsAs = array('Acl' => 'requester');
function parentNode() {
if (!$this->id && empty($this->data)) {
return null;
}
$data = $this->data;
if (empty($this->data)) {
$data = $this->read();
}
if (!$data['User']['group_id']) {
return null;
} else {
return array('Group' => array('id' => $data['User']['group_id']));
}
}
function afterSave($created) {
if (!$created) {
$parent = $this->parentNode();
$parent = $this->node($parent);
$node = $this->node();
$aro = $node[0];
$aro['Aro']['parent_id'] = $parent[0]['Aro']['id'];
$this->Aro->save($aro);
}
}
}
?>
<?php
echo $form->create('User', array('action' => 'add'));
echo $form->input('username',array('type' => 'text'));
echo $form->input('password',array('type' => 'text'));
echo $form->input('group_id',array('type' => 'text'));
echo $form->end('登録');
?>
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>PassWord</th>
</tr>
</thead>
<tbody>
<?php for($i=0;$i<count($users);$i++){ ?>
<tr>
<td><?php echo $users[$i]['User']['id']; ?></td>
<td><?php echo $users[$i]['User']['username']; ?></td>
<td><?php echo $users[$i]['User']['password']; ?></td>
</tr>
<?php } ?>
</tbody>
</table>
<h2>Login</h2>
<?php
echo $form->create('User', array('url' => array('controller' => 'users', 'action' =>'login')));
echo $form->input('User.username');
echo $form->input('User.password');
echo $form->end('Login');
?>
<?php echo $html->tag('h3', 'ログアウトしました。') ?>
<?php
class GroupsController extends AppController {
public $name = 'Groups';
/*************************************************************************************
*Method : beforeFilter
*************************************************************************************/
function beforeFilter() {
parent::beforeFilter();
//初期導入用
$this->Auth->allowedActions = array('*');
}
/*************************************************************************************
*Method : index
*************************************************************************************/
function index() {
$this->set('groups', $this->paginate());
}
/*************************************************************************************
*Method : add
*************************************************************************************/
function add(){
if(!empty($this->data)){
if($this->data){
$this->Group->create();
$this->Group->save($this->data);
$this->redirect(array('action' => 'add'));
}
}
}
}
?>
<?php
class Group extends AppModel{
public $name = 'Group';
public $useTable = 'groups';
public $actsAs = array('Acl' => 'requester');
public $hasMany = array('User' => array('className' => 'User'
,'foreignKey' => 'group_id'
,'dependent' => false
,'conditions' => ''
,'fields' => ''
,'order' => ''
,'limit' => ''
,'offset' => ''
,'exclusive' => ''
,'finderQuery' => ''
,'counterQuery' => ''));
function parentNode() {
return null;
}
}
?>
<?php
echo $form->create('Group', array('action' => 'add'));
echo $form->input('name');
echo $form->end('login');
?>
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<?php for($i=0;$i<count($groups);$i++){ ?>
<tr>
<td><?php echo $groups[$i]['Group']['id']; ?></td>
<td><?php echo $groups[$i]['Group']['name']; ?></td>
</tr>
<?php } ?>
</tbody>
</table>


