I am currently developing an application in Codeigniter framework. My project consists of different levels of users who have different operations.
I have created a Default_model
which handles all the interactions with database. All controllers interact with this single model.
Each user has a designation chosen by the user at the time of registration (He gets to access profile after getting profile approval by Admin only).
My implementaion:
Let a user1
is registered with designation Level1
and he can access an operation with the name operation1
What I am doing currently is written a function in controller and the user1
access the operation by www.example.com/page/operation1
. Here in the function I check for the designation of the user (==="level1"
) if he has authorization to access the function which I retrieved from the database(Load needed data in constructor of controller includes designation, userid
is set in session).If the designation (if not level1
) is incorrect 404
is shown.
Currently I do not have designation checking in the model. If the function in the model is called it returns the data. Do I have to again check if he is authorized in the model? Is there a more generic or easy to implement approach to my scenario?
Update
Controller: page.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Page extends CI_Controller {
public $id;
public function __construct() {
parent::__construct();
//load libraries and model(Default_model) here
$this->id = $this->getData(); //loading data from DB, returns FALSE if session empty
if ($this->id) {
//has data
} else {
$data = array(
'error' => 'Login to continue. <a href="' . base_url() . '">CLICK HERE</a>'
);
$this->load->view('error_view', $data);
}
}
public function operation1()
{
if($this->id->designation === 1)
{
//call model method because he is LEVEL 1 user
}
}
}
You can utilize hooks for that easy way write once only
step 1 :
enable hooks in config.php
$config['enable_hooks'] = TRUE;
step 2: use post_controller_constructor of hooks like this : Location /config/hooks.php
$hook['post_controller_constructor'] = array(
'class' => 'Auth_module',
'function' => 'index',
'filename' => 'Auth_module.php',
'filepath' => 'hooks',
'params' => array()
);
The code above,Auth_module.php is reside in the folder application/hooks/Auth_module.php and the function name is index that function is called after the constructor of called class
the Auth_module.php code like
<?php
class Auth_module {
var $CI;
var $user_id;
var $role_id;
var $collegeId;
public function __construct() {
$this->CI = & get_instance();
$this->CI->load->library('session'); //if it's not autoloaded in your CI setup
$admin_user_data = $this->CI->session->userdata('admin_user_data');
$this->CI->load->model('admin_model');
$this->CI->load->library('user_agent');
}
public function index() {
if (!empty($this->user_id)) {
$class= $this->CI->router->fetch_class();
$method= $this->CI->router->fetch_method();
$role_name = $this->getRoleName($this->role_id);
if ($role_name) {
$Adminpermission = $this->CI->admin_model->getPermissions($class,$role_name);
$Adminpermission_lower = array();
foreach($Adminpermission as $mm_name)
$Adminpermission_lower[] = strtolower($mm_name);
if(!empty($Adminpermission)){
if(in_array($method, $Adminpermission) || in_array($method, $Adminpermission_lower)){
$log_data['access'] = 'success';
//* all is ok here*/
}else if($class !='dashboard' and $class !='admin'){
$message='You don\'t have permissions to access this module. Please contact your administrator.';
$this->redirectMethod($message,$class);
$log_data['access'] = 'failed';
}
}else if($class !='dashboard' and $class !='admin'){
$message='You don\'t have sufficient permissions.please contact your administrator.';
$this->redirectMethod($message);
$log_data['access'] = 'not defined in db';
}
}
else if($class !='dashboard' and $class !='admin') {
$message='Request role is not defined. Please contact to your administrator or mail : test@test.com .';
$this->redirectMethod($message);
$log_data['access'] = 'role name not defined';
}
}
}
public function redirectMethod($message,$class=''){
$message = "<div class='alert alert-danger' role='alert'>".$message."</div>" ;
$this->CI->session->set_flashdata('flashMessage', $message);
if($class==null){
redirect('dashboard');
}else{
redirect($class);
}
}
public function getRoleName($id) {
$master_db = $this->CI->load->database('master', TRUE);
$result = $master_db->query("select role_name from role where id='$id'");
$num_rows = $result->num_rows();
if ($num_rows == 1) {
return $result->row()->role_name;
} else {
return false;
}
}
}
Modify auth file as per your requirement.
This is pure theoretical and explains how I would approach your issue.
public $accessLevel = 0;
in this base controllerTo answer your question. You will not have to double check this in your model. This is logic that is supposed to be done in your controller. However, you could store all pages in your database and give them an accessLevel there. You can then check if the user is allowed to access the page in your query.
when you check the user is at level 1 basically you have to put restriction to each method wether the user is allowed or not .. in your case when you check the condition with if you dont write the condition when if fails .. else should execute when if fails where user see a error message or better you should use a __constructor and put restriction in there and separate each level of user in differents modals