Security update for Core, with self-updated composer
[yaffs-website] / web / core / modules / node / tests / src / Functional / NodeAccessBaseTableTest.php
1 <?php
2
3 namespace Drupal\Tests\node\Functional;
4
5 use Drupal\node\Entity\NodeType;
6
7 /**
8  * Tests behavior of the node access subsystem if the base table is not node.
9  *
10  * @group node
11  */
12 class NodeAccessBaseTableTest extends NodeTestBase {
13
14   /**
15    * Modules to enable.
16    *
17    * @var array
18    */
19   public static $modules = ['node_access_test', 'views'];
20
21   /**
22    * The installation profile to use with this test.
23    *
24    * This test class requires the "tags" taxonomy field.
25    *
26    * @var string
27    */
28   protected $profile = 'standard';
29
30   /**
31    * Nodes by user.
32    *
33    * @var array
34    */
35   protected $nodesByUser;
36
37   /**
38    * A public tid.
39    *
40    * @var \Drupal\Core\Database\StatementInterface
41    */
42   protected $publicTid;
43
44   /**
45    * A private tid.
46    *
47    * @var \Drupal\Core\Database\StatementInterface
48    */
49   protected $privateTid;
50
51   /**
52    * A web user.
53    */
54   protected $webUser;
55
56   /**
57    * The nids visible.
58    *
59    * @var array
60    */
61   protected $nidsVisible;
62
63   protected function setUp() {
64     parent::setUp();
65
66     node_access_test_add_field(NodeType::load('article'));
67
68     node_access_rebuild();
69     \Drupal::state()->set('node_access_test.private', TRUE);
70   }
71
72   /**
73    * Tests the "private" node access functionality.
74    *
75    * - Create 2 users with "access content" and "create article" permissions.
76    * - Each user creates one private and one not private article.
77    *
78    * - Test that each user can view the other user's non-private article.
79    * - Test that each user cannot view the other user's private article.
80    * - Test that each user finds only appropriate (non-private + own private)
81    *   in taxonomy listing.
82    * - Create another user with 'view any private content'.
83    * - Test that user 4 can view all content created above.
84    * - Test that user 4 can view all content on taxonomy listing.
85    */
86   public function testNodeAccessBasic() {
87     $num_simple_users = 2;
88     $simple_users = [];
89
90     // Nodes keyed by uid and nid: $nodes[$uid][$nid] = $is_private;
91     $this->nodesByUser = [];
92     // Titles keyed by nid.
93     $titles = [];
94     // Array of nids marked private.
95     $private_nodes = [];
96     for ($i = 0; $i < $num_simple_users; $i++) {
97       $simple_users[$i] = $this->drupalCreateUser(['access content', 'create article content']);
98     }
99     foreach ($simple_users as $this->webUser) {
100       $this->drupalLogin($this->webUser);
101       foreach ([0 => 'Public', 1 => 'Private'] as $is_private => $type) {
102         $edit = [
103           'title[0][value]' => t('@private_public Article created by @user', ['@private_public' => $type, '@user' => $this->webUser->getUsername()]),
104         ];
105         if ($is_private) {
106           $edit['private[0][value]'] = TRUE;
107           $edit['body[0][value]'] = 'private node';
108           $edit['field_tags[target_id]'] = 'private';
109         }
110         else {
111           $edit['body[0][value]'] = 'public node';
112           $edit['field_tags[target_id]'] = 'public';
113         }
114
115         $this->drupalPostForm('node/add/article', $edit, t('Save'));
116         $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
117         $this->assertEqual($is_private, (int) $node->private->value, 'The private status of the node was properly set in the node_access_test table.');
118         if ($is_private) {
119           $private_nodes[] = $node->id();
120         }
121         $titles[$node->id()] = $edit['title[0][value]'];
122         $this->nodesByUser[$this->webUser->id()][$node->id()] = $is_private;
123       }
124     }
125     $this->publicTid = db_query('SELECT tid FROM {taxonomy_term_field_data} WHERE name = :name AND default_langcode = 1', [':name' => 'public'])->fetchField();
126     $this->privateTid = db_query('SELECT tid FROM {taxonomy_term_field_data} WHERE name = :name AND default_langcode = 1', [':name' => 'private'])->fetchField();
127     $this->assertTrue($this->publicTid, 'Public tid was found');
128     $this->assertTrue($this->privateTid, 'Private tid was found');
129     foreach ($simple_users as $this->webUser) {
130       $this->drupalLogin($this->webUser);
131       // Check own nodes to see that all are readable.
132       foreach ($this->nodesByUser as $uid => $data) {
133         foreach ($data as $nid => $is_private) {
134           $this->drupalGet('node/' . $nid);
135           if ($is_private) {
136             $should_be_visible = $uid == $this->webUser->id();
137           }
138           else {
139             $should_be_visible = TRUE;
140           }
141           $this->assertResponse($should_be_visible ? 200 : 403, strtr('A %private node by user %uid is %visible for user %current_uid.', [
142             '%private' => $is_private ? 'private' : 'public',
143             '%uid' => $uid,
144             '%visible' => $should_be_visible ? 'visible' : 'not visible',
145             '%current_uid' => $this->webUser->id(),
146           ]));
147         }
148       }
149
150       // Check to see that the correct nodes are shown on taxonomy/private
151       // and taxonomy/public.
152       $this->assertTaxonomyPage(FALSE);
153     }
154
155     // Now test that a user with 'node test view' permissions can view content.
156     $access_user = $this->drupalCreateUser(['access content', 'create article content', 'node test view', 'search content']);
157     $this->drupalLogin($access_user);
158
159     foreach ($this->nodesByUser as $private_status) {
160       foreach ($private_status as $nid => $is_private) {
161         $this->drupalGet('node/' . $nid);
162         $this->assertResponse(200);
163       }
164     }
165
166     // This user should be able to see all of the nodes on the relevant
167     // taxonomy pages.
168     $this->assertTaxonomyPage(TRUE);
169
170     // Rebuild the node access permissions, repeat the test. This is done to
171     // ensure that node access is rebuilt correctly even if the current user
172     // does not have the bypass node access permission.
173     node_access_rebuild();
174
175     foreach ($this->nodesByUser as $private_status) {
176       foreach ($private_status as $nid => $is_private) {
177         $this->drupalGet('node/' . $nid);
178         $this->assertResponse(200);
179       }
180     }
181
182     // This user should be able to see all of the nodes on the relevant
183     // taxonomy pages.
184     $this->assertTaxonomyPage(TRUE);
185   }
186
187   /**
188    * Checks taxonomy/term listings to ensure only accessible nodes are listed.
189    *
190    * @param $is_admin
191    *   A boolean indicating whether the current user is an administrator. If
192    *   TRUE, all nodes should be listed. If FALSE, only public nodes and the
193    *   user's own private nodes should be listed.
194    */
195   protected function assertTaxonomyPage($is_admin) {
196     foreach ([$this->publicTid, $this->privateTid] as $tid_is_private => $tid) {
197       $this->drupalGet("taxonomy/term/$tid");
198       $this->nidsVisible = [];
199       foreach ($this->xpath("//a[text()='Read more']") as $link) {
200         // See also testTranslationRendering() in NodeTranslationUITest.
201         $this->assertTrue(preg_match('|node/(\d+)$|', $link->getAttribute('href'), $matches), 'Read more points to a node');
202         $this->nidsVisible[$matches[1]] = TRUE;
203       }
204       foreach ($this->nodesByUser as $uid => $data) {
205         foreach ($data as $nid => $is_private) {
206           // Private nodes should be visible on the private term page,
207           // public nodes should be visible on the public term page.
208           $should_be_visible = $tid_is_private == $is_private;
209           // Non-administrators can only see their own nodes on the private
210           // term page.
211           if (!$is_admin && $tid_is_private) {
212             $should_be_visible = $should_be_visible && $uid == $this->webUser->id();
213           }
214           $this->assertIdentical(isset($this->nidsVisible[$nid]), $should_be_visible, strtr('A %private node by user %uid is %visible for user %current_uid on the %tid_is_private page.', [
215             '%private' => $is_private ? 'private' : 'public',
216             '%uid' => $uid,
217             '%visible' => isset($this->nidsVisible[$nid]) ? 'visible' : 'not visible',
218             '%current_uid' => $this->webUser->id(),
219             '%tid_is_private' => $tid_is_private ? 'private' : 'public',
220           ]));
221         }
222       }
223     }
224   }
225
226 }