Ejemplo n.º 1
0
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $io = new DrupalStyle($input, $output);
     $resource_id = $input->getArgument('resource-id');
     $rest_resources = $this->getRestResources();
     $rest_resources_ids = array_merge(array_keys($rest_resources['enabled']), array_keys($rest_resources['disabled']));
     if (!$resource_id) {
         $resource_id = $io->choiceNoList($this->trans('commands.rest.enable.arguments.resource-id'), $rest_resources_ids);
     }
     $this->validateRestResource($resource_id, $rest_resources_ids, $this->getTranslator());
     $input->setArgument('resource-id', $resource_id);
     // Calculate states available by resource and generate the question
     $plugin = $this->pluginManagerRest->getInstance(['id' => $resource_id]);
     $states = $plugin->availableMethods();
     $state = $io->choice($this->trans('commands.rest.enable.arguments.states'), $states);
     $io->writeln($this->trans('commands.rest.enable.messages.selected-state') . ' ' . $state);
     // Get Authentication Provider and generate the question
     $authenticationProviders = $this->authenticationCollector->getSortedProviders();
     $authenticationProvidersSelected = $io->choice($this->trans('commands.rest.enable.messages.authentication-providers'), array_keys($authenticationProviders), 0, true);
     $io->writeln($this->trans('commands.rest.enable.messages.selected-authentication-providers') . ' ' . implode(', ', $authenticationProvidersSelected));
     $rest_settings = $this->getRestDrupalConfig();
     $rest_settings[$resource_id][$state]['supported_formats'] = $formats;
     $rest_settings[$resource_id][$state]['supported_auth'] = $authenticationProvidersSelected;
     $config = $this->configFactory->getEditable('rest.settings');
     $config->set('resources', $rest_settings);
     $config->save();
     return 0;
 }
Ejemplo n.º 2
0
 private function restDetail(DrupalStyle $io, $resource_id)
 {
     $config = $this->getRestDrupalConfig();
     $plugin = $this->pluginManagerRest->getInstance(['id' => $resource_id]);
     if (empty($plugin)) {
         $io->error(sprintf($this->trans('commands.rest.debug.messages.not-found'), $resource_id));
         return false;
     }
     $resource = $plugin->getPluginDefinition();
     $configuration = [];
     $configuration[] = [$this->trans('commands.rest.debug.messages.id'), $resource['id']];
     $configuration[] = [$this->trans('commands.rest.debug.messages.label'), (string) $resource['label']];
     $configuration[] = [$this->trans('commands.rest.debug.messages.canonical_url'), $resource['uri_paths']['canonical']];
     $configuration[] = [$this->trans('commands.rest.debug.messages.status'), isset($config[$resource['id']]) ? $this->trans('commands.rest.debug.messages.enabled') : $this->trans('commands.rest.debug.messages.disabled')];
     $configuration[] = [$this->trans(sprintf('commands.rest.debug.messages.provider', $resource['provider']))];
     $io->comment($resource_id);
     $io->newLine();
     $io->table([], $configuration, 'compact');
     $tableHeader = [$this->trans('commands.rest.debug.messages.rest-state'), $this->trans('commands.rest.debug.messages.supported-formats'), $this->trans('commands.rest.debug.messages.supported_auth')];
     $tableRows = [];
     foreach ($config[$resource['id']] as $method => $settings) {
         $tableRows[] = [$method, implode(', ', $settings['supported_formats']), implode(', ', $settings['supported_auth'])];
     }
     $io->table($tableHeader, $tableRows);
 }
Ejemplo n.º 3
0
 /**
  * Returns an array of REST permissions.
  *
  * @return array
  */
 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());
         }
     }
     return $permissions;
 }
 /**
  * Adds routes to enabled REST resources.
  *
  * @param \Drupal\Core\Routing\RouteBuildEvent $event
  *   The route building event.
  */
 public function dynamicRoutes(RouteBuildEvent $event)
 {
     $collection = $event->getRouteCollection();
     $enabled_resources = $this->config->get('rest.settings')->load()->get('resources');
     // Iterate over all enabled resource plugins.
     foreach ($enabled_resources as $id => $enabled_methods) {
         $plugin = $this->manager->getInstance(array('id' => $id));
         foreach ($plugin->routes() as $route) {
             $operation = $route->getRequirement('_operation');
             if ($operation) {
                 $collection->add("services.{$operation}", $route);
             }
         }
     }
 }
 /**
  * Implements \Drupal\Core\Form\FormInterface::buildForm().
  *
  * @var array $form
  *   The form array.
  * @var array $form_state
  *   The $form_state array.
  * @param \Drupal\Core\Form\FormStateInterface $form_state
  *   The form state.
  * @var string $resource_id
  *   A string that identfies the REST resource.
  *
  * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
  */
 public function buildForm(array $form, FormStateInterface $form_state, $resource_id = NULL)
 {
     $plugin = $this->resourcePluginManager->getInstance(array('id' => $resource_id));
     if (empty($plugin)) {
         throw new NotFoundHttpException();
     }
     $config = \Drupal::config('rest.settings')->get('resources') ?: array();
     $methods = $plugin->availableMethods();
     $pluginDefinition = $plugin->getPluginDefinition();
     $form['#tree'] = TRUE;
     $form['resource_id'] = array('#type' => 'value', '#value' => $resource_id);
     $form['title'] = array('#markup' => '<h2>' . t('Settings for resource @label', array('@label' => $pluginDefinition['label'])) . '</h2>');
     $form['description'] = array('#markup' => '<p>' . t('Here you can restrict which HTTP methods should this resource support.' . ' And within each method, the available serialization formats and ' . 'authentication providers.') . '</p>');
     $form['note'] = array('#markup' => '<p>' . t('<b>Note:</b> Leaving all formats unchecked will enable all of them, while leaving all authentication providers unchecked will default to <code>cookie</code>') . '</p>');
     $form['methods'] = array('#type' => 'container');
     foreach ($methods as $method) {
         $group = array();
         $group[$method] = array('#title' => $method, '#type' => 'checkbox', '#default_value' => isset($config[$resource_id][$method]));
         $group['settings'] = array('#type' => 'container', '#attributes' => array('style' => 'padding-left:20px'));
         // Available formats
         $enabled_formats = array();
         if (isset($config[$resource_id][$method]['supported_formats'])) {
             $enabled_formats = $config[$resource_id][$method]['supported_formats'];
         }
         $group['settings']['formats'] = array('#title' => 'Supported formats', '#type' => 'checkboxes', '#options' => array_combine($this->formats, $this->formats), '#multiple' => TRUE, '#default_value' => $enabled_formats);
         // Authentication providers.
         $enabled_auth = array();
         if (isset($config[$resource_id][$method]['supported_auth'])) {
             $enabled_auth = $config[$resource_id][$method]['supported_auth'];
         }
         $group['settings']['auth'] = array('#title' => 'Authentication providers', '#type' => 'checkboxes', '#options' => array_combine($this->authenticationProviders, $this->authenticationProviders), '#multiple' => TRUE, '#default_value' => $enabled_auth);
         $form['methods'][$method] = $group;
     }
     return parent::buildForm($form, $form_state);
 }
Ejemplo n.º 6
0
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $io = new DrupalStyle($input, $output);
     $resource_id = $input->getArgument('resource-id');
     $rest_resources = $this->getRestResources();
     $rest_resources_ids = array_merge(array_keys($rest_resources['enabled']), array_keys($rest_resources['disabled']));
     if (!$resource_id) {
         $resource_id = $io->choiceNoList($this->trans('commands.rest.enable.arguments.resource-id'), $rest_resources_ids);
     }
     $this->validateRestResource($resource_id, $rest_resources_ids, $this->translator);
     $input->setArgument('resource-id', $resource_id);
     // Calculate states available by resource and generate the question.
     $plugin = $this->pluginManagerRest->getInstance(['id' => $resource_id]);
     $methods = $plugin->availableMethods();
     $method = $io->choice($this->trans('commands.rest.enable.arguments.methods'), $methods);
     $io->writeln($this->trans('commands.rest.enable.messages.selected-method') . ' ' . $method);
     $format = $io->choice($this->trans('commands.rest.enable.arguments.formats'), $this->formats);
     $io->writeln($this->trans('commands.rest.enable.messages.selected-format') . ' ' . $format);
     // Get Authentication Provider and generate the question
     $authenticationProviders = $this->authenticationCollector->getSortedProviders();
     $authenticationProvidersSelected = $io->choice($this->trans('commands.rest.enable.messages.authentication-providers'), array_keys($authenticationProviders), 0, true);
     $io->writeln($this->trans('commands.rest.enable.messages.selected-authentication-providers') . ' ' . implode(', ', $authenticationProvidersSelected));
     $format_resource_id = str_replace(':', '.', $resource_id);
     $config = $this->entityManager->getStorage('rest_resource_config')->load($format_resource_id);
     if (!$config) {
         $config = $this->entityManager->getStorage('rest_resource_config')->create(['id' => $format_resource_id, 'granularity' => RestResourceConfigInterface::METHOD_GRANULARITY, 'configuration' => []]);
     }
     $configuration = $config->get('configuration') ?: [];
     $configuration[$method] = ['supported_formats' => [$format], 'supported_auth' => $authenticationProvidersSelected];
     $config->set('configuration', $configuration);
     $config->save();
     $message = sprintf($this->trans('commands.rest.enable.messages.success'), $resource_id);
     $io->info($message);
     return true;
 }
Ejemplo n.º 7
0
 /**
  * Alters existing routes for a specific collection.
  *
  * @param \Symfony\Component\Routing\RouteCollection $collection
  *   The route collection for adding routes.
  * @return array
  */
 protected function alterRoutes(RouteCollection $collection)
 {
     $routes = array();
     // Silently ignore resources that are in the settings but are not defined on
     // the plugin manager currently. That avoids exceptions when REST module is
     // enabled before another module that provides the resource plugin specified
     // in the settings.
     // @todo Remove in https://www.drupal.org/node/2308745
     $resources = $this->config->get('rest.settings')->get('resources') ?: array();
     $enabled_resources = array_intersect_key($resources, $this->manager->getDefinitions());
     if (count($resources) != count($enabled_resources)) {
         trigger_error('rest.settings lists resources relying on the following missing plugins: ' . implode(', ', array_keys(array_diff_key($resources, $enabled_resources))));
     }
     // Iterate over all enabled resource plugins.
     foreach ($enabled_resources as $id => $enabled_methods) {
         $plugin = $this->manager->getInstance(array('id' => $id));
         foreach ($plugin->routes() as $name => $route) {
             // @todo: Are multiple methods possible here?
             $methods = $route->getMethods();
             // Only expose routes where the method is enabled in the configuration.
             if ($methods && ($method = $methods[0]) && $method && isset($enabled_methods[$method])) {
                 $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));
                     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));
                     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'])) {
                     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']);
                 $routes["rest.{$name}"] = $route;
                 $collection->add("rest.{$name}", $route);
             }
         }
     }
 }
Ejemplo n.º 8
0
 /**
  * Alters existing routes for a specific collection.
  *
  * @param \Symfony\Component\Routing\RouteCollection $collection
  *   The route collection for adding routes.
  * @return array
  */
 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));
         foreach ($plugin->routes() as $name => $route) {
             // @todo: Are multiple methods possible here?
             $methods = $route->getMethods();
             // Only expose routes where the method is enabled in the configuration.
             if ($methods && ($method = $methods[0]) && $method && isset($enabled_methods[$method])) {
                 $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));
                     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));
                     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'])) {
                     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']);
                 $routes["rest.{$name}"] = $route;
                 $collection->add("rest.{$name}", $route);
             }
         }
     }
 }
 /**
  * Disables a resource.
  *
  * @param string $resource_id
  *   The identifier or the REST resource.
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   The current request.
  *
  * @return \Drupal\Core\Ajax\AjaxResponse|\Symfony\Component\HttpFoundation\RedirectResponse
  *   Redirects back to the listing page.
  *
  * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
  *   Access is denied, if the token is invalid or missing.
  */
 public function disable($resource_id, Request $request)
 {
     if (!\Drupal::csrfToken()->validate($request->query->get('token'), 'restui_disable')) {
         throw new AccessDeniedHttpException();
     }
     $config = \Drupal::configFactory()->getEditable('rest.settings');
     $resources = $config->get('resources') ?: array();
     $plugin = $this->resourcePluginManager->getInstance(array('id' => $resource_id));
     if (!empty($plugin)) {
         // disable the resource.
         unset($resources[$resource_id]);
         $config->set('resources', $resources);
         $config->save();
         // Rebuild routing cache.
         $this->routeBuilder->rebuild();
         drupal_set_message(t('The resource was disabled successfully.'));
     }
     // Redirect back to the page.
     return new RedirectResponse($this->urlGenerator->generate('restui.list', array(), TRUE));
 }
Ejemplo n.º 10
0
 /**
  * {@inheritdoc}
  */
 public function importContent($module)
 {
     $created = array();
     $folder = drupal_get_path('module', $module) . "/content";
     if (file_exists($folder)) {
         $file_map = array();
         foreach ($this->entityManager->getDefinitions() as $entity_type_id => $entity_type) {
             $reflection = new \ReflectionClass($entity_type->getClass());
             // We are only interested in importing content entities.
             if ($reflection->implementsInterface('\\Drupal\\Core\\Config\\Entity\\ConfigEntityInterface')) {
                 continue;
             }
             if (!file_exists($folder . '/' . $entity_type_id)) {
                 continue;
             }
             $files = $this->scanner()->scan($folder . '/' . $entity_type_id);
             // Default content uses drupal.org as domain.
             // @todo Make this use a uri like default-content:.
             $this->linkManager->setLinkDomain(static::LINK_DOMAIN);
             // Parse all of the files and sort them in order of dependency.
             foreach ($files as $file) {
                 $contents = $this->parseFile($file);
                 // Decode the file contents.
                 $decoded = $this->serializer->decode($contents, 'hal_json');
                 // Get the link to this entity.
                 $self = $decoded['_links']['self']['href'];
                 // Throw an exception when this URL already exists.
                 if (isset($file_map[$self])) {
                     $args = array('@href' => $self, '@first' => $file_map[$self]->uri, '@second' => $file->uri);
                     // Reset link domain.
                     $this->linkManager->setLinkDomain(FALSE);
                     throw new \Exception(SafeMarkup::format('Default content with href @href exists twice: @first @second', $args));
                 }
                 // Store the entity type with the file.
                 $file->entity_type_id = $entity_type_id;
                 // Store the file in the file map.
                 $file_map[$self] = $file;
                 // Create a vertex for the graph.
                 $vertex = $this->getVertex($self);
                 $this->graph[$vertex->link]['edges'] = [];
                 if (empty($decoded['_embedded'])) {
                     // No dependencies to resolve.
                     continue;
                 }
                 // Here we need to resolve our dependencies;
                 foreach ($decoded['_embedded'] as $embedded) {
                     foreach ($embedded as $item) {
                         $edge = $this->getVertex($item['_links']['self']['href']);
                         $this->graph[$vertex->link]['edges'][$edge->link] = TRUE;
                     }
                 }
             }
         }
         // @todo what if no dependencies?
         $sorted = $this->sortTree($this->graph);
         foreach ($sorted as $link => $details) {
             if (!empty($file_map[$link])) {
                 $file = $file_map[$link];
                 $entity_type_id = $file->entity_type_id;
                 $resource = $this->resourcePluginManager->getInstance(array('id' => 'entity:' . $entity_type_id));
                 $definition = $resource->getPluginDefinition();
                 $contents = $this->parseFile($file);
                 $class = $definition['serialization_class'];
                 $entity = $this->serializer->deserialize($contents, $class, 'hal_json', array('request_method' => 'POST'));
                 $entity->enforceIsNew(TRUE);
                 $entity->save();
                 $created[$entity->uuid()] = $entity;
             }
         }
         $this->eventDispatcher->dispatch(DefaultContentEvents::IMPORT, new ImportEvent($created, $module));
     }
     // Reset the tree.
     $this->resetTree();
     // Reset link domain.
     $this->linkManager->setLinkDomain(FALSE);
     return $created;
 }