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 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_vocabularyfiltro, 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;
};

1
¿Por qué creaste una instancia Accessen el ámbito global? ¿Lo necesitas en otro lado? En caso de que responda esto con un , es posible que desee adjuntarlo a un filtro.
kaiser

3
Pregunta justa: lo anterior es solo un fragmento, estoy usando la carga automática de compositor y PSR4 para dibujar módulos de clase en una clase de aplicación principal, de la cual estaría el fragmento anterior, por lo que no es realmente global global, sería un espacio de nombres \Appy el acceso es en realidad\App\Services\Access
Chris

1
No he investigado este problema yo mismo, pero ¿comprobaste en Trac un ticket o creaste uno si no existe? Suena como una característica razonable tener ...
kraftner 05 de

1
Realmente no entiendo el problema. "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". ¿Puedes aclarar lo que quieres decir aquí? Lo siento si soy estúpido!
Jim Maguire

2
Estoy rechazando esta pregunta. No entiendo por qué 18 personas lo votaron. Es incomprensible.
Jim Maguire

Respuestas:


1

He revisado la fuente y, por lo que puedo ver, no hay ganchos / filtros para aprovechar los permisos cambiantes.

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_classargumento 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_Controllerclase 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_Controllerclase, register_routes()no se llama al método, por lo que deberá registrar manualmente sus rutas personalizadas.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.