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_vocabulary
Filter 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_queryable
usw.) , 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;
};
\App
und Zugang ist eigentlich\App\Services\Access
Access
im 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.