Con Rest V2 (WP4.7) ¿cómo se restringen ciertos verbos RESTFUL?

20

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 ningún gancho / filtro para aprovechar los permisos cambiantes.

Mi solución actual es la siguiente. Se compromete a una clase en la que puede cargar en una matriz de tipos de publicaciones personalizadas contra acciones permitidas. Esto puede luego ser llamado en el filtro rest_prepare_vocabulary , destruyendo la respuesta si los permisos no se alinean.

Problema

No creo que esta sea una solución razonable. Significa que los permisos se están resolviendo 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, preferiría pasar reglas (en la línea de exclude_from_search , publicly_queryable , etc.) en lugar de realizar una consulta posterior "snip".

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]);
    }
}

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;
};
    
pregunta Chris 09.12.2016 - 13:47

1 respuesta

1
  

He revisado la fuente y, por lo que puedo ver, no hay ningún gancho / filtro para aprovechar los permisos cambiantes.

Entiendo que esto 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 REST API , pero la esencia de esto es que a medida que la API envejece, más código (ya sea central o de terceros) comenzará a depender de las acciones específicas que estén disponibles y proporcionen el estándar. respuestas.

En su lugar, debe crear un controlador personalizado.

A los tipos de publicaciones personalizadas se les puede otorgar un controlador personalizado especificando un nombre de clase en argumento rest_controller_class a register_post_type() .

Puede encontrar una descripción general de cómo deberían funcionar los controladores personalizados en REST Manual de API .

Algo más que se debe tener en cuenta es que si crea un controlador personalizado que amplíe la clase WP_REST_Controller abstracta para un tipo de publicación que admita revisiones, se crearán automáticamente varios puntos finales de revisión específicos para cada tipo de publicación.

Si no extiende la clase WP_REST_Controller , no se invoca el método register_routes() , por lo que tendrá que registrar manualmente sus rutas personalizadas.

    
respondido por el ssnepenthe 15.10.2017 - 09:02

Lea otras preguntas en las etiquetas