Com Rest V2 (WP4.7) como restringir certos verbos RESTFUL?

20

Estou com o objetivo de restringir certos verbos RESTUL por tipo de postagem personalizada. Por exemplo, dado um tipo de post personalizado de vocabulário, gostaria de dizer:

Matriz de permissões

+-------+---+----------+
|index  | X | GET      |
|show   | O | GET      |
|create | X | POST     |
|update | X | PATCH/PUT|
|delete | X | DELETE   |
+-------+---+----------+

O V2 não parece fornecer esse nível de controle. Eu passei pela fonte e, pelo que vejo, não há ganchos / filtros para mudar as permissões.

Minha solução atual é a seguinte. Compromete-se de uma classe em que você pode carregar uma matriz de tipos de postagem personalizados em relação a ações permitidas. Isso pode ser chamado no filtro rest_prepare_vocabulary , destruindo a resposta se as permissões não estiverem alinhadas.

Problema

Eu não sinto que esta seja uma solução razoável. Isso significa que as permissões estão sendo resolvidas em dois pontos (um, no núcleo, como eles ainda são aplicados) e nos meus filtros.

Idealmente, seria em um nível de configuração, ou seja, onde os tipos de postagem personalizados são definidos.

Em outras palavras, eu preferiria passar regras (ao longo das linhas de exclude_from_search , publicly_queryable , etc) em vez de executar uma consulta "recorte".

Solução atual (funciona, mas não é desejável)

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;
};
    
por Chris 09.12.2016 / 13:47
fonte

1 resposta

1
  

Eu passei pela fonte e, pelo que vejo, não há ganchos / filtros para mudar as permissões.

Meu entendimento é que essa foi uma decisão de design intencional.

Embora a API REST tenha sido criada para ser extensível, não é recomendável modificar os endpoints principais da maneira como você está perguntando.

Existem algumas informações limitadas disponíveis em esta seção do manual da API REST , mas a essência disso é que à medida que a API envelhece, mais código (seja ele principal ou de terceiros) começará a depender de ações específicas disponíveis e fornecendo respostas.

Em vez disso, você deve criar um controlador personalizado.

Os tipos de postagens personalizadas podem receber um controlador personalizado, especificando um nome de classe no argumento rest_controller_class para register_post_type() .

Uma visão geral de como os controladores personalizados devem funcionar pode ser encontrada no REST Manual da API .

Outra coisa a ter em mente é que, se você criar um controlador personalizado que estenda a classe abstrata WP_REST_Controller para um tipo de postagem que suporte revisões, serão criados automaticamente vários pontos de extremidade de revisão específicos de tipo de postagem.

Se não estender a classe WP_REST_Controller , o método register_routes() não será chamado, portanto você terá que registrar manualmente suas rotas personalizadas.

    
por ssnepenthe 15.10.2017 / 09:02
fonte