mirror of
https://github.com/flarum/core.git
synced 2025-08-04 15:37:51 +02:00
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:
@@ -49,11 +49,26 @@ class ShowTagController extends AbstractShowController
|
|||||||
$slug = Arr::get($request->getQueryParams(), 'slug');
|
$slug = Arr::get($request->getQueryParams(), 'slug');
|
||||||
$actor = RequestUtil::getActor($request);
|
$actor = RequestUtil::getActor($request);
|
||||||
$include = $this->extractInclude($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)
|
->with($include, $actor)
|
||||||
->whereVisibleTo($actor)
|
->whereVisibleTo($actor)
|
||||||
->where('slug', $slug)
|
->where('slug', $slug)
|
||||||
->firstOrFail();
|
->firstOrFail();
|
||||||
|
|
||||||
|
if ($setParentOnChildren && $tag->parent) {
|
||||||
|
foreach ($tag->parent->children as $child) {
|
||||||
|
$child->parent = $tag->parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $tag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,7 +14,7 @@ use Illuminate\Database\Eloquent\Builder;
|
|||||||
|
|
||||||
class TagRepository
|
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.
|
* Get a new query builder for the tags table.
|
||||||
|
@@ -83,15 +83,16 @@ class ListTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @dataProvider listTagsIncludes
|
||||||
* @test
|
* @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(
|
$response = $this->send(
|
||||||
$this->request('GET', '/api/tags', [
|
$this->request('GET', '/api/tags', [
|
||||||
'authenticatedAs' => 2,
|
'authenticatedAs' => 2,
|
||||||
])->withQueryParams([
|
])->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
|
// 6, 7, 8 aren't included because child access shouldnt work unless parent
|
||||||
// access is also given.
|
// access is also given.
|
||||||
$this->assertEquals(['1', '2', '3', '4', '9', '10', '11'], Arr::pluck($data, 'id'));
|
$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');
|
$ids = Arr::pluck($data, 'id');
|
||||||
$this->assertEquals(['1', '2', '3', '4', '9', '10'], $ids);
|
$this->assertEquals(['1', '2', '3', '4', '9', '10'], $ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function listTagsIncludes(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
['children', ['3', '4']],
|
||||||
|
['parent', ['2']],
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
75
extensions/tags/tests/integration/api/tags/ShowTest.php
Normal file
75
extensions/tags/tests/integration/api/tags/ShowTest.php
Normal 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']],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user