Mostrar endpoint de tipo de publicación personalizada en REST API solo si el usuario tiene capacidad

20 feb 2017, 19:31:08
Vistas: 2.57K
Votos: 4

He creado un tipo de publicación personalizada para WP, que solo debe ser accesible para usuarios que tengan un capability personalizado read_cpt. Dentro de las plantillas y pre_get_posts puedo ejecutar verificaciones para incluir o excluir el CPT usando current_user_can().

No quiero que el CPT, ni siquiera el endpoint, aparezca en la API REST, para mantenerlo completamente secreto, mientras el usuario no tenga el capability personalizado.

La única forma que encontré para ocultar los endpoints en la API es ejecutar este código.

Registrar el tipo de post para WP "clásico":

function add_post_type() {
    $args = array(
        [...]
        'public'                => false,
        'has_archive'           => false,
        'exclude_from_search'   => true,
        'publicly_queryable'   => false,
        'show_in_rest'          => false,
    );
    register_post_type( 'cpt', $args );
}
add_action( 'init', 'add_post_type', 0 );

y por separado agregarlo a la API REST:

add_action( 'init', 'cpt_rest_support', 25 );
function cpt_rest_support() {
    global $wp_post_types;

    if ( current_user_can( 'read_addresses' ) ) {
        //¡asegúrate de establecer esto como el nombre de tu tipo de post!
        $post_type_name = 'address';
        if( isset( $wp_post_types[ 'cpt' ] ) ) {
            $wp_post_types[ 'cpt' ]->show_in_rest = true;
        }
    }
}

Al crear una clase personalizada WP_REST_Posts_Controller no encontré forma de ocultar el endpoint modificando alguno de los *_permissions_check

¿Existe algo como un argumento "show_in_rest_permition_check" para register_post_type() o es la forma descrita el único método?

0
Todas las respuestas a la pregunta 4
0

La API REST no tiene parámetros ni opciones para resolver esto, en mi opinión. Pero deberías registrarlo solo si los usuarios tienen la capacidad en su rol, como en el siguiente ejemplo.

add_action( 'rest_api_init', function() {

    // Salir si el usuario logueado no tiene suficientes permisos.
    if ( ! current_user_can( 'edit_posts' ) ) {
        return;
    }

    // Registrar Meta Datos.
    register_meta( 'post', 'foo', array(
        'show_in_rest' => true,
    ));
});

Esto activará los datos personalizados en la API REST solo si el usuario tiene suficientes derechos y capacidades en su rol. Mi register_meta() es solo un ejemplo, que también debería funcionar con tu parámetro adicional para register_post_type, como $wp_post_types[ 'cpt' ]->show_in_rest = true;.

20 feb 2017 22:25:34
0

Pregunta antigua pero esto funcionó para mí siguiendo los requisitos de @Drivingralle. Podrías usar current_user_can() como un interruptor booleano para modificar el comportamiento del parámetro show_in_rest:

function add_post_type() {

    $show_in_rest = current_user_can( 'read_cpt' ); //esto devolverá verdadero o falso

    $args = array(
        [...]
        'public'                => false,
        'has_archive'           => false,
        'exclude_from_search'   => true,
        'publicly_queryable'    => false,
        'show_in_rest'          => $show_in_rest, //interruptor booleano de current_user_can()
    );
    register_post_type( 'cpt', $args );
}
add_action( 'init', 'add_post_type' );

De esta manera, el tipo de contenido personalizado solo se muestra en REST para usuarios con la capacidad requerida.

22 sept 2021 15:23:53
0

No confíes únicamente en ocultarlo.

En su lugar, devuelve un error en el manejador:

if (!current_user_can('read_addresses')) {
    return new WP_REST_Response('restricted', 403);
}

Para ocultarlo también, filtra el contenido de los hooks rest_index y rest_namespace_index.

12 nov 2019 08:55:04
0

Utiliza la función register_rest_route().

if( current_user_can( 'read_addresses' ) ) {
    register_rest_route( 'namespace/v1', 'cpt', array(
        'methods' => array( 'GET' ),
        'callback' => 'callback_function',
        'permission_callback' => 'permission_callback_function'
    ) );
}

Tu callback_function manejaría la solicitud y devolvería la respuesta. La permissions_callback_function verificaría los permisos del usuario y devolvería un error si el usuario no tiene las capacidades especificadas. En este caso, probablemente no sea necesario el callback de permisos, pero no estaría de más tenerlo implementado por si acaso.

12 nov 2019 19:01:35