Reputation: 67
I am making an app with cakephp 3, and i want to restric normal user ('alumnos' in this case) to see and edit only their profiles, so i try to compare the id of the logged user and the value send by the request in the url, but it does not working, it sends the following error "Notice (8): Undefined offset: 0 [APP/Controller\UsersController.php, line 144]", the $this->request->params['pass'][0] variable is empty. How i can fix this?
This is my userController.php
class UsersController extends AppController{
/**
* Index method
*
* @return void
*/
public function index()
{
$this->paginate = [
'contain' => ['Grados']
];
$this->set('users', $this->paginate($this->Users));
$this->set('_serialize', ['users']);
}
/**
* View method
*
* @param string|null $id User id.
* @return void
* @throws \Cake\Network\Exception\NotFoundException When record not found.
*/
public function view($id = null)
{
$user = $this->Users->get($id, [
'contain' => ['Grados', 'Clases', 'ConveniosUsuarios', 'Desvinculaciones', 'HistorialAlumnos', 'Pagos', 'Pedidos']
]);
$this->set('user', $user);
$this->set('_serialize', ['user']);
}
/**
* Add method
*
* @return void Redirects on successful add, renders view otherwise.
*/
public function add()
{
$user = $this->Users->newEntity();
if ($this->request->is('post')) {
$user = $this->Users->patchEntity($user, $this->request->data);
if ($this->Users->save($user)) {
$this->Flash->success(__('The user has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The user could not be saved. Please, try again.'));
}
}
$grados = $this->Users->Grados->find('list', ['limit' => 200]);
$this->set(compact('user', 'grados'));
$this->set('_serialize', ['user']);
}
/**
* Edit method
*
* @param string|null $id User id.
* @return void Redirects on successful edit, renders view otherwise.
* @throws \Cake\Network\Exception\NotFoundException When record not found.
*/
public function edit($id = null)
{
$user = $this->Users->get($id, [
'contain' => []
]);
if ($this->request->is(['patch', 'post', 'put'])) {
$user = $this->Users->patchEntity($user, $this->request->data);
if ($this->Users->save($user)) {
$this->Flash->success(__('The user has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The user could not be saved. Please, try again.'));
}
}
$grados = $this->Users->Grados->find('list', ['limit' => 200]);
$this->set(compact('user', 'grados'));
$this->set('_serialize', ['user']);
}
/**
* Delete method
*
* @param string|null $id User id.
* @return void Redirects to index.
* @throws \Cake\Network\Exception\NotFoundException When record not found.
*/
public function delete($id = null)
{
$this->request->allowMethod(['post', 'delete']);
$user = $this->Users->get($id);
if ($this->Users->delete($user)) {
$this->Flash->success(__('The user has been deleted.'));
} else {
$this->Flash->error(__('The user could not be deleted. Please, try again.'));
}
return $this->redirect(['action' => 'index']);
}
public function beforeFilter(Event $event)
{
$this->Auth->allow(['logout']);
}
public function login()
{
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
if ($this->Auth->user('rol') == 'Alumno') {
$this->redirect('users'.DS.'view'.DS.$this->Auth->user('id'));
}else{
return $this->redirect($this->Auth->redirectUrl());
}
}else{
$this->Flash->error(__('Usario o contraseña invalidos!'));
}
}
}
public function logout()
{
return $this->redirect($this->Auth->logout());
}
public function isAuthorized($user)
{
$userid=$this->Auth->user('id');
$id= $this->request->params['pass'][0];//here is the problem!!
$action = $this->request->params['action'];
if ($user['rol']=='Instructor') {
return true;
}else if ($user['rol']!='Instructor') {
if (in_array($action, ['edit', 'view']) && $userid == $id) {
return true;
}
return false;
}
return parent::isAuthorized($user);
}
}
When if the user is correct debug($this->request->params) display:
[
'plugin' => null,
'controller' => 'Users',
'action' => 'view',
'_ext' => null,
'pass' => [
(int) 0 => '4'
]
]
But if the user try to see other profile debug($this->request->params) display:
[
'plugin' => null,
'controller' => 'Users',
'action' => 'index',
'_ext' => null,
'pass' => []
]
AppController.php
class AppController extends Controller
{
/**
* Initialization hook method.
*
* Use this method to add common initialization code like loading components.
*
* @return void
*/
public function initialize()
{
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'authorize' => ['Controller'],
'loginRedirect' => [
'controller' => 'Users',
'action' => 'index'
],
'logoutRedirect' => [
'controller' => 'Users',
'action' => 'login'
]
]);
}
public function beforeFilter(Event $event)
{
$this->Auth->allow(['login']);
}
public function isAuthorized($user)
{
// Admin can access every action
if (isset($user['role']) && $user['role'] === 'admin') {
return true;
}
// Default deny
return false;
}
}
Upvotes: 0
Views: 1183
Reputation: 67
I solve this error, using this plugin: https://github.com/AlessandroMinoccheri/UserPermissions
Upvotes: 0
Reputation: 660
Thanks for your edit.
I believe that pass
is set after the condition in_array()
, so you need to set $id
after this condition :
public function isAuthorized($user)
{
$userid = $this->Auth->user('id');
$action = $this->request->params['action'];
if ($user['rol'] == 'Instructor') {
return true;
} else if ($user['rol'] != 'Instructor') {
if (in_array($action, ['edit', 'view'])) {
$id = $this->request->params['pass'][0]; // Moved here
if ($userid == $id) {
return true;
}
}
return false;
}
return parent::isAuthorized($user);
}
If it does not work, you can still check if $this->request->params['pass'][0]
exists before trying to set $id
.
Upvotes: 0