Mi objetivo es restringir ciertos verbos RESTUL por tipo de publicación personalizada. Por ejemplo, dado un tipo de publicación personalizada de vocabulario, me gustaría decir:
Matriz de permisos
+-------+---+----------+
|index | X | GET |
|show | O | GET |
|create | X | POST |
|update | X | PATCH/PUT|
|delete | X | DELETE |
+-------+---+----------+
El V2 no parece proporcionar ese nivel de control. He revisado la fuente y, por lo que puedo ver, no hay ganchos / filtros para aprovechar los permisos cambiantes.
Mi solución actual es la siguiente. Compromete una clase en la que puede cargar en una matriz de tipos de publicaciones personalizadas contra acciones permitidas. Esto se puede invocar en el rest_prepare_vocabulary
filtro, destruyendo la respuesta si los permisos no se alinean.
Problema
No siento que esta sea una solución razonable. Significa que los permisos se resuelven en dos puntos (uno, en el núcleo, ya que todavía se aplican) y en mis filtros.
Idealmente, sería en un nivel de configuración, es decir, donde se definen los tipos de publicaciones personalizadas.
En otras palabras, yo preferiría pasar en las reglas (a lo largo de las líneas de exclude_from_search
, publicly_queryable
, etc) en lugar de realizar una consulta post "cortar".
Solución actual (funciona pero no es deseable)
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]);
}
}
funciones.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;
};
Access
en el ámbito global? ¿Lo necesitas en otro lado? En caso de que responda esto con un sí , es posible que desee adjuntarlo a un filtro.\App
y el acceso es en realidad\App\Services\Access
Respuestas:
Entiendo que esta fue una decisión de diseño intencional.
Si bien la API REST se creó para ser extensible, no se recomienda modificar los puntos finales centrales de la forma en que lo solicita.
Hay información limitada disponible en esta sección del manual de la API REST , pero lo esencial es que a medida que la API envejezca, más código (ya sea de núcleo o de terceros) comenzará a depender de las acciones específicas que estén disponibles y proporcionen estándares. respuestas
En su lugar, debe crear un controlador personalizado.
Los tipos de publicación personalizados pueden recibir un controlador personalizado especificando un nombre de clase en el
rest_controller_class
argumento aregister_post_type()
.Puede encontrar una descripción general de cómo deberían funcionar los controladores personalizados en el manual de la API REST .
Otra cosa a tener en cuenta es que si crea un controlador personalizado que amplía la
WP_REST_Controller
clase abstracta para un tipo de publicación que admite revisiones, se crearán automáticamente una serie de puntos finales de revisión específicos de tipo de publicación.Si no extiende la
WP_REST_Controller
clase,register_routes()
no se llama al método, por lo que deberá registrar manualmente sus rutas personalizadas.fuente