PHPJunior
PHPJunior

Reputation: 75

How to show only those records that belong to the group of the currently logged in user?

I'm sure this is a trivial task, but I'm not very experienced in PHP and in CakePHP.

I've got Events, Users and Groups tables and I want to show the user in an index view only events created by him and by members of his group.

I was trying to work on a piece of code from tutorial about Authorizations but it's still not working. The user can see events created by him, but not these created by a group he belongs to.

Please, help me with that. I've spent hours on this and I can't figure it out.

Users table:

CREATE TABLE users (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(60) NOT NULL,
  password VARCHAR(255) NOT NULL,
  group_id INT NOT NULL REFERENCES groups(id)
);

Events table:

CREATE TABLE events (
  id INT AUTO_INCREMENT PRIMARY KEY,
  title VARCHAR(100),
  created DATETIME DEFAULT NOW(),
  description VARCHAR(1000) NOT NULL,
  ended DATETIME,
  working_hours INT,
  price DECIMAL,
  user_id INT NOT NULL REFERENCES users(id),
  status_id INT NOT NULL REFERENCES statuses(id),
  employee_id INT REFERENCES REFERENCES employees(id)
);

isAuthorized function in AppController:

public function isAuthorized($user)
{
    // Admin can access every action
    if ($user['group_id'] === 1) {
        return true;
    }

    // Default deny
    return false;
}

isAuthorized function in EventsController:

public function isAuthorized($user)
{
  $action = $this->request->params['action'];

  // The index action is always allowed.
  //Every user can add a new event
  if (in_array($action, ['index','add','przekaz'])) {
    return true;
  }

   // The owner of an event can edit and delete it
  if (in_array($this->request->action, ['edit', 'view'])) {
    $eventId = (int)$this->request->params['pass'][0];

    //This block is a remnant of my attempt to create authorization by group
    $event = $this->Events->get($eventId, [
        'contain' => []
    ]);
    $authorId = $event->user_id;
    $author = $this->Users->get($authorId, [
      'contain' => []
    ]);
    $groupId = $author->group_id;
    $loggedUserGroupId = $user['group_id'];
    //end of remnant



    if ($user['group_id'] === 1 || $this->Events->isOwnedBy($eventId, $user['id']) || $groupId === $loggedUserGroupId) {
      return true;
    }
  }
  return parent::isAuthorized($user);
}

isOwnedBy function in EventsTable:

public function isOwnedBy($eventId, $userId)
{
  return $this->exists(['id' => $eventId, 'user_id' => $userId]);
}

Upvotes: 1

Views: 74

Answers (1)

PHPJunior
PHPJunior

Reputation: 75

It appears I misunderstood what exactly isAuthorized do. Instead of looking at the isAuthorized method I should have just edited one line in index method. Well I'm ashamed of my lack of knowledge.

The solution:

public function index()
{
  if($this->Auth->user('group_id') != 1) {
    $this->paginate = [
      'conditions' => [
        'Users.group_id' => $this->Auth->user('group_id')  // this line was changed
      ],
      'contain' => ['Employees', 'Users', 'Statuses']
      ];
  } else {
    $this->paginate = [
      'contain' => ['Employees', 'Users', 'Statuses']
      ];
  }

Upvotes: 1

Related Questions