0
votes

I developed a cakePHP application for managing some books and it uses 'Auth' componenet for its authentication mechanism. I have 2 user roles: admin & user. In this application i have below rules for Book and its index view:

  1. every admin can view all books, edit them and ...
  2. every normal user can only view his/her books, edit his/hers only (not all books)

in other words, I want to know is it possible to filter data based on user role before passing model information to view or not?

I guess that passing all data to views and then filter them based on user role inside view, may cause DB overhead but I'm not sure if i am right. Currently my index.ctp is like this and it only displays books related to logged-in user (without caring about his role):

<div class="books index">
<h2><?php echo __('Books'); ?></h2>
<?php if ($loggedIn) { ?>
    <table cellpadding="0" cellspacing="0">
        <thead>
            <tr>
                <th><?php echo $this->Paginator->sort('id'); ?></th>
                <th><?php echo $this->Paginator->sort('book_user_id'); ?></th>
                <th><?php echo $this->Paginator->sort('name'); ?></th>
                <th><?php echo $this->Paginator->sort('revision'); ?></th>
                <th><?php echo $this->Paginator->sort('price'); ?></th>
                <th><?php echo $this->Paginator->sort('publication_year'); ?></th>
                <th><?php echo $this->Paginator->sort('url_cover_page'); ?></th>
                <th><?php echo $this->Paginator->sort('url_last_page'); ?></th>
                <th><?php echo $this->Paginator->sort('author'); ?></th>
                <th><?php echo $this->Paginator->sort('publisher'); ?></th>
                <th><?php echo $this->Paginator->sort('translator'); ?></th>
                <th><?php echo $this->Paginator->sort('tags'); ?></th>
                <th><?php echo $this->Paginator->sort('created'); ?></th>
                <th><?php echo $this->Paginator->sort('modified'); ?></th>
                <th class="actions"><?php echo __('Actions'); ?></th>
            </tr>
        </thead>
        <tbody>
            <?php foreach ($books as $book): ?>
                <?php if ($book['BookUser']['id'] == $loggedIn) { ?>
                    <tr>
                        <td><?php echo h($book['Book']['id']); ?>&nbsp;</td>
                        <td>
                            <?php echo $this->Html->link($book['BookUser']['username'], array('controller' => 'users', 'action' => 'view', $book['BookUser']['id'])); ?>
                        </td>
                        <td><?php echo h($book['Book']['name']); ?>&nbsp;</td>
                        <td><?php echo h($book['Book']['revision']); ?>&nbsp;</td>
                        <td><?php echo h($book['Book']['price']); ?>&nbsp;</td>
                        <td><?php echo h($book['Book']['publication_year']); ?>&nbsp;</td>
                        <td><?php echo h($book['Book']['url_cover_page']); ?>&nbsp;</td>
                        <td><?php echo h($book['Book']['url_last_page']); ?>&nbsp;</td>
                        <td><?php echo h($book['Book']['author']); ?>&nbsp;</td>
                        <td><?php echo h($book['Book']['publisher']); ?>&nbsp;</td>
                        <td><?php echo h($book['Book']['translator']); ?>&nbsp;</td>
                        <td><?php echo h($book['Book']['tags']); ?>&nbsp;</td>
                        <td><?php echo h($book['Book']['created']); ?>&nbsp;</td>
                        <td><?php echo h($book['Book']['modified']); ?>&nbsp;</td>
                        <td class="actions">
                            <?php echo $this->Html->link(__('View'), array('action' => 'view', $book['Book']['id'])); ?>
                            <?php echo $this->Html->link(__('Edit'), array('action' => 'edit', $book['Book']['id'])); ?>
                            <?php echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $book['Book']['id']), array(), __('Are you sure you want to delete # %s?', $book['Book']['id'])); ?>
                        </td>
                    </tr>
                <?php } ?>
            <?php endforeach; ?>
        </tbody>
    </table>
<?php } else { ?>
    <p>To view your books, please login or Sign Up.</p>
<?php } ?>
<p>
    <?php
    echo $this->Paginator->counter(array(
        'format' => __('Page {:page} of {:pages}, showing {:current} records out of {:count} total, starting on record {:start}, ending on {:end}')
    ));
    ?>  </p>
<div class="paging">
    <?php
    echo $this->Paginator->prev('< ' . __('previous'), array(), null, array('class' => 'prev disabled'));
    echo $this->Paginator->numbers(array('separator' => ''));
    echo $this->Paginator->next(__('next') . ' >', array(), null, array('class' => 'next disabled'));
    ?>
</div>

  • Html->link(__('New Book'), array('action' => 'add')); ?>
  • Html->link(__('List Users'), array('controller' => 'users', 'action' => 'index')); ?>
  • Html->link(__('New Book User'), array('controller' => 'users', 'action' => 'add')); ?>
  • Html->link(__('List Pgs'), array('controller' => 'pgs', 'action' => 'index')); ?>
  • Html->link(__('New Book Pgs'), array('controller' => 'pgs', 'action' => 'add')); ?>
1

1 Answers

0
votes

You should not be retrieving the data, let alone sending all data to the view. You should be filtering in your model queries based on the role of the currently logged in user. Then passing it along.

If for some reason it's difficult to filter in the actual queries (not sure why it would be), I'd recommend still filtering the data in the Model method using Cake's Hash or php array functions....etc depending on your needs before passing back to the Controller.

In your view, it's acceptable to write if statements for different display blocks, but that's based on the role of the user.