Skip to content

Commit a4b6684

Browse files
authored
[Tag]: Incorrect permission check in tags (#1785)
* fix: incorrect permission check in tags * fix: sonar * fix: update throw tags
1 parent 1e7c986 commit a4b6684

24 files changed

Lines changed: 184 additions & 57 deletions

src/Asset/Controller/Export/ZipFolderController.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Pimcore\Bundle\StudioBackendBundle\Controller\AbstractApiController;
2121
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\EnvironmentException;
2222
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\ForbiddenException;
23+
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidQueryTypeException;
2324
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\MaxFileSizeExceededException;
2425
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\NotFoundException;
2526
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\StreamResourceNotFoundException;
@@ -48,8 +49,12 @@ public function __construct(
4849
}
4950

5051
/**
51-
* @throws ForbiddenException|NotFoundException|StreamResourceNotFoundException
52-
* @throws EnvironmentException|MaxFileSizeExceededException
52+
* @throws ForbiddenException
53+
* @throws NotFoundException
54+
* @throws StreamResourceNotFoundException
55+
* @throws EnvironmentException
56+
* @throws MaxFileSizeExceededException
57+
* @throws InvalidQueryTypeException
5358
*/
5459
#[Route('/assets/export/zip/folder', name: 'pimcore_studio_api_asset_export_zip_folder', methods: ['POST'])]
5560
#[IsGranted(UserPermissions::ASSETS->value)]

src/Asset/Controller/Grid/GetController.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
use Pimcore\Bundle\StudioBackendBundle\Controller\AbstractApiController;
1818
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\GdiParsingException;
1919
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException;
20+
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidElementTypeException;
21+
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidQueryTypeException;
2022
use Pimcore\Bundle\StudioBackendBundle\Grid\Attribute\Property\GridCollection;
2123
use Pimcore\Bundle\StudioBackendBundle\Grid\Attribute\Request\GridRequestBody;
2224
use Pimcore\Bundle\StudioBackendBundle\Grid\MappedParameter\GridParameter;
@@ -46,7 +48,10 @@ public function __construct(
4648
}
4749

4850
/**
49-
* @throws InvalidArgumentException|GdiParsingException
51+
* @throws InvalidArgumentException
52+
* @throws InvalidQueryTypeException
53+
* @throws InvalidElementTypeException
54+
* @throws GdiParsingException
5055
*/
5156
#[Route('/assets/grid', name: 'pimcore_studio_api_get_asset_grid', methods: ['POST'])]
5257
#[IsGranted(UserPermissions::ASSETS->value)]

src/Asset/Service/AssetService.php

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,14 @@
2626
use Pimcore\Bundle\StudioBackendBundle\Asset\Schema\Type\Text;
2727
use Pimcore\Bundle\StudioBackendBundle\Asset\Schema\Type\Unknown;
2828
use Pimcore\Bundle\StudioBackendBundle\Asset\Schema\Type\Video;
29-
use Pimcore\Bundle\StudioBackendBundle\DataIndex\Query\AssetQueryInterface;
29+
use Pimcore\Bundle\StudioBackendBundle\DataIndex\Provider\AssetQueryProviderInterface;
3030
use Pimcore\Bundle\StudioBackendBundle\DataIndex\Request\ElementParameters;
3131
use Pimcore\Bundle\StudioBackendBundle\DataIndex\SearchIndexFilterInterface;
3232
use Pimcore\Bundle\StudioBackendBundle\DataIndex\Service\AssetSearchServiceInterface;
3333
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\DatabaseException;
3434
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\ForbiddenException;
3535
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidElementTypeException;
36-
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidFilterServiceTypeException;
37-
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidFilterTypeException;
38-
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidQueryTypeException;
3936
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\NotFoundException;
40-
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\SearchException;
41-
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\UserNotFoundException;
4237
use Pimcore\Bundle\StudioBackendBundle\Filter\Service\FilterServiceProviderInterface;
4338
use Pimcore\Bundle\StudioBackendBundle\Response\Collection;
4439
use Pimcore\Bundle\StudioBackendBundle\Security\Service\SecurityServiceInterface;
@@ -60,6 +55,7 @@
6055
use UserPermissionTrait;
6156

6257
public function __construct(
58+
private AssetQueryProviderInterface $assetQueryProvider,
6359
private AssetSearchServiceInterface $assetSearchService,
6460
private AssetServiceResolverInterface $assetServiceResolver,
6561
private EventDispatcherInterface $eventDispatcher,
@@ -71,15 +67,16 @@ public function __construct(
7167
}
7268

7369
/**
74-
* @throws InvalidFilterServiceTypeException|SearchException|InvalidQueryTypeException|InvalidFilterTypeException
70+
* {@inheritdoc}
7571
*/
7672
public function getAssets(ElementParameters $parameters): Collection
7773
{
7874
/** @var SearchIndexFilterInterface $filterService */
7975
$filterService = $this->filterServiceProvider->create(SearchIndexFilterInterface::SERVICE_TYPE);
8076

81-
/** @var AssetQueryInterface $assetQuery */
77+
$assetQuery = $this->assetQueryProvider->createAssetQuery();
8278
$assetQuery = $filterService->applyFilters(
79+
$assetQuery,
8380
$parameters,
8481
ElementTypes::TYPE_ASSET
8582
);
@@ -99,7 +96,7 @@ public function getAssets(ElementParameters $parameters): Collection
9996
}
10097

10198
/**
102-
* @throws SearchException|NotFoundException|UserNotFoundException
99+
* {@inheritdoc}
103100
*/
104101
public function getAsset(
105102
int $id,
@@ -121,7 +118,7 @@ public function getAsset(
121118
}
122119

123120
/**
124-
* @throws SearchException|NotFoundException
121+
* {@inheritdoc}
125122
*/
126123
public function getAssetForUser(
127124
int $id,
@@ -135,7 +132,7 @@ public function getAssetForUser(
135132
}
136133

137134
/**
138-
* @throws SearchException|NotFoundException
135+
* {@inheritdoc}
139136
*/
140137
public function getAssetFolder(int $id, bool $checkPermissionsForCurrentUser = true): AssetFolder
141138
{
@@ -154,7 +151,7 @@ public function getAssetFolder(int $id, bool $checkPermissionsForCurrentUser = t
154151
}
155152

156153
/**
157-
* @throws SearchException|NotFoundException
154+
* {@inheritdoc}
158155
*/
159156
public function getAssetFolderForUser(int $id, UserInterface $user): AssetFolder
160157
{
@@ -170,7 +167,7 @@ public function getAssetFolderForUser(int $id, UserInterface $user): AssetFolder
170167
}
171168

172169
/**
173-
* @throws SearchException
170+
* {@inheritdoc}
174171
*/
175172
public function assetFolderExists(int $id, bool $checkPermissionsForCurrentUser = true): bool
176173
{
@@ -184,7 +181,7 @@ public function assetFolderExists(int $id, bool $checkPermissionsForCurrentUser
184181
}
185182

186183
/**
187-
* @throws SearchException
184+
* {@inheritdoc}
188185
*/
189186
public function assetFolderExistsForUser(int $id, UserInterface $user): bool
190187
{
@@ -198,7 +195,7 @@ public function assetFolderExistsForUser(int $id, UserInterface $user): bool
198195
}
199196

200197
/**
201-
* @throws ForbiddenException|NotFoundException
198+
* {@inheritdoc}
202199
*/
203200
public function getAssetElement(
204201
UserInterface $user,
@@ -215,7 +212,7 @@ public function getAssetElement(
215212
}
216213

217214
/**
218-
* @throws ForbiddenException|NotFoundException
215+
* {@inheritdoc}
219216
*/
220217
public function getAssetElementByPath(
221218
UserInterface $user,
@@ -252,7 +249,7 @@ public function getUniqueAssetName(string $targetPath, string $filename): string
252249
}
253250

254251
/**
255-
* @throws DatabaseException|ForbiddenException
252+
* {@inheritdoc}
256253
*/
257254
public function clearThumbnails(int $id): void
258255
{

src/Asset/Service/ExecutionEngine/ZipService.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,9 @@ public function generateZipFileForAssets(ExportAssetFileParameter $parameter): i
152152
return $this->createJobRunAndStartExecution($parameter->getAssets());
153153
}
154154

155+
/**
156+
* {@inheritdoc}
157+
*/
155158
public function generateZipFileForFolders(ExportFolderFileParameter $parameter): int
156159
{
157160
$folders = $parameter->getFolders();

src/Asset/Service/ExecutionEngine/ZipServiceInterface.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Pimcore\Bundle\StudioBackendBundle\Asset\MappedParameter\ExportFolderFileParameter;
1818
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\EnvironmentException;
1919
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\ForbiddenException;
20+
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidQueryTypeException;
2021
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\MaxFileSizeExceededException;
2122
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\NotFoundException;
2223
use Pimcore\Model\Asset;
@@ -70,6 +71,9 @@ public function uploadZipAssets(
7071
*/
7172
public function generateZipFileForAssets(ExportAssetFileParameter $parameter): int;
7273

74+
/**
75+
* @throws InvalidQueryTypeException
76+
*/
7377
public function generateZipFileForFolders(ExportFolderFileParameter $parameter): int;
7478

7579
/**

src/DataIndex/Filter/FilterInterface.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,12 @@
2020
*/
2121
interface FilterInterface
2222
{
23+
/**
24+
* @template T of QueryInterface
25+
*
26+
* @param T $query
27+
*
28+
* @return T
29+
*/
2330
public function apply(mixed $parameters, QueryInterface $query): QueryInterface;
2431
}

src/DataIndex/Filter/TagFilter.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
namespace Pimcore\Bundle\StudioBackendBundle\DataIndex\Filter;
1515

1616
use Pimcore\Bundle\StudioBackendBundle\DataIndex\Query\QueryInterface;
17+
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\ForbiddenException;
1718
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException;
1819
use Pimcore\Bundle\StudioBackendBundle\Grid\Column\ColumnType;
1920
use Pimcore\Bundle\StudioBackendBundle\MappedParameter\Filter\SimpleColumnFiltersParameterInterface;
21+
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\UserPermissions;
2022

2123
/**
2224
* @internal
@@ -34,6 +36,16 @@ public function apply(mixed $parameters, QueryInterface $query): QueryInterface
3436
if (!$filter) {
3537
return $query;
3638
}
39+
40+
$user = $query->getSearch()->getUser();
41+
if (!$user || !$user->isAllowed(UserPermissions::TAGS_SEARCH->value)) {
42+
throw new ForbiddenException(
43+
sprintf(
44+
'User does not have permission: %s',
45+
UserPermissions::TAGS_SEARCH->value
46+
)
47+
);
48+
}
3749

3850
$filterValue = $filter->getFilterValue();
3951

src/DataIndex/Grid/GridSearch.php

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,16 @@
2020
use Pimcore\Bundle\StudioBackendBundle\DataIndex\Query\AssetQueryInterface;
2121
use Pimcore\Bundle\StudioBackendBundle\DataIndex\Query\DataObjectQueryInterface;
2222
use Pimcore\Bundle\StudioBackendBundle\DataIndex\Query\DocumentQueryInterface;
23+
use Pimcore\Bundle\StudioBackendBundle\DataIndex\Query\QueryInterface;
2324
use Pimcore\Bundle\StudioBackendBundle\DataIndex\SearchIndexFilterInterface;
2425
use Pimcore\Bundle\StudioBackendBundle\DataIndex\Service\AssetSearchServiceInterface;
2526
use Pimcore\Bundle\StudioBackendBundle\DataIndex\Service\DataObjectSearchServiceInterface;
2627
use Pimcore\Bundle\StudioBackendBundle\DataIndex\Service\DocumentSearchServiceInterface;
2728
use Pimcore\Bundle\StudioBackendBundle\DataObject\Schema\DataObject;
2829
use Pimcore\Bundle\StudioBackendBundle\DataObject\Schema\Type\DataObjectFolder;
29-
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException;
3030
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidElementTypeException;
3131
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\NotFoundException;
32-
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\SearchException;
32+
use Pimcore\Bundle\StudioBackendBundle\Factory\QueryFactoryInterface;
3333
use Pimcore\Bundle\StudioBackendBundle\Filter\MappedParameter\FilterParameter;
3434
use Pimcore\Bundle\StudioBackendBundle\Filter\Service\FilterServiceProviderInterface;
3535
use Pimcore\Bundle\StudioBackendBundle\Grid\MappedParameter\GridParameter;
@@ -46,17 +46,18 @@
4646
private SearchIndexFilterInterface $filterService;
4747

4848
public function __construct(
49-
private FilterServiceProviderInterface $filterServiceProvider,
5049
private AssetSearchServiceInterface $assetSearchService,
5150
private DataObjectSearchServiceInterface $dataObjectSearchService,
5251
private DocumentSearchServiceInterface $documentSearchService,
52+
private FilterServiceProviderInterface $filterServiceProvider,
53+
private QueryFactoryInterface $queryFactory,
5354
private SecurityServiceInterface $securityService
5455
) {
5556
$this->filterService = $this->filterServiceProvider->create(SearchIndexFilterInterface::SERVICE_TYPE);
5657
}
5758

5859
/**
59-
* @throws NotFoundException|SearchException|InvalidArgumentException
60+
* {@inheritdoc}
6061
*/
6162
public function searchAssets(GridParameter $gridParameter): AssetSearchResult
6263
{
@@ -67,6 +68,9 @@ public function searchAssets(GridParameter $gridParameter): AssetSearchResult
6768
);
6869
}
6970

71+
/**
72+
* {@inheritdoc}
73+
*/
7074
public function searchAssetsForUser(GridParameter $gridParameter, UserInterface $user): AssetSearchResult
7175
{
7276
return $this->searchElementsForUser(
@@ -76,6 +80,9 @@ public function searchAssetsForUser(GridParameter $gridParameter, UserInterface
7680
);
7781
}
7882

83+
/**
84+
* {@inheritdoc}
85+
*/
7986
public function searchDataObjects(GridParameter $gridParameter): DataObjectSearchResult
8087
{
8188
return $this->searchElementsForUser(
@@ -85,6 +92,9 @@ public function searchDataObjects(GridParameter $gridParameter): DataObjectSearc
8592
);
8693
}
8794

95+
/**
96+
* {@inheritdoc}
97+
*/
8898
public function searchDocuments(GridParameter $gridParameter): DocumentSearchResult
8999
{
90100
return $this->searchElementsForUser(
@@ -94,18 +104,16 @@ public function searchDocuments(GridParameter $gridParameter): DocumentSearchRes
94104
);
95105
}
96106

107+
/**
108+
* {@inheritdoc}
109+
*/
97110
public function searchElementsForUser(
98111
string $type,
99112
GridParameter $gridParameter,
100113
UserInterface $user
101114
): AssetSearchResult|DataObjectSearchResult|DocumentSearchResult {
102-
$filter = $gridParameter->getFilters();
103-
$type = $this->getStudioElementType($type);
104-
$filter = $this->setFilterPath($filter, $type, $gridParameter->getFolderId(), $user);
105-
106115
/** @var AssetQueryInterface|DataObjectQueryInterface|DocumentQueryInterface $query */
107-
$query = $this->filterService->applyFilters($filter, $type);
108-
$query->setUser($user);
116+
$query = $this->getSearchQuery($type, $gridParameter, $user);
109117

110118
return match($type) {
111119
ElementTypes::TYPE_ASSET => $this->assetSearchService->searchAssets($query),
@@ -115,18 +123,16 @@ public function searchElementsForUser(
115123
};
116124
}
117125

126+
/**
127+
* {@inheritdoc}
128+
*/
118129
public function searchElementIdsForUser(
119130
string $type,
120131
GridParameter $gridParameter,
121132
UserInterface $user
122133
): array {
123-
$filter = $gridParameter->getFilters();
124-
$type = $this->getStudioElementType($type);
125-
$filter = $this->setFilterPath($filter, $type, $gridParameter->getFolderId(), $user);
126-
127134
/** @var AssetQueryInterface|DataObjectQueryInterface $query */
128-
$query = $this->filterService->applyFilters($filter, $type);
129-
$query->setUser($user);
135+
$query = $this->getSearchQuery($type, $gridParameter, $user);
130136

131137
return match($type) {
132138
ElementTypes::TYPE_ASSET => $this->assetSearchService->fetchAssetIds($query),
@@ -135,6 +141,23 @@ public function searchElementIdsForUser(
135141
};
136142
}
137143

144+
private function getSearchQuery(
145+
string $type,
146+
GridParameter $gridParameter,
147+
UserInterface $user
148+
): QueryInterface
149+
{
150+
$filter = $gridParameter->getFilters();
151+
$type = $this->getStudioElementType($type);
152+
$filter = $this->setFilterPath($filter, $type, $gridParameter->getFolderId(), $user);
153+
154+
$query = $this->queryFactory->create($type);
155+
$query = $this->filterService->applyFilters($query, $filter, $type);
156+
$query->setUser($user);
157+
158+
return $query;
159+
}
160+
138161
private function setFilterPath(
139162
FilterParameter $filter,
140163
string $type,

0 commit comments

Comments
 (0)