Security update for Core, with self-updated composer
[yaffs-website] / web / core / modules / node / tests / src / Functional / NodeRevisionPermissionsTest.php
1 <?php
2
3 namespace Drupal\Tests\node\Functional;
4
5 use Drupal\Tests\Traits\Core\GeneratePermutationsTrait;
6
7 /**
8  * Tests user permissions for node revisions.
9  *
10  * @group node
11  */
12 class NodeRevisionPermissionsTest extends NodeTestBase {
13
14   use GeneratePermutationsTrait;
15
16   /**
17    * The node revisions.
18    *
19    * @var array
20    */
21   protected $nodeRevisions = [];
22
23   /**
24    * The accounts.
25    *
26    * @var array
27    */
28   protected $accounts = [];
29
30   // Map revision permission names to node revision access ops.
31   protected $map = [
32     'view' => 'view all revisions',
33     'update' => 'revert all revisions',
34     'delete' => 'delete all revisions',
35   ];
36
37   // Map revision permission names to node type revision access ops.
38   protected $typeMap = [
39     'view' => 'view page revisions',
40     'update' => 'revert page revisions',
41     'delete' => 'delete page revisions',
42   ];
43
44   protected function setUp() {
45     parent::setUp();
46
47     $types = ['page', 'article'];
48
49     foreach ($types as $type) {
50       // Create a node with several revisions.
51       $nodes[$type] = $this->drupalCreateNode(['type' => $type]);
52       $this->nodeRevisions[$type][] = $nodes[$type];
53
54       for ($i = 0; $i < 3; $i++) {
55         // Create a revision for the same nid and settings with a random log.
56         $revision = clone $nodes[$type];
57         $revision->setNewRevision();
58         $revision->revision_log = $this->randomMachineName(32);
59         $revision->save();
60         $this->nodeRevisions[$type][] = $revision;
61       }
62     }
63   }
64
65   /**
66    * Tests general revision access permissions.
67    */
68   public function testNodeRevisionAccessAnyType() {
69     // Create three users, one with each revision permission.
70     foreach ($this->map as $op => $permission) {
71       // Create the user.
72       $account = $this->drupalCreateUser(
73         [
74           'access content',
75           'edit any page content',
76           'delete any page content',
77           $permission,
78         ]
79       );
80       $account->op = $op;
81       $this->accounts[] = $account;
82     }
83
84     // Create an admin account (returns TRUE for all revision permissions).
85     $admin_account = $this->drupalCreateUser(['access content', 'administer nodes']);
86     $admin_account->is_admin = TRUE;
87     $this->accounts['admin'] = $admin_account;
88     $accounts['admin'] = $admin_account;
89
90     // Create a normal account (returns FALSE for all revision permissions).
91     $normal_account = $this->drupalCreateUser();
92     $normal_account->op = FALSE;
93     $this->accounts[] = $normal_account;
94     $accounts[] = $normal_account;
95     $revision = $this->nodeRevisions['page'][1];
96
97     $parameters = [
98       'op' => array_keys($this->map),
99       'account' => $this->accounts,
100     ];
101
102     $permutations = $this->generatePermutations($parameters);
103
104     $node_revision_access = \Drupal::service('access_check.node.revision');
105     foreach ($permutations as $case) {
106       // Skip this test if there are no revisions for the node.
107       if (!($revision->isDefaultRevision() && (db_query('SELECT COUNT(vid) FROM {node_field_revision} WHERE nid = :nid', [':nid' => $revision->id()])->fetchField() == 1 || $case['op'] == 'update' || $case['op'] == 'delete'))) {
108         if (!empty($case['account']->is_admin) || $case['account']->hasPermission($this->map[$case['op']])) {
109           $this->assertTrue($node_revision_access->checkAccess($revision, $case['account'], $case['op']), "{$this->map[$case['op']]} granted.");
110         }
111         else {
112           $this->assertFalse($node_revision_access->checkAccess($revision, $case['account'], $case['op']), "{$this->map[$case['op']]} not granted.");
113         }
114       }
115     }
116
117     // Test that access is FALSE for a node administrator with an invalid $node
118     // or $op parameters.
119     $admin_account = $accounts['admin'];
120     $this->assertFalse($node_revision_access->checkAccess($revision, $admin_account, 'invalid-op'), 'NodeRevisionAccessCheck() returns FALSE with an invalid op.');
121   }
122
123   /**
124    * Tests revision access permissions for a specific content type.
125    */
126   public function testNodeRevisionAccessPerType() {
127     // Create three users, one with each revision permission.
128     foreach ($this->typeMap as $op => $permission) {
129       // Create the user.
130       $account = $this->drupalCreateUser(
131         [
132           'access content',
133           'edit any page content',
134           'delete any page content',
135           $permission,
136         ]
137       );
138       $account->op = $op;
139       $accounts[] = $account;
140     }
141
142     $parameters = [
143       'op' => array_keys($this->typeMap),
144       'account' => $accounts,
145     ];
146
147     // Test that the accounts have access to the corresponding page revision
148     // permissions.
149     $revision = $this->nodeRevisions['page'][1];
150
151     $permutations = $this->generatePermutations($parameters);
152     $node_revision_access = \Drupal::service('access_check.node.revision');
153     foreach ($permutations as $case) {
154       // Skip this test if there are no revisions for the node.
155       if (!($revision->isDefaultRevision() && (db_query('SELECT COUNT(vid) FROM {node_field_revision} WHERE nid = :nid', [':nid' => $revision->id()])->fetchField() == 1 || $case['op'] == 'update' || $case['op'] == 'delete'))) {
156         if (!empty($case['account']->is_admin) || $case['account']->hasPermission($this->typeMap[$case['op']], $case['account'])) {
157           $this->assertTrue($node_revision_access->checkAccess($revision, $case['account'], $case['op']), "{$this->typeMap[$case['op']]} granted.");
158         }
159         else {
160           $this->assertFalse($node_revision_access->checkAccess($revision, $case['account'], $case['op']), "{$this->typeMap[$case['op']]} not granted.");
161         }
162       }
163     }
164
165     // Test that the accounts have no access to the article revisions.
166     $revision = $this->nodeRevisions['article'][1];
167
168     foreach ($permutations as $case) {
169       $this->assertFalse($node_revision_access->checkAccess($revision, $case['account'], $case['op']), "{$this->typeMap[$case['op']]} did not grant revision permission for articles.");
170     }
171   }
172
173 }