Skip to content

Commit

Permalink
Merge pull request from GHSA-36mj-6r7r-mqhf
Browse files Browse the repository at this point in the history
* IBX-969: Refactored JWT authorization

* IBX-969: Applied review remark

* IBX-969: Updated caught exceptions
  • Loading branch information
barw4 authored Sep 28, 2021
1 parent b8fed91 commit 04c4c56
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 20 deletions.
2 changes: 1 addition & 1 deletion src/bundle/Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,8 @@ services:
EzSystems\EzPlatformRest\Server\Controller\JWT:
parent: ezpublish_rest.controller.base
arguments:
- '@ezpublish.api.service.user'
- '@Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface'
- '@?ezpublish_rest.session_authenticator'
tags: [controller.service_arguments]

ezpublish_rest.request_listener:
Expand Down
52 changes: 33 additions & 19 deletions src/lib/Server/Controller/JWT.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,32 @@

namespace EzSystems\EzPlatformRest\Server\Controller;

use eZ\Publish\API\Repository\Exceptions\NotFoundException;
use eZ\Publish\API\Repository\UserService;
use eZ\Publish\Core\Base\Exceptions\UnauthorizedException;
use eZ\Publish\Core\MVC\Symfony\Security\User;
use eZ\Publish\Core\MVC\Symfony\Security\Authentication\AuthenticatorInterface;
use EzSystems\EzPlatformRest\Message;
use EzSystems\EzPlatformRest\Server\Controller as RestController;
use EzSystems\EzPlatformRest\Server\Values;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\Exception\AuthenticationException;

/**
* @internal
*/
final class JWT extends RestController
{
/** @var \eZ\Publish\API\Repository\UserService */
private $userService;

/** @var \Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface */
private $tokenManager;

/** @var \eZ\Publish\Core\MVC\Symfony\Security\Authentication\AuthenticatorInterface|null */
private $authenticator;

public function __construct(
UserService $userService,
JWTTokenManagerInterface $tokenManager
JWTTokenManagerInterface $tokenManager,
?AuthenticatorInterface $authenticator = null
) {
$this->userService = $userService;
$this->tokenManager = $tokenManager;
$this->authenticator = $authenticator;
}

public function createToken(Request $request): Values\JWT
Expand All @@ -49,15 +47,31 @@ public function createToken(Request $request): Values\JWT
);

try {
$user = $this->userService->loadUserByLogin($jwtTokenInput->username);
if (!$this->userService->checkUserCredentials($user, $jwtTokenInput->password)) {
throw new BadCredentialsException();
}
$token = $this->tokenManager->create(new User($user, ['ROLE_USER']));

return new Values\JWT($token);
} catch (NotFoundException | BadCredentialsException $e) {
throw new UnauthorizedException('Invalid username or password', $request->getPathInfo());
$request->attributes->set('username', $jwtTokenInput->username);
$request->attributes->set('password', (string) $jwtTokenInput->password);

$token = $this->getAuthenticator()->authenticate($request);

$jwtToken = $this->tokenManager->create($token->getUser());

return new Values\JWT($jwtToken);
} catch (AuthenticationException $e) {
$this->getAuthenticator()->logout($request);
throw new UnauthorizedException('Invalid login or password', $request->getPathInfo());
}
}

private function getAuthenticator(): AuthenticatorInterface
{
if (null === $this->authenticator) {
throw new \RuntimeException(
sprintf(
"No %s instance injected. Ensure 'ezpublish_rest_session' is configured under your firewall",
AuthenticatorInterface::class
)
);
}

return $this->authenticator;
}
}

0 comments on commit 04c4c56

Please sign in to comment.