Skip to content

Commit

Permalink
BAP-20198: Disable WSSE functionality (#40234)
Browse files Browse the repository at this point in the history
  • Loading branch information
yurio authored Jan 27, 2025
1 parent 6c18a7e commit 6ddd64c
Show file tree
Hide file tree
Showing 16 changed files with 50 additions and 132 deletions.
2 changes: 0 additions & 2 deletions src/Oro/Bundle/ApiBundle/ApiDoc/Formatter/HtmlFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
40 changes: 0 additions & 40 deletions src/Oro/Bundle/ApiBundle/ApiDoc/SecurityContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
{
Expand Down
10 changes: 0 additions & 10 deletions src/Oro/Bundle/ApiBundle/ApiDoc/SecurityContextInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
31 changes: 3 additions & 28 deletions src/Oro/Bundle/ApiBundle/Resources/views/ApiDoc/motd.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -148,24 +145,6 @@
*/
$('.autogenerated-header', this).remove();
/**
* Add WSSE authentication related headers
*/
if (authType === 'wsse') {
$headers.append(
'<div class="tuple autogenerated-header">' +
'<input type="hidden" class="key" placeholder="Key" value="Authorization">' +
'<input type="hidden" class="value authorization-header" placeholder="Value">' +
'</div>' +
'<div class="tuple autogenerated-header">' +
'<input type="hidden" class="key" placeholder="Key" value="X-WSSE">' +
'<input type="hidden" class="value x-wsse-header" placeholder="Value">' +
'</div>'
);
$('input.authorization-header', this).val('WSSE profile="UsernameToken"');
$('input.x-wsse-header', this).val(wsseHeader(userName, apiKey, serverTimeOffset));
}
/**
* Add Session authentication related headers
*/
Expand Down Expand Up @@ -244,17 +223,13 @@
* Add the authentication type selector
*/
$('#sandbox_configuration').prepend(
(wsseAllowed || !apiKeyGenerationHint ? '' : '<span class="authentication-warning"' +
' title="' + escapeHtmlAttribute(apiKeyGenerationHint) + '"' +
'>{{ include('@OroApi/ApiDoc/warning.svg') }}</span>') +
'authentication: ' +
'<select id="authentication_type">' +
'<option value=""' + (!wsseAllowed && !sessionAllowed ? ' selected=""' : '') + '>None</option>' +
'<option value="wsse"' + (wsseAllowed ? ' selected=""' : ' disabled=""') + '>WSSE</option>' +
'<option value="session"' + (!sessionAllowed ? ' disabled=""' : (!wsseAllowed ? ' selected=""' : '')) + '>Session</option>' +
'<option value=""' + (!sessionAllowed ? ' selected=""' : '') + '>None</option>' +
'<option value="session"' + (!sessionAllowed ? ' disabled="" selected=""' : 'selected="selected"') + '>Session</option>' +
'</select>'
);
if (!wsseAllowed && !sessionAllowed) {
if (!sessionAllowed) {
$('#header').css('background-color', '#f7fe2e');
}
Expand Down
7 changes: 5 additions & 2 deletions src/Oro/Bundle/UserBundle/Controller/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 }),
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -19,6 +20,7 @@ services:
class: Oro\Bundle\WsseAuthenticationBundle\Security\Http\EntryPoint\WsseEntryPoint
abstract: true
arguments:
- '%kernel.environment%'
- '@?logger'
- ''
- 'UsernameToken'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
);
Expand All @@ -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()
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ protected function setUp(): void
$cache = new ArrayAdapter();

$this->wsseAuthenticator = new WsseAuthenticator(
'test',
$this->featureDependAuthenticatorChecker,
$tokenStorage,
$this->wsseTokenFactory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 6ddd64c

Please sign in to comment.