Вопрос

I am completely and utterly lost on how to do this. I have 3 different roles : Admin, Staff and Donors. My problem is that It really gets confusing(for me anyway) with permissions and as well as appropriate redirections, should an unauthorized user tries to access an action from the URL.

In my UsersController I have the following actions

  1. admin_index
  2. admin_add
  3. admin_edit
  4. admin_view
  5. admin_delete

non-prefixed actions

  1. login
  2. logout
  3. view
  4. add
  5. edit

The admin should be allowed to access all admin-prefixed actions as well as login and logout, whilst the staff and donor should only be able to access the latter 5. Also note that all users are using the same login form.

In my AppControlles's component I have the following :

 'Auth' => array(
            'loginRedirect' => array(  
                'controller' => 'donors',
                'action' => 'index'
            ),
            'logoutRedirect' => array(  
                'controller' => 'users',
                'action' => 'login'
            ),
            'authorize' => array('Controller')
)

However, In my login action I check for the user role to change the loginRedirect accordingly :

if($this->request->is('post')){
            if($this->Auth->login()){   

            switch($this->Auth->user('role')){
                case 'admin':
                    $this->Auth->loginRedirect = array('controller'=>'users','action'=>'admin_index','prefix'=>'admin','admin'=>true);
                    break;
                case 'donor':
                ...
                break; 
                case .....
            }
         }
 }

Question 1 Now, if a current user with a role of donor is logged in, and tries to access localhost/sitename/admin/users/add he is redirected to admin/donors rather then just /donors . So how am I able to remove the admin prefix ?

Question 2 Also I do not fully understand hwo $this->Auth->allow(), works.. If In my donorsController I want to control the access to the controllers action according to roles, how can I do it? So for instance, If there is the 'delete' action in my donorsController, How will I be able to permit the staff user whilst denying the donor user to access the delete action. I believe the beforeFilter is the solution, but can't find how to do it! Any pointers ? Thanks

Это было полезно?

Решение

1) In your login() action impelement a check for the user role, if the role is admin redirect to whatever controller/action and set the admin prefix. If hes not an admin redirect him to something else.

if ($this->Auth->login()) {
    if ($this->Auth->user('role') === 'admin') {
        $this->redirect(array(
            'admin' => true,
            'controller' => 'foo',
            'action' => 'bar')));
    } else {
        // Do something else, another redirect or whatever
    }
}

There is no need to remove the /admin from the URL as it should show the user hes not authorized when he tries to access an URL he is not allowed to.

2) If you want to grant access for different roles you can use the SimpleRbacAuth I've written. Check the tests for examples of how it works. You simply define a nested array structure and add the roles you want to an action or a whole controller or grant access to everyone by using *.

Другие советы

This may be a solution for you.

Go to the core.php file and uncomment if present/add if not present the below line.

Configure::write('Routing.prefixes', array('admin'));
Location: app/config/core.php 

Put the below code inside the beforeFilter method of AppController.php (cake version 2.X) / app_controller.php (cake version < 2.X)

function beforeFilter(){
    if($this->Auth->user('role') == 'admin'){
        if(!in_array($this->params['action'],array('login','logout')) && (stristr($this->params['action'], 'admin_') === FALSE)){
            $this->redirect(array("controller"=>$this->params['controller'],"action"=>'admin_'.$this->params['action'],"admin" => 1));
        }
    }else{
        if(stristr($this->params['action'], 'admin_')){
        $action = explode('_',$this->params['action']);
        $this->redirect(array("controller"=>$this->params['controller'],"action"=>$action[1],"admin" => false));
        }
    }
}

Rest of the functionality you can manage by handling the custom error page.

You can refer to Customize error pae

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top