Passed
Pull Request — 4 (#10330)
by
unknown
06:45
created

PermissionTest::testGetCodesGrouped()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\Security\Tests;
4
5
use SilverStripe\Security\Permission;
6
use SilverStripe\Security\Group;
7
use SilverStripe\Security\Member;
8
use SilverStripe\Security\PermissionCheckboxSetField;
9
use SilverStripe\Core\Config\Config;
10
use SilverStripe\Dev\SapphireTest;
11
12
/**
13
 * @skipUpgrade
14
 */
15
class PermissionTest extends SapphireTest
16
{
17
18
    protected static $fixture_file = 'PermissionTest.yml';
19
20
    public function testGetCodesGrouped()
21
    {
22
        $codes = Permission::get_codes();
23
        $this->assertArrayNotHasKey('SITETREE_VIEW_ALL', $codes);
24
    }
25
26
    public function testGetCodesUngrouped()
27
    {
28
        $codes = Permission::get_codes(false);
29
        $this->assertArrayHasKey('SITETREE_VIEW_ALL', $codes);
30
    }
31
32
    public function testDirectlyAppliedPermissions()
33
    {
34
        $member = $this->objFromFixture(Member::class, 'author');
35
        $this->assertTrue(Permission::checkMember($member, "SITETREE_VIEW_ALL"));
36
    }
37
38
    public function testCMSAccess()
39
    {
40
        $members = Member::get()->byIDs($this->allFixtureIDs(Member::class));
41
        foreach ($members as $member) {
42
            $this->assertTrue(Permission::checkMember($member, 'CMS_ACCESS'));
43
            $this->assertTrue(Permission::checkMember($member, ['CMS_ACCESS', 'CMS_ACCESS_Security']));
44
            $this->assertTrue(Permission::checkMember($member, ['CMS_ACCESS_Security', 'CMS_ACCESS']));
45
        }
46
47
        $member = new Member();
48
        $member->update(
49
            [
50
            'FirstName' => 'No CMS',
51
            'Surname' => 'Access',
52
            'Email' => '[email protected]',
53
            ]
54
        );
55
        $member->write();
56
        $this->assertFalse(Permission::checkMember($member, 'CMS_ACCESS'));
57
        $this->assertFalse(Permission::checkMember($member, ['CMS_ACCESS', 'CMS_ACCESS_Security']));
58
        $this->assertFalse(Permission::checkMember($member, ['CMS_ACCESS_Security', 'CMS_ACCESS']));
59
    }
60
61
    public function testLeftAndMainAccessAll()
62
    {
63
        //add user and group
64
        $member = $this->objFromFixture(Member::class, 'leftandmain');
65
66
        $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_MyAdmin"));
67
        $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_AssetAdmin"));
68
        $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_SecurityAdmin"));
69
    }
70
71
    public function testPermissionAreInheritedFromOneRole()
72
    {
73
        $member = $this->objFromFixture(Member::class, 'author');
74
        $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_MyAdmin"));
75
        $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_AssetAdmin"));
76
        $this->assertFalse(Permission::checkMember($member, "CMS_ACCESS_SecurityAdmin"));
77
    }
78
79
    public function testPermissionAreInheritedFromMultipleRoles()
80
    {
81
        $member = $this->objFromFixture(Member::class, 'access');
82
        $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_MyAdmin"));
83
        $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_AssetAdmin"));
84
        $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_SecurityAdmin"));
85
        $this->assertTrue(Permission::checkMember($member, "EDIT_PERMISSIONS"));
86
        $this->assertFalse(Permission::checkMember($member, "SITETREE_VIEW_ALL"));
87
    }
88
89
    public function testPermissionsForMember()
90
    {
91
        $member = $this->objFromFixture(Member::class, 'access');
92
        $permissions = Permission::permissions_for_member($member->ID);
93
        $this->assertEquals(4, count($permissions ?? []));
94
        $this->assertTrue(in_array('CMS_ACCESS_MyAdmin', $permissions ?? []));
95
        $this->assertTrue(in_array('CMS_ACCESS_AssetAdmin', $permissions ?? []));
96
        $this->assertTrue(in_array('CMS_ACCESS_SecurityAdmin', $permissions ?? []));
97
        $this->assertTrue(in_array('EDIT_PERMISSIONS', $permissions ?? []));
98
99
        $group = $this->objFromFixture("SilverStripe\\Security\\Group", "access");
100
101
        Permission::deny($group->ID, "CMS_ACCESS_MyAdmin");
102
        $permissions = Permission::permissions_for_member($member->ID);
103
        $this->assertEquals(3, count($permissions ?? []));
104
        $this->assertFalse(in_array('CMS_ACCESS_MyAdmin', $permissions ?? []));
105
    }
106
107
    public function testRolesAndPermissionsFromParentGroupsAreInherited()
108
    {
109
        $member = $this->objFromFixture(Member::class, 'globalauthor');
110
111
        // Check that permissions applied to the group are there
112
        $this->assertTrue(Permission::checkMember($member, "SITETREE_EDIT_ALL"));
113
114
        // Check that roles from parent groups are there
115
        $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_MyAdmin"));
116
        $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_AssetAdmin"));
117
118
        // Check that permissions from parent groups are there
119
        $this->assertTrue(Permission::checkMember($member, "SITETREE_VIEW_ALL"));
120
121
        // Check that a random permission that shouldn't be there isn't
122
        $this->assertFalse(Permission::checkMember($member, "CMS_ACCESS_SecurityAdmin"));
123
    }
124
    /**
125
     * Ensure the the get_*_by_permission functions are permission role aware
126
     */
127
    public function testGettingMembersByPermission()
128
    {
129
        $accessMember = $this->objFromFixture(Member::class, 'access');
130
        $accessAuthor = $this->objFromFixture(Member::class, 'author');
131
132
        $result = Permission::get_members_by_permission(['CMS_ACCESS_SecurityAdmin']);
133
        $resultIDs = $result ? $result->column() : [];
134
135
        $this->assertContains(
136
            $accessMember->ID,
137
            $resultIDs,
138
            'Member is found via a permission attached to a role'
139
        );
140
        $this->assertNotContains($accessAuthor->ID, $resultIDs);
141
    }
142
143
144
    public function testHiddenPermissions()
145
    {
146
        $permissionCheckboxSet = new PermissionCheckboxSetField('Permissions', 'Permissions', Permission::class, 'GroupID');
147
        $this->assertStringContainsString('CMS_ACCESS_LeftAndMain', $permissionCheckboxSet->Field());
148
149
        Config::modify()->merge(Permission::class, 'hidden_permissions', ['CMS_ACCESS_LeftAndMain']);
150
151
        $this->assertStringNotContainsString('CMS_ACCESS_LeftAndMain', $permissionCheckboxSet->Field());
152
153
        Config::inst()->remove(Permission::class, 'hidden_permissions');
0 ignored issues
show
Bug introduced by
The method remove() does not exist on SilverStripe\Config\Coll...nfigCollectionInterface. It seems like you code against a sub-type of SilverStripe\Config\Coll...nfigCollectionInterface such as SilverStripe\Config\Coll...nfigCollectionInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

153
        Config::inst()->/** @scrutinizer ignore-call */ remove(Permission::class, 'hidden_permissions');
Loading history...
154
        $this->assertStringContainsString('CMS_ACCESS_LeftAndMain', $permissionCheckboxSet->Field());
155
    }
156
157
    public function testEmptyMemberFails()
158
    {
159
        $member = new Member();
160
        $this->assertFalse($member->exists());
161
162
        $this->logInWithPermission('ADMIN');
163
164
        $this->assertFalse(Permission::checkMember($member, 'ADMIN'));
165
        $this->assertFalse(Permission::checkMember($member, 'CMS_ACCESS_LeftAndMain'));
166
    }
167
168
    public function testGrantPermission()
169
    {
170
        $id = rand(15, 20);
171
172
        Permission::grant($id, 'CMS_ACCESS_CMSMain');
173
        Permission::grant($id, 'CMS_ACCESS_AssetAdmin');
174
        Permission::grant($id, 'CMS_ACCESS_ReportAdmin');
175
176
        $groupPermission = Permission::get()->filter(['GroupID' => $id]);
177
178
        $this->assertEquals(3, $groupPermission->count());
179
        $this->assertEquals(0, $groupPermission->first()->Arg);
0 ignored issues
show
Bug Best Practice introduced by
The property Arg does not exist on SilverStripe\ORM\DataObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
180
        $this->assertEquals(1, $groupPermission->first()->Type);
0 ignored issues
show
Bug Best Practice introduced by
The property Type does not exist on SilverStripe\ORM\DataObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
181
182
183
        Permission::grant($id, 'CMS_ACCESS_CMSMain', 'all');
184
        Permission::grant($id, 'CMS_ACCESS_AssetAdmin', 'all');
185
        Permission::grant($id, 'CMS_ACCESS_ReportAdmin', 'all');
186
187
        $groupPermission = Permission::get()->filter(['GroupID' => $id]);
188
189
        $this->assertEquals(3, $groupPermission->count());
190
        $this->assertEquals(-1, $groupPermission->first()->Arg);
191
        $this->assertEquals(1, $groupPermission->first()->Type);
192
193
        Permission::grant($id, 'CMS_ACCESS_CMSMain', 'any');
194
        Permission::grant($id, 'CMS_ACCESS_AssetAdmin', 'any');
195
        Permission::grant($id, 'CMS_ACCESS_ReportAdmin', 'any');
196
197
        $groupPermission = Permission::get()->filter(['GroupID' => $id]);
198
199
        $this->assertEquals(3, $groupPermission->count());
200
        $this->assertEquals(-1, $groupPermission->first()->Arg);
201
        $this->assertEquals(1, $groupPermission->first()->Type);
202
    }
203
204
    public function testDenyPermission()
205
    {
206
        $id = rand(15, 20);
207
208
        Permission::deny($id, 'CMS_ACCESS_CMSMain');
209
        Permission::deny($id, 'CMS_ACCESS_AssetAdmin');
210
        Permission::deny($id, 'CMS_ACCESS_ReportAdmin');
211
212
        $groupPermission = Permission::get()->filter(['GroupID' => $id]);
213
214
        $this->assertEquals(3, $groupPermission->count());
215
        $this->assertEquals(0, $groupPermission->first()->Arg);
0 ignored issues
show
Bug Best Practice introduced by
The property Arg does not exist on SilverStripe\ORM\DataObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
216
        $this->assertEquals(-1, $groupPermission->first()->Type);
0 ignored issues
show
Bug Best Practice introduced by
The property Type does not exist on SilverStripe\ORM\DataObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
217
218
        Permission::deny($id, 'CMS_ACCESS_CMSMain', 'all');
219
        Permission::deny($id, 'CMS_ACCESS_AssetAdmin', 'all');
220
        Permission::deny($id, 'CMS_ACCESS_ReportAdmin', 'all');
221
222
        $groupPermission = Permission::get()->filter(['GroupID' => $id]);
223
224
        $this->assertEquals(3, $groupPermission->count());
225
        $this->assertEquals(-1, $groupPermission->first()->Arg);
226
        $this->assertEquals(-1, $groupPermission->first()->Type);
227
228
        Permission::deny($id, 'CMS_ACCESS_CMSMain', 'any');
229
        Permission::deny($id, 'CMS_ACCESS_AssetAdmin', 'any');
230
        Permission::deny($id, 'CMS_ACCESS_ReportAdmin', 'any');
231
232
        $groupPermission = Permission::get()->filter(['GroupID' => $id]);
233
234
        $this->assertEquals(3, $groupPermission->count());
235
        $this->assertEquals(-1, $groupPermission->first()->Arg);
236
        $this->assertEquals(-1, $groupPermission->first()->Type);
237
    }
238
239
    public function testDenyThenGrantPermission()
240
    {
241
        $member = $this->objFromFixture(Member::class, 'testcmseditormember');
242
        $group = $this->objFromFixture(Group::class, 'testcmseditorgroup');
243
        $id = $group->ID;
244
245
        $this->logInAs($member);
246
247
        Permission::grant($id, 'TEST_CMS_EDITOR');
248
        $groupPermission = Permission::get()->filter(['GroupID' => $id]);
249
250
        $this->assertEquals(1, $groupPermission->count());
251
        $this->assertEquals(1, $groupPermission->first()->Type);
0 ignored issues
show
Bug Best Practice introduced by
The property Type does not exist on SilverStripe\ORM\DataObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
252
        $this->assertTrue(Permission::check('TEST_CMS_EDITOR'));
253
254
        Permission::deny($id, 'TEST_CMS_EDITOR');
255
        $groupPermission = Permission::get()->filter(['GroupID' => $id]);
256
257
        $this->assertEquals(1, $groupPermission->count());
258
        $this->assertEquals(-1, $groupPermission->last()->Type);
259
        $this->assertFalse(Permission::check('TEST_CMS_EDITOR'));
260
261
        Permission::grant($id, 'TEST_CMS_EDITOR');
262
        $groupPermission = Permission::get()->filter(['GroupID' => $id]);
263
264
        $this->assertEquals(1, $groupPermission->count());
265
        $this->assertEquals(1, $groupPermission->first()->Type);
266
        $this->assertTrue(Permission::check('TEST_CMS_EDITOR'));
267
268
        Permission::grant($id, 'CMS_ACCESS_AssetAdmin');
269
        $groupPermission = Permission::get()->filter(['GroupID' => $id]);
270
        $this->assertEquals(2, $groupPermission->count());
271
272
        $groupPermissionAssetAdmin = Permission::get()->filter(
273
            [
274
                'GroupID' => $id,
275
                'Code' => 'CMS_ACCESS_AssetAdmin',
276
            ]
277
        );
278
        $this->assertEquals(1, $groupPermissionAssetAdmin->count());
279
        $this->assertEquals(1, $groupPermissionAssetAdmin->first()->Type);
280
281
        $this->assertTrue(Permission::check('CMS_ACCESS_AssetAdmin'));
282
283
        $this->logOut();
284
    }
285
}
286