From 85f5da018db44081e2f0a36c806152338018bcfa Mon Sep 17 00:00:00 2001 From: rpnykanen Date: Thu, 24 Oct 2024 13:51:03 +0300 Subject: [PATCH 1/7] UHF-10826: get rid of the unnecessary nesting --- .../Controller/GrantsMandateController.php | 86 +++++++++++-------- 1 file changed, 50 insertions(+), 36 deletions(-) diff --git a/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php b/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php index 468716943..95d49380f 100644 --- a/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php +++ b/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php @@ -164,56 +164,36 @@ public static function create(ContainerInterface $container): GrantsMandateContr */ public function mandateCallbackYpa(): RedirectResponse { $tOpts = ['context' => 'grants_mandate']; - $code = $this->requestStack->getMainRequest()->query->get('code'); - $state = $this->requestStack->getMainRequest()->query->get('state'); $callbackUrl = Url::fromRoute('grants_mandate.callback_ypa', [], ['absolute' => TRUE]) ->toString(); $appEnv = Helpers::getAppEnv(); - if (is_string($code) && $code != '') { - $this->grantsMandateService->changeCodeToToken($code, $callbackUrl); - $roles = $this->grantsMandateService->getRoles(); - $isAllowed = FALSE; - if ($roles && isset($roles[0]) && $roles[0]['roles']) { - $rolesArray = $roles[0]['roles']; - $isAllowed = $this->hasAllowedRole($rolesArray); - } - if (!$isAllowed && !str_contains($appEnv, 'LOCAL')) { - $this->messenger()->addError($this->t('Your mandate does not allow you to use this service.', [], $tOpts)); - // Redirect user to grants profile page. - $redirectUrl = Url::fromRoute('grants_mandate.mandateform'); - return new RedirectResponse($redirectUrl->toString()); - } - - $roles = reset($roles); - $roles['type'] = 'registered_community'; - $this->grantsProfileService->setSelectedRoleData($roles); + // @todo What is the meaning and purpose of the "code" (returned by api). + if (!is_string($code) || !$code) { + return $this->handleNoCode($tOpts); } - else { - - $error = $this->requestStack->getMainRequest()->query->get('error'); - $error_description = $this->requestStack->getMainRequest()->query->get('error_description'); - $error_uri = $this->requestStack->getMainRequest()->query->get('error_uri'); - $msg = $this->t('Code exchange error. @error: @error_desc. State: @state, Error URI: @error_uri', - [ - '@error' => $error, - '@error_description' => $error_description, - '@state' => $state, - '@error_uri' => $error_uri, - ], $tOpts); - - $this->logger->error('Error: %error', ['%error' => $msg->render()]); - - $this->messenger()->addError($this->t('Mandate process was interrupted or there was an error. Please try again.', [], $tOpts)); + $this->grantsMandateService->changeCodeToToken($code, $callbackUrl); + $roles = $this->grantsMandateService->getRoles(); + $isAllowed = FALSE; + if ($roles && isset($roles[0]) && $roles[0]['roles']) { + $rolesArray = $roles[0]['roles']; + $isAllowed = $this->hasAllowedRole($rolesArray); + } + if (!$isAllowed && !str_contains($appEnv, 'LOCAL')) { + $this->messenger()->addError($this->t('Your mandate does not allow you to use this service.', [], $tOpts)); // Redirect user to grants profile page. $redirectUrl = Url::fromRoute('grants_mandate.mandateform'); return new RedirectResponse($redirectUrl->toString()); } + $roles = reset($roles); + $roles['type'] = 'registered_community'; + $this->grantsProfileService->setSelectedRoleData($roles); + $selectedRoleData = $this->grantsProfileService->getSelectedRoleData(); // Load grants profile. @@ -226,16 +206,50 @@ public function mandateCallbackYpa(): RedirectResponse { return $this->redirectService->getRedirect($defaultRedirect); } + /** + * Api did not return a valid code. + * + * @param array $tOpts + * The options. + * + * @return \Symfony\Component\HttpFoundation\RedirectResponse + * Redirect in case of bad code. + */ + private function handleNoCode(array $tOpts): RedirectResponse { + $state = $this->requestStack->getMainRequest()->query->get('state'); + + $error = $this->requestStack->getMainRequest()->query->get('error'); + $error_description = $this->requestStack->getMainRequest()->query->get('error_description'); + $error_uri = $this->requestStack->getMainRequest()->query->get('error_uri'); + + $msg = $this->t('Code exchange error. @error: @error_desc. State: @state, Error URI: @error_uri', + [ + '@error' => $error, + '@error_description' => $error_description, + '@state' => $state, + '@error_uri' => $error_uri, + ], $tOpts); + + $this->logger->error('Error: %error', ['%error' => $msg->render()]); + + $this->messenger()->addError($this->t('Mandate process was interrupted or there was an error. Please try again.', [], $tOpts)); + // Redirect user to grants profile page. + $redirectUrl = Url::fromRoute('grants_mandate.mandateform'); + return new RedirectResponse($redirectUrl->toString()); + } + /** * Callback for user mandates. */ public function mandateCallbackHpa() { + throw new \Exception('Called a function which has no implementation'); } /** * Callback for hpa listing. */ public function mandateCallbackHpaList() { + throw new \Exception('Called a function which has no implementation'); } } From 6176bcbb1b08229e9895b062a2cbd4b88be2fb5f Mon Sep 17 00:00:00 2001 From: rpnykanen Date: Thu, 24 Oct 2024 14:59:20 +0300 Subject: [PATCH 2/7] UHF-10826: clean the old style properties --- .../Controller/GrantsMandateController.php | 122 +++++------------- 1 file changed, 31 insertions(+), 91 deletions(-) diff --git a/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php b/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php index 95d49380f..108f759eb 100644 --- a/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php +++ b/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php @@ -2,13 +2,9 @@ namespace Drupal\grants_mandate\Controller; -use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Controller\ControllerBase; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; -use Drupal\Core\Language\LanguageManagerInterface; -use Drupal\Core\Logger\LoggerChannel; use Drupal\Core\Messenger\MessengerTrait; -use Drupal\Core\Session\AccountProxyInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\Url; use Drupal\grants_handler\Helpers; @@ -30,49 +26,6 @@ class GrantsMandateController extends ControllerBase implements ContainerInjecti use MessengerTrait; use StringTranslationTrait; - /** - * The request stack used to access request globals. - * - * @var \Symfony\Component\HttpFoundation\RequestStack - */ - protected RequestStack $requestStack; - - /** - * The current user. - * - * @var \Drupal\Core\Session\AccountProxyInterface - */ - protected $currentUser; - - /** - * The language manager. - * - * @var \Drupal\Core\Language\LanguageManagerInterface - */ - protected $languageManager; - - /** - * Mandate service. - * - * @var \Drupal\grants_mandate\GrantsMandateService - */ - protected GrantsMandateService $grantsMandateService; - - - /** - * Access to profile data. - * - * @var \Drupal\grants_profile\GrantsProfileService - */ - protected GrantsProfileService $grantsProfileService; - - /** - * Logger access. - * - * @var \Drupal\Core\Logger\LoggerChannel|\Psr\Log\LoggerInterface - */ - protected LoggerChannel|LoggerInterface $logger; - /** * Allowed roles. * @@ -81,75 +34,43 @@ class GrantsMandateController extends ControllerBase implements ContainerInjecti protected array $allowedRoles; /** - * The redirect service. + * The logger. * - * @var \Drupal\grants_mandate\GrantsMandateRedirectService + * @var \Psr\Log\LoggerInterface */ - protected $redirectService; + private LoggerInterface $logger; /** * Grants Mandate Controller constructor. */ public function __construct( - RequestStack $requestStack, - AccountProxyInterface $current_user, - LanguageManagerInterface $language_manager, - GrantsMandateService $grantsMandateService, - GrantsProfileService $grantsProfileService, - ConfigFactoryInterface $configFactory, - GrantsMandateRedirectService $redirectService, + private RequestStack $requestStack, + private GrantsMandateService $grantsMandateService, + private GrantsProfileService $grantsProfileService, + private GrantsMandateRedirectService $redirectService, ) { - $this->requestStack = $requestStack; - $this->currentUser = $current_user; - $this->languageManager = $language_manager; - $this->grantsMandateService = $grantsMandateService; - $this->grantsProfileService = $grantsProfileService; - $this->redirectService = $redirectService; $this->logger = $this->getLogger('grants_mandate'); + $config = $this->configFactory->get('grants_mandate.settings'); + $extraRoles = is_array($config->get('extra_access_roles')) ? $config->get('extra_access_roles') : []; $this->allowedRoles = [ 'http://valtuusrekisteri.suomi.fi/avustushakemuksen_tekeminen', 'PJ', 'J', + ...$extraRoles, ]; - $config = $configFactory->get('grants_mandate.settings'); - $extraRoles = $config->get('extra_access_roles'); - if ($extraRoles && is_array($extraRoles)) { - $this->allowedRoles = array_merge($this->allowedRoles, $extraRoles); - } - } - - /** - * Check if user has required role in their mandate. - * - * @param array $roles - * Array of user's roles. - * - * @return bool - * Is user allowed to use this mandate. - */ - protected function hasAllowedRole(array $roles) { - $allowedRoles = $this->allowedRoles; - foreach ($roles as $role) { - if (in_array($role, $allowedRoles)) { - return TRUE; - } - } - return FALSE; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container): GrantsMandateController|static { - return new static( + $controller = new static( $container->get('request_stack'), - $container->get('current_user'), - $container->get('language_manager'), $container->get('grants_mandate.service'), $container->get('grants_profile.service'), - $container->get('config.factory'), $container->get('grants_mandate_redirect.service'), ); + return $controller->setLoggerFactory($container->get('logger.factory')); } /** @@ -238,6 +159,25 @@ private function handleNoCode(array $tOpts): RedirectResponse { return new RedirectResponse($redirectUrl->toString()); } + /** + * Check if user has required role in their mandate. + * + * @param array $roles + * Array of user's roles. + * + * @return bool + * Is user allowed to use this mandate. + */ + protected function hasAllowedRole(array $roles) { + $allowedRoles = $this->allowedRoles; + foreach ($roles as $role) { + if (in_array($role, $allowedRoles)) { + return TRUE; + } + } + return FALSE; + } + /** * Callback for user mandates. */ From a1684e76d32c7da70d081f0392672f6ea9e81cfe Mon Sep 17 00:00:00 2001 From: rpnykanen Date: Thu, 24 Oct 2024 15:00:30 +0300 Subject: [PATCH 3/7] UHF-10826: both traits are in base class --- .../grants_mandate/src/Controller/GrantsMandateController.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php b/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php index 108f759eb..196e13699 100644 --- a/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php +++ b/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php @@ -23,9 +23,6 @@ */ class GrantsMandateController extends ControllerBase implements ContainerInjectionInterface { - use MessengerTrait; - use StringTranslationTrait; - /** * Allowed roles. * From c32ba1e940c04a6a8ede528d35222da90d42d4c2 Mon Sep 17 00:00:00 2001 From: rpnykanen Date: Fri, 25 Oct 2024 09:08:57 +0300 Subject: [PATCH 4/7] UHF-10826: get company data after mandating user and send it to ATV --- .../Controller/GrantsMandateController.php | 39 ++++++++++++++++--- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php b/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php index 196e13699..0d45a9529 100644 --- a/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php +++ b/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php @@ -4,13 +4,12 @@ use Drupal\Core\Controller\ControllerBase; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; -use Drupal\Core\Messenger\MessengerTrait; -use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\Url; use Drupal\grants_handler\Helpers; use Drupal\grants_mandate\GrantsMandateRedirectService; use Drupal\grants_mandate\GrantsMandateService; use Drupal\grants_profile\GrantsProfileService; +use Drupal\grants_profile\ProfileConnector; use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\RedirectResponse; @@ -22,7 +21,6 @@ * @phpstan-consistent-constructor */ class GrantsMandateController extends ControllerBase implements ContainerInjectionInterface { - /** * Allowed roles. * @@ -39,15 +37,26 @@ class GrantsMandateController extends ControllerBase implements ContainerInjecti /** * Grants Mandate Controller constructor. + * + * @param \Symfony\Component\HttpFoundation\RequestStack $requestStack + * The request stack. + * @param \Drupal\grants_mandate\GrantsMandateService $grantsMandateService + * The grants mandate service. + * @param \Drupal\grants_profile\GrantsProfileService $grantsProfileService + * The grants profile service. + * @param \Drupal\grants_mandate\GrantsMandateRedirectService $redirectService + * The grants mandate redirect service. */ public function __construct( private RequestStack $requestStack, private GrantsMandateService $grantsMandateService, private GrantsProfileService $grantsProfileService, private GrantsMandateRedirectService $redirectService, + private ProfileConnector $profileConnector, ) { $this->logger = $this->getLogger('grants_mandate'); - $config = $this->configFactory->get('grants_mandate.settings'); + $config = $this->config('grants_mandate.settings'); + $extraRoles = is_array($config->get('extra_access_roles')) ? $config->get('extra_access_roles') : []; $this->allowedRoles = [ 'http://valtuusrekisteri.suomi.fi/avustushakemuksen_tekeminen', @@ -66,6 +75,7 @@ public static function create(ContainerInterface $container): GrantsMandateContr $container->get('grants_mandate.service'), $container->get('grants_profile.service'), $container->get('grants_mandate_redirect.service'), + $container->get('grants_profile.profile_connector'), ); return $controller->setLoggerFactory($container->get('logger.factory')); } @@ -114,9 +124,28 @@ public function mandateCallbackYpa(): RedirectResponse { $selectedRoleData = $this->grantsProfileService->getSelectedRoleData(); - // Load grants profile. + /** @var \Drupal\helfi_atv\AtvDocument $grantsProfile */ $grantsProfile = $this->grantsProfileService->getGrantsProfile($selectedRoleData, TRUE); + try { + $companyData = $this->profileConnector + ->getRegisteredCompanyDataFromYdjhClient($selectedRoleData['identifier']); + + $grantsProfile->setBusinessId($companyData['businessId']); + $content = $grantsProfile->getContent(); + $content['businessId'] = $companyData['businessId']; + $content['companyHome'] = $companyData['companyHome']; + $content['registrationDate'] = $companyData['registrationDate']; + $grantsProfile->setContent($content); + + $this->grantsProfileService->saveGrantsProfile($grantsProfile->toArray()); + } + catch (\Exception $e) { + // Failing at this point does not matter, the execution can continue. + $this->logger + ->error('Failed to update grants profile after getting the mandate.'); + } + // Redirect user based on if the user has a profile. $redirectUrl = $grantsProfile ? Url::fromRoute('grants_oma_asiointi.front') : Url::fromRoute('grants_profile.edit'); $defaultRedirect = new RedirectResponse($redirectUrl->toString()); From 883bd9b5d7a3126f96f74fa2ca599776153aadbc Mon Sep 17 00:00:00 2001 From: rpnykanen Date: Fri, 25 Oct 2024 09:11:05 +0300 Subject: [PATCH 5/7] UHF-10826: missing comment --- .../grants_mandate/src/Controller/GrantsMandateController.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php b/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php index 0d45a9529..52c6158a0 100644 --- a/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php +++ b/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php @@ -46,6 +46,8 @@ class GrantsMandateController extends ControllerBase implements ContainerInjecti * The grants profile service. * @param \Drupal\grants_mandate\GrantsMandateRedirectService $redirectService * The grants mandate redirect service. + * @param \Drupal\grants_profile\ProfileConnector $profileConnector + * The profile connector. */ public function __construct( private RequestStack $requestStack, From 2e8ccf52357d4e14be89e9604c28fa2750203343 Mon Sep 17 00:00:00 2001 From: Janne Suominen Date: Fri, 25 Oct 2024 11:58:45 +0300 Subject: [PATCH 6/7] UHF-10826: Add single document query to HTTP --- tools/http/ATV.http | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/http/ATV.http b/tools/http/ATV.http index be6ec438c..094be07b8 100644 --- a/tools/http/ATV.http +++ b/tools/http/ATV.http @@ -1,4 +1,9 @@ -# Get single document by transaction_id +# Get single document by document id +GET {{atvUrl}}/v1/documents/{{document_id}} +Accept-Encoding: utf8 +X-Api-Key: {{atvApiKey}} + +#### Get single document by transaction_id GET {{atvUrl}}/v1/documents/? transaction_id={{transaction_id}} Accept-Encoding: utf8 From a0b5360c03985971a42dc23e8119e5d601c7d742 Mon Sep 17 00:00:00 2001 From: Janne Suominen Date: Fri, 25 Oct 2024 12:05:01 +0300 Subject: [PATCH 7/7] UHF-10826: Small changes + handle new profile. --- .../Controller/GrantsMandateController.php | 74 +++++++++++++------ 1 file changed, 51 insertions(+), 23 deletions(-) diff --git a/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php b/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php index 52c6158a0..234ac8684 100644 --- a/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php +++ b/public/modules/custom/grants_mandate/src/Controller/GrantsMandateController.php @@ -10,6 +10,7 @@ use Drupal\grants_mandate\GrantsMandateService; use Drupal\grants_profile\GrantsProfileService; use Drupal\grants_profile\ProfileConnector; +use Drupal\helfi_atv\AtvDocument; use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\RedirectResponse; @@ -21,6 +22,7 @@ * @phpstan-consistent-constructor */ class GrantsMandateController extends ControllerBase implements ContainerInjectionInterface { + /** * Allowed roles. * @@ -91,21 +93,24 @@ public static function create(ContainerInterface $container): GrantsMandateContr * * @throws \GuzzleHttp\Exception\GuzzleException * @throws \Drupal\grants_mandate\GrantsMandateException + * @throws \Drupal\grants_profile\GrantsProfileException */ public function mandateCallbackYpa(): RedirectResponse { $tOpts = ['context' => 'grants_mandate']; - $code = $this->requestStack->getMainRequest()->query->get('code'); - $callbackUrl = Url::fromRoute('grants_mandate.callback_ypa', [], ['absolute' => TRUE]) ->toString(); $appEnv = Helpers::getAppEnv(); - // @todo What is the meaning and purpose of the "code" (returned by api). + // We need to exchange the code to token that can be used to authorize + // the user in oAuth calls. + $code = $this->requestStack->getMainRequest()->query->get('code'); if (!is_string($code) || !$code) { + // If code is not set, we need to handle the error and not allow + // user to progress. return $this->handleNoCode($tOpts); } - + // If we have code, we can then exchange it to token. $this->grantsMandateService->changeCodeToToken($code, $callbackUrl); $roles = $this->grantsMandateService->getRoles(); $isAllowed = FALSE; @@ -114,7 +119,8 @@ public function mandateCallbackYpa(): RedirectResponse { $isAllowed = $this->hasAllowedRole($rolesArray); } if (!$isAllowed && !str_contains($appEnv, 'LOCAL')) { - $this->messenger()->addError($this->t('Your mandate does not allow you to use this service.', [], $tOpts)); + $this->messenger() + ->addError($this->t('Your mandate does not allow you to use this service.', [], $tOpts)); // Redirect user to grants profile page. $redirectUrl = Url::fromRoute('grants_mandate.mandateform'); return new RedirectResponse($redirectUrl->toString()); @@ -129,23 +135,8 @@ public function mandateCallbackYpa(): RedirectResponse { /** @var \Drupal\helfi_atv\AtvDocument $grantsProfile */ $grantsProfile = $this->grantsProfileService->getGrantsProfile($selectedRoleData, TRUE); - try { - $companyData = $this->profileConnector - ->getRegisteredCompanyDataFromYdjhClient($selectedRoleData['identifier']); - - $grantsProfile->setBusinessId($companyData['businessId']); - $content = $grantsProfile->getContent(); - $content['businessId'] = $companyData['businessId']; - $content['companyHome'] = $companyData['companyHome']; - $content['registrationDate'] = $companyData['registrationDate']; - $grantsProfile->setContent($content); - - $this->grantsProfileService->saveGrantsProfile($grantsProfile->toArray()); - } - catch (\Exception $e) { - // Failing at this point does not matter, the execution can continue. - $this->logger - ->error('Failed to update grants profile after getting the mandate.'); + if ($grantsProfile) { + $this->updateProfileWithRecentData($selectedRoleData['identifier'], $grantsProfile); } // Redirect user based on if the user has a profile. @@ -181,7 +172,8 @@ private function handleNoCode(array $tOpts): RedirectResponse { $this->logger->error('Error: %error', ['%error' => $msg->render()]); - $this->messenger()->addError($this->t('Mandate process was interrupted or there was an error. Please try again.', [], $tOpts)); + $this->messenger() + ->addError($this->t('Mandate process was interrupted or there was an error. Please try again.', [], $tOpts)); // Redirect user to grants profile page. $redirectUrl = Url::fromRoute('grants_mandate.mandateform'); return new RedirectResponse($redirectUrl->toString()); @@ -220,4 +212,40 @@ public function mandateCallbackHpaList() { throw new \Exception('Called a function which has no implementation'); } + /** + * Update user profile data from ytj/yrtti and save it. + * + * @param string $identifier + * Business to get data for. + * @param \Drupal\helfi_atv\AtvDocument $grantsProfile + * Grants profile to update. + * + * @return void + * No return. + * + * @throws \GuzzleHttp\Exception\GuzzleException + */ + public function updateProfileWithRecentData( + string $identifier, + AtvDocument $grantsProfile, + ): void { + + $grantsProfileContent = $grantsProfile->getContent(); + try { + $companyData = $this->profileConnector + ->getRegisteredCompanyDataFromYdjhClient($identifier); + + $grantsProfileContent['businessId'] = $companyData['businessId']; + $grantsProfileContent['companyHome'] = $companyData['companyHome']; + $grantsProfileContent['registrationDate'] = $companyData['registrationDate']; + + $this->grantsProfileService->saveGrantsProfile($grantsProfileContent); + } + catch (\Exception $e) { + // Failing at this point does not matter, the execution can continue. + $this->logger + ->error('Failed to update grants profile after getting the mandate.'); + } + } + }