Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 2.x
  • 3.x
  • 8.x-1.x
  • 8.x-1.x--annotated-endpoints
  • 8.x-1.x--config-endpoints
  • 2.0.1
  • 2.0.2
  • 2.0.3
  • 2.0.4
  • 2.0.5
  • 2.0.6
  • 2.1.0
  • 2.1.1
  • 2.1.2
  • 8.x-1.0-alpha0
  • 8.x-1.0-alpha1
  • 8.x-1.0-alpha2
  • 8.x-1.0-alpha3
  • 8.x-1.0-alpha4
  • 8.x-1.0-alpha5
  • 8.x-1.0-alpha6
  • 8.x-1.0-alpha7
  • 8.x-1.0-beta1
  • 8.x-1.0-beta2
  • 8.x-1.0-beta3
  • 8.x-1.0-beta4
  • 8.x-1.0-beta5
  • 8.x-1.0-beta6
  • 8.x-1.0-beta7
29 results

Target

Select target project
  • project/jsonrpc
  • issue/jsonrpc-3269347
  • issue/jsonrpc-3291299
  • issue/jsonrpc-3328243
  • issue/jsonrpc-3339557
  • issue/jsonrpc-3283740
  • issue/jsonrpc-3374241
  • issue/jsonrpc-3391824
  • issue/jsonrpc-3436360
  • issue/jsonrpc-3284838
  • issue/jsonrpc-3436320
  • issue/jsonrpc-3285339
  • issue/jsonrpc-3449877
  • issue/jsonrpc-3451151
  • issue/jsonrpc-3471329
  • issue/jsonrpc-3471345
  • issue/jsonrpc-3471349
  • issue/jsonrpc-3471351
  • issue/jsonrpc-3471505
  • issue/jsonrpc-3471507
  • issue/jsonrpc-3471517
  • issue/jsonrpc-3471857
  • issue/jsonrpc-3472010
  • issue/jsonrpc-3471922
  • issue/jsonrpc-3471816
  • issue/jsonrpc-3472101
  • issue/jsonrpc-3216615
  • issue/jsonrpc-3473362
  • issue/jsonrpc-3473531
  • issue/jsonrpc-3473712
  • issue/jsonrpc-3474318
  • issue/jsonrpc-3475910
  • issue/jsonrpc-3471306
  • issue/jsonrpc-3471347
  • issue/jsonrpc-3476351
  • issue/jsonrpc-3481908
  • issue/jsonrpc-3481911
  • issue/jsonrpc-3483666
  • issue/jsonrpc-3484262
39 results
Select Git revision
  • 2.x
  • 3.x
  • 8.x-1.x
  • 8.x-1.x--annotated-endpoints
  • 8.x-1.x--config-endpoints
  • attributes
  • 2.0.1
  • 2.0.2
  • 2.0.3
  • 2.0.4
  • 2.0.5
  • 2.0.6
  • 2.1.0
  • 2.1.1
  • 2.1.2
  • 8.x-1.0-alpha0
  • 8.x-1.0-alpha1
  • 8.x-1.0-alpha2
  • 8.x-1.0-alpha3
  • 8.x-1.0-alpha4
  • 8.x-1.0-alpha5
  • 8.x-1.0-alpha6
  • 8.x-1.0-alpha7
  • 8.x-1.0-beta1
  • 8.x-1.0-beta2
  • 8.x-1.0-beta3
  • 8.x-1.0-beta4
  • 8.x-1.0-beta5
  • 8.x-1.0-beta6
  • 8.x-1.0-beta7
  • previous/attributes/2024-11-07
31 results
Show changes
Commits on Source (2)
Showing
with 610 additions and 120 deletions
basic_auth: TRUE
cookie: FALSE
jwt: FALSE
oauth2: TRUE
# Schema for the configuration files of the JSON-RPC module.
jsonrpc.settings:
type: config_object
label: 'JSON-RPC settings'
mapping:
basic_auth:
type: boolean
label: 'Allow access via basic authentication'
cookie:
type: boolean
label: 'Allow access via cookies'
jwt:
type: boolean
label: 'Allow access via JWT'
oauth2:
type: boolean
label: 'Allow access via OAuth 2.0'
name: JSON-RPC 2.0
type: module
description: Infrastructure for JSON-RPC 2.0 compliant web services.
core_version_requirement: ^9 || ^10 || ^11
configure: jsonrpc.settings
core_version_requirement: ^10.2 || ^11
package: Web services
<?php
/**
* @file
* Hook update implementations for the JSON-RPC module.
*/
declare(strict_types=1);
use Drupal\jsonrpc\Enum\JsonRpcSetting;
/**
* Add config for access control to the JSON-RPC module.
*/
function jsonrpc_update_2001(): void {
$config_factory = \Drupal::configFactory();
$config = $config_factory->getEditable('jsonrpc.configuration');
$config->set(JsonRpcSetting::BasicAuth->value, TRUE);
$config->set(JsonRpcSetting::Cookie->value, FALSE);
$config->set(JsonRpcSetting::OAuth2->value, TRUE);
$config->save(TRUE);
}
use jsonrpc services:
title: 'Use JSON-RPC services.'
administer jsonrpc:
title: 'Administer JSON-RPC.'
......@@ -6,4 +6,12 @@ jsonrpc.handler:
requirements:
_permission: 'use jsonrpc services'
options:
_auth: ['basic_auth', 'oauth2']
# Allowed authorization methods are set on the module configuration page.
_auth: []
jsonrpc.settings:
path: '/admin/config/system/jsonrpc'
defaults:
_title: 'JSON-RPC'
_form: 'Drupal\jsonrpc\Form\JsonRpcConfigurationForm'
requirements:
_permission: 'administer jsonrpc'
......@@ -14,6 +14,11 @@ services:
'@renderer',
'@Drupal\jsonrpc\Exception\ErrorHandler',
]
jsonrpc.route_subscriber:
class: Drupal\jsonrpc\Routing\JsonRpcRouteSubscriber
arguments: ['@config.factory']
tags:
- { name: event_subscriber }
jsonrpc.schema_validator:
class: JsonSchema\Validator
jsonrpc.options_request_listener:
......
name: JSON-RPC 2.0 Core
type: module
description: JSON-RPC 2.0 services for Drupal core.
core_version_requirement: ^9 || ^10 || ^11
core_version_requirement: ^10.2 || ^11
package: Web services
dependencies:
- jsonrpc:jsonrpc
......@@ -5,10 +5,13 @@ declare(strict_types=1);
namespace Drupal\Tests\jsonrpc_core\Functional;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Url;
use Drupal\Tests\jsonrpc\Functional\JsonRpcTestBase;
use Drupal\jsonrpc\Enum\JsonRpcSetting;
use GuzzleHttp\RequestOptions;
/**
* Test turning the maintenance mode on or off using JSON RPC.
* Test turning the maintenance mode on or off using JSON-RPC.
*
* @group jsonrpc
*/
......@@ -25,30 +28,48 @@ class MaintenanceModeEnabledTest extends JsonRpcTestBase {
];
/**
* Tests enabling the maintenance mode.
* The POST request to enable maintenance mode.
*
* @var array
*/
public function testEnablingMaintenanceMode(): void {
protected array $enableRequest = [
'jsonrpc' => '2.0',
'method' => 'maintenance_mode.isEnabled',
'params' => [
'enabled' => TRUE,
],
'id' => 'maintenance_mode_enabled',
];
$enabled_request = [
'jsonrpc' => '2.0',
'method' => 'maintenance_mode.isEnabled',
'params' => [
'enabled' => TRUE,
],
'id' => 'maintenance_mode_enabled',
];
/**
* The POST request to disabled maintenance mode.
*
* @var array
*/
protected array $disableRequest = [
'jsonrpc' => '2.0',
'method' => 'maintenance_mode.isEnabled',
'params' => [
'enabled' => FALSE,
],
'id' => 'maintenance_mode_disabled',
];
/**
* Tests enabling maintenance mode.
*
* @param \Drupal\jsonrpc\Enum\JsonRpcSetting $auth_method
* The auth method to use for the test.
*/
private function enableMaintenanceModeTestFlow(JsonRpcSetting $auth_method): void {
// Assert that anonymous users are not able to enable the maintenance page.
$response = $this->postRpc($enabled_request);
$this->assertSame(401, $response->getStatusCode());
// Assign correct permission and login.
$account = $this->createUser(['administer site configuration'], NULL, TRUE);
$anon_response = $this->postRpc($this->enableRequest);
$this->assertSame(401, $anon_response->getStatusCode());
// Retry request with basic auth.
$response = $this->postRpc($enabled_request, $account);
$this->assertSame(200, $response->getStatusCode());
$parsed_body = Json::decode($response->getBody());
// Retry request with auth.
$auth_response = $this->postRpc($this->enableRequest, $this->adminUser, $auth_method);
$this->assertSame(200, $auth_response->getStatusCode());
$parsed_body = Json::decode($auth_response->getBody());
$expected = [
'jsonrpc' => '2.0',
'id' => 'maintenance_mode_enabled',
......@@ -57,22 +78,17 @@ class MaintenanceModeEnabledTest extends JsonRpcTestBase {
$this->assertEquals($expected, $parsed_body);
// Assert maintenance mode is enabled.
// If using cookie auth, we need to log out first because we are an admin.
if ($auth_method === JsonRpcSetting::Cookie) {
$this->drupalLogout();
}
$this->drupalGet('/jsonrpc');
$this->assertEquals('Site under maintenance', $this->cssSelect('main h1')[0]->getText());
// Send request to disable maintenance mode.
$disabled_request = [
'jsonrpc' => '2.0',
'method' => 'maintenance_mode.isEnabled',
'params' => [
'enabled' => FALSE,
],
'id' => 'maintenance_mode_disabled',
];
$response = $this->postRpc($disabled_request, $account);
$this->assertSame(200, $response->getStatusCode());
$parsed_body = Json::decode($response->getBody());
$disabled_response = $this->postRpc($this->disableRequest, $this->adminUser, $auth_method);
$this->assertSame(200, $disabled_response->getStatusCode());
$parsed_body = Json::decode($disabled_response->getBody());
$expected = [
'jsonrpc' => '2.0',
'id' => 'maintenance_mode_disabled',
......@@ -81,8 +97,52 @@ class MaintenanceModeEnabledTest extends JsonRpcTestBase {
$this->assertEquals($expected, $parsed_body);
// Assert maintenance mode is disabled.
// If using cookie auth, we need to log out first because we are an admin.
if ($auth_method === JsonRpcSetting::Cookie) {
$this->drupalLogout();
}
$this->drupalGet('/jsonrpc');
$this->assertNotEquals('Site under maintenance', $this->cssSelect('main h1')[0]->getText());
}
/**
* Tests enabling maintenance mode with basic auth.
*/
public function testEnablingMaintenanceModeBasicAuth(): void {
$this->enableBasicAuth();
$this->enableMaintenanceModeTestFlow(JsonRpcSetting::BasicAuth);
}
/**
* Tests enabling maintenance mode with cookie auth.
*/
public function testEnablingMaintenanceModeCookie(): void {
$this->enableCookieAuth();
$this->enableMaintenanceModeTestFlow(JsonRpcSetting::Cookie);
}
/**
* Tests that enabling maintenance mode by cookie requires a CSRF token.
*/
public function testEnablingMaintenanceModeCookieNoCsrfToken(): void {
$this->enableCookieAuth();
$url = $this->buildUrl(Url::fromRoute('jsonrpc.handler'));
$request_options = [
RequestOptions::HTTP_ERRORS => FALSE,
RequestOptions::ALLOW_REDIRECTS => FALSE,
RequestOptions::JSON => $this->enableRequest,
];
// For cookies, we need to log in get the cookie.
$this->drupalLogin($this->adminUser);
// Include cookies, but do not include a CSRF token.
$request_options[RequestOptions::COOKIES] = $this->getSessionCookies();
$client = $this->getHttpClient();
$no_csrf_token_response = $client->request('POST', $url, $request_options);
$this->assertSame(403, $no_csrf_token_response->getStatusCode());
}
}
......@@ -6,6 +6,7 @@ namespace Drupal\Tests\jsonrpc_core\Functional;
use Drupal\Component\Serialization\Json;
use Drupal\Tests\jsonrpc\Functional\JsonRpcTestBase;
use Drupal\jsonrpc\Enum\JsonRpcSetting;
/**
* Test turning the maintenance mode on or off using JSON RPC.
......@@ -27,8 +28,11 @@ class PluginsTest extends JsonRpcTestBase {
/**
* Tests the plugin list.
*
* @param \Drupal\jsonrpc\Enum\JsonRpcSetting $auth_method
* The auth method to use for the test.
*/
public function testPlugins(): void {
public function pluginTestFlow(JsonRpcSetting $auth_method): void {
// 1. Test without a pager.
$rpc_request = [
'jsonrpc' => '2.0',
......@@ -43,11 +47,8 @@ class PluginsTest extends JsonRpcTestBase {
$response = $this->getRpc($rpc_request);
$this->assertSame(401, $response->getStatusCode());
// Assign correct permission and login.
$account = $this->createUser(['administer site configuration'], NULL, TRUE);
// Retry request with auth.
$response = $this->getRpc($rpc_request, $account);
$response = $this->getRpc($rpc_request, $this->adminUser, $auth_method);
$this->assertSame(200, $response->getStatusCode());
$parsed_body = Json::decode($response->getBody());
$this->assertArrayHasKey('result', $parsed_body, 'Could not find results');
......@@ -64,7 +65,7 @@ class PluginsTest extends JsonRpcTestBase {
'page' => ['limit' => 2, 'offset' => 1],
],
];
$response = $this->getRpc($rpc_request, $account);
$response = $this->getRpc($rpc_request, $this->adminUser, $auth_method);
$this->assertSame(200, $response->getStatusCode());
$parsed_body = Json::decode($response->getBody());
$this->assertCount(2, $parsed_body['result']);
......@@ -79,7 +80,7 @@ class PluginsTest extends JsonRpcTestBase {
'page' => ['limit' => 2, 'offset' => 1],
],
];
$response = $this->getRpc($rpc_request, $account);
$response = $this->getRpc($rpc_request, $this->adminUser, $auth_method);
$this->assertSame(400, $response->getStatusCode());
$parsed_body = Json::decode($response->getBody());
$expected = [
......@@ -94,4 +95,20 @@ class PluginsTest extends JsonRpcTestBase {
$this->assertEquals($expected, $parsed_body);
}
/**
* Tests the plugin list with basic auth.
*/
public function testPluginListBasicAuth(): void {
$this->enableBasicAuth();
$this->pluginTestFlow(JsonRpcSetting::BasicAuth);
}
/**
* Tests the plugin list with cookie auth.
*/
public function testPluginListCookie(): void {
$this->enableCookieAuth();
$this->pluginTestFlow(JsonRpcSetting::Cookie);
}
}
name: JSON-RPC 2.0 Discovery
type: module
description: JSON-RPC 2.0 discovery features.
core_version_requirement: ^8 || ^9 || ^10 || ^11
core_version_requirement: ^10.2 || ^11
package: Web services
dependencies:
- drupal:serialization
......
<?php
declare(strict_types=1);
namespace Drupal\Tests\jsonrpc\Functional;
use Drupal\Tests\jsonrpc_discovery\Functional\JsonRpcDiscoveryFunctionalTestBase;
/**
* Tests the configuration for basic_auth.
*
* @group jsonrpc
*/
class JsonRpcDiscoveryBasicAuthTest extends JsonRpcDiscoveryFunctionalTestBase {
/**
* Tests getting the methods as an anonymous user with basic auth.
*/
public function testBasicAuthAnon(): void {
$this->enableBasicAuth();
// Anon does not have access to JSON-RPC services.
$method_url = $this->getMethodsUrl();
try {
$this->getJsonRpcMethod($method_url);
}
catch (\Exception $e) {
$this->assertStringContainsString('401 Unauthorized', $e->getMessage());
}
}
/**
* Tests getting the methods as an auth user with basic auth.
*/
public function testBasicAuthAuth(): void {
$this->enableBasicAuth();
$method_url = $this->getMethodsUrl();
$auth_response = $this->getJsonRpcMethod($method_url, $this->user);
$this->assertEquals(200, $auth_response->getStatusCode());
$this->disableBasicAuth();
try {
$this->getJsonRpcMethod($method_url, $this->user);
}
catch (\Exception $e) {
$this->assertStringContainsString('403', $e->getMessage());
}
}
/**
* Tests getting the methods as an admin user with basic auth.
*/
public function testBasicAuthAdmin(): void {
$this->enableBasicAuth();
$method_url = $this->getMethodsUrl();
$admin_response = $this->getJsonRpcMethod($method_url, $this->adminUser);
$this->assertEquals(200, $admin_response->getStatusCode());
$this->disableBasicAuth();
try {
$this->getJsonRpcMethod($method_url, $this->adminUser);
}
catch (\Exception $e) {
$this->assertStringContainsString('403', $e->getMessage());
}
}
}
<?php
declare(strict_types=1);
namespace Drupal\Tests\jsonrpc\Functional;
use Drupal\Tests\jsonrpc_discovery\Functional\JsonRpcDiscoveryFunctionalTestBase;
use Drupal\user\UserInterface;
use GuzzleHttp\RequestOptions;
use Psr\Http\Message\ResponseInterface;
/**
* Tests the configuration for cookie auth.
*
* @group jsonrpc
*/
class JsonRpcDiscoveryCookieAuthTest extends JsonRpcDiscoveryFunctionalTestBase {
/**
* Sends a GET request to a JSON-RPC method.
*
* @param string $method_url
* The URL of the JSON-RPC method.
* @param \Drupal\user\UserInterface|null $user
* The user interface of the user account. For anon, use null.
*
* @return \Psr\Http\Message\ResponseInterface
* The response from the JSON-RPC method.
*
* @throws \GuzzleHttp\Exception\GuzzleException
*/
#[\Override]
protected function getJsonRpcMethod(string $method_url, ?UserInterface $user = NULL): ResponseInterface {
$request_options = [
RequestOptions::BODY => NULL,
RequestOptions::HEADERS => [],
];
if ($user instanceof UserInterface) {
$request_options[RequestOptions::COOKIES] = $this->getSessionCookies();
}
return \Drupal::httpClient()->get($method_url, $request_options);
}
/**
* Tests getting the methods as an anonymous user with cookie auth.
*/
public function testCookieAnon(): void {
$this->enableCookieAuth();
// Anon does not have access to JSON-RPC services.
$method_url = $this->getMethodsUrl();
try {
$this->getJsonRpcMethod($method_url);
}
catch (\Exception $e) {
$this->assertStringContainsString('401 Unauthorized', $e->getMessage());
}
}
/**
* Tests getting the methods as an auth user with cookie auth.
*/
public function testCookieAuth(): void {
$this->enableCookieAuth();
$this->drupalLogin($this->user);
$method_url = $this->getMethodsUrl();
$auth_response = $this->getJsonRpcMethod($method_url, $this->user);
$this->assertEquals(200, $auth_response->getStatusCode());
$this->disableCookieAuth();
try {
$this->getJsonRpcMethod($method_url, $this->user);
}
catch (\Exception $e) {
$this->assertStringContainsString('403', $e->getMessage());
}
}
/**
* Tests getting the methods as an admin user with cookie auth.
*/
public function testCookieAdmin(): void {
$this->enableCookieAuth();
$this->drupalLogin($this->adminUser);
$method_url = $this->getMethodsUrl();
$admin_response = $this->getJsonRpcMethod($method_url, $this->adminUser);
$this->assertEquals(200, $admin_response->getStatusCode());
$this->disableCookieAuth();
try {
$this->getJsonRpcMethod($method_url, $this->adminUser);
}
catch (\Exception $e) {
$this->assertStringContainsString('403', $e->getMessage());
}
}
}
......@@ -4,17 +4,18 @@ declare(strict_types=1);
namespace Drupal\Tests\jsonrpc_discovery\Functional;
use Drupal\Tests\BrowserTestBase;
use Drupal\user\Entity\Role;
use Drupal\user\RoleInterface;
use Drupal\Core\Url;
use Drupal\Tests\jsonrpc\Functional\JsonRpcTestBase;
use Drupal\user\UserInterface;
use GuzzleHttp\RequestOptions;
use Psr\Http\Message\ResponseInterface;
/**
* This class provides methods specifically for testing something.
*
* @group jsonrpc
*/
abstract class JsonRpcDiscoveryFunctionalTestBase extends BrowserTestBase {
abstract class JsonRpcDiscoveryFunctionalTestBase extends JsonRpcTestBase {
/**
* {@inheritdoc}
......@@ -27,40 +28,59 @@ abstract class JsonRpcDiscoveryFunctionalTestBase extends BrowserTestBase {
];
/**
* A user with authenticated permissions.
*
* @var \Drupal\user\UserInterface
* {@inheritdoc}
*/
protected UserInterface $user;
protected $defaultTheme = 'stark';
/**
* A user with admin permissions.
* Executes a request to jsonrpc/methods.
*
* @var \Drupal\user\UserInterface
* @return string
* The absolute url.
*/
protected UserInterface $adminUser;
protected function getMethodsUrl(): string {
return Url::fromRoute('jsonrpc.method_collection')
->setAbsolute()->toString();
}
/**
* {@inheritdoc}
* Provides a basic auth header.
*
* @param \Drupal\user\UserInterface $user
* The user account.
*
* @return string
* The basic auth header value formatted for Guzzle.
*/
protected $defaultTheme = 'stark';
private function getAuthForUser(UserInterface $user): string {
$name = $user->getAccountName();
$pass = $user->passRaw;
return 'Basic ' . base64_encode($name . ':' . $pass);
}
/**
* {@inheritdoc}
* Sends a GET request to a JSON-RPC method.
*
* @param string $method_url
* The URL of the JSON-RPC method.
* @param \Drupal\user\UserInterface|null $user
* The user interface of the user account. For anon, use null.
*
* @return \Psr\Http\Message\ResponseInterface
* The response from the JSON-RPC method.
*
* @throws \GuzzleHttp\Exception\GuzzleException
*/
#[\Override]
protected function setUp(): void {
parent::setUp();
// Grant authorized users permission to use JSON-RPC.
$auth_role = Role::load(RoleInterface::AUTHENTICATED_ID);
$this->grantPermissions($auth_role, ['use jsonrpc services']);
$this->user = $this->drupalCreateUser([], 'user', FALSE, ['mail' => 'user@example.com']);
$this->adminUser = $this->drupalCreateUser([], 'adminUser', TRUE, ['mail' => 'admin@example.com']);
protected function getJsonRpcMethod(string $method_url, ?UserInterface $user = NULL): ResponseInterface {
$request_options = [
RequestOptions::BODY => NULL,
RequestOptions::HEADERS => [],
];
$this->adminUser->save();
if ($user instanceof UserInterface) {
$request_options[RequestOptions::HEADERS]['Authorization'] = $this->getAuthForUser($user);
}
return \Drupal::httpClient()->get($method_url, $request_options);
}
}
......@@ -4,9 +4,7 @@ declare(strict_types=1);
namespace Drupal\Tests\jsonrpc\Functional;
use Drupal\Core\Url;
use Drupal\Tests\jsonrpc_discovery\Functional\JsonRpcDiscoveryFunctionalTestBase;
use Drupal\user\UserInterface;
use Psr\Http\Message\ResponseInterface;
/**
......@@ -17,32 +15,6 @@ use Psr\Http\Message\ResponseInterface;
class JsonRpcDiscoveryHttpTest extends JsonRpcDiscoveryFunctionalTestBase {
const PLUGINS_METHOD_NAME = 'List defined plugins';
/**
* Executes a request to jsonrpc/methods.
*
* @return string
* The absolute url.
*/
protected function getMethodsUrl(): string {
return Url::fromRoute('jsonrpc.method_collection')
->setAbsolute()->toString();
}
/**
* Provides a basic auth header.
*
* @param \Drupal\user\UserInterface $user
* The user account.
*
* @return string
* The basic auth header value formatted for Guzzle.
*/
protected function getAuthForUser(UserInterface $user): string {
$name = $user->getAccountName();
$pass = $user->passRaw;
return 'Basic ' . base64_encode($name . ':' . $pass);
}
/**
* Gets the JSON-RPC result from the response.
*
......@@ -65,10 +37,7 @@ class JsonRpcDiscoveryHttpTest extends JsonRpcDiscoveryFunctionalTestBase {
// Anon does not have access to JSON-RPC services.
$method_url = $this->getMethodsUrl();
try {
\Drupal::httpClient()->get($method_url, [
'body' => NULL,
'headers' => [],
]);
$this->getJsonRpcMethod($method_url);
}
catch (\Exception $e) {
$this->assertStringContainsString('401 Unauthorized', $e->getMessage());
......@@ -84,12 +53,7 @@ class JsonRpcDiscoveryHttpTest extends JsonRpcDiscoveryFunctionalTestBase {
$this->assertFalse($has_plugins_method_permission, 'User account has "administer site configuration" permission to access the Plugins JSON-RPC method, but it should not have this permission.');
$method_url = $this->getMethodsUrl();
$auth_response = \Drupal::httpClient()->get($method_url, [
'body' => NULL,
'headers' => [
'Authorization' => $this->getAuthForUser($this->user),
],
]);
$auth_response = $this->getJsonRpcMethod($method_url, $this->user);
$this->assertEquals(200, $auth_response->getStatusCode());
// Auth does not have access to the plugins method.
$this->assertStringNotContainsString(self::PLUGINS_METHOD_NAME, $this->getJsonRpcResultFromResponse($auth_response));
......@@ -104,12 +68,7 @@ class JsonRpcDiscoveryHttpTest extends JsonRpcDiscoveryFunctionalTestBase {
$this->assertTrue($has_plugins_method_permission, 'Admin account does not have permission to access the Plugins JSON-RPC method.');
$method_url = $this->getMethodsUrl();
$admin_response = \Drupal::httpClient()->get($method_url, [
'body' => NULL,
'headers' => [
'Authorization' => $this->getAuthForUser($this->adminUser),
],
]);
$admin_response = $this->getJsonRpcMethod($method_url, $this->adminUser);
$this->assertEquals(200, $admin_response->getStatusCode());
// Admin does have access to the plugins method.
$this->assertStringContainsString(self::PLUGINS_METHOD_NAME, $this->getJsonRpcResultFromResponse($admin_response));
......@@ -124,12 +83,7 @@ class JsonRpcDiscoveryHttpTest extends JsonRpcDiscoveryFunctionalTestBase {
$this->assertTrue($has_plugins_method_permission, 'Admin account does not have permission to access the Plugins JSON-RPC method.');
$method_url = $this->getMethodsUrl() . '/plugins.list';
$admin_response = \Drupal::httpClient()->get($method_url, [
'body' => NULL,
'headers' => [
'Authorization' => $this->getAuthForUser($this->adminUser),
],
]);
$admin_response = $this->getJsonRpcMethod($method_url, $this->adminUser);
$this->assertEquals(200, $admin_response->getStatusCode());
$this->assertStringContainsString(self::PLUGINS_METHOD_NAME, $this->getJsonRpcResultFromResponse($admin_response));
}
......
......@@ -88,7 +88,7 @@ class JsonRpcMethod extends AnnotationBase implements MethodInterface {
*/
#[\Override]
public function call(): string {
if (!isset($this->call)) {
if ($this->call === NULL) {
$this->call = 'execute';
}
return $this->call;
......
<?php
declare(strict_types=1);
namespace Drupal\jsonrpc\Drush\Generators;
use DrupalCodeGenerator\Asset\AssetCollection as Assets;
use DrupalCodeGenerator\Attribute\Generator;
use DrupalCodeGenerator\Command\BaseGenerator;
use DrupalCodeGenerator\GeneratorType;
/**
* Generates a JSON-RPC plugin.
*/
#[Generator(
name: 'jsonrpc:method',
description: 'Creates a new JSON-RPC method.',
templatePath: __DIR__,
type: GeneratorType::MODULE_COMPONENT,
)]
final class JsonRpcMethodGenerator extends BaseGenerator {
/**
* {@inheritdoc}
*/
protected function generate(array &$vars, Assets $assets): void {
$ir = $this->createInterviewer($vars);
$vars['machine_name'] = $ir->askMachineName();
$vars['name'] = $ir->askName();
$vars['class'] = $ir->askClass(default: '');
$vars['id'] = $ir->ask('What should we use for the JSON-RPC ID? (This will be used as the name of the method when calling the JSON-RPC endpoint.', '');
$vars['description'] = $ir->ask('Description: What does this method do?', '');
$vars['access'] = $ir->ask('Which permission to set for access control for this method?', 'administer site configuration');
$assets->addFile('src/Plugin/jsonrpc/Method/{class}.php', 'method.twig');
}
}
<?php
declare(strict_types=1);
namespace Drupal\{{ method_machine_name }}\Plugin\jsonrpc\Method;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\jsonrpc\Attribute\JsonRpcMethod;
use Drupal\jsonrpc\Attribute\JsonRpcParameterDefinition;
use Drupal\jsonrpc\Plugin\JsonRpcMethodBase;
/**
* {{ description }}
*/
#[JsonRpcMethod(
id: "{{ id }}",
usage: new TranslatableMarkup("{{ description }}"),
access: ["{{ permission }}"],
)]
class {{ class }} extends JsonRpcMethodBase {
/**
* {@inheritdoc}
*/
public function execute(ParameterBag $params) {
// @todo Add code to execute when the method is called.
}
/**
* {@inheritdoc}
*/
public static function outputSchema(): null {
// @todo Provide the schema that describes the results of the RPC method.
return NULL;
}
}
<?php
declare(strict_types=1);
namespace Drupal\jsonrpc\Enum;
/**
* Settings values for the JSON-RPC module.
*/
enum JsonRpcSetting: string {
case BasicAuth = 'basic_auth';
case Cookie = 'cookie';
case JWT = 'jwt_auth';
case OAuth2 = 'oauth2';
}
<?php
declare(strict_types=1);
namespace Drupal\jsonrpc\Form;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteBuilderInterface;
use Drupal\jsonrpc\Enum\JsonRpcSetting;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Configures the JSON-RPC module.
*/
final class JsonRpcConfigurationForm extends ConfigFormBase {
public function __construct(
ConfigFactoryInterface $config_factory,
TypedConfigManagerInterface $typed_config_manager,
protected ModuleHandlerInterface $moduleHandler,
protected RouteBuilderInterface $routeBuilder,
) {
parent::__construct($config_factory, $typed_config_manager);
}
/**
* {@inheritdoc}
*/
#[\Override]
public static function create(ContainerInterface $container): JsonRpcConfigurationForm {
return new self(
$container->get('config.factory'),
$container->get('config.typed'),
$container->get('module_handler'),
$container->get('router.builder')
);
}
const string FORM_ID = 'jsonrpc.settings';
/**
* {@inheritdoc}
*/
#[\Override]
public function getFormId(): string {
return self::FORM_ID;
}
/**
* {@inheritdoc}
*/
#[\Override]
protected function getEditableConfigNames(): array {
return [self::FORM_ID];
}
/**
* {@inheritdoc}
*/
#[\Override]
public function buildForm(array $form, FormStateInterface $form_state): array {
$config = $this->config(self::FORM_ID);
$form[self::FORM_ID] = [
'#type' => 'details',
'#title' => $this->t('Configure JSON-RPC access'),
'#open' => TRUE,
];
$form[self::FORM_ID][JsonRpcSetting::BasicAuth->value] = [
'#type' => 'checkbox',
'#title' => $this->t('Allow access via basic authentication'),
'#default_value' => $config->get(JsonRpcSetting::BasicAuth->value),
'#required' => FALSE,
];
$form[self::FORM_ID][JsonRpcSetting::Cookie->value] = [
'#type' => 'checkbox',
'#title' => $this->t('Allow access via cookies'),
'#default_value' => $config->get(JsonRpcSetting::Cookie->value),
'#required' => FALSE,
];
$form[self::FORM_ID][JsonRpcSetting::JWT->value] = [
'#type' => 'checkbox',
'#title' => $this->t('Allow access via JWT'),
'#default_value' => $config->get(JsonRpcSetting::JWT->value),
'#required' => FALSE,
];
$form[self::FORM_ID][JsonRpcSetting::OAuth2->value] = [
'#type' => 'checkbox',
'#title' => $this->t('Allow access via basic authentication'),
'#default_value' => $config->get(JsonRpcSetting::OAuth2->value),
'#required' => FALSE,
];
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
#[\Override]
public function submitForm(array &$form, FormStateInterface $form_state): void {
$config = $this->config(self::FORM_ID);
$config
->set(JsonRpcSetting::BasicAuth->value, boolval($form_state->getValue(JsonRpcSetting::BasicAuth->value)))
->set(JsonRpcSetting::Cookie->value, boolval($form_state->getValue(JsonRpcSetting::Cookie->value)))
->set(JsonRpcSetting::JWT->value, boolval($form_state->getValue(JsonRpcSetting::JWT->value)))
->set(JsonRpcSetting::OAuth2->value, boolval($form_state->getValue(JsonRpcSetting::OAuth2->value)))
->save();
// Altering routes requires us to rebuild the routing table.
$this->routeBuilder->setRebuildNeeded();
parent::submitForm($form, $form_state);
}
}