Skip to content

Commit 199b857

Browse files
[1.x] fix(tags): defer policy if min primary & secondary tags 0 (#4277)
* fix(tags): defer policy if min primary & secondary tags 0 Deferring it rather then force allowing in that case allows other policies to take action. Consider this more of a POC * test(tags): add integration test for forum attributes * style: formatting * chore: skip ci commit [skip ci] * chore * chore(tags): return `null` instead of `void` * style(tags): change formatting * chore: change back return type
1 parent b8b423d commit 199b857

File tree

3 files changed

+102
-1
lines changed

3 files changed

+102
-1
lines changed

extensions/tags/composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@
7979
},
8080
"require-dev": {
8181
"flarum/core": "*@dev",
82-
"flarum/testing": "^1.0.0"
82+
"flarum/testing": "^1.0.0",
83+
"flarum/suspend": "*@dev"
8384
},
8485
"repositories": [
8586
{

extensions/tags/src/Access/GlobalPolicy.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@ public function can(User $actor, string $ability)
4242
return $this->allow();
4343
}
4444

45+
if ($ability === 'startDiscussion') {
46+
$minPrimaryTags = (int) $this->settings->get('flarum-tags.min_primary_tags');
47+
$minSecondaryTags = (int) $this->settings->get('flarum-tags.min_secondary_tags');
48+
49+
if ($minPrimaryTags === 0 && $minSecondaryTags === 0) {
50+
return;
51+
}
52+
}
53+
4554
if (in_array($ability, ['viewForum', 'startDiscussion'])) {
4655
if (! isset($enoughPrimary[$actor->id][$ability])) {
4756
$primaryTagsWhereNeedsPermission = $this->settings->get('flarum-tags.min_primary_tags');
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
3+
/*
4+
* This file is part of Flarum.
5+
*
6+
* For detailed copyright and license information, please view the
7+
* LICENSE file that was distributed with this source code.
8+
*/
9+
10+
namespace Flarum\Tags\Tests\integration\api\forum;
11+
12+
use Flarum\Tags\Tests\integration\RetrievesRepresentativeTags;
13+
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
14+
use Flarum\Testing\integration\TestCase;
15+
use Illuminate\Support\Arr;
16+
17+
class ForumAttributeTest extends TestCase
18+
{
19+
use RetrievesAuthorizedUsers;
20+
use RetrievesRepresentativeTags;
21+
22+
/**
23+
* @inheritDoc
24+
*/
25+
protected function setUp(): void
26+
{
27+
parent::setUp();
28+
29+
$this->extension('flarum-tags');
30+
$this->extension('flarum-suspend');
31+
32+
$this->prepareDatabase([
33+
'tags' => $this->tags(),
34+
'users' => [
35+
$this->normalUser(),
36+
['id' => 3, 'username' => 'suspended-user', 'email' => '[email protected]', 'suspended_until' => '2043-11-17 22:05:23', 'is_email_confirmed' => 1],
37+
]
38+
]);
39+
}
40+
41+
public function canStartDiscussionProvider()
42+
{
43+
return [
44+
'admin user, min 0/0' => ['authenticatedAs' => 1, 'minPrimary' => 0, 'minSecondary' => 0, 'expected' => true],
45+
'normal user, min 0/0' => ['authenticatedAs' => 2, 'minPrimary' => 0, 'minSecondary' => 0, 'expected' => true],
46+
'suspended user, min 0/0' => ['authenticatedAs' => 3, 'minPrimary' => 0, 'minSecondary' => 0, 'expected' => false],
47+
'guest user, min 0/0' => ['authenticatedAs' => null, 'minPrimary' => 0, 'minSecondary' => 0, 'expected' => false],
48+
49+
'admin user, min 1/0' => ['authenticatedAs' => 1, 'minPrimary' => 1, 'minSecondary' => 0, 'expected' => true],
50+
'normal user, min 1/0' => ['authenticatedAs' => 2, 'minPrimary' => 1, 'minSecondary' => 0, 'expected' => true],
51+
'suspended user, min 1/0' => ['authenticatedAs' => 3, 'minPrimary' => 1, 'minSecondary' => 0, 'expected' => false],
52+
'guest user, min 1/0' => ['authenticatedAs' => null, 'minPrimary' => 1, 'minSecondary' => 0, 'expected' => false],
53+
54+
'admin user, min 0/1' => ['authenticatedAs' => 1, 'minPrimary' => 0, 'minSecondary' => 1, 'expected' => true],
55+
'normal user, min 0/1' => ['authenticatedAs' => 2, 'minPrimary' => 0, 'minSecondary' => 1, 'expected' => true],
56+
'suspended user, min 0/1' => ['authenticatedAs' => 3, 'minPrimary' => 0, 'minSecondary' => 1, 'expected' => false],
57+
'guest user, min 0/1' => ['authenticatedAs' => null, 'minPrimary' => 0, 'minSecondary' => 1, 'expected' => false],
58+
59+
'admin user, min 1/1' => ['authenticatedAs' => 1, 'minPrimary' => 1, 'minSecondary' => 1, 'expected' => true],
60+
'normal user, min 1/1' => ['authenticatedAs' => 2, 'minPrimary' => 1, 'minSecondary' => 1, 'expected' => true],
61+
'suspended user, min 1/1' => ['authenticatedAs' => 3, 'minPrimary' => 1, 'minSecondary' => 1, 'expected' => false],
62+
'guest user, min 1/1' => ['authenticatedAs' => null, 'minPrimary' => 1, 'minSecondary' => 1, 'expected' => false],
63+
];
64+
}
65+
66+
/**
67+
* @test
68+
*
69+
* @dataProvider canStartDiscussionProvider
70+
*/
71+
public function it_returns_the_expected_can_start_discussion_attribute(
72+
?int $authenticatedAs,
73+
int $minPrimary,
74+
int $minSecondary,
75+
bool $expected
76+
) {
77+
$this->setting('flarum-tags.min_primary_tags', $minPrimary);
78+
$this->setting('flarum-tags.min_secondary_tags', $minSecondary);
79+
80+
$response = $this->send(
81+
$this->request('GET', '/api', [
82+
'authenticatedAs' => $authenticatedAs,
83+
])
84+
);
85+
86+
$this->assertEquals(200, $response->getStatusCode());
87+
88+
$json = json_decode($response->getBody()->getContents(), true);
89+
$this->assertEquals($expected, Arr::get($json, 'data.attributes.canStartDiscussion'));
90+
}
91+
}

0 commit comments

Comments
 (0)