Skip to content

Commit

Permalink
Replace custom authenticator passport with custom badge usage (#1976)
Browse files Browse the repository at this point in the history
  • Loading branch information
stloyd committed Feb 16, 2024
1 parent 30e3f0e commit b54e42b
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 67 deletions.
25 changes: 19 additions & 6 deletions src/Security/Http/Authenticator/OAuthAuthenticator.php
Expand Up @@ -16,7 +16,7 @@
use HWI\Bundle\OAuthBundle\Security\Core\Authentication\Token\OAuthToken;
use HWI\Bundle\OAuthBundle\Security\Core\Exception\OAuthAwareExceptionInterface;
use HWI\Bundle\OAuthBundle\Security\Core\User\OAuthAwareUserProviderInterface;
use HWI\Bundle\OAuthBundle\Security\Http\Authenticator\Passport\SelfValidatedOAuthPassport;
use HWI\Bundle\OAuthBundle\Security\Http\Authenticator\Passport\Badge\OAuthTokenBadge;
use HWI\Bundle\OAuthBundle\Security\Http\ResourceOwnerMapInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
Expand All @@ -32,7 +32,9 @@
use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
use Symfony\Component\Security\Http\Authenticator\InteractiveAuthenticatorInterface;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\RememberMeBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
use Symfony\Component\Security\Http\HttpUtils;

Expand Down Expand Up @@ -139,8 +141,18 @@ public function authenticate(Request $request): Passport

$token = new OAuthToken($accessToken);
$token->setResourceOwnerName($resourceOwner->getName());
$token = $this->refreshToken($token);

return new SelfValidatedOAuthPassport($this->refreshToken($token), [new RememberMeBadge()]);
$user = $token->getUser();

$userBadge = class_exists(UserBadge::class)
? new UserBadge(
$user ? method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername() : null,
static function () use ($user) { return $user; }
)
: $user;

return new SelfValidatingPassport($userBadge, [new RememberMeBadge(), new OAuthTokenBadge($token)]);
}

/**
Expand Down Expand Up @@ -246,15 +258,16 @@ public function createToken(Passport $passport, string $firewallName): TokenInte
}

/**
* @param Passport|SelfValidatedOAuthPassport $passport
* @param Passport $passport
*/
public function createAuthenticatedToken($passport, string $firewallName): TokenInterface
{
if ($passport instanceof SelfValidatedOAuthPassport) {
return $passport->getToken();
$badge = $passport->getBadge(OAuthTokenBadge::class);
if ($badge instanceof OAuthTokenBadge) {
return $badge->getToken();
}

throw new \LogicException(sprintf('The first argument of "%s" must be instance of "%s", "%s" provided.', __METHOD__, SelfValidatedOAuthPassport::class, $passport::class));
throw new \LogicException(sprintf('Given passport must contain instance of "%s".', OAuthTokenBadge::class));
}

public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
Expand Down
37 changes: 37 additions & 0 deletions src/Security/Http/Authenticator/Passport/Badge/OAuthTokenBadge.php
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

/*
* This file is part of the HWIOAuthBundle package.
*
* (c) Hardware Info <opensource@hardware.info>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace HWI\Bundle\OAuthBundle\Security\Http\Authenticator\Passport\Badge;

use HWI\Bundle\OAuthBundle\Security\Core\Authentication\Token\OAuthToken;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\BadgeInterface;

final class OAuthTokenBadge implements BadgeInterface
{
private OAuthToken $token;

public function __construct(OAuthToken $token)
{
$this->token = $token;
}

public function isResolved(): bool
{
return true;
}

public function getToken(): OAuthToken
{
return $this->token;
}
}

This file was deleted.

11 changes: 1 addition & 10 deletions tests/Security/Http/Authenticator/OAuthAuthenticatorTest.php
Expand Up @@ -31,7 +31,6 @@
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
use Symfony\Component\Security\Http\HttpUtils;

Expand All @@ -40,14 +39,6 @@
*/
final class OAuthAuthenticatorTest extends TestCase
{
protected function setUp(): void
{
// Symfony < 5.1 BC layer.
if (!interface_exists(AuthenticatorInterface::class)) {
$this->markTestSkipped('Symfony new Authenticator-based security system is not available.');
}
}

public function testSupports(): void
{
$httpUtilsMock = $this->getHttpUtilsMock();
Expand Down Expand Up @@ -162,7 +153,7 @@ public function testAuthenticate(): void
$this->assertEquals($user, $passport->getUser());

/** @var AbstractOAuthToken $token */
$token = $authenticator->createAuthenticatedToken($passport, 'main');
$token = $authenticator->createToken($passport, 'main');
$this->assertInstanceOf(OAuthToken::class, $token);
$this->assertEquals($resourceOwnerName, $token->getResourceOwnerName());
$this->assertEquals($user, $token->getUser());
Expand Down

0 comments on commit b54e42b

Please sign in to comment.