This article will cover all following aspects
- How to install cakephp,
- How to set environment variable path on window 7,
- How to generate code by using bake console feature of cakephp
- How to permission users on the basis of their groups (ACL) .
To achieve first point just click on How to install cakephp
Then set environment variable path Click here
Execute Following query if you created database in during installation
CREATE TABLE users (
id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) NOT NULL UNIQUE,
password CHAR(40) NOT NULL,
group_id INT(11) NOT NULL,
created DATETIME,
modified DATETIME
);
CREATE TABLE groups (
id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
created DATETIME,
modified DATETIME
);
CREATE TABLE posts (
id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
user_id INT(11) NOT NULL,
title VARCHAR(255) NOT NULL,
body TEXT,
created DATETIME,
modified DATETIME
);
CREATE TABLE widgets (
id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
part_no VARCHAR(12),
quantity INT(11)
);
These are the tables we will be using to build the rest of our application. Once we have the table structure in the database we can start cooking. Use Code Generation with Bake to quickly create your models, controllers, and views.
To bake you just need to follow this video, in video we only baked Group model so repeat same step for User, Post and Widget model. This will have generated the 4 controllers, models and your views for you.
Video
Our third point would be completed here.
Now we are going to set permission to users on the basis of their Group. Which is our last 4th point.
Open app/Controller/UsersController.php and paste following function in that
public function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error(__('Your username or password was incorrect.'));
}
}
public function logout() {
//Leave empty for now.
}
Create login.ctp in app/View/Users/login.ctp and put following code in that
<?php
echo $this->Form->create('User', array('action' => 'login'));
echo $this->Form->inputs(array(
'legend' => __('Login'),
'username',
'password'
));
echo $this->Form->end('Login');
?>
In app/Model/User.php add the following code
public function beforeSave($options = array()) {
$this->data['User']['password'] = AuthComponent::password(
$this->data['User']['password']
);
return true;
}
Open /app/Controller/AppController.php and put following code in AppController class
public $components = array(
'Acl',
'Auth' => array(
'authorize' => array(
'Actions' => array('actionPath' => 'controllers')
)
),
'Session',
'Flash'
);
public $helpers = array('Html', 'Form', 'Session');
public function beforeFilter() {
//Configure AuthComponent
$this->Auth->loginAction = array(
'controller' => 'users',
'action' => 'login'
);
$this->Auth->logoutRedirect = array(
'controller' => 'users',
'action' => 'login'
);
$this->Auth->loginRedirect = array(
'controller' => 'posts',
'action' => 'add'
);
}
In both your /app/Controller/GroupsController.php and your /app/Controller/UsersController.php Add the following code
public function beforeFilter() {
parent::beforeFilter();
// For CakePHP 2.1 and up
$this->Auth->allow();
}
Create ACL tables , you can do in two ways first is by Command and second by execution of SQL, so just do one which you like most
1) Execute following command if you want to do by command
cake schema create DbAcl
see image
2) Execute following query if you want to do by sql
you can see SQL in app/Config/Schema/db_acl.sql
Acts As a Requester
Open app/Model/User.php and put the below code.
public $actsAs = array('Acl' => array('type' => 'requester', 'enabled' => false));
public function parentNode() {
if (!$this->id && empty($this->data)) {
return null;
}
if (isset($this->data['User']['group_id'])) {
$groupId = $this->data['User']['group_id'];
} else {
$groupId = $this->field('group_id');
}
if (!$groupId) {
return null;
}
return array('Group' => array('id' => $groupId));
}
public function bindNode($user) {
return array('model' => 'Group', 'foreign_key' => $user['User']['group_id']);
}
Open app/Model/Group.php and put the below code.
public $actsAs = array('Acl' => array('type' => 'requester'));
public function parentNode() {
return null;
}
Now Run application http://localhost/acl/groups/add
Add Following Groups
·
administrators
·
managers
·
users
Then Add users for each
group,
http://localhost/acl/users/add
Note: acl is my project name so do change if your project name is different.
Creating ACOs (Access Control Objects)
Now that we have our users and groups (aros), we can begin inputting our existing controllers into the Acl and setting permissions for our groups and users, as well as enabling login / logout.
Our ARO are automatically creating themselves when new users and groups are created. What about a way to auto-generate ACOs from our controllers and their actions? Well unfortunately there is no magic way in CakePHP’s core to accomplish this. The core classes offer a few ways to manually create ACO’s though. You can create ACO objects from the Acl shell OR by Query. Creating Acos from the shell looks like below OR execute below query
By Shell or Command
cake acl create aco root controllers
see image
By Query
INSERT INTO `acos` (`id`, `parent_id`, `model`,
`foreign_key`, `alias`, `lft`, `rght`) VALUES
(1, NULL, NULL, NULL, 'controllers', 1, 2);
An Automated tool for creating ACOs
As mentioned before, there is no pre-built way to input all of our controllers and actions into the Acl. However, we all hate doing repetitive things like typing in what could be hundreds of actions in a large application.
For this purpose exists a very handy plugin available on GitHub, called AclExtras which can be downloaded in The GitHub Downloads page.
https://github.com/markstory/acl_extras/zipball/master
After download just extract zip file and rename folder “AclExtras” and put “AclExtras” folder in app/Plugin/
Now open /app/Config/boostrap.php and Put the below code to load plugin
CakePlugin::load('AclExtras');
Finally execute the following command in the CakePHP console
cake AclExtras.AclExtras aco_sync
see image
Setting permission for all Groups
Add below code in /app/Controller/UsersController.php
public function initDB() {
$group = $this->User->Group;
// Allow admins to everything
$group->id = 1;
$this->Acl->allow($group, 'controllers');
// allow managers to posts and widgets
$group->id = 2;
$this->Acl->deny($group, 'controllers');
$this->Acl->allow($group, 'controllers/Posts');
$this->Acl->allow($group, 'controllers/Widgets');
$this->Acl->allow($group, 'controllers/users/logout');
// allow users to only add and edit on posts and widgets
$group->id = 3;
$this->Acl->deny($group, 'controllers');
$this->Acl->allow($group, 'controllers/Posts/add');
$this->Acl->allow($group, 'controllers/Posts/edit');
$this->Acl->allow($group, 'controllers/Widgets/add');
$this->Acl->allow($group, 'controllers/Widgets/edit');
// allow basic users to log out
$this->Acl->allow($group, 'controllers/users/logout');
// we add an exit to avoid an ugly "missing views" error message
echo "all done";
exit;
}
Now run initDB function on browser by below link you will
get all done message.
After execution
remove this line $this->Auth->allow(); from beforeFilter function and also
remove initDB function from usersController.
Also remove this line $this->Auth->allow(); from beforeFilter function groupsController.
We now have set up some basic access rules. We’ve allowed administrators to everything. Managers can access everything in posts and widgets. While users can only access add and edit in posts & widgets.
You may have noticed that I deliberately left out index and view from my Acl permissions. We are going to make view and index public actions in PostsController and WidgetsController. This allows non-authorized users to view these pages, making them public pages.
So add below beforeFilter function in /app/Controller/PostsController.php and /app/Controller/WidgetsController.php
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('index', 'view');
}
In AppController::beforeFilter() add the following line
$this->Auth->allow('display');
This makes the ‘display’ action public. This will keep our PagesController::display() public. This is important as often the default routing has this action as the home page for your application.
Replace Login and logout
function in /app/Controller/UsersController.php with below Login and logout function.
public function login() {
if
($this->request->is('post')) {
if
($this->Auth->login()) {
return
$this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error(__('Your
username or password was incorrect.'));
}
if
($this->Session->read('Auth.User')) {
$this->Flash->success('You
are logged in!');
return
$this->redirect('/');
}
}
public
function logout() {
$this->Flash->success(__('Good-Bye
Ubed'));
$this->redirect($this->Auth->logout());
}
When access is denied Auth messages will be displayed if you added the echo $this->Session->flash('auth');
just below $this->flash->render in app\View\Layouts\default.ctp
Hope you will enjoy ACL , Good or Bad, both comments will be appreciate. ;)