diff --git a/core/modules/page_cache/src/Tests/PageCacheTest.php b/core/modules/page_cache/src/Tests/PageCacheTest.php index b3b0430..406164b 100644 --- a/core/modules/page_cache/src/Tests/PageCacheTest.php +++ b/core/modules/page_cache/src/Tests/PageCacheTest.php @@ -102,7 +102,7 @@ function testAcceptHeaderRequests() { $this->assertRaw('{"content":"oh hai this is json"}', 'The correct Json response was returned.'); // Enable REST support for nodes and hal+json. - \Drupal::service('module_installer')->install(['node', 'rest', 'hal']); + \Drupal::service('module_installer')->install(['node', 'rest', 'hal', 'basic_auth']); $this->drupalCreateContentType(['type' => 'article']); $node = $this->drupalCreateNode(['type' => 'article']); $node_uri = 'node/' . $node->id(); diff --git a/core/modules/rest/config/install/rest.settings.yml b/core/modules/rest/config/install/rest.settings.yml deleted file mode 100644 index 0a44346..0000000 --- a/core/modules/rest/config/install/rest.settings.yml +++ /dev/null @@ -1,46 +0,0 @@ -# Enable all methods on nodes. -# You must install Hal and Basic_auth modules for this to work. Also, if you are -# going to use Basic_auth in a production environment then you should consider -# setting up SSL. -# There are alternatives to Basic_auth in contrib such as OAuth module. -resources: - entity:node: - GET: - supported_formats: - - hal_json - supported_auth: - - basic_auth - POST: - supported_formats: - - hal_json - supported_auth: - - basic_auth - PATCH: - supported_formats: - - hal_json - supported_auth: - - basic_auth - DELETE: - supported_formats: - - hal_json - supported_auth: - - basic_auth - -# Multiple formats and multiple authentication providers can be defined for a -# resource: -# -# resources: -# entity:node: -# GET: -# supported_formats: -# - json -# - hal_json -# - xml -# supported_auth: -# - cookie -# - basic_auth -# -# hal_json is the only format supported for POST and PATCH methods. -# -# The full documentation is located at -# https://drupal.org/documentation/modules/rest diff --git a/core/modules/rest/config/optional/rest.endpoint.entity__node.yml b/core/modules/rest/config/optional/rest.endpoint.entity__node.yml new file mode 100644 index 0000000..e8c73d5 --- /dev/null +++ b/core/modules/rest/config/optional/rest.endpoint.entity__node.yml @@ -0,0 +1,28 @@ +id: entity__node +plugin_id: "entity:node" +configuration: + GET: + supported_formats: + - hal_json + supported_auth: + - basic_auth + POST: + supported_formats: + - hal_json + supported_auth: + - basic_auth + PATCH: + supported_formats: + - hal_json + supported_auth: + - basic_auth + DELETE: + supported_formats: + - hal_json + supported_auth: + - basic_auth +dependencies: + module: + - node + - basic_auth + - hal diff --git a/core/modules/rest/config/schema/rest.schema.yml b/core/modules/rest/config/schema/rest.schema.yml index 8421d13..10292b2 100644 --- a/core/modules/rest/config/schema/rest.schema.yml +++ b/core/modules/rest/config/schema/rest.schema.yml @@ -1,16 +1,4 @@ # Schema for the configuration files of the REST module. - -rest.settings: - type: config_object - label: 'REST settings' - mapping: - resources: - type: sequence - label: 'Resources' - sequence: - type: rest_resource - label: 'Resource' - rest_resource: type: mapping mapping: @@ -42,3 +30,17 @@ rest_request: sequence: type: string label: 'Authentication' + +rest.endpoint.*: + type: config_entity + label: 'REST endpooint' + mapping: + id: + type: string + label: 'REST endpoint ID' + plugin_id: + type: string + label: 'REST endpoint plugin id' + configuration: + type: rest_resource + label: 'REST endpoint configuration' diff --git a/core/modules/rest/rest.permissions.yml b/core/modules/rest/rest.permissions.yml index 2ab7154..0a276ee 100644 --- a/core/modules/rest/rest.permissions.yml +++ b/core/modules/rest/rest.permissions.yml @@ -1,2 +1,5 @@ permission_callbacks: - Drupal\rest\RestPermissions::permissions + +administer rest endpoints: + title: 'Administer REST endpoint configuration' diff --git a/core/modules/rest/rest.services.yml b/core/modules/rest/rest.services.yml index bfba7bb..5ebc39a 100644 --- a/core/modules/rest/rest.services.yml +++ b/core/modules/rest/rest.services.yml @@ -25,7 +25,7 @@ services: arguments: ['@cache.default', '@entity.manager', '@unrouted_url_assembler'] rest.resource_routes: class: Drupal\rest\Routing\ResourceRoutes - arguments: ['@plugin.manager.rest', '@config.factory', '@logger.channel.rest'] + arguments: ['@plugin.manager.rest', '@entity.manager', '@logger.channel.rest'] tags: - { name: 'event_subscriber' } logger.channel.rest: diff --git a/core/modules/rest/src/Entity/RestEndpoint.php b/core/modules/rest/src/Entity/RestEndpoint.php new file mode 100644 index 0000000..1d56c06 --- /dev/null +++ b/core/modules/rest/src/Entity/RestEndpoint.php @@ -0,0 +1,224 @@ +pluginManager = \Drupal::service('plugin.manager.rest'); + parent::__construct($values, $entity_type); + // The config entity id looks like the plugin id but uses _ instead of : because : is not valid for config entities. + if (!isset($this->plugin_id) && isset($this->id)) { + $this->plugin_id = str_replace('__', ':', $this->id); + } + } + + /** + * The label callback for this configuration entity. + * + * @return string The label + */ + protected function getLabelFromPlugin() { + $plugin_definition = \Drupal::service('plugin.manager.rest') + ->getDefinition(['id' => $this->getResourcePluginID()]); + return $plugin_definition['label']; + } + + /** + * {@inheritdoc} + */ + public function getResourcePluginID() { + return $this->plugin_id; + } + + /** + * {@inheritdoc} + */ + public function getResourcePlugin() { + return $this->getPluginCollections()['resource']->get($this->getResourcePluginID()); + } + + /** + * {@inheritdoc} + */ + public function getSupportedAuthenticationProviders($method) { + $method = $this->normaliseRestMethod($method); + if (isset($this->configuration[$method]) && isset($this->configuration[$method]['supported_auth'])) { + return $this->configuration[$method]['supported_auth']; + } + return []; + } + + /** + * {@inheritdoc} + */ + public function hasSupportForAuthenticationProvider($method, $auth) { + $method = $this->normaliseRestMethod($method); + return $this->hasSupportedAuthenticationProviders($method) + && in_array($auth, $this->configuration[$method]['supported_auth']); + } + + public function hasSupportedAuthenticationProviders($method) { + $method = $this->normaliseRestMethod($method); + return isset($this->configuration[$method]) + && isset($this->configuration[$method]['supported_auth']) + && !empty($this->configuration[$method]['supported_auth']); + } + + /** + * {@inheritdoc} + */ + public function addSupportedAuthenticationProvider($method, $auth) { + $method = $this->normaliseRestMethod($method); + if (!isset($this->configuration[$method])) { + $this->configuration[$method] = [ 'supported_auth' => [] ]; + } + if (!isset($this->configuration[$method]['supported_auth'])){ + $this->configuration[$method]['supported_auth'] = []; + } + if (!in_array($auth, $this->configuration[$method]['supported_auth'])) { + $this->configuration[$method]['supported_auth'][] = $auth; + } + return $this; + } + + /** + * {@inheritdoc} + */ + public function removeSupportedAuthenticationProvider($method, $auth) { + $method = $this->normaliseRestMethod($method); + $new_auth = array_filter($this->configuration[$method]['supported_auth'], function ($val) use ($auth) { + return ($val != $auth); + }); + $this->configuration[$method]['supported_auth'] = $new_auth; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getSupportedFormats($method) { + $method = $this->normaliseRestMethod($method); + if (isset($this->configuration[$method]) && isset($this->configuration[$method]['supported_formats'])) { + return $this->configuration[$method]['supported_formats']; + } + return []; + } + + /** + * {@inheritdoc} + */ + public function supportsFormat($method, $format) { + $method = $this->normaliseRestMethod($method); + return $this->hasSupportedFormats($method) + && in_array($format, $this->configuration[$method]['supported_formats']); + } + + /** + * {@inheritdoc} + */ + public function hasSupportedFormats($method) { + $method = $this->normaliseRestMethod($method); + return isset($this->configuration[$method]) + && isset($this->configuration[$method]['supported_formats']) + && !empty($this->configuration[$method]['supported_formats']); + } + + /** + * {@inheritdoc} + */ + public function addSupportedFormat($method, $format) { + $method = $this->normaliseRestMethod($method); + if (!isset($this->configuration[$method])) { + $this->configuration[$method] = [ 'supported_formats' => [] ]; + } + if (!isset($this->configuration[$method]['supported_formats'])){ + $this->configuration[$method]['supported_formats'] = []; + } + if (!in_array($format, $this->configuration[$method]['supported_formats'])) { + $this->configuration[$method]['supported_formats'][] = $format; + } + return $this; + } + + /** + * {@inheritdoc} + */ + public function removeSupportedFormat($method, $format) { + $method = $this->normaliseRestMethod($method); + $new_auth = array_filter($this->configuration[$method]['supported_formats'], function ($val) use ($format) { + return ($val != $format); + }); + $this->configuration[$method]['supported_formats'] = $new_auth; + return $this; + } + + /** + * Returns the plugin collections used by this entity. + * + * @return \Drupal\Component\Plugin\LazyPluginCollection[] + * An array of plugin collections, keyed by the property name they use to + * store their configuration. + */ + public function getPluginCollections() { + $plugin_configuration = [ $this->getResourcePluginID() => [ 'id' => $this->getResourcePluginID() ] ]; + return [ + 'resource' => new DefaultLazyPluginCollection($this->pluginManager, $plugin_configuration) + ]; + } + + protected function normaliseRestMethod($method) { + $valid_methods = [ 'GET', 'POST', 'PATCH', 'DELETE' ]; + $normalised_method = strtoupper($method); + if (!in_array($normalised_method, $valid_methods)) { + throw new \InvalidArgumentException('The method is not supported.'); + } + return $normalised_method; + } +} diff --git a/core/modules/rest/src/RequestHandler.php b/core/modules/rest/src/RequestHandler.php index b962b32..ea69fea 100644 --- a/core/modules/rest/src/RequestHandler.php +++ b/core/modules/rest/src/RequestHandler.php @@ -9,6 +9,7 @@ use Drupal\Core\Cache\Cache; use Drupal\Core\Routing\RouteMatchInterface; +use Drupal\rest\Entity\RestEndpoint; use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerAwareTrait; use Symfony\Component\HttpFoundation\Request; @@ -41,10 +42,15 @@ public function handle(RouteMatchInterface $route_match, Request $request) { $plugin = $route_match->getRouteObject()->getDefault('_plugin'); $method = strtolower($request->getMethod()); + /** @var \Drupal\rest\Plugin\ResourceInterface $resource */ $resource = $this->container ->get('plugin.manager.rest') ->getInstance(array('id' => $plugin)); + /** @var \Drupal\rest\RestEndpointInterface $endpoint */ + $endpoint_id = str_replace(':', '__', $plugin); + $endpoint = RestEndpoint::load($endpoint_id); + // Deserialize incoming data if available. $serializer = $this->container->get('serializer'); $received = $request->getContent(); @@ -56,9 +62,8 @@ public function handle(RouteMatchInterface $route_match, Request $request) { // formats are configured allow all and hope that the serializer knows the // format. If the serializer cannot handle it an exception will be thrown // that bubbles up to the client. - $config = $this->container->get('config.factory')->get('rest.settings')->get('resources'); - $method_settings = $config[$plugin][$request->getMethod()]; - if (empty($method_settings['supported_formats']) || in_array($format, $method_settings['supported_formats'])) { + $request_method = $request->getMethod(); + if (!$endpoint->hasSupportedFormats($request_method) || $endpoint->supportsFormat($request_method, $format)) { $definition = $resource->getPluginDefinition(); $class = $definition['serialization_class']; try { @@ -111,7 +116,7 @@ public function handle(RouteMatchInterface $route_match, Request $request) { $response->headers->set('Content-Type', $request->getMimeType($format)); // Add cache tags, but do not overwrite any that exist already on the // response object. - $cache_tags = $this->container->get('config.factory')->get('rest.settings')->getCacheTags(); + $cache_tags = $endpoint->getCacheTags(); if ($response->headers->has('X-Drupal-Cache-Tags')) { $existing_cache_tags = explode(' ', $response->headers->get('X-Drupal-Cache-Tags')); $cache_tags = Cache::mergeTags($existing_cache_tags, $cache_tags); diff --git a/core/modules/rest/src/RestEndpointInterface.php b/core/modules/rest/src/RestEndpointInterface.php new file mode 100644 index 0000000..671ed97 --- /dev/null +++ b/core/modules/rest/src/RestEndpointInterface.php @@ -0,0 +1,120 @@ +restPluginManager = $rest_plugin_manager; - $this->configFactory = $config_factory; + $this->endpoint_storage = $entity_manager->getStorage('rest_endpoint'); } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { - return new static($container->get('plugin.manager.rest'), $container->get('config.factory')); + return new static($container->get('plugin.manager.rest'), $container->get('entity.manager')); } /** @@ -58,12 +58,11 @@ public static function create(ContainerInterface $container) { */ public function permissions() { $permissions = []; - $resources = $this->configFactory->get('rest.settings')->get('resources'); - if ($resources && $enabled = array_intersect_key($this->restPluginManager->getDefinitions(), $resources)) { - foreach ($enabled as $key => $resource) { - $plugin = $this->restPluginManager->getInstance(['id' => $key]); - $permissions = array_merge($permissions, $plugin->permissions()); - } + /** @var \Drupal\rest\RestEndpointInterface[] $endpoints */ + $endpoints = $this->endpoint_storage->loadMultiple(); + foreach ($endpoints as $endpoint) { + $plugin = $endpoint->getResourcePlugin(); + $permissions = array_merge($permissions, $plugin->permissions()); } return $permissions; } diff --git a/core/modules/rest/src/Routing/ResourceRoutes.php b/core/modules/rest/src/Routing/ResourceRoutes.php index db439dc..f32d86e 100644 --- a/core/modules/rest/src/Routing/ResourceRoutes.php +++ b/core/modules/rest/src/Routing/ResourceRoutes.php @@ -7,13 +7,10 @@ namespace Drupal\rest\Routing; -use Drupal\Core\Config\ConfigFactoryInterface; -use Drupal\Core\DependencyInjection\ContainerInjectionInterface; +use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Routing\RouteSubscriberBase; use Drupal\rest\Plugin\Type\ResourcePluginManager; use Psr\Log\LoggerInterface; -use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Routing\RouteCollection; /** @@ -29,11 +26,11 @@ class ResourceRoutes extends RouteSubscriberBase{ protected $manager; /** - * The Drupal configuration factory. + * The REST endpoint storage. * - * @var \Drupal\Core\Config\ConfigFactoryInterface + * @var \Drupal\Core\Entity\EntityManagerInterface */ - protected $config; + protected $endpoint_storage; /** * A logger instance. @@ -47,14 +44,14 @@ class ResourceRoutes extends RouteSubscriberBase{ * * @param \Drupal\rest\Plugin\Type\ResourcePluginManager $manager * The resource plugin manager. - * @param \Drupal\Core\Config\ConfigFactoryInterface $config - * The configuration factory holding resource settings. + * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager + * The entity manager * @param \Psr\Log\LoggerInterface $logger * A logger instance. */ - public function __construct(ResourcePluginManager $manager, ConfigFactoryInterface $config, LoggerInterface $logger) { + public function __construct(ResourcePluginManager $manager, EntityManagerInterface $entity_manager, LoggerInterface $logger) { $this->manager = $manager; - $this->config = $config; + $this->endpoint_storage = $entity_manager->getStorage('rest_endpoint'); $this->logger = $logger; } @@ -67,11 +64,12 @@ public function __construct(ResourcePluginManager $manager, ConfigFactoryInterfa */ protected function alterRoutes(RouteCollection $collection) { $routes = array(); - $enabled_resources = $this->config->get('rest.settings')->get('resources') ?: array(); // Iterate over all enabled resource plugins. - foreach ($enabled_resources as $id => $enabled_methods) { - $plugin = $this->manager->getInstance(array('id' => $id)); + /** @var \Drupal\rest\RestEndpointInterface[] $endpoints */ + $endpoints = $this->endpoint_storage->loadMultiple(); + foreach ($endpoints as $endpoint) { + $plugin = $endpoint->getResourcePlugin(); foreach ($plugin->routes() as $name => $route) { $method = $route->getRequirement('_method'); @@ -80,27 +78,27 @@ protected function alterRoutes(RouteCollection $collection) { $route->setRequirement('_access_rest_csrf', 'TRUE'); // Check that authentication providers are defined. - if (empty($enabled_methods[$method]['supported_auth']) || !is_array($enabled_methods[$method]['supported_auth'])) { - $this->logger->error('At least one authentication provider must be defined for resource @id', array(':id' => $id)); + if (!$endpoint->hasSupportedAuthenticationProviders($method)) { + $this->logger->error('At least one authentication provider must be defined for resource @id', array(':id' => $endpoint->id())); continue; } // Check that formats are defined. - if (empty($enabled_methods[$method]['supported_formats']) || !is_array($enabled_methods[$method]['supported_formats'])) { - $this->logger->error('At least one format must be defined for resource @id', array(':id' => $id)); + if (!$endpoint->hasSupportedFormats($method)) { + $this->logger->error('At least one format must be defined for resource @id', array(':id' => $endpoint->id())); continue; } // If the route has a format requirement, then verify that the // resource has it. $format_requirement = $route->getRequirement('_format'); - if ($format_requirement && !in_array($format_requirement, $enabled_methods[$method]['supported_formats'])) { + if ($format_requirement && $endpoint->supportsFormat($method, $format_requirement)) { continue; } // The configuration seems legit at this point, so we set the // authentication provider and add the route. - $route->setOption('_auth', $enabled_methods[$method]['supported_auth']); + $route->setOption('_auth', $endpoint->getSupportedAuthenticationProviders($method)); $routes["rest.$name"] = $route; $collection->add("rest.$name", $route); } diff --git a/core/modules/rest/src/Tests/AuthTest.php b/core/modules/rest/src/Tests/AuthTest.php index 09537c8..1919aa6 100644 --- a/core/modules/rest/src/Tests/AuthTest.php +++ b/core/modules/rest/src/Tests/AuthTest.php @@ -22,7 +22,7 @@ class AuthTest extends RESTTestBase { * * @var array */ - public static $modules = array('basic_auth', 'hal', 'rest', 'entity_test', 'comment'); + public static $modules = array('basic_auth', 'hal', 'rest', 'entity_test'); /** * Tests reading from an authenticated resource. diff --git a/core/modules/rest/src/Tests/CreateTest.php b/core/modules/rest/src/Tests/CreateTest.php index 98b944a..1d143ab 100644 --- a/core/modules/rest/src/Tests/CreateTest.php +++ b/core/modules/rest/src/Tests/CreateTest.php @@ -25,7 +25,7 @@ class CreateTest extends RESTTestBase { * * @var array */ - public static $modules = array('hal', 'rest', 'entity_test'); + public static $modules = array('hal', 'rest', 'entity_test', 'node'); /** * The 'serializer' service. diff --git a/core/modules/rest/src/Tests/DeleteTest.php b/core/modules/rest/src/Tests/DeleteTest.php index 5a86d77..b95ee9f 100644 --- a/core/modules/rest/src/Tests/DeleteTest.php +++ b/core/modules/rest/src/Tests/DeleteTest.php @@ -22,7 +22,7 @@ class DeleteTest extends RESTTestBase { * * @var array */ - public static $modules = array('hal', 'rest', 'entity_test'); + public static $modules = array('hal', 'rest', 'entity_test', 'node'); /** * Tests several valid and invalid delete requests on all entity types. diff --git a/core/modules/rest/src/Tests/NodeTest.php b/core/modules/rest/src/Tests/NodeTest.php index 7169102..8fecfd5 100644 --- a/core/modules/rest/src/Tests/NodeTest.php +++ b/core/modules/rest/src/Tests/NodeTest.php @@ -24,7 +24,7 @@ class NodeTest extends RESTTestBase { * * @var array */ - public static $modules = array('hal', 'rest', 'comment'); + public static $modules = array('hal', 'rest', 'comment', 'node'); /** * Enables node specific REST API configuration and authentication. diff --git a/core/modules/rest/src/Tests/PageCacheTest.php b/core/modules/rest/src/Tests/PageCacheTest.php index 9cf2859..4405ac5 100644 --- a/core/modules/rest/src/Tests/PageCacheTest.php +++ b/core/modules/rest/src/Tests/PageCacheTest.php @@ -38,23 +38,23 @@ public function testConfigChangePageCache() { $this->httpRequest($entity->urlInfo(), 'GET', NULL, $this->defaultMimeType); $this->assertResponse(200, 'HTTP response code is correct.'); $this->assertHeader('x-drupal-cache', 'MISS'); - $this->assertCacheTag('config:rest.settings'); + $this->assertCacheTag('config:rest.endpoint.entity__entity_test'); $this->assertCacheTag('entity_test:1'); // Read it again, should be page-cached now. $this->httpRequest($entity->urlInfo(), 'GET', NULL, $this->defaultMimeType); $this->assertResponse(200, 'HTTP response code is correct.'); $this->assertHeader('x-drupal-cache', 'HIT'); - $this->assertCacheTag('config:rest.settings'); + $this->assertCacheTag('config:rest.endpoint.entity__entity_test'); $this->assertCacheTag('entity_test:1'); - // Trigger a config save which should clear the page cache, so we should get + // Trigger an endpoint save which should clear the page cache, so we should get // a cache miss now for the same request. - $this->config('rest.settings')->save(); + $this->endpoint_storage->load('entity__entity_test')->save(); $this->httpRequest($entity->urlInfo(), 'GET', NULL, $this->defaultMimeType); $this->assertResponse(200, 'HTTP response code is correct.'); $this->assertHeader('x-drupal-cache', 'MISS'); - $this->assertCacheTag('config:rest.settings'); + $this->assertCacheTag('config:rest.endpoint.entity__entity_test'); $this->assertCacheTag('entity_test:1'); } diff --git a/core/modules/rest/src/Tests/RESTTestBase.php b/core/modules/rest/src/Tests/RESTTestBase.php index ff382d5..0bfbccf 100644 --- a/core/modules/rest/src/Tests/RESTTestBase.php +++ b/core/modules/rest/src/Tests/RESTTestBase.php @@ -19,6 +19,13 @@ abstract class RESTTestBase extends WebTestBase { /** + * The REST endpoint storage. + * + * @var \Drupal\Core\Entity\EntityStorageInterface + */ + protected $endpoint_storage; + + /** * The default serialization format to use for testing REST operations. * * @var string @@ -51,15 +58,18 @@ * * @var array */ - public static $modules = array('rest', 'entity_test', 'node'); + public static $modules = array('rest', 'entity_test'); protected function setUp() { parent::setUp(); $this->defaultFormat = 'hal_json'; $this->defaultMimeType = 'application/hal+json'; $this->defaultAuth = array('cookie'); + $this->endpoint_storage = $this->container->get('entity.manager')->getStorage('rest_endpoint'); // Create a test content type for node testing. - $this->drupalCreateContentType(array('name' => 'resttest', 'type' => 'resttest')); + if (in_array('node', static::$modules)) { + $this->drupalCreateContentType(array('name' => 'resttest', 'type' => 'resttest')); + } } /** @@ -232,23 +242,29 @@ protected function entityValues($entity_type) { * (Optional) The list of valid authentication methods. */ protected function enableService($resource_type, $method = 'GET', $format = NULL, $auth = NULL) { - // Enable REST API for this entity type. - $config = $this->config('rest.settings'); - $settings = array(); - if ($resource_type) { + // Enable REST API for this entity type. + $endpoint_id = str_replace(':', '__', $resource_type); + // get entity by id + /** @var \Drupal\rest\RestEndpointInterface $endpoint */ + $endpoint = $this->endpoint_storage->load($endpoint_id); + $endpoint = ($endpoint !== NULL) ? $endpoint : $this->endpoint_storage->create(['id' => $endpoint_id]); + if ($format == NULL) { $format = $this->defaultFormat; } - $settings[$resource_type][$method]['supported_formats'][] = $format; + $endpoint->addSupportedFormat($method, $format); if ($auth == NULL) { $auth = $this->defaultAuth; } - $settings[$resource_type][$method]['supported_auth'] = $auth; + $endpoint->addSupportedAuthenticationProvider($method, $auth); + $endpoint->save(); + } else { + foreach ($this->endpoint_storage->loadMultiple() AS $endpoint) { + $endpoint->delete(); + } } - $config->set('resources', $settings); - $config->save(); $this->rebuildCache(); } diff --git a/core/modules/rest/src/Tests/ReadTest.php b/core/modules/rest/src/Tests/ReadTest.php index d5f2fc1..e7d29e9 100644 --- a/core/modules/rest/src/Tests/ReadTest.php +++ b/core/modules/rest/src/Tests/ReadTest.php @@ -22,7 +22,7 @@ class ReadTest extends RESTTestBase { * * @var array */ - public static $modules = array('hal', 'rest', 'entity_test'); + public static $modules = array('hal', 'rest', 'entity_test', 'node'); /** * Tests several valid and invalid read requests on all entity types. diff --git a/core/modules/rest/src/Tests/ResourceTest.php b/core/modules/rest/src/Tests/ResourceTest.php index be02617..233b078 100644 --- a/core/modules/rest/src/Tests/ResourceTest.php +++ b/core/modules/rest/src/Tests/ResourceTest.php @@ -7,8 +7,6 @@ namespace Drupal\rest\Tests; -use Drupal\rest\Tests\RESTTestBase; - /** * Tests the structure of a REST resource. * @@ -28,8 +26,6 @@ class ResourceTest extends RESTTestBase { */ protected function setUp() { parent::setUp(); - $this->config = $this->config('rest.settings'); - // Create an entity programmatically. $this->entity = $this->entityCreate('entity_test'); $this->entity->save(); @@ -39,19 +35,11 @@ protected function setUp() { * Tests that a resource without formats cannot be enabled. */ public function testFormats() { - $settings = array( - 'entity:entity_test' => array( - 'GET' => array( - 'supported_auth' => array( - 'basic_auth', - ), - ), - ), - ); - - // Attempt to enable the resource. - $this->config->set('resources', $settings); - $this->config->save(); + /** @var \Drupal\rest\RestEndpointInterface $endpoint */ + $endpoint = $this->endpoint_storage->create(['id' => 'entity__entity_test']); + $endpoint + ->addSupportedAuthenticationProvider('GET', 'basic_auth') + ->save();// Attempt to enable the resource. $this->rebuildCache(); // Verify that accessing the resource returns 401. @@ -68,19 +56,11 @@ public function testFormats() { * Tests that a resource without authentication cannot be enabled. */ public function testAuthentication() { - $settings = array( - 'entity:entity_test' => array( - 'GET' => array( - 'supported_formats' => array( - 'hal_json', - ), - ), - ), - ); - - // Attempt to enable the resource. - $this->config->set('resources', $settings); - $this->config->save(); + /** @var \Drupal\rest\RestEndpointInterface $endpoint */ + $endpoint = $this->endpoint_storage->create(['id' => 'entity__entity_test']); + $endpoint + ->addSupportedFormat('GET', 'hal_json') + ->save();// Attempt to enable the resource. $this->rebuildCache(); // Verify that accessing the resource returns 401.