fix: restricted sibling tags appearing for unauthorized members on the sidebar (#3419)

* test: user should only be able to see related tags when allowed

* fix: restricted sibling tags appearing for unauthorized members on the sidebar

* fix: apply logic on tags with parents
This commit is contained in:
Sami Mazouz 2022-07-04 12:19:03 +01:00 committed by GitHub
parent 709c5566bb
commit bf4c543692
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 104 additions and 5 deletions

View File

@ -49,11 +49,26 @@ class ShowTagController extends AbstractShowController
$slug = Arr::get($request->getQueryParams(), 'slug');
$actor = RequestUtil::getActor($request);
$include = $this->extractInclude($request);
$setParentOnChildren = false;
return $this->tags
if (in_array('parent.children.parent', $include, true)) {
$setParentOnChildren = true;
$include[] = 'parent.children';
$include = array_unique(array_diff($include, ['parent.children.parent']));
}
$tag = $this->tags
->with($include, $actor)
->whereVisibleTo($actor)
->where('slug', $slug)
->firstOrFail();
if ($setParentOnChildren && $tag->parent) {
foreach ($tag->parent->children as $child) {
$child->parent = $tag->parent;
}
}
return $tag;
}
}

View File

@ -14,7 +14,7 @@ use Illuminate\Database\Eloquent\Builder;
class TagRepository
{
private const TAG_RELATIONS = ['children', 'parent'];
private const TAG_RELATIONS = ['children', 'parent', 'parent.children'];
/**
* Get a new query builder for the tags table.

View File

@ -83,15 +83,16 @@ class ListTest extends TestCase
}
/**
* @dataProvider listTagsIncludes
* @test
*/
public function user_sees_where_allowed_with_included_tags()
public function user_sees_where_allowed_with_included_tags(string $include, array $expectedIncludes)
{
$response = $this->send(
$this->request('GET', '/api/tags', [
'authenticatedAs' => 2,
])->withQueryParams([
'include' => 'children'
'include' => $include
])
);
@ -106,7 +107,7 @@ class ListTest extends TestCase
// 6, 7, 8 aren't included because child access shouldnt work unless parent
// access is also given.
$this->assertEquals(['1', '2', '3', '4', '9', '10', '11'], Arr::pluck($data, 'id'));
$this->assertEquals(['3', '4'], Arr::pluck($included, 'id'));
$this->assertEquals($expectedIncludes, Arr::pluck($included, 'id'));
}
/**
@ -125,4 +126,12 @@ class ListTest extends TestCase
$ids = Arr::pluck($data, 'id');
$this->assertEquals(['1', '2', '3', '4', '9', '10'], $ids);
}
public function listTagsIncludes(): array
{
return [
['children', ['3', '4']],
['parent', ['2']],
];
}
}

View File

@ -0,0 +1,75 @@
<?php
/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/
namespace Flarum\Tags\Tests\integration\api\tags;
use Flarum\Group\Group;
use Flarum\Tags\Tests\integration\RetrievesRepresentativeTags;
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase;
use Illuminate\Support\Arr;
class ShowTest extends TestCase
{
use RetrievesAuthorizedUsers;
use RetrievesRepresentativeTags;
/**
* @inheritDoc
*/
protected function setUp(): void
{
parent::setUp();
$this->extension('flarum-tags');
$this->prepareDatabase([
'tags' => $this->tags(),
'users' => [
$this->normalUser(),
],
'group_permission' => [
['group_id' => Group::MEMBER_ID, 'permission' => 'tag8.viewForum'],
['group_id' => Group::MEMBER_ID, 'permission' => 'tag11.viewForum']
]
]);
}
/**
* @dataProvider showTagIncludes
* @test
*/
public function user_sees_tag_relations_where_allowed(string $include, array $expectedIncludes)
{
$response = $this->send(
$this->request('GET', '/api/tags/primary-2-child-2', [
'authenticatedAs' => 2,
])->withQueryParams([
'include' => $include
])
);
$this->assertEquals(200, $response->getStatusCode());
$responseBody = json_decode($response->getBody()->getContents(), true);
$included = $responseBody['included'] ?? [];
$this->assertEqualsCanonicalizing($expectedIncludes, Arr::pluck($included, 'id'));
}
public function showTagIncludes(): array
{
return [
['children', []],
['parent', ['2']],
['parent.children', ['3', '2']],
['parent.children.parent', ['3', '2']],
];
}
}