|
6 | 6 |
|
7 | 7 | use Doctrine\ORM\EntityManagerInterface; |
8 | 8 | use OpenApi\Attributes as OA; |
9 | | -use PhpList\Core\Domain\Common\Model\Filter\PaginatedFilter; |
| 9 | +use PhpList\Core\Domain\Identity\Model\Administrator; |
10 | 10 | use PhpList\Core\Domain\Messaging\Model\Filter\SubscriberListFilter; |
11 | 11 | use PhpList\Core\Domain\Subscription\Model\SubscriberList; |
12 | 12 | use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberListManager; |
|
32 | 32 | #[Route('/lists', name: 'subscriber_list_')] |
33 | 33 | class SubscriberListController extends BaseController |
34 | 34 | { |
35 | | - private SubscriberListNormalizer $normalizer; |
36 | | - private SubscriberListManager $subscriberListManager; |
37 | | - private PaginatedDataProvider $paginatedDataProvider; |
38 | | - private EntityManagerInterface $entityManager; |
39 | | - |
40 | 35 | public function __construct( |
41 | 36 | Authentication $authentication, |
42 | 37 | RequestValidator $validator, |
43 | | - SubscriberListNormalizer $normalizer, |
44 | | - SubscriberListManager $subscriberListManager, |
45 | | - PaginatedDataProvider $paginatedDataProvider, |
46 | | - EntityManagerInterface $entityManager, |
| 38 | + private readonly SubscriberListNormalizer $normalizer, |
| 39 | + private readonly SubscriberListManager $subscriberListManager, |
| 40 | + private readonly PaginatedDataProvider $paginatedDataProvider, |
| 41 | + private readonly EntityManagerInterface $entityManager, |
47 | 42 | ) { |
48 | 43 | parent::__construct($authentication, $validator); |
49 | | - $this->normalizer = $normalizer; |
50 | | - $this->subscriberListManager = $subscriberListManager; |
51 | | - $this->paginatedDataProvider = $paginatedDataProvider; |
52 | | - $this->entityManager = $entityManager; |
53 | 44 | } |
54 | 45 |
|
55 | 46 | #[Route('', name: 'get_list', methods: ['GET'])] |
@@ -167,19 +158,26 @@ className: SubscriberList::class, |
167 | 158 | ], |
168 | 159 | type: 'object' |
169 | 160 | ) |
170 | | - ) |
| 161 | + ), |
| 162 | + new OA\Response( |
| 163 | + response: 405, |
| 164 | + description: 'Failure', |
| 165 | + content: new OA\JsonContent(ref: '#/components/schemas/UnauthorizedResponse') |
| 166 | + ), |
171 | 167 | ] |
172 | 168 | )] |
173 | 169 | public function getList( |
174 | 170 | Request $request, |
175 | 171 | #[MapEntity(mapping: ['listId' => 'id'])] ?SubscriberList $list = null |
176 | 172 | ): JsonResponse { |
177 | | - $this->requireAuthentication($request); |
| 173 | + $authUser = $this->requireAuthentication($request); |
178 | 174 |
|
179 | 175 | if (!$list) { |
180 | 176 | throw $this->createNotFoundException('Subscriber list not found.'); |
181 | 177 | } |
182 | 178 |
|
| 179 | + $this->denyAccessUnlessOwnerOrPublic($list, $authUser); |
| 180 | + |
183 | 181 | return $this->json($this->normalizer->normalize($list), Response::HTTP_OK); |
184 | 182 | } |
185 | 183 |
|
@@ -220,19 +218,26 @@ public function getList( |
220 | 218 | response: 404, |
221 | 219 | description: 'Failure', |
222 | 220 | content: new OA\JsonContent(ref: '#/components/schemas/NotFoundErrorResponse') |
223 | | - ) |
| 221 | + ), |
| 222 | + new OA\Response( |
| 223 | + response: 405, |
| 224 | + description: 'Failure', |
| 225 | + content: new OA\JsonContent(ref: '#/components/schemas/UnauthorizedResponse') |
| 226 | + ), |
224 | 227 | ] |
225 | 228 | )] |
226 | 229 | public function deleteList( |
227 | 230 | Request $request, |
228 | 231 | #[MapEntity(mapping: ['listId' => 'id'])] ?SubscriberList $list = null |
229 | 232 | ): JsonResponse { |
230 | | - $this->requireAuthentication($request); |
| 233 | + $authUser = $this->requireAuthentication($request); |
231 | 234 |
|
232 | 235 | if (!$list) { |
233 | 236 | throw $this->createNotFoundException('Subscriber list not found.'); |
234 | 237 | } |
235 | 238 |
|
| 239 | + $this->denyAccessUnlessOwnerOrPublic($list, $authUser); |
| 240 | + |
236 | 241 | $this->subscriberListManager->delete($list); |
237 | 242 | $this->entityManager->flush(); |
238 | 243 |
|
@@ -289,4 +294,93 @@ public function createList(Request $request, SubscriberListNormalizer $normalize |
289 | 294 |
|
290 | 295 | return $this->json($normalizer->normalize($data), Response::HTTP_CREATED); |
291 | 296 | } |
| 297 | + |
| 298 | + #[Route('/{listId}', name: 'update', requirements: ['listId' => '\d+'], methods: ['PUT'])] |
| 299 | + #[OA\Post( |
| 300 | + path: '/api/v2/lists/{listId}', |
| 301 | + description: '🚧 **Status: Beta** – This method is under development. Avoid using in production. ' . |
| 302 | + 'Returns updated list.', |
| 303 | + summary: 'Update a subscriber list.', |
| 304 | + requestBody: new OA\RequestBody( |
| 305 | + description: 'Pass parameters to create a new subscriber list.', |
| 306 | + required: true, |
| 307 | + content: new OA\JsonContent(ref: '#/components/schemas/CreateSubscriberListRequest') |
| 308 | + ), |
| 309 | + tags: ['lists'], |
| 310 | + parameters: [ |
| 311 | + new OA\Parameter( |
| 312 | + name: 'php-auth-pw', |
| 313 | + description: 'Session key obtained from login', |
| 314 | + in: 'header', |
| 315 | + required: true, |
| 316 | + schema: new OA\Schema(type: 'string') |
| 317 | + ), |
| 318 | + new OA\Parameter( |
| 319 | + name: 'listId', |
| 320 | + description: 'List ID', |
| 321 | + in: 'path', |
| 322 | + required: true, |
| 323 | + schema: new OA\Schema(type: 'string') |
| 324 | + ), |
| 325 | + ], |
| 326 | + responses: [ |
| 327 | + new OA\Response( |
| 328 | + response: 200, |
| 329 | + description: 'Success', |
| 330 | + content: new OA\JsonContent(ref: '#/components/schemas/SubscriberList') |
| 331 | + ), |
| 332 | + new OA\Response( |
| 333 | + response: 403, |
| 334 | + description: 'Failure', |
| 335 | + content: new OA\JsonContent(ref: '#/components/schemas/UnauthorizedResponse') |
| 336 | + ), |
| 337 | + new OA\Response( |
| 338 | + response: 405, |
| 339 | + description: 'Failure', |
| 340 | + content: new OA\JsonContent(ref: '#/components/schemas/UnauthorizedResponse') |
| 341 | + ), |
| 342 | + new OA\Response( |
| 343 | + response: 422, |
| 344 | + description: 'Failure', |
| 345 | + content: new OA\JsonContent(ref: '#/components/schemas/ValidationErrorResponse') |
| 346 | + ), |
| 347 | + ] |
| 348 | + )] |
| 349 | + public function updateList( |
| 350 | + Request $request, |
| 351 | + SubscriberListNormalizer $normalizer, |
| 352 | + #[MapEntity(mapping: ['listId' => 'id'])] ?SubscriberList $list = null, |
| 353 | + ): JsonResponse { |
| 354 | + $authUser = $this->requireAuthentication($request); |
| 355 | + |
| 356 | + if (!$list) { |
| 357 | + throw $this->createNotFoundException('Subscriber list not found.'); |
| 358 | + } |
| 359 | + |
| 360 | + $this->denyAccessUnlessOwnerOrPublic($list, $authUser); |
| 361 | + |
| 362 | + /** @var CreateSubscriberListRequest $subscriberListRequest */ |
| 363 | + $subscriberListRequest = $this->validator->validate($request, CreateSubscriberListRequest::class); |
| 364 | + $data = $this->subscriberListManager->updateSubscriberList( |
| 365 | + $list, |
| 366 | + $subscriberListRequest->getDto(), |
| 367 | + $authUser, |
| 368 | + ); |
| 369 | + $this->entityManager->flush(); |
| 370 | + |
| 371 | + return $this->json($normalizer->normalize($data), Response::HTTP_OK); |
| 372 | + } |
| 373 | + |
| 374 | + private function denyAccessUnlessOwnerOrPublic(SubscriberList $list, Administrator $user): void |
| 375 | + { |
| 376 | + if ($list->getOwner() === null) { |
| 377 | + return; |
| 378 | + } |
| 379 | + |
| 380 | + if ($list->getOwner()->getId() === $user->getId()) { |
| 381 | + return; |
| 382 | + } |
| 383 | + |
| 384 | + throw $this->createAccessDeniedException('Access denied.'); |
| 385 | + } |
292 | 386 | } |
0 commit comments