Wie schränkt man mit Rest V2 (WP4.7) bestimmte RESTFUL-Verben ein?

20

Ich möchte bestimmte RESTUL-Verben pro benutzerdefiniertem Beitragstyp einschränken. Zum Beispiel möchte ich bei einem benutzerdefinierten Vokabeltyp Folgendes sagen:

Berechtigungsmatrix

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

Die V2 scheint diese Kontrolle nicht zu bieten. Ich habe die Quelle durchgesehen, und soweit ich sehen kann, gibt es keine Hooks / Filter, mit denen sich Berechtigungen ändern lassen.

Meine derzeitige Lösung lautet wie folgt. Kompromisse einer Klasse, in der Sie eine Matrix benutzerdefinierter Beitragstypen gegen zulässige Aktionen laden können. Dies kann dann im rest_prepare_vocabularyFilter aufgerufen werden, wodurch die Antwort zerstört wird, wenn die Berechtigungen nicht übereinstimmen.

Problem

Ich halte das nicht für eine vernünftige Lösung. Dies bedeutet, dass Berechtigungen an zwei Stellen (eine im Kern, da sie noch angewendet werden) und in meinen Filtern aufgelöst werden.

Idealerweise ist dies eine Konfigurationsebene, in der die benutzerdefinierten Beitragstypen definiert sind.

Mit anderen Worten, ich würde es vorziehen , in Regeln passieren (entlang der Linien exclude_from_search, publicly_queryableusw.) , anstatt einen Beitrag Abfrage „schnippeln“ durchgeführt wird .

Aktuelle Lösung (funktioniert aber nicht wünschenswert)

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
quelle
1
Warum haben Sie Accessim globalen Bereich instanziiert ? Benötigen Sie es woanders? Wenn Sie dies mit Ja beantworten , möchten Sie es möglicherweise stattdessen an einen Filter anhängen.
Kaiser
3
Messe Frage - Die oben ist nur ein Ausschnitt, ich bin mit Komponisten und PSR4 selbstladende Klasse Module in eine übergeordnete App Klasse zu zeichnen, von denen das obige Snippet in sein würde - so ist es nicht wirklich global global ist, wäre es sein Namensraum zu \Appund Zugang ist eigentlich\App\Services\Access
Chris
1
Ich habe dieses Problem nicht selbst untersucht, aber haben Sie Trac nach einem Ticket durchsucht oder ein Ticket erstellt, wenn es nicht vorhanden ist? Klingt nach einer vernünftigen Eigenschaft zu haben ...
Kraftner
1
Ich verstehe das Problem nicht wirklich. "Dies bedeutet, dass Berechtigungen an zwei Stellen (eine im Kern, da sie noch angewendet werden) und in meinen Filtern aufgelöst werden. Idealerweise ist dies eine Konfigurationsebene, in der die benutzerdefinierten Beitragstypen definiert sind." Können Sie möglicherweise klarstellen, was Sie hier meinen? Entschuldigung, wenn ich dumm bin!
Jim Maguire
2
Ich stimme dieser Frage ab. Ich verstehe nicht, warum 18 Leute es hochgestuft haben. Es ist unverständlich.
Jim Maguire

Antworten:

1

Ich habe die Quelle durchgesehen, und soweit ich sehen kann, gibt es keine Hooks / Filter, mit denen sich Berechtigungen ändern lassen.

Mein Verständnis ist, dass dies eine beabsichtigte Entwurfsentscheidung war.

Obwohl die REST-API so erstellt wurde, dass sie erweiterbar ist, wird nicht empfohlen, die Kernendpunkte auf die von Ihnen gewünschte Weise zu ändern.

In diesem Abschnitt des REST-API-Handbuchs sind einige Informationen nur in begrenztem Umfang verfügbar. Der Kern des Handbuchs ist jedoch, dass mit zunehmendem Alter der API mehr Code (unabhängig davon, ob es sich um Kern- oder Drittanbieter handelt) von bestimmten verfügbaren Aktionen und Standardfunktionen abhängt Antworten.

Stattdessen sollten Sie einen benutzerdefinierten Controller erstellen.

Benutzerdefinierte Post-Typen können durch Angabe eines Klassennamens im rest_controller_classArgument fürregister_post_type() einen benutzerdefinierten Controller zugewiesen werden .

Eine Übersicht über die Funktionsweise benutzerdefinierter Controller finden Sie im REST-API-Handbuch .

Beachten Sie außerdem, dass beim Erstellen eines benutzerdefinierten Controllers, der die abstrakte WP_REST_ControllerKlasse für einen Beitragstyp erweitert, der Revisionen unterstützt, automatisch eine Reihe von Beitragstyp-spezifischen Revisionsendpunkten erstellt wird.

Wenn die WP_REST_ControllerKlasse nicht erweitert wird , wird die register_routes()Methode nicht aufgerufen, sodass Sie Ihre benutzerdefinierten Routen manuell registrieren müssen.

ssnepenthe
quelle