From 2ad5f7716a2673429b179ac340470527c1d5249e Mon Sep 17 00:00:00 2001 From: Michiel Kodde Date: Mon, 2 Sep 2024 14:57:03 +0200 Subject: [PATCH] Make the other Authentication controllers invokable --- src/Controller/AuthenticationController.php | 134 +-------------- .../AuthenticationNotificationController.php | 155 ++++++++++++++++++ src/Controller/AuthenticationQrController.php | 65 ++++++++ 3 files changed, 221 insertions(+), 133 deletions(-) create mode 100644 src/Controller/AuthenticationNotificationController.php create mode 100644 src/Controller/AuthenticationQrController.php diff --git a/src/Controller/AuthenticationController.php b/src/Controller/AuthenticationController.php index e0cf98a4..79bfd9f0 100644 --- a/src/Controller/AuthenticationController.php +++ b/src/Controller/AuthenticationController.php @@ -38,7 +38,6 @@ use Surfnet\Tiqr\Tiqr\TiqrUserRepositoryInterface; use Surfnet\Tiqr\WithContextLogger; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; -use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; @@ -65,7 +64,7 @@ public function __construct( * @throws Exception */ #[Route(path: '/authentication', name: 'app_identity_authentication', methods: ['GET', 'POST'])] - public function authentication(Request $request): Response + public function __invoke(Request $request): Response { $nameId = $this->authenticationService->getNameId(); $sari = $this->stateHandler->getRequestId(); @@ -151,105 +150,6 @@ public function authentication(Request $request): Response ]); } - /** - * Generate a notification response for authentication.html. - * - * The javascript in the authentication page expects one of three statuses: - * - * - success: Notification send successfully - * - error: Notification was not send successfully - * - no-device: There was no device to send the notification - * - * @return JsonResponse - */ - private function generateNotificationResponse(string $status): JsonResponse - { - return new JsonResponse($status); - } - - /** - * - * @throws InvalidArgumentException - */ - #[Route(path: '/authentication/qr', name: 'app_identity_authentication_qr', methods: ['GET'])] - public function authenticationQr(): Response - { - $nameId = $this->authenticationService->getNameId(); - $sari = $this->stateHandler->getRequestId(); - $logger = WithContextLogger::from($this->logger, ['nameId' => $nameId, 'sari' => $sari]); - $logger->info('Client request QR image'); - - // Do have a valid sample AuthnRequest?. - if (!$this->authenticationService->authenticationRequired()) { - $logger->error('There is no pending authentication request from SP'); - - return new Response('No authentication required', Response::HTTP_BAD_REQUEST); - } - - $logger->info('Return QR image response'); - - return $this->tiqrService->createAuthenticationQRResponse(); - } - - /** - * - * @throws InvalidArgumentException - */ - #[Route(path: '/authentication/notification', name: 'app_identity_authentication_notification', methods: ['POST'])] - public function authenticationNotification(): Response - { - $nameId = $this->authenticationService->getNameId(); - $sari = $this->stateHandler->getRequestId(); - $logger = WithContextLogger::from($this->logger, ['nameId' => $nameId, 'sari' => $sari]); - $logger->info('Client requests sending push notification'); - - // Do have a valid sample AuthnRequest?. - if (!$this->authenticationService->authenticationRequired()) { - $logger->error('There is no pending authentication request from SP'); - - return new Response('No authentication required', Response::HTTP_BAD_REQUEST); - } - - $logger->info('Sending push notification'); - - // Get user. - try { - $user = $this->userRepository->getUser($nameId); - } catch (UserNotExistsException $exception) { - $logger->error(sprintf( - 'User with nameId "%s" not found, error "%s"', - $nameId, - $exception->getMessage() - )); - - return new Response(null, Response::HTTP_BAD_REQUEST); - } - - // Send notification. - $notificationType = $user->getNotificationType(); - $notificationAddress = $user->getNotificationAddress(); - - if ($notificationType && $notificationAddress) { - $this->logger->notice(sprintf( - 'Sending push notification for user "%s" with type "%s" and (untranslated) address "%s"', - $nameId, - $notificationType, - $notificationAddress - )); - - $result = $this->sendNotification($notificationType, $notificationAddress); - if ($result) { - return $this->generateNotificationResponse('success'); - } - return $this->generateNotificationResponse('error'); - } - - $this->logger->notice(sprintf('No notification address for user "%s", no notification was sent', $nameId)); - - return $this->generateNotificationResponse('no-device'); - } - - private function handleInvalidResponse(TiqrUserInterface $user, AuthenticationResponse $response, LoggerInterface $logger): Response { try { @@ -285,36 +185,4 @@ private function showUserIsBlockedErrorPage(bool $isBlockedPermanently): Respons ] ); } - - /** - * @return bool True when the notification was successfully sent, false otherwise - */ - private function sendNotification(string $notificationType, string $notificationAddress): bool - { - try { - $this->tiqrService->sendNotification($notificationType, $notificationAddress); - } catch (Exception $e) { - $this->logger->warning( - sprintf( - 'Failed to send push notification for type "%s" and address "%s"', - $notificationType, - $notificationAddress - ), - [ - 'exception' => $e, - ] - ); - return false; - } - - $this->logger->notice( - sprintf( - 'Successfully sent push notification for type "%s" and address "%s"', - $notificationType, - $notificationAddress - ) - ); - - return true; - } } diff --git a/src/Controller/AuthenticationNotificationController.php b/src/Controller/AuthenticationNotificationController.php new file mode 100644 index 00000000..3ebbce69 --- /dev/null +++ b/src/Controller/AuthenticationNotificationController.php @@ -0,0 +1,155 @@ +authenticationService->getNameId(); + $sari = $this->stateHandler->getRequestId(); + $logger = WithContextLogger::from($this->logger, ['nameId' => $nameId, 'sari' => $sari]); + $logger->info('Client requests sending push notification'); + + // Do have a valid sample AuthnRequest?. + if (!$this->authenticationService->authenticationRequired()) { + $logger->error('There is no pending authentication request from SP'); + + return new Response('No authentication required', Response::HTTP_BAD_REQUEST); + } + + $logger->info('Sending push notification'); + + // Get user. + try { + $user = $this->userRepository->getUser($nameId); + } catch (UserNotExistsException $exception) { + $logger->error(sprintf( + 'User with nameId "%s" not found, error "%s"', + $nameId, + $exception->getMessage() + )); + + return new Response(null, Response::HTTP_BAD_REQUEST); + } + + // Send notification. + $notificationType = $user->getNotificationType(); + $notificationAddress = $user->getNotificationAddress(); + + if ($notificationType && $notificationAddress) { + $this->logger->notice(sprintf( + 'Sending push notification for user "%s" with type "%s" and (untranslated) address "%s"', + $nameId, + $notificationType, + $notificationAddress + )); + + $result = $this->sendNotification($notificationType, $notificationAddress); + if ($result) { + return $this->generateNotificationResponse('success'); + } + return $this->generateNotificationResponse('error'); + } + + $this->logger->notice(sprintf('No notification address for user "%s", no notification was sent', $nameId)); + + return $this->generateNotificationResponse('no-device'); + } + + /** + * @return bool True when the notification was successfully sent, false otherwise + */ + private function sendNotification(string $notificationType, string $notificationAddress): bool + { + try { + $this->tiqrService->sendNotification($notificationType, $notificationAddress); + } catch (Exception $e) { + $this->logger->warning( + sprintf( + 'Failed to send push notification for type "%s" and address "%s"', + $notificationType, + $notificationAddress + ), + [ + 'exception' => $e, + ] + ); + return false; + } + + $this->logger->notice( + sprintf( + 'Successfully sent push notification for type "%s" and address "%s"', + $notificationType, + $notificationAddress + ) + ); + + return true; + } + + /** + * Generate a notification response for authentication.html. + * + * The javascript in the authentication page expects one of three statuses: + * + * - success: Notification send successfully + * - error: Notification was not send successfully + * - no-device: There was no device to send the notification + * + * @return JsonResponse + */ + private function generateNotificationResponse(string $status): JsonResponse + { + return new JsonResponse($status); + } +} diff --git a/src/Controller/AuthenticationQrController.php b/src/Controller/AuthenticationQrController.php new file mode 100644 index 00000000..809d4c36 --- /dev/null +++ b/src/Controller/AuthenticationQrController.php @@ -0,0 +1,65 @@ +authenticationService->getNameId(); + $sari = $this->stateHandler->getRequestId(); + $logger = WithContextLogger::from($this->logger, ['nameId' => $nameId, 'sari' => $sari]); + $logger->info('Client request QR image'); + + // Do have a valid sample AuthnRequest?. + if (!$this->authenticationService->authenticationRequired()) { + $logger->error('There is no pending authentication request from SP'); + + return new Response('No authentication required', Response::HTTP_BAD_REQUEST); + } + + $logger->info('Return QR image response'); + + return $this->tiqrService->createAuthenticationQRResponse(); + } +}