Dengan Rest V2 (WP4.7) bagaimana seseorang membatasi kata kerja RESTFUL tertentu?

20

Saya bertujuan untuk membatasi kata kerja RESTUL tertentu per jenis posting kustom. Misalnya, mengingat jenis posting khusus Kosakata, saya ingin mengatakan:

Matriks Izin

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

V2 tampaknya tidak memberikan tingkat kontrol itu. Saya telah menelusuri sumbernya, dan dari apa yang dapat saya lihat, tidak ada kait / filter untuk memanfaatkan perubahan izin.

Solusi saya saat ini adalah sebagai berikut. Ini mengkompromikan kelas di mana Anda dapat memuat dalam matriks jenis posting khusus terhadap tindakan yang diizinkan. Ini kemudian dapat disebut dalam rest_prepare_vocabularyfilter, menghancurkan respons jika izin tidak berbaris.

Masalah

Saya tidak merasa ini solusi yang masuk akal. Itu berarti izin sedang diselesaikan di dua tempat (satu, di inti, karena masih diterapkan) dan di filter saya.

Idealnya, ini akan berada pada tingkat konfigurasi, yaitu di mana jenis posting kustom didefinisikan.

Dengan kata lain, saya akan lebih memilih untuk lulus dalam aturan (sepanjang garis exclude_from_search, publicly_queryable, dll) daripada melakukan query posting "snip".

Solusi saat ini (berfungsi tetapi tidak diinginkan)

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;
};
Chris
sumber
1
Mengapa Anda instantiate Accessdalam lingkup global? Apakah Anda membutuhkannya di tempat lain? Jika Anda menjawab ini dengan ya , Anda mungkin ingin melampirkannya ke filter.
kaiser
3
Pertanyaan wajar - Di atas hanyalah cuplikan, saya menggunakan komposer dan autoloading PSR4 untuk menggambar modul kelas ke dalam kelas App induk, di mana cuplikan di atas akan berada - jadi itu bukan global yang sebenarnya, itu akan dinamai dengan ruang global \Appdan Akses sebenarnya\App\Services\Access
Chris
1
Saya sendiri belum menyelidiki masalah ini, tetapi apakah Anda memeriksa tiket Trac atau membuat tiket jika tidak ada? Kedengarannya seperti fitur yang masuk akal untuk memiliki ...
kraftner
1
Saya tidak begitu mengerti masalahnya. "Itu berarti izin sedang diselesaikan di dua tempat (satu, di inti, saat masih diterapkan) dan di filter saya. Idealnya, itu akan berada pada tingkat konfigurasi, yaitu di mana jenis pos kustom didefinisikan." Bisakah Anda menjelaskan apa yang Anda maksud di sini? Maaf kalau saya bodoh!
Jim Maguire
2
Saya menurunkan pertanyaan ini. Saya tidak mengerti mengapa 18 orang memilihnya. Ini tidak bisa dimengerti.
Jim Maguire

Jawaban:

1

Saya telah menelusuri sumbernya, dan dari apa yang dapat saya lihat, tidak ada kait / filter untuk memanfaatkan perubahan izin.

Pemahaman saya adalah bahwa ini adalah keputusan desain yang disengaja.

Meskipun REST API dibuat agar dapat diperluas, tidak disarankan untuk memodifikasi titik akhir inti dengan cara yang Anda minta.

Ada beberapa informasi terbatas yang tersedia di bagian buku pegangan REST API ini , tetapi intinya adalah bahwa seiring bertambahnya usia API, lebih banyak kode (apakah itu inti atau pihak ketiga) akan mulai bergantung pada tindakan spesifik yang tersedia dan memberikan standar tanggapan.

Sebagai gantinya Anda harus membuat pengontrol khusus.

Jenis pos khusus dapat diberikan pengontrol khusus dengan menentukan nama kelas dalam rest_controller_classargumen untukregister_post_type() .

Gambaran umum tentang cara kerja pengontrol kustom dapat ditemukan di buku pegangan REST API .

Hal lain yang perlu diingat adalah bahwa jika Anda membuat pengontrol khusus yang memperluas WP_REST_Controllerkelas abstrak untuk tipe posting yang mendukung revisi, sejumlah titik akhir revisi tipe spesifik posting akan dibuat secara otomatis.

Jika tidak memperpanjang WP_REST_Controllerkelas, register_routes()metode ini tidak dipanggil sehingga Anda harus mendaftarkan rute kustom Anda secara manual.

ssnepenthe
sumber