More updates to stop using dev or alpha or beta versions.
[yaffs-website] / web / modules / contrib / security_review / src / Checks / ViewsAccess.php
diff --git a/web/modules/contrib/security_review/src/Checks/ViewsAccess.php b/web/modules/contrib/security_review/src/Checks/ViewsAccess.php
new file mode 100644 (file)
index 0000000..5a28b19
--- /dev/null
@@ -0,0 +1,150 @@
+<?php
+
+namespace Drupal\security_review\Checks;
+
+use Drupal\Core\Link;
+use Drupal\security_review\Check;
+use Drupal\security_review\CheckResult;
+use Drupal\views\Entity\View;
+
+/**
+ * Checks for Views that do not check access.
+ */
+class ViewsAccess extends Check {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getNamespace() {
+    return 'Security Review';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTitle() {
+    return 'Views access';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function run() {
+    // If views is not enabled return with INFO.
+    if (!$this->moduleHandler()->moduleExists('views')) {
+      return $this->createResult(CheckResult::INFO);
+    }
+
+    $result = CheckResult::SUCCESS;
+    $findings = [];
+
+    $views = View::loadMultiple();
+    /** @var View[] $views */
+
+    // Iterate through views and their displays.
+    foreach ($views as $view) {
+      if ($view->status()) {
+        foreach ($view->get('display') as $display_name => $display) {
+          $access = &$display['display_options']['access'];
+          if (isset($access) && $access['type'] == 'none') {
+            // Access is not controlled for this display.
+            $findings[$view->id()][] = $display_name;
+          }
+        }
+      }
+    }
+
+    if (!empty($findings)) {
+      $result = CheckResult::FAIL;
+    }
+
+    return $this->createResult($result, $findings);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function help() {
+    $paragraphs = [];
+    $paragraphs[] = $this->t("Views can check if the user is allowed access to the content. It is recommended that all Views implement some amount of access control, at a minimum checking for the permission 'access content'.");
+
+    return [
+      '#theme' => 'check_help',
+      '#title' => $this->t('Views access'),
+      '#paragraphs' => $paragraphs,
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function evaluate(CheckResult $result) {
+    $findings = $result->findings();
+    if (empty($findings)) {
+      return [];
+    }
+
+    $paragraphs = [];
+    $paragraphs[] = $this->t('The following View displays do not check access.');
+
+    $items = [];
+    foreach ($findings as $view_id => $displays) {
+      $view = View::load($view_id);
+      /** @var View $view */
+
+      foreach ($displays as $display) {
+        $items[] = Link::createFromRoute(
+          $view->label() . ': ' . $display,
+          'entity.view.edit_display_form',
+          [
+            'view' => $view_id,
+            'display_id' => $display,
+          ]
+        );
+      }
+    }
+
+    return [
+      '#theme' => 'check_evaluation',
+      '#paragraphs' => $paragraphs,
+      '#items' => $items,
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function evaluatePlain(CheckResult $result) {
+    $findings = $result->findings();
+    if (empty($findings)) {
+      return '';
+    }
+
+    $output = $this->t('Views without access check:') . ":\n";
+    foreach ($findings as $view_id => $displays) {
+      $output .= "\t" . $view_id . ": " . implode(', ', $displays) . "\n";
+    }
+
+    return $output;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getMessage($result_const) {
+    switch ($result_const) {
+      case CheckResult::SUCCESS:
+        return $this->t('Views are access controlled.');
+
+      case CheckResult::FAIL:
+        return $this->t('There are Views that do not provide any access checks.');
+
+      case CheckResult::INFO:
+        return $this->t('Module views is not enabled.');
+
+      default:
+        return $this->t('Unexpected result.');
+    }
+  }
+
+}