What's the differences between table and entity policies?

What’s the differences between table and entity policies? When should I use which?

You use entity policies when you want to authorize row level access, for example when you ask “is identity x allowed to access record y with the id z” (where “access” could be read/write/delete).

You use table/repository policies when you want to authorize model level access, for example “is identity x allowed to access the records of table y” (again “access” could be read/write/delete). Furthermore table/repository policies are used to apply scopes, eg if you want to “allow identity x to only read those records of table y that do match the conditions z”.

2 Likes

I see table policies more like a filter for what users can see

Lets say user bob can only edit other users with the group value authors

Then a table policy would reduce the authors bob can see in the index template /authors to only those

// src/Policy/UsersTablePolicy.php
namespace App\Policy;

class UsersTablePolicy
{
    public function scopeIndex($user, $query)
    {
        // Add more conditional logic on which user can see what here
        return $query->where(['Users.group' => 'authors']);
    }
}

// src/Controller/UsersController.php
public function index() 
{
    $query = $this->Authorization->applyScope($this->Users->find());
    $users = $this->paginate($query);
    $this->set(compact('users'));
}

and the entity policy is then responsible for the add/edit/delete restriction

1 Like

So there are no “can”-methodes in a table policy class? Only the “scope” ones?

Appling your provided example code with “scoped” raised an error in my application:

Policy for Cake\ORM\Query has not been defined.
Authorization\Policy\Exception\MissingPolicyException

class AdministratorsController extends QfbUsersController
{
  public function initialize(): void
  {
    parent::initialize();
    $this->loadModel('QfbUsers');
  }
  public function editSearch()
  {
    ...
    $query =  $this->Authorization->applyScope($this->QfbUsers->find('search', ['search' => $this->request->getQueryParams(), 'collection' => $collection]));
    ...
  }
}
--
class QfbUserTablePolicy
{
    public function scopeEditSearch(IdentityInterface $identity, $query)
    {
        return $query; // just for testing
    }
}

I really understand now (due to @ndm explanation) to use the policies in a conceptional way, but how to run it in code is still unclear for me. The book + cms tutorial examples are about entity policy - and that works in my code too, but how the other kind of policy can be used is unclear - eg. the use of table policy in code.
I found some additional methode:

$this->Authorization->authorizeModel('actionNameHere');
$this->Authorization->authorizeAction();

…but which one is using / finding the right policy class.

Will still do a try and error and search the forum and the web.

You’re missing an s there, needs to be QfbUsersTablePolicy, ie Users vs User.

Oh…! Thanks for the hint. The biggest mistake is often in front of the computer :slight_smile:
Now it works…