Create Authentication and Authorization Application in CakePHP

In this article, we are going to discuss about How to create an authentication and authorization application in cakePHP.  imagine we wanted to secure the access to certain URLs, based on the logged in user. We also have another requirement, to allow our blog to have multiple authors so each one of them can create their own posts, edit and delete them at will disallowing other authors to make any changes on one's posts.

Creating all users' related code

First, let's create a new table in our blog database to hold our users' data:

CREATE TABLE users (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50),
    password VARCHAR(255),
    role VARCHAR(20),
    created DATETIME DEFAULT NULL,
    modified DATETIME DEFAULT NULL
);

We have adhered to the CakePHP conventions in naming tables, but we're also taking advantage of another convention: by using the username and password columns in a users table, CakePHP will be able to auto configure most things for us when implementing the user login.

Next step is to create our User model, responsible for finding, saving and validating any user data:

// app/Model/User.php
App::uses('AppModel', 'Model');

class User extends AppModel {
    public $validate = array(
        'username' => array(
            'required' => array(
                'rule' => array('notEmpty'),
                'message' => 'A username is required'
            )
        ),
        'password' => array(
            'required' => array(
                'rule' => array('notEmpty'),
                'message' => 'A password is required'
            )
        ),
        'role' => array(
            'valid' => array(
                'rule' => array('inList', array('admin', 'author')),
                'message' => 'Please enter a valid role',
                'allowEmpty' => false
            )
        )
    );
}

Let's also create our UsersController, the following contents correspond to a basic baked UsersController class using the code generation utilities bundled with CakePHP:

// app/Controller/UsersController.php
App::uses('AppController', 'Controller');

class UsersController extends AppController {

    public function beforeFilter() {
        parent::beforeFilter();
        $this->Auth->allow('add');
    }

    public function index() {
        $this->User->recursive = 0;
        $this->set('users', $this->paginate());
    }

    public function view($id = null) {
        $this->User->id = $id;
        if (!$this->User->exists()) {
            throw new NotFoundException(__('Invalid user'));
        }
        $this->set('user', $this->User->read(null, $id));
    }

    public function add() {
        if ($this->request->is('post')) {
            $this->User->create();
            if ($this->User->save($this->request->data)) {
                $this->Session->setFlash(__('The user has been saved'));
                return $this->redirect(array('action' => 'index'));
            }
            $this->Session->setFlash(
                __('The user could not be saved. Please, try again.')
            );
        }
    }

    public function edit($id = null) {
        $this->User->id = $id;
        if (!$this->User->exists()) {
            throw new NotFoundException(__('Invalid user'));
        }
        if ($this->request->is('post') || $this->request->is('put')) {
            if ($this->User->save($this->request->data)) {
                $this->Session->setFlash(__('The user has been saved'));
                return $this->redirect(array('action' => 'index'));
            }
            $this->Session->setFlash(
                __('The user could not be saved. Please, try again.')
            );
        } else {
            $this->request->data = $this->User->read(null, $id);
            unset($this->request->data['User']['password']);
        }
    }

    public function delete($id = null) {
        // Prior to 2.5 use
        // $this->request->onlyAllow('post');

        $this->request->allowMethod('post');

        $this->User->id = $id;
        if (!$this->User->exists()) {
            throw new NotFoundException(__('Invalid user'));
        }
        if ($this->User->delete()) {
            $this->Session->setFlash(__('User deleted'));
            return $this->redirect(array('action' => 'index'));
        }
        $this->Session->setFlash(__('User was not deleted'));
        return $this->redirect(array('action' => 'index'));
    }

}

In the same way we created the views for our blog posts or by using the code generation tool, we implement the views. For the purpose of this tutorial, we will show just the add.ctp:

<!-- app/View/Users/add.ctp -->
<div class="users form">
<?php echo $this->Form->create('User'); ?>
    <fieldset>
        <legend><?php echo __('Add User'); ?></legend>
        <?php echo $this->Form->input('username');
        echo $this->Form->input('password');
        echo $this->Form->input('role', array(
            'options' => array('admin' => 'Admin', 'author' => 'Author')
        ));
    ?>
    </fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
</div>

Authentication (login and logout)

We're now ready to add our authentication layer. In CakePHP this is handled by the AuthComponent, a class responsible for requiring login for certain actions, handling user sign-in and sign-out, and also authorizing logged in users to the actions they are allowed to reach.

To add this component to your application open your app/Controller/AppController.php file and add the following lines:

// app/Controller/AppController.php
class AppController extends Controller {
    //...

    public $components = array(
        'Session',
        'Auth' => array(
            'loginRedirect' => array(
                'controller' => 'posts',
                'action' => 'index'
            ),
            'logoutRedirect' => array(
                'controller' => 'pages',
                'action' => 'display',
                'home'
            ),
            'authenticate' => array(
                'Form' => array(
                    'passwordHasher' => 'Blowfish'
                )
            )
        )
    );

    public function beforeFilter() {
        $this->Auth->allow('index', 'view');
    }
    //...
}

There is not much to configure, as we used the conventions for the users table. We just set up the URLs that will be loaded after the login and logout actions is performed, in our case to /posts/ and / respectively.

What we did in the beforeFilter function was to tell the AuthComponent to not require a login for all index and view actions, in every controller. We want our visitors to be able to read and list the entries without registering in the site.

Now, we need to be able to register new users, save their username and password, and, more importantly, hash their password so it is not stored as plain text in our database. Let's tell the AuthComponent to let un-authenticated users access the users add function and implement the login and logout action:

// app/Controller/UsersController.php

public function beforeFilter() {
    parent::beforeFilter();
    // Allow users to register and logout.
    $this->Auth->allow('add', 'logout');
}

public function login() {
    if ($this->request->is('post')) {
        if ($this->Auth->login()) {
            return $this->redirect($this->Auth->redirectUrl());
        }
        $this->Session->setFlash(__('Invalid username or password, try again'));
    }
}

public function logout() {
    return $this->redirect($this->Auth->logout());
}

Password hashing is not done yet, open your app/Model/User.php model file and add the following:

// app/Model/User.php

App::uses('AppModel', 'Model');
App::uses('BlowfishPasswordHasher', 'Controller/Component/Auth');

class User extends AppModel {

// ...

public function beforeSave($options = array()) {
    if (isset($this->data[$this->alias]['password'])) {
        $passwordHasher = new BlowfishPasswordHasher();
        $this->data[$this->alias]['password'] = $passwordHasher->hash(
            $this->data[$this->alias]['password']
        );
    }
    return true;
}

// ...

So, now every time a user is saved, the password is hashed using the BlowfishPasswordHasher class. We're just missing a template view file for the login function. Open up your app/View/Users/login.ctp file and add the following lines:

//app/View/Users/login.ctp

<div class="users form">
<?php echo $this->Session->flash('auth'); ?>
<?php echo $this->Form->create('User'); ?>
    <fieldset>
        <legend>
            <?php echo __('Please enter your username and password'); ?>
        </legend>
        <?php echo $this->Form->input('username');
        echo $this->Form->input('password');
    ?>
    </fieldset>
<?php echo $this->Form->end(__('Login')); ?>
</div>

You can now register a new user by accessing the /users/add URL and log-in with the newly created credentials by going to /users/login URL. Also try to access any other URL that was not explicitly allowed such as /posts/add, you will see that the application automatically redirects you to the login page.

And that's it! It looks too simple to be truth. Let's go back a bit to explain what happened. The beforeFilter function is telling the AuthComponent to not require a login for the add action in addition to the index and view actions that were already allowed in the AppController's beforeFilter function.

The login action calls the $this->Auth->login() function in the AuthComponent, and it works without any further config because we are following conventions as mentioned earlier. That is, having a User model with a username and a password column, and use a form posted to a controller with the user data. This function returns whether the login was successful or not, and in the case it succeeds, then we redirect the user to the configured redirection URL that we used when adding the AuthComponent to our application.

The logout works by just accessing the /users/logout URL and will redirect the user to the configured logoutUrl formerly described. This URL is the result of the AuthComponent::logout() function on success.

Authorization (who's allowed to access what)

As stated before, we are converting this blog into a multi-user authoring tool, and in order to do this, we need to modify the posts table a bit to add the reference to the User model:

ALTER TABLE posts ADD COLUMN user_id INT(11);

Also, a small change in the PostsController is required to store the currently logged in user as a reference for the created post:

// app/Controller/PostsController.php
public function add() {
    if ($this->request->is('post')) {
        //Added this line
        $this->request->data['Post']['user_id'] = $this->Auth->user('id');
        if ($this->Post->save($this->request->data)) {
            $this->Session->setFlash(__('Your post has been saved.'));
            return $this->redirect(array('action' => 'index'));
        }
    }
}

The user() function provided by the component returns any column from the currently logged in user. We used this method to add the data into the request info that is saved.

Let's secure our app to prevent some authors from editing or deleting the others' posts. Basic rules for our app are that admin users can access every URL, while normal users (the author role) can only access the permitted actions. Open again the AppController class and add a few more options to the Auth config:

// app/Controller/AppController.php

public $components = array(
    'Session',
    'Auth' => array(
        'loginRedirect' => array('controller' => 'posts', 'action' => 'index'),
        'logoutRedirect' => array(
            'controller' => 'pages',
            'action' => 'display',
            'home'
        ),
        'authenticate' => array(
            'Form' => array(
                'passwordHasher' => 'Blowfish'
            )
        ),
        'authorize' => array('Controller') // Added this line
    )
);

public function isAuthorized($user) {
    // Admin can access every action
    if (isset($user['role']) && $user['role'] === 'admin') {
        return true;
    }

    // Default deny
    return false;
}

We just created a very simple authorization mechanism. In this case the users with role admin will be able to access any URL in the site when logged in, but the rest of them (i.e the role author) can't do anything different from not logged in users.

This is not exactly what we wanted, so we need to supply more rules to our isAuthorized() method. But instead of doing it in AppController, let's delegate each controller to supply those extra rules. The rules we're going to add to PostsController should allow authors to create posts but prevent the edition of posts if the author does not match. Open the file PostsController.php and add the following content:

// app/Controller/PostsController.php

public function isAuthorized($user) {
    // All registered users can add posts
    if ($this->action === 'add') {
        return true;
    }

    // The owner of a post can edit and delete it
    if (in_array($this->action, array('edit', 'delete'))) {
        $postId = (int) $this->request->params['pass'][0];
        if ($this->Post->isOwnedBy($postId, $user['id'])) {
            return true;
        }
    }

    return parent::isAuthorized($user);
}

We're now overriding the AppController's isAuthorized() call and internally checking if the parent class is already authorizing the user. If he isn't, then just allow him to access the add action, and conditionally access edit and delete. A final thing is left to be implemented, to tell whether the user is authorized to edit the post or not, we're calling a isOwnedBy() function in the Post model. It is in general a good practice to move as much logic as possible into models. Let's then implement the function:

// app/Model/Post.php

public function isOwnedBy($post, $user) {
    return $this->field('id', array('id' => $post, 'user_id' => $user)) !== false;
}

This concludes our simple authentication and authorization tutorial. For securing the UsersController you can follow the same technique we did for PostsController. You could also be more creative and code something more general in AppController based on your own rules.

iCagenda - Joomla Events Management extension free download

Events Management extension with a calendar module. Cross-platform Joomla 2.5 & Joomla 3! Available in more 30 languages, iCagenda has a responsive and flexible design, with a theme pack installer inside.

Display of events takes the form of a list, for which you can apply filters (upcoming dates and/or past, category(ies), ordering by dates...) and customize graphic elements (choice of theme, size of the Google map, number events displayed per page, date format in your culture (for languages available in iCagenda), etc ...)

The Theme Manager allows you to create your own theme pack for iCagenda and install it easily via the component.

Two Themes are included in iCagenda : default and ic_rounded.

Other themes are currently in process, and a documentation will soon be opened to give users all the help and tips for creating a custom theme pack!

Extension Name: iCagenda

Price: Free

More info and reviews: iCagenda on JED

For Demo - Click Here

Download Free Version - Click Here

Add category name to body class in Magento

In this article, we are going to discuss about How to add the category name to the body class in Magento. The Magento eCommerce platform serves more than 110,000 merchants worldwide and is supported by a global ecosystem of solution partners and third-party developers. Magento is a feature-rich, open-source, enterprise-class platform that offers merchants a high degree of flexibility and control over the user experience, catalog, content and functionality of their online store.

Sometimes you would like to modify the page according to the category. For example, you want to change the banner, background or other things.

Step 1

you can add the next code snippet to the /template/page/1column.phtml or /template/page/2columns-left.phtml or anywhere else you want:

<?php
$class = '';
$currentCategory = Mage::registry('current_category');

if ($currentCategory) {
    $parentCategories = $currentCategory->getParentCategories();
    $topCategory = reset($parentCategories);
    $class .= $topCategory->getUrlKey();
}
?>

Step 2

Next, append the $addClass variable to the body class like this:

<body <?php echo $this->getBodyClass()?' class="'.$this->getBodyClass() . " " . $class . '"':'' ?> >

Steps to Install a premium Magento extension

In this article, we are going to discuss about how to install a premium extension in Magento. There are two ways you can install premium Magento extensions and each different method has it's own merits. Before installing any Magento extension, you should disable your Magento Cache and the Magento Compiler. After installing the extension, you should always recompile the Compiler instead of simply enabling it again.

Magento Connect - Downloader

It is possible to install the .tgz extension file automatically through Magento Connect (Downloader). To access your Magento Downloader, add /downloader/index.php to the end of your Magento URL. You can login to the Downloader using your Magento Admin login details.

Once you have logged in, upload the .tgz file using the 'Direct package file upload' form. This will automatically install the extension for you.

Upgrading using the Downloader

If you want to upgrade a premium Magento extension using the Downloader, you must first uninstall the extension. You can do this automatically via the Downloader and then install the new updated version using the steps outlined above.

Installing Manually

Installing Magento extensions automatically via the Downloader is the best option. It is much easier and makes it easy to remove an installed extension. That being said, there are many problems with the Downloader that may stop it working for your site (permissions being the main problem). If you are unable to use the Downloader, you can install the extension manually. You can also add the extension to the Downloader so that if in future you fix your Downloader, the extension will be registered there and can be upgraded or uninstalled automatically.

To install the extension manually, extract the files from the .tgz file. Next, ignore the package.xml (this is used by the Downloader to automatically install the extension) and merge the rest of the files with your Magento site using either FTP or SFTP. Refresh the Magento Admin and the extension will be installed.

To register the extension with your Magento Downloader, copy the name of the .tgz file (not including the .tgz part) and rename package.xml as the file you just copied followed by '.xml'. Upload this file to var/package/ and the extension will be registered in your Downloader.

Installing Magento WordPress Integration Add-On Extensions

Add-on extensions for Magento WordPress Integration are just like regular Magento extensions and can be installed using either of the methods outlined above. Before installing though, always ensure that Magento WordPress Integration is upgraded to the latest version. This will reduce the chances of encountering any problems with your new add-on extension.

Authentication Library for CodeIgniter PHP framework

In this article, we are going to discuss about the various authentication library for the CodeIgniter PHP Framework. Codeigniter still does not has a native authentication library. Many people try to build thier own authentication library. Now we can find few good Codeigniter authentication library, they are free as well.

I would like to suggest some of Codeigniter authentication library.

Tank Auth

Tank Auth is an authentication library for PHP-framework CodeIgniter. It's based on DX Auth, although the code was seriously reworked.

Features

  1. Basic auth options (login, logout, register, unregister).
  2. Very compact (less than 20 files and 4 DB-tables).
  3. Username is optional, only email is obligatory.
  4. Using phpass library for password hashing (instead of unsafe md5).
  5. Counting login attempt for bruteforce preventing (optional). Failed login attempts determined by IP and by username.
  6. Logging last login IP-address and time (optional).
  7. CAPTCHA for registration and repetitive login attempt (optional).
  8. Unactivated accounts and forgotten password requests auto-expire.
  9. Strict MVC model: controller for controlling, views for representation and library as model interface.
  10. Language file support.
  11. View files contain only necessary HTML code without redundant decoration.
  12. Most of the features are optional and can be tuned or switched-off in well-documented config file.
  13. Login using username, email address or both (depending on config settings).
  14. Registration is instant or after activation by email (optional).
  15. "Remember me" option.
  16. Forgot password (letting users pick a new password upon reactivation).
  17. Change password or email for registered users.
  18. Email or password can be changed even before account is activated.
  19. Ban user (optional).
  20. User Profile (optional).
  21. CAPTCHA support (CI-native and reCAPTCHA are available).
  22. HTML or plain-text emails.

DX Auth

DX Auth is an authentication library for Code Igniter. It's goal to enable you to easily include secure and easy to use authentication library to your project, while giving you the flexibility to choose from simple authentication system to full fledged authentication system.

DX Auth is also build with internationalization in mind, so every string is available in language file. (Except the examples because that is your code, not the library).

It's based on CL Auth 0.2.5 beta developed by Jason Ashdown.

Features

  1. Basic auth (Login, logout, register, change password).
  2. Remember me.
  3. Login using username or email address or both (depend on config settings).
  4. Forgot password.
  5. Ban user.
  6. Last login IP address and time (optional).
  7. Email activation (optional).
  8. User Profile (optional).
  9. Role based (admin, user, moderator, etc). Inheritance also supported (optional)
  10. Restrict page based on URI and role (optional).
  11. Custom permission for each role (optional).
  12. Login attempt (optional). You can use this to display catpcha after specified try to login to prevent bot.
  13. Event feature (For example: You can put your own code like PM welcome message after user activated, etc).
  14. Captcha (optional, native and reCAPTCHA is available).
  15. Simple admin panel (So you can customize it, include it into your own admin panel, or delete if you don't need it).
  16. Most of the feature is optional, means you can turn it off in config file, delete it, or just don't use it.

DX Auth is tested in CI 1.7.0, but should be working for above version.

CodeIgniter-Ion-Auth 

Redux Auth 2 had a lot of potential. It's lightweight, simple, and clean, but had a ton of bugs and was missing some key features. So we refactored the code and added new features.

Community Auth

Community Auth is a user authentication application for CodeIgniter. It is completely unique, and not based on anyone's previous work. If you've come here looking for a CodeIgniter authentication library, then please keep in mind that Community Auth is more than just a library. Community Auth is distributed with example controllers, models, views, and should be considered a project foundation.

Features

  1. User Authentication (User Login)
  2. Access Granted by Level / Role
  3. Access Granted by Role Group
  4. Content Switching in Views
  5. Limits Failed Login Attempts
  6. Limits Login to a Single Device (Default)
  7. Deny Access by IP (Requires Local Apache Configuration File)
  8. Persistent Login (Remember Me) (Turned Off by Default)
  9. Forgotten Password and Username Recovery
  10. New User Registration
    • Off by Default
    • Instant Registration Mode
    • Registration by Email Verification Mode
    • Registration by Admin Approval Mode
  11. User Account Update
    • Self Update
    • Update by Superior Role