Open Data Catalog v2.0.0
NonPublicResourceProtector.php
Go to the documentation of this file.
1 <?php
2 
4 
5 use Drupal\Core\Database\Connection;
6 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
7 use Drupal\Core\Routing\RouteMatchInterface;
9 use Symfony\Component\DependencyInjection\ContainerInterface;
10 
21 class NonPublicResourceProtector extends DataModifierBase implements ContainerFactoryPluginInterface {
22 
28  private $schemasToModify = [
29  'dataset',
30  'distribution',
31  ];
32 
38  private $routeMatch;
39 
45  private $database;
46 
61  public function __construct(array $configuration, $plugin_id, $plugin_definition, Connection $database, RouteMatchInterface $routeMatch) {
62  parent::__construct($configuration, $plugin_id, $plugin_definition);
63  $this->configuration = $configuration;
64  $this->pluginId = $plugin_id;
65  $this->pluginDefinition = $plugin_definition;
66  $this->database = $database;
67  $this->routeMatch = $routeMatch;
68  }
69 
73  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
74  return new static(
75  $configuration,
76  $plugin_id,
77  $plugin_definition,
78  $container->get('database'),
79  $container->get('current_route_match')
80  );
81  }
82 
94  public function requiresModification(string $schema, $data) {
95  return in_array($schema, $this->schemasToModify)
96  && !$this->alternateEndpoint()
97  && $this->accessLevel($schema, $data) === 'non-public';
98  }
99 
106  private function alternateEndpoint() {
107  $routeName = $this->routeMatch->getRouteName();
108  return strpos($routeName, 'dkan_alt_api.') === 0;
109  }
110 
122  private function accessLevel(string $schema, $data) : string {
123  // For distributions, check their parent dataset's access level.
124  if ('distribution' === $schema) {
125  return $this->parentDatasetAccessLevel($data);
126  }
127  return $this->datasetAccessLevel($data);
128  }
129 
139  private function datasetAccessLevel($data) {
140  if (is_string($data)) {
141  $data = json_decode($data);
142  }
143  return $data->accessLevel;
144  }
145 
155  private function parentDatasetAccessLevel($dist) {
156  $identifier = $this->getIdentifier($dist);
157  $parentDataset = $this->getParentDataset($identifier);
158  return $this->datasetAccessLevel($parentDataset);
159  }
160 
170  private function getIdentifier($dist) : string {
171  if (is_string($dist)) {
172  if ($decoded = json_decode($dist)) {
173  $dist = $decoded;
174  }
175  else {
176  return $dist;
177  }
178  }
179  return $dist->identifier;
180  }
181 
191  private function getParentDataset($identifier) {
192  $datasets = $this->database->select('node__field_json_metadata', 'm')
193  ->condition('m.field_json_metadata_value', '%accessLevel%', 'LIKE')
194  ->condition('m.field_json_metadata_value', "%{$identifier}%", 'LIKE')
195  ->fields('m', ['field_json_metadata_value'])
196  ->execute()
197  ->fetchCol();
198 
199  return reset($datasets);
200  }
201 
213  public function modify(string $schema, $data) {
214  if ('distribution' === $schema) {
215  return $this->protectDistribution($data);
216  }
217  return $this->protectDataset($data);
218  }
219 
229  private function protectDataset($dataset) {
230  if (is_string($dataset)) {
231  $datasetObj = json_decode($dataset);
232  $datasetObj = $this->protectDatasetObject($datasetObj);
233  return json_encode($datasetObj);
234  }
235  return $this->protectDatasetObject($dataset);
236  }
237 
247  private function protectDatasetObject($dataset) {
248  if (isset($dataset->distribution) && is_array($dataset->distribution)) {
249  foreach ($dataset->distribution as $key => &$dist) {
250  $dataset->distribution[$key] = $this->protectDistributionObject($dist);
251  }
252  }
253  return $dataset;
254  }
255 
265  private function protectDistribution($dist) {
266  if (is_string($dist)) {
267  $distObj = json_decode($dist);
268  $distObj = $this->protectDistributionObject($distObj);
269  return json_encode($distObj);
270  }
271  return $this->protectDistributionObject($dist);
272  }
273 
283  private function protectDistributionObject($dist) {
284  unset($dist);
285  return (object) ['title' => $this->message()];
286  }
287 
288 }
Drupal\dkan_non_public\Plugin\DataModifier\NonPublicResourceProtector\__construct
__construct(array $configuration, $plugin_id, $plugin_definition, Connection $database, RouteMatchInterface $routeMatch)
Definition: NonPublicResourceProtector.php:61
Drupal\dkan_common\Plugin\DataModifierBase\message
message()
Definition: DataModifierBase.php:18
Drupal\dkan_common\Plugin\DataModifierBase
Definition: DataModifierBase.php:10
Drupal\dkan_non_public\Plugin\DataModifier\NonPublicResourceProtector\requiresModification
requiresModification(string $schema, $data)
Definition: NonPublicResourceProtector.php:94
Drupal\dkan_non_public\Plugin\DataModifier
Definition: NonPublicResourceProtector.php:3
Drupal\dkan_non_public\Plugin\DataModifier\NonPublicResourceProtector
Definition: NonPublicResourceProtector.php:21
Drupal\dkan_non_public\Plugin\DataModifier\NonPublicResourceProtector\modify
modify(string $schema, $data)
Definition: NonPublicResourceProtector.php:213
Drupal\dkan_non_public\Plugin\DataModifier\NonPublicResourceProtector\create
static create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition)
Definition: NonPublicResourceProtector.php:73