diff --git a/src/Oro/Bundle/ApiBundle/ApiDoc/Formatter/HtmlFormatter.php b/src/Oro/Bundle/ApiBundle/ApiDoc/Formatter/HtmlFormatter.php index b843787a38c..d5492047daf 100644 --- a/src/Oro/Bundle/ApiBundle/ApiDoc/Formatter/HtmlFormatter.php +++ b/src/Oro/Bundle/ApiBundle/ApiDoc/Formatter/HtmlFormatter.php @@ -174,8 +174,6 @@ protected function getGlobalVars(): array 'organizations' => $this->securityContext->getOrganizations(), 'organization' => $this->securityContext->getOrganization(), 'userName' => $this->securityContext->getUserName(), - 'apiKey' => $this->securityContext->getApiKey(), - 'apiKeyGenerationHint' => $this->securityContext->getApiKeyGenerationHint(), 'csrfCookieName' => $this->securityContext->getCsrfCookieName(), 'switchOrganizationRoute' => $this->securityContext->getSwitchOrganizationRoute(), 'loginRoute' => $this->securityContext->getLoginRoute(), diff --git a/src/Oro/Bundle/ApiBundle/ApiDoc/SecurityContext.php b/src/Oro/Bundle/ApiBundle/ApiDoc/SecurityContext.php index dc85dd845b0..14bcd578362 100644 --- a/src/Oro/Bundle/ApiBundle/ApiDoc/SecurityContext.php +++ b/src/Oro/Bundle/ApiBundle/ApiDoc/SecurityContext.php @@ -6,7 +6,6 @@ use Oro\Bundle\SecurityBundle\Authentication\Token\OrganizationAwareTokenInterface; use Oro\Bundle\SecurityBundle\Csrf\CsrfRequestManager; use Oro\Bundle\UserBundle\Entity\AbstractUser; -use Oro\Bundle\UserBundle\Security\AdvancedApiUserInterface; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\User\UserInterface; @@ -85,45 +84,6 @@ public function getUserName(): ?string return $user->getUserIdentifier(); } - #[\Override] - public function getApiKey(): ?string - { - $token = $this->tokenStorage->getToken(); - if (null === $token) { - return null; - } - - $user = $token->getUser(); - if (!$user instanceof AdvancedApiUserInterface) { - return null; - } - - $apiKeyKeys = $user->getApiKeys(); - if ($apiKeyKeys->isEmpty()) { - return null; - } - - if ($token instanceof OrganizationAwareTokenInterface) { - $organization = $token->getOrganization(); - foreach ($apiKeyKeys as $apiKeyKey) { - if ($apiKeyKey->getOrganization()->getId() === $organization->getId()) { - return $apiKeyKey->getApiKey(); - } - } - } - - return null; - } - - #[\Override] - public function getApiKeyGenerationHint(): ?string - { - return - 'To use WSSE authentication you need to generate API key for the current logged-in user.' - . ' To do this, go to the My User page and click Generate Key near to API Key.' - . ' After that reload this page.'; - } - #[\Override] public function getCsrfCookieName(): ?string { diff --git a/src/Oro/Bundle/ApiBundle/ApiDoc/SecurityContextInterface.php b/src/Oro/Bundle/ApiBundle/ApiDoc/SecurityContextInterface.php index 8b29aed3402..2770ce2ee97 100644 --- a/src/Oro/Bundle/ApiBundle/ApiDoc/SecurityContextInterface.php +++ b/src/Oro/Bundle/ApiBundle/ApiDoc/SecurityContextInterface.php @@ -29,16 +29,6 @@ public function getOrganization(): ?string; */ public function getUserName(): ?string; - /** - * Gets the API key that is used to identify the origin of an API request. - */ - public function getApiKey(): ?string; - - /** - * Gets a hint with instructions how to generate API key. - */ - public function getApiKeyGenerationHint(): ?string; - /** * Gets the name of CSRF cookie. */ diff --git a/src/Oro/Bundle/ApiBundle/Resources/views/ApiDoc/motd.html.twig b/src/Oro/Bundle/ApiBundle/Resources/views/ApiDoc/motd.html.twig index 4de3eee8daf..d723ff6afcc 100644 --- a/src/Oro/Bundle/ApiBundle/Resources/views/ApiDoc/motd.html.twig +++ b/src/Oro/Bundle/ApiBundle/Resources/views/ApiDoc/motd.html.twig @@ -85,13 +85,10 @@ var organizations = {{ organizations|json_encode|raw }}, organization = {{ organization|json_encode|raw }}, userName = {{ userName|json_encode|raw }}, - apiKey = {{ apiKey|json_encode|raw }}, - apiKeyGenerationHint = {{ apiKeyGenerationHint|default('')|json_encode|raw }}, switchOrganizationUrl = {{ switchOrganizationRoute ? path(switchOrganizationRoute)|json_encode|raw : 'null' }}, loginUrl = {{ loginRoute ? path(loginRoute)|json_encode|raw : 'null' }}, logoutUrl = {{ logoutRoute ? path(logoutRoute)|json_encode|raw : 'null' }}, sessionAllowed = {{ hasSecurityToken|json_encode|raw }}, - wsseAllowed = userName && apiKey, serverTime = {{ 'now'|date('c', 'UTC')|json_encode|raw }}, clientTime = new Date(), serverTimeOffset = Date.parse(serverTime) - clientTime, @@ -148,24 +145,6 @@ */ $('.autogenerated-header', this).remove(); - /** - * Add WSSE authentication related headers - */ - if (authType === 'wsse') { - $headers.append( - '
' + - '' + - '' + - '
' + - '
' + - '' + - '' + - '
' - ); - $('input.authorization-header', this).val('WSSE profile="UsernameToken"'); - $('input.x-wsse-header', this).val(wsseHeader(userName, apiKey, serverTimeOffset)); - } - /** * Add Session authentication related headers */ @@ -244,17 +223,13 @@ * Add the authentication type selector */ $('#sandbox_configuration').prepend( - (wsseAllowed || !apiKeyGenerationHint ? '' : '{{ include('@OroApi/ApiDoc/warning.svg') }}') + 'authentication: ' + '' ); - if (!wsseAllowed && !sessionAllowed) { + if (!sessionAllowed) { $('#header').css('background-color', '#f7fe2e'); } diff --git a/src/Oro/Bundle/UserBundle/Controller/UserController.php b/src/Oro/Bundle/UserBundle/Controller/UserController.php index 90a113ad27d..25f02e30781 100644 --- a/src/Oro/Bundle/UserBundle/Controller/UserController.php +++ b/src/Oro/Bundle/UserBundle/Controller/UserController.php @@ -261,8 +261,11 @@ private function isDeleteGranted(User $entity): bool */ private function isUserApiGenAllowed(User $entity) { - return $this->container->get(TokenAccessorInterface::class)->getUserId() === $entity->getId() - || $this->isGranted('MANAGE_API_KEY', $entity); + return $this->getParameter('kernel.environment') === 'test' + && ( + $this->container->get(TokenAccessorInterface::class)->getUserId() === $entity->getId() + || $this->isGranted('MANAGE_API_KEY', $entity) + ); } private function saveUserApi(User $user, UserApi $userApi) diff --git a/src/Oro/Bundle/UserBundle/Resources/views/User/view.html.twig b/src/Oro/Bundle/UserBundle/Resources/views/User/view.html.twig index 6334bee2e62..8a7afe1d1e6 100644 --- a/src/Oro/Bundle/UserBundle/Resources/views/User/view.html.twig +++ b/src/Oro/Bundle/UserBundle/Resources/views/User/view.html.twig @@ -119,7 +119,7 @@ }) }} {% endset %} {% set apiKeyWidget %} - {% if isProfileView or app.user.id == entity.id or is_granted('MANAGE_API_KEY', entity) %} + {% if app.environment == 'test' and (isProfileView or app.user.id == entity.id or is_granted('MANAGE_API_KEY', entity)) %} {{ oro_widget_render({ 'widgetType': 'block', 'url': path('oro_user_apigen', { id: entity.id }), diff --git a/src/Oro/Bundle/UserBundle/Tests/Behat/Features/generate_key_for_user.feature b/src/Oro/Bundle/UserBundle/Tests/Behat/Features/generate_key_for_user.feature deleted file mode 100644 index 5b0c1d45aca..00000000000 --- a/src/Oro/Bundle/UserBundle/Tests/Behat/Features/generate_key_for_user.feature +++ /dev/null @@ -1,15 +0,0 @@ -@ticket-BAP-21510 -@fixture-OroUserBundle:user.yml - -Feature: Generate Key for user - In order to create users - As a OroCRM Admin user - I need to be able to open Create User dialog and create new user - - Scenario: Generate Key for user - Given I enable API - And I login as administrator - And I go to System/User Management/Users - And I click View Charlie in grid - And I click "Generate Key" - And I should see "Generate key was successful. New key: " diff --git a/src/Oro/Bundle/WsseAuthenticationBundle/Command/GenerateWsseHeaderCommand.php b/src/Oro/Bundle/WsseAuthenticationBundle/Command/GenerateWsseHeaderCommand.php index 50e27a69f21..b2573a947a1 100644 --- a/src/Oro/Bundle/WsseAuthenticationBundle/Command/GenerateWsseHeaderCommand.php +++ b/src/Oro/Bundle/WsseAuthenticationBundle/Command/GenerateWsseHeaderCommand.php @@ -51,6 +51,10 @@ public function configure() #[\Override] public function execute(InputInterface $input, OutputInterface $output): int { + if ('test' !== $input->getOption('env')) { + throw new \BadMethodCallException('WSSE is deprecated and can be used only in test env.'); + } + $apiKey = $input->getArgument('apiKey'); /** @var UserApi $userApi */ $userApi = $this->registry->getRepository($this->getApiKeyEntityClass())->findOneBy( diff --git a/src/Oro/Bundle/WsseAuthenticationBundle/DependencyInjection/Security/Factory/WsseSecurityAuthenticatorFactory.php b/src/Oro/Bundle/WsseAuthenticationBundle/DependencyInjection/Security/Factory/WsseSecurityAuthenticatorFactory.php index 956f18fd927..321497b1626 100644 --- a/src/Oro/Bundle/WsseAuthenticationBundle/DependencyInjection/Security/Factory/WsseSecurityAuthenticatorFactory.php +++ b/src/Oro/Bundle/WsseAuthenticationBundle/DependencyInjection/Security/Factory/WsseSecurityAuthenticatorFactory.php @@ -55,12 +55,12 @@ public function createAuthenticator( $authenticatorId = self::AUTHENTICATOR . '.' . $firewallName; $container ->setDefinition($authenticatorId, new ChildDefinition(self::AUTHENTICATOR)) - ->replaceArgument(3, new Reference($userProviderId)) - ->replaceArgument(4, new Reference($entryPointId)) - ->replaceArgument(5, $firewallName) - ->replaceArgument(6, new Reference($hasherId)) - ->replaceArgument(7, new Reference($nonceCacheId)) - ->replaceArgument(8, $config['lifetime']); + ->replaceArgument(4, new Reference($userProviderId)) + ->replaceArgument(5, new Reference($entryPointId)) + ->replaceArgument(6, $firewallName) + ->replaceArgument(7, new Reference($hasherId)) + ->replaceArgument(8, new Reference($nonceCacheId)) + ->replaceArgument(9, $config['lifetime']); return $authenticatorId; } @@ -144,8 +144,8 @@ private function createEntryPoint(ContainerBuilder $container, string $firewallN $entryPointId = self::ENTRY_POINT . '.' . $firewallName; $container ->setDefinition($entryPointId, new ChildDefinition(self::ENTRY_POINT)) - ->replaceArgument(1, $config['realm']) - ->replaceArgument(2, $config['profile']); + ->replaceArgument(2, $config['realm']) + ->replaceArgument(3, $config['profile']); return $entryPointId; } diff --git a/src/Oro/Bundle/WsseAuthenticationBundle/Resources/config/services.yml b/src/Oro/Bundle/WsseAuthenticationBundle/Resources/config/services.yml index 7ebe1e55de7..31074065e86 100644 --- a/src/Oro/Bundle/WsseAuthenticationBundle/Resources/config/services.yml +++ b/src/Oro/Bundle/WsseAuthenticationBundle/Resources/config/services.yml @@ -3,6 +3,7 @@ services: class: Oro\Bundle\WsseAuthenticationBundle\Security\Core\Authentication\WsseAuthenticator abstract: true arguments: + - '%kernel.environment%' - '@oro_api.security.authenticator.feature_checker' - '@security.token_storage' - '@oro_wsse_authentication.security.wsse_token_factory' @@ -19,6 +20,7 @@ services: class: Oro\Bundle\WsseAuthenticationBundle\Security\Http\EntryPoint\WsseEntryPoint abstract: true arguments: + - '%kernel.environment%' - '@?logger' - '' - 'UsernameToken' diff --git a/src/Oro/Bundle/WsseAuthenticationBundle/Security/Core/Authentication/WsseAuthenticator.php b/src/Oro/Bundle/WsseAuthenticationBundle/Security/Core/Authentication/WsseAuthenticator.php index 03fd18fb62b..adf43bbed49 100644 --- a/src/Oro/Bundle/WsseAuthenticationBundle/Security/Core/Authentication/WsseAuthenticator.php +++ b/src/Oro/Bundle/WsseAuthenticationBundle/Security/Core/Authentication/WsseAuthenticator.php @@ -39,7 +39,11 @@ class WsseAuthenticator implements AuthenticatorInterface, AuthenticationEntryPo . '(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?0' . '0)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/'; + /** + * @SuppressWarnings(PHPMD.ExcessiveParameterList) + */ public function __construct( + private string $env, private FeatureDependAuthenticatorChecker $featureDependAuthenticatorChecker, private TokenStorageInterface $tokenStorage, private WsseTokenFactoryInterface $wsseTokenFactory, @@ -55,6 +59,10 @@ public function __construct( #[\Override] public function supports(Request $request): ?bool { + if ($this->env !== 'test') { + return false; + } + if (!$this->featureDependAuthenticatorChecker->isEnabled($this, $this->firewallName)) { return false; } diff --git a/src/Oro/Bundle/WsseAuthenticationBundle/Security/Http/EntryPoint/WsseEntryPoint.php b/src/Oro/Bundle/WsseAuthenticationBundle/Security/Http/EntryPoint/WsseEntryPoint.php index 8e484aef38c..7b98d5f9b1f 100644 --- a/src/Oro/Bundle/WsseAuthenticationBundle/Security/Http/EntryPoint/WsseEntryPoint.php +++ b/src/Oro/Bundle/WsseAuthenticationBundle/Security/Http/EntryPoint/WsseEntryPoint.php @@ -3,7 +3,6 @@ namespace Oro\Bundle\WsseAuthenticationBundle\Security\Http\EntryPoint; use Psr\Log\LoggerInterface; -use Psr\Log\NullLogger; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Security\Core\Exception\AuthenticationException; @@ -14,28 +13,21 @@ */ class WsseEntryPoint implements AuthenticationEntryPointInterface { - /** @var LoggerInterface */ - private $logger; - - /** @var string */ - private $realmName; - - /** @var string */ - private $profile; - public function __construct( - ?LoggerInterface $logger = null, - string $realmName = '', - string $profile = 'UsernameToken' + private string $env, + private ?LoggerInterface $logger = null, + private string $realmName = '', + private string $profile = 'UsernameToken' ) { - $this->logger = $logger ?? new NullLogger(); - $this->realmName = $realmName; - $this->profile = $profile; } #[\Override] public function start(Request $request, AuthenticationException $authException = null): Response { + if ($this->env !== 'test') { + return new Response('WSSE is deprecated', 401); + } + if ($authException instanceof AuthenticationException) { $this->logger->warning($authException->getMessage()); } diff --git a/src/Oro/Bundle/WsseAuthenticationBundle/Tests/Unit/DependencyInjection/Security/Factory/WsseSecurityAuthenticatorFactoryTest.php b/src/Oro/Bundle/WsseAuthenticationBundle/Tests/Unit/DependencyInjection/Security/Factory/WsseSecurityAuthenticatorFactoryTest.php index 27a67ea6e51..2f349440284 100644 --- a/src/Oro/Bundle/WsseAuthenticationBundle/Tests/Unit/DependencyInjection/Security/Factory/WsseSecurityAuthenticatorFactoryTest.php +++ b/src/Oro/Bundle/WsseAuthenticationBundle/Tests/Unit/DependencyInjection/Security/Factory/WsseSecurityAuthenticatorFactoryTest.php @@ -51,8 +51,8 @@ public function testCreateAuthenticator(string $firewallName, array $configurati $entriPointDefinition = $container->getDefinition($expectedEntriPointId); self::assertEquals( [ - 'index_1' => $configuration['realm'], - 'index_2' => $configuration['profile'], + 'index_2' => $configuration['realm'], + 'index_3' => $configuration['profile'], ], $entriPointDefinition->getArguments() ); @@ -64,12 +64,12 @@ public function testCreateAuthenticator(string $firewallName, array $configurati $authenticatorDefinition = $container->getDefinition($expectedAuthId); self::assertEquals( [ - 'index_3' => new Reference('user_provider_test'), - 'index_4' => new Reference($expectedEntriPointId), - 'index_5' => $firewallName, - 'index_6' => new Reference($expectedEncoderId), - 'index_7' => new Reference($expectedNonceCacheId), - 'index_8' => $configuration['lifetime'], + 'index_4' => new Reference('user_provider_test'), + 'index_5' => new Reference($expectedEntriPointId), + 'index_6' => $firewallName, + 'index_7' => new Reference($expectedEncoderId), + 'index_8' => new Reference($expectedNonceCacheId), + 'index_9' => $configuration['lifetime'], ], $authenticatorDefinition->getArguments() ); diff --git a/src/Oro/Bundle/WsseAuthenticationBundle/Tests/Unit/Security/Core/Authentication/WsseAuthenticatorTest.php b/src/Oro/Bundle/WsseAuthenticationBundle/Tests/Unit/Security/Core/Authentication/WsseAuthenticatorTest.php index 89e74315e1e..e04121fd9ac 100644 --- a/src/Oro/Bundle/WsseAuthenticationBundle/Tests/Unit/Security/Core/Authentication/WsseAuthenticatorTest.php +++ b/src/Oro/Bundle/WsseAuthenticationBundle/Tests/Unit/Security/Core/Authentication/WsseAuthenticatorTest.php @@ -53,6 +53,7 @@ protected function setUp(): void $cache = new ArrayAdapter(); $this->wsseAuthenticator = new WsseAuthenticator( + 'test', $this->featureDependAuthenticatorChecker, $tokenStorage, $this->wsseTokenFactory, diff --git a/src/Oro/Bundle/WsseAuthenticationBundle/Tests/Unit/Security/Http/EntryPoint/EntryPointTest.php b/src/Oro/Bundle/WsseAuthenticationBundle/Tests/Unit/Security/Http/EntryPoint/EntryPointTest.php index 568a2c262d0..2fc63901229 100644 --- a/src/Oro/Bundle/WsseAuthenticationBundle/Tests/Unit/Security/Http/EntryPoint/EntryPointTest.php +++ b/src/Oro/Bundle/WsseAuthenticationBundle/Tests/Unit/Security/Http/EntryPoint/EntryPointTest.php @@ -27,7 +27,7 @@ protected function setUp(): void $this->logger = $this->createMock(LoggerInterface::class); $this->request = $this->createMock(Request::class); - $this->entryPoint = new WsseEntryPoint($this->logger, self::REALM, self::PROFILE); + $this->entryPoint = new WsseEntryPoint('test', $this->logger, self::REALM, self::PROFILE); } public function testStart(): void diff --git a/src/Oro/Bundle/WsseAuthenticationBundle/Tests/Unit/Security/Http/EntryPoint/WsseEntryPointTest.php b/src/Oro/Bundle/WsseAuthenticationBundle/Tests/Unit/Security/Http/EntryPoint/WsseEntryPointTest.php index 55ee21be25e..5c0eae442be 100644 --- a/src/Oro/Bundle/WsseAuthenticationBundle/Tests/Unit/Security/Http/EntryPoint/WsseEntryPointTest.php +++ b/src/Oro/Bundle/WsseAuthenticationBundle/Tests/Unit/Security/Http/EntryPoint/WsseEntryPointTest.php @@ -26,7 +26,7 @@ protected function setUp(): void { $this->logger = $this->createMock(LoggerInterface::class); $this->request = $this->createMock(Request::class); - $this->entryPoint = new WsseEntryPoint($this->logger, self::REALM_NAME, self::PROFILE); + $this->entryPoint = new WsseEntryPoint('test', $this->logger, self::REALM_NAME, self::PROFILE); } public function testStart(): void