From f660bb4c1e34f96ee7c2f4d2a9f1922a811d3bf4 Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Sun, 18 Feb 2024 09:47:18 +0000
Subject: [PATCH] Issue #3387172 by Mingsong, smustgrave, mlncn, Kanchan
 Bhogade, larowlan: Unpublished forum accessible to public

---
 core/modules/forum/forum.routing.yml          |  1 +
 core/modules/forum/src/ForumManager.php       |  3 +
 .../src/Functional/ForumTermAccessTest.php    | 93 +++++++++++++++++++
 3 files changed, 97 insertions(+)
 create mode 100644 core/modules/forum/tests/src/Functional/ForumTermAccessTest.php

diff --git a/core/modules/forum/forum.routing.yml b/core/modules/forum/forum.routing.yml
index 14e55e261e08..798acbb473cf 100644
--- a/core/modules/forum/forum.routing.yml
+++ b/core/modules/forum/forum.routing.yml
@@ -29,6 +29,7 @@ forum.page:
     _title_callback: '\Drupal\taxonomy\Controller\TaxonomyController::termTitle'
   requirements:
     _permission: 'access content'
+    _entity_access: 'taxonomy_term.view'
 
 forum.add_container:
   path: '/admin/structure/forum/add/container'
diff --git a/core/modules/forum/src/ForumManager.php b/core/modules/forum/src/ForumManager.php
index 3e9a16e9a6cc..79b91b1db39f 100644
--- a/core/modules/forum/src/ForumManager.php
+++ b/core/modules/forum/src/ForumManager.php
@@ -415,6 +415,9 @@ public function getChildren($vid, $tid) {
     $forums = [];
     $_forums = $this->entityTypeManager->getStorage('taxonomy_term')->loadTree($vid, $tid, NULL, TRUE);
     foreach ($_forums as $forum) {
+      if (!$forum->access('view')) {
+        continue;
+      }
       // Merge in the topic and post counters.
       if (($count = $this->getForumStatistics($forum->id()))) {
         $forum->num_topics = $count->topic_count;
diff --git a/core/modules/forum/tests/src/Functional/ForumTermAccessTest.php b/core/modules/forum/tests/src/Functional/ForumTermAccessTest.php
new file mode 100644
index 000000000000..944b37241ce0
--- /dev/null
+++ b/core/modules/forum/tests/src/Functional/ForumTermAccessTest.php
@@ -0,0 +1,93 @@
+<?php
+
+namespace Drupal\Tests\forum\Functional;
+
+use Drupal\Tests\BrowserTestBase;
+use Drupal\taxonomy\Entity\Term;
+
+/**
+ * Tests forum taxonomy terms for access.
+ *
+ * @group forum
+ */
+class ForumTermAccessTest extends BrowserTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  protected static $modules = [
+    'forum',
+    'taxonomy',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * Creates some users and creates a public forum and an unpublished forum.
+   *
+   * Adds both published and unpublished forums.
+   * Tests to ensure publish/unpublished forums access is respected.
+   */
+  public function testForumTermAccess(): void {
+    $assert_session = $this->assertSession();
+    // Create some users.
+    $public_user = $this->drupalCreateUser(['access content']);
+    $admin_user = $this->drupalCreateUser([
+      'access administration pages',
+      'administer forums',
+      'administer taxonomy',
+      'access taxonomy overview',
+    ]);
+
+    $this->drupalLogin($admin_user);
+    // The vocabulary for forums.
+    $vid = $this->config('forum.settings')->get('vocabulary');
+    // Create an unpublished forum.
+    $unpublished_forum_name = $this->randomMachineName(8);
+    $unpublished_forum = Term::create([
+      'vid' => $vid,
+      'name' => $unpublished_forum_name,
+      'status' => 0,
+    ]);
+    $unpublished_forum->save();
+
+    // Create a new published forum.
+    $published_forum_name = $this->randomMachineName(8);
+    $published_forum = Term::create([
+      'vid' => $vid,
+      'name' => $published_forum_name,
+      'status' => 1,
+    ]);
+    $published_forum->save();
+
+    // Test for admin user.
+    // Go to the Forum index page.
+    $this->drupalGet('forum');
+    // The unpublished forum should be in this page for an admin user.
+    $assert_session->pageTextContains($unpublished_forum_name);
+    // Go to the unpublished forum page.
+    $this->drupalGet('forum/' . $unpublished_forum->id());
+    $assert_session->statusCodeEquals(200);
+    $assert_session->pageTextContains($unpublished_forum_name);
+
+    // Test for public user.
+    $this->drupalLogin($public_user);
+    // Go to the Forum index page.
+    $this->drupalGet('forum');
+    // The published forum should be in this page.
+    $assert_session->pageTextContains($published_forum_name);
+    // The unpublished forum should not be in this page.
+    $assert_session->pageTextNotContains($unpublished_forum_name);
+    // Go to the unpublished forum page.
+    $this->drupalGet('forum/' . $unpublished_forum->id());
+    // Public should not be able to access the unpublished forum.
+    $assert_session->statusCodeEquals(403);
+    $assert_session->pageTextNotContains($unpublished_forum_name);
+  }
+
+}
-- 
GitLab