Differentiation of access rights Kohana 3.3

Published on May 29, 2013

Differentiation of access rights Kohana 3.3

image
Cohan has a built-in user authorization module. The database already has a table with roles. But having rummaged through Internet spaces, I have not found how convenient it is to make access rights differentiation. Therefore, I offer you my solution to this problem.

Let's start

I inherit all the controllers from one common Common.php. I prescribe the basic settings of the project in it: connecting css, js, headers, content, loading all configs, etc. Depending on what is needed from the project.

To begin with, we announce everything that will be useful to us in other controllers.

<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Common extends Controller_Template {
    public $sys_mes, $auth, $session, $user, $class_id;
    public $user_roles = array();
    public $security   = array();
    public $template = 'v_common';
    public $layout   = 'v_column_12';
    public $css      = array('bootstrap.min', 'style');
    public $js       = array('jquery-2.0.0.min', 'bootstrap.min');
    public $configs  = array('order_control', 'payment_method');
}


Next, we write a function that fires before the controller loads any page. Only those settings that we need are described below. The list of roles can be recorded in the session.

The function that makes the distinction is _check_permission ()

public function before() 
	{   parent::before();
		# Установка
                $this->auth     = Auth::instance();
                $this->session  = Session::instance();
                $this->class_id = Get_class($this);
		# Проверка на авторизованность 
		if($this->auth->logged_in()) 
		{
            # Индификационные данные
            $this->user = $this->auth->get_user();
            # Получаем список ролей пользователя
            $this->user_roles = Model::factory('User')->user_roles($this->user->id);
		}
        # Проверка прав доступа
        $this->_check_permission();
        # Загрузка конфигов
        foreach($this->configs as $config)
        {
            $this->template->set_global($config, Kohana::$config->load($config)->as_array());
        }
	}


Model for getting a list of roles. Everything is just clear here.

class Model_User extends Model_Auth_User {
    public function user_roles($user_id)
    {
            $result = array();
            $db = DB::select(array('roles.name', 'name'));
            # SELECT -> ROLES_USERS
            $db->from('roles_users');
            $db->where('roles_users.user_id', '=', $user_id);
            # SELECT -> ROLES
            $db->join('roles');
            $db->on('roles.id', '=', 'roles_users.role_id');
            $roles = $db->execute()->as_array();
            foreach($roles as $role)
            {
                array_push($result, $role['name']);  
            }
        }


The function itself that delimits access. Regardless of the controller directory, it will still work as it should.

    private function _check_permission()
    {
        $check_permission = FALSE;
        $config_security = Kohana::$config->load('security')->as_array();
        $action = Request::current()->action();
        if(isset($config_security[$this->class_id][$action]))
        {
            foreach($config_security[$this->class_id][$action] as $users_role)
                if(in_array($users_role, $this->user_roles) || in_array($users_role, array('public')))
                    $check_permission = TRUE;
        }
        if(isset($config_security[$this->class_id]['all_actions']))
        {
            foreach($config_security[$this->class_id]['all_actions'] as $users_role)
                if(in_array($users_role, $this->user_roles))
                     $check_permission = TRUE;   
        }
        if($check_permission != TRUE)
            exit('Access deny - 403 ');
    }


The config is here application / config / security.php

In it we write permission to access the action, otherwise get 403.

<?php defined('SYSPATH') or die('No direct script access.');
return array(
    # Order
    'Controller_Orders' => array(
        'index'           => array('root', 'manager', 'admin'),
        'by_organization' => array('root'),
        'add'             => array('admin', 'manager'),
        'edit'            => array('admin', 'manager'),
    # Auth
    'Controller_Auth' => array(
        'all_actions' => array('login'),
        'login'       => array('public'),
    ),
    # Organization   
    'Controller_Organization' => array(
        'all_actions' => array('root'),
    ),
);


Controller_Orders - the name of the controller.
index - an action that works out (if you want to open access for everyone, then write 'all_actions')
array ('admin', 'manager') - a list of roles that are allowed access.

It is interesting to know your opinion on this method of solving the problem.