CodeIgniter Ion Auth User Groups

Introduction

In the previous tutorial, we looked at how to integrate Ion Auth library with CodeIgniter. We also implemented the user authentication system for our CodeIgniter admin panel. This tutorial will pick up from the previous tutorial and add a section that will allow us to create user accounts and user groups. By the end of this tutorial, you should have the following working application.
CodeIgniter Authorization

Topics to be covered

In this tutorial, we will cover the following topics
  • Tutorial pre-requisites
  • Authentication and authorization
  • Ion Auth User Groups Entity Relationship Diagram (ERD)
  • Ion Auth Model
  • Ion Auth Configuration File
  • Tutorial Project Ion Auth User Groups implementation

Tutorial Pre-requisites

This tutorial assumes you are familiar with;
  • PHP basics and Object-oriented programming
  • CodeIgniter Basics
  • You have a web server, PHP and MySQL already configured and running
  • You have a cool IDE i.e. NetBeans IDE, Aptana Studio etc.
  • You have access to a command line/terminal that you can use to run commands
  • You have been following the tutorial series [optional but highly recommended]

Authentication and Authorization

Authentication deals with proving that one is who they claim to be. We handled that in the previous tutorial. Authorization determines whether a user is allowed to access a resource or perform certain operations. This tutorial will handle the authorization aspect of our application.
Ion Auth library implements authorization using user groups. A user group is used to categorize users and allow them to perform certain operations. Ion Auth supports multiple groups. This means a user can belong to more than one group at a time. But for the sake of simplicity, we will assume a user can only belong to a single group at a time.
We will have two user groups namely administrators and members. Administrators will be able to create and update users and user groups. Members will not be able to access the users and user groups data or perform any operations.
This will be implemented in two easy steps;
  1. We will hide the links to user groups and users in the admin panel navigation links
  2. In case the user knows the URL and types it directly, we will check if they have access rights to it and redirect them to the dashboard if they do not access.

Ion Auth Users Groups Entity Relationship Diagram (ERD)

The following diagram shows the Ion Auth users groups ERD diagram
Ion Auth ERD
The relationship between the users and groups tables is many to many. This is implemented by introducing the intermediate table users_groups that links the two tables using the user_id and group_id fields.

Ion Auth Model

Ion Auth model ships with its own model that handles all database interactions for us. It is possible to create our own models but for the sake of simplicity we will stick with the Ion Auth model. The model is location in the directory /application/models/ion_auth_model.php. I don’t recommend changing anything in the model for the sake of this tutorial. We will leave the model as it is.

Ion Auth Configuration File

One of the things that I love about Ion Auth is its flexibility. Ion Auth ships with a configuration file that is located in /application/config/ion_auth.php.
The configuration file can be used to;
  • Set the unique identify – the default is email field
  • Set table users – the default tables names are users, groups and users_groups. You can change the table names if you have to but we will stick with defaults in this tutotial
  • Password minimum and maximum lengths
  • And many more… you can explore the various options available
For the sake of simplicity, we will work with default settings that ship with Ion Auth.

Tutorial Project Ion Auth User Groups implementation

Let’s now get our hands dirty. We will start with the controllers then create missing views and update some of the existing views

Admin_Controller

All admin controllers are extending the class Admin_Controller. Open the file located in /application/libraries/Admin_Controller.php
Update the code to the following
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class Admin_Controller extends MY_Controller {
    public $is_admin;
    public $logged_in_name;

    function __construct() {
        parent::__construct();

        // Set container variable
        $this->_container = $this->config->item('ci_my_admin_template_dir_admin') . "layout.php";
        $this->_modules = $this->config->item('modules_locations');

        $this->load->library(array('ion_auth'));

        if (!$this->ion_auth->logged_in()) {
            redirect('/auth', 'refresh');
        }

        $this->is_admin = $this->ion_auth->is_admin();
        $user = $this->ion_auth->user()->row();
        $this->logged_in_name = $user->first_name;

        log_message('debug', 'CI My Admin : Admin_Controller class loaded');
    }
}
HERE,
  • public $is_admin; defines a variable that determines whether the user is an admin or not
  • public $logged_in_name; defines a variable that contains the name of the user who is currently logged in
  • $this->load->library(array('ion_auth')); loads the Ion Auth library
  • if (!$this->ion_auth->logged_in()) {} redirects the user to the home page if they are not logged in
  • $this->is_admin = $this->ion_auth->is_admin(); stores the admin status of the user into the the variable is_admin
  • $user = $this->ion_auth->user()->row(); retrieves the user object of the currently logged in user
  • $this->logged_in_name = $user->first_name; populates the variable logged_in_name with the first name of the logged in user

UserGroups Controller

Create a new controller in /application/modules/admin/UserGroups.php
Add the following code

<?php

class UserGroups extends Admin_Controller {

    function __construct() {
        parent::__construct();

        $group = 'admin';

        if (!$this->ion_auth->in_group($group))
        {
            $this->session->set_flashdata('message', 'You must be an administrator to view the user groups page.');
            redirect('admin/dashboard');
        }
    }

    public function index() {    
        $groups = $this->ion_auth->groups()->result();

        $data['groups'] = $groups;
        $data['page'] = $this->config->item('ci_my_admin_template_dir_admin') . "groups_list";
        $this->load->view($this->_container, $data);
    }

    public function create() {
        if ($this->input->post('name')) {
            $name = $this->input->post('name');
            $description = $this->input->post('description');

            $group = $this->ion_auth->create_group($name,$description);

            if(!$group)
            {
                $view_errors = $this->ion_auth->messages();
            }
            else
            {
                redirect('/admin/user-groups', 'refresh');
            }
        }
        $data['page'] = $this->config->item('ci_my_admin_template_dir_admin') . "groups_create";
        $this->load->view($this->_container, $data);
    }

    public function edit($id) {
        if ($this->input->post('name')) {
            $name = $this->input->post('name');
            $description = $this->input->post('description');

            $group_update = $this->ion_auth->update_group($id, $name, $description);

            redirect('/admin/user-groups', 'refresh');
        }

        $group =  $this->ion_auth->group($id)->row();

        $data['group'] = $group;
        $data['page'] = $this->config->item('ci_my_admin_template_dir_admin') . "groups_edit";
        $this->load->view($this->_container, $data);
    }

    public function delete($id) {
        $group_delete = $this->ion_auth->delete_group($id);

        redirect('/admin/user-groups', 'refresh');
    }
}
HERE,
  • $group = 'admin'; defines the allowed user group by name
  • if (!$this->ion_auth->in_group($group)){} checks if the current logged in user belongs to the admin group. If yes access is grated. If it is not, the user is redirected to the dashboard. This code is placed in the __constructor so that it is applicable to all the methods in the class.
  • $groups = $this->ion_auth->groups()->result(); retrieves all groups as an object array
  • $group = $this->ion_auth->create_group($name,$description); creates a new group
  • $group_update = $this->ion_auth->update_group($id, $name, $description); updates an existing group
  • $group_delete = $this->ion_auth->delete_group($id); deletes an existing group

Users Controller

Create a new controller in /application/modules/admin/Users.php
Add the following code

<?php

class Users extends Admin_Controller {

    function __construct() {
        parent::__construct();

        $group = 'admin';

        if (!$this->ion_auth->in_group($group))
        {
            $this->session->set_flashdata('message', 'You must be an administrator to view the users page.');
            redirect('admin/dashboard');
        }
    }

    public function index() {    
        $users = $this->ion_auth->users()->result();

        $data['users'] = $users;
        $data['page'] = $this->config->item('ci_my_admin_template_dir_admin') . "users_list";
        $this->load->view($this->_container, $data);
    }

    public function create() {
        if ($this->input->post('username')) {
            $username = $this->input->post('username');
            $password = $this->input->post('password');
            $email = $this->input->post('email');
            $group_id = array( $this->input->post('group_id'));

            $additional_data = array(
                'first_name' => $this->input->post('first_name'),
                'last_name' => $this->input->post('last_name'),
                'username' => $this->input->post('username'),
                'phone' => $this->input->post('phone'),
            );

            $user = $this->ion_auth->register($email, $password, $email, $additional_data,$group_id);

            if(!$user)
            {
                $errors = $this->ion_auth->errors();
                echo $errors;
                die('done');
            }
            else
            {
                redirect('/admin/users', 'refresh');
            }


        }

        $data['groups'] = $this->ion_auth->groups()->result();
        $data['page'] = $this->config->item('ci_my_admin_template_dir_admin') . "users_create";
        $this->load->view($this->_container, $data);
    }

    public function edit($id) {
        if ($this->input->post('first_name')) {
            $data['first_name'] = $this->input->post('first_name');
            $data['last_name'] = $this->input->post('last_name');
            $data['email'] = $this->input->post('email');
            $data['phone'] = $this->input->post('phone');
            $group_id = $this->input->post('group_id');

            $this->ion_auth->remove_from_group('', $id);
            $this->ion_auth->add_to_group($group_id, $id);

            $this->ion_auth->update($id, $data);

            redirect('/admin/users', 'refresh');
        }

        $this->load->helper('ui');

        $data['groups'] = $this->ion_auth->groups()->result();
        $data['user'] = $this->ion_auth->user($id)->row();
        $data['user_group'] = $this->ion_auth->get_users_groups($id)->row();
        $data['page'] = $this->config->item('ci_my_admin_template_dir_admin') . "users_edit";
        $this->load->view($this->_container, $data);
    }

    public function delete($id) {
        $this->ion_auth->delete_user($id);

        redirect('/admin/users', 'refresh');
    }
}
HERE,
  • $group = 'admin'; defines the allowed user group by name
  • if (!$this->ion_auth->in_group($group)){} checks if the current logged in user belongs to the admin group. If yes access is grated. If it is not, the user is redirected to the dashboard. This code is placed in the __constructor so that it is applicable to all the methods in the class.
  • $users = $this->ion_auth->users()->result(); retrieves all users as an object array
  • $user = $this->ion_auth->register($email, $password, $email, $additional_data,$group_id); creates a new user. The first parameter $email is the identity column, it is followed by the $password field which Ion Auth will encrypt for us. The third parameter $email is the email field value. $additional_data contains additional data such as firstname, lastname phone etc. $group_id specifies the group id. If no value is specified, Ion Auth will use the default value that is specified in the Ion configuration file.
  • $this->ion_auth->update($id, $data); updates an existing user. Unfortunately, we cannot pass the group ids when updating a user. We instead used a hack to accomplish that. $this->ion_auth->remove_from_group('', $id); removes the existing user from all groups. $this->ion_auth->add_to_group($group_id, $id); adds a the updated user group.
  • $this->ion_auth->delete_user($id); deletes an existing user and all groups associated with the user.

Users and Groups views

Let’s now create the following views in /application/modules/admin/views/themes/default 1. groups_create.php 2. groups_edit.php 3. groups_list.php 4. users_create.php 5. users_edit.php 6. users_list.php
For the sake of simplicity, we will not include the code for the views in the tutorial. Download the attached tutorial files and replace the above files. The code is for views is pretty standard. Use the comments section to ask if you have any questions.
Next we will need to update the header view located in /application/views/admin/themes/default/header.php. Replace the header.php with the file from the downloaded tutorial file. Replace the file /application/modules/admin/views/themes/default/dashboard.php with the one that you downloaded.

Testing the authorization

Login as an administrator
The admin panel should now appear as follows
CodeIgniter Authorization
You can view the user groups, edit and add new ones if you want. Note: Don’t delete the default groups. We need them in this tutorial.
Using the users link, create a new user and put members as the group
Login using the new user that you created
You will get results similar to the following
CodeIgniter Authorization
Try to access the following URL directly

http://localhost/ci-my-admin/admin/users/
You will get the following message
CodeIgniter Authorization

Summary

Managing authorization using Ion Auth is very simple and straight forward. The library has most functionality that you need out of the box. It is also very flexible and can be configured to suit your requirements via the configuration file.