Je vise à restreindre certains verbes RESTUL par type de publication personnalisé. Par exemple, étant donné un type de message personnalisé de vocabulaire, je voudrais dire:
Matrice des autorisations
+-------+---+----------+
|index | X | GET |
|show | O | GET |
|create | X | POST |
|update | X | PATCH/PUT|
|delete | X | DELETE |
+-------+---+----------+
Le V2 ne semble pas fournir ce niveau de contrôle. J'ai parcouru la source, et d'après ce que je peux voir, il n'y a pas de crochets / filtres pour exploiter les autorisations changeantes.
Ma solution actuelle est la suivante. Il compromet une classe où vous pouvez charger dans une matrice de types de publication personnalisés contre les actions autorisées. Cela peut ensuite être appelé dans le rest_prepare_vocabulary
filtre, détruisant la réponse si les autorisations ne s'alignent pas.
Problème
Je ne pense pas que ce soit une solution raisonnable. Cela signifie que les autorisations sont résolues à deux endroits (un, dans le noyau, car ils sont toujours appliqués) et dans mes filtres.
Idéalement, ce serait au niveau de la configuration, à savoir où les types de publication personnalisés sont définis.
En d' autres termes, je préférerais passer dans les règles ( le long des lignes de exclude_from_search
, publicly_queryable
, etc.) plutôt que d' effectuer une requête post « snip ».
Solution actuelle (fonctionne mais n'est pas souhaitable)
Access.php
class Access
{
function __construct($permissions) {
$this->permissions = $permissions;
}
protected function hasId($request) {
return ! is_null($request->get_param('id'));
}
protected function resolveType($request) {
$method = strtoupper($request->get_method());
if($method === 'GET' && $this->hasId($request)) {
return 'show';
} else if($method === 'GET') {
return 'index';
} else if($method === 'DELETE') {
return 'delete';
} else if($method === 'POST') {
return 'create';
} else if($method === 'PATCH') {
return 'update';
}
}
function validate($type, $request) {
return in_array($this->resolveType($request), $this->permissions[$type]);
}
}
functions.php
// bootstrap the permissions for this particular
// application
//
$access = new Access([
'vocabulary' => ['show'],
]);
add_filter('rest_prepare_vocabulary', 'validate_permissions', 30, 3);
function validate_permissions($response, $post, $request) {
global $access;
// Give access->validate the type + request data
// and it will figure out if this is allowed
//
if( ! $access->validate($post->post_type, $request)) {
$response->set_data([]);
$response->set_status(403);
}
return $response;
};
\App
et l'accès est en fait\App\Services\Access
Access
dans la portée mondiale? En avez-vous besoin ailleurs? Si vous répondez par oui , vous voudrez peut-être le joindre à un filtre.