Skip to content

Commit

Permalink
cleanup JWTProvider, added and updated tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Nicolas Cabot committed Jul 12, 2014
1 parent d7e7c46 commit 1dce62e
Show file tree
Hide file tree
Showing 13 changed files with 237 additions and 42 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
phpunit.xml
build
vendor
composer.lock
composer.phar
4 changes: 2 additions & 2 deletions Encoder/JWTEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ public function __construct($privateKey, $publicKey, $passPhrase)
/**
* @param array $data
*
* @return JWS
* @return string the token
*/
public function encode(array $data)
{
$jws = new JWS('RS256');
$jws->setPayload($data);
$jws->sign($this->getPrivateKey());

return $jws;
return $jws->getTokenString();
}

/**
Expand Down
26 changes: 21 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,15 +174,31 @@ lexik_jwt_authentication:
In your functional tests, create an authenticated client :

``` php
protected function createAuthenticatedClient($username = '[email protected]')
/**
* Create a client with a default Authorization header.
*
* @param string $username
* @param string $password
*
* @return \Symfony\Bundle\FrameworkBundle\Client
*/
protected function createAuthenticatedClient($username = 'user', $password = 'password')
{
$client = static::createClient();
$client->request(
'POST',
'/login_check',
array(
'username' => $username,
'password' => $password,
)
);
$jwt = $client->getContainer()->get('lexik_jwt_authentication.jwt_encoder')->encode([
'username' => $username,
]);
$response = $client->getResponse();
$data = json_decode($response->getContent(), true);
$client->setServerParameter('HTTP_Authorization', sprintf('Bearer %s', $jwt->getTokenString()));
$client = static::createClient();
$client->setServerParameter('HTTP_Authorization', sprintf('Bearer %s', $data['token']));
return $client;
}
Expand Down
10 changes: 2 additions & 8 deletions Security/Authentication/Provider/JWTProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,11 @@ public function authenticate(TokenInterface $token)
{
$payload = $this->jwtManager->decode($token);

if (!$payload) {
if (!$payload || !isset($payload['username'])) {
throw new AuthenticationException('Invalid JWT Token');
}

if (!isset($payload['username'])) {
throw new AuthenticationException('No username found in token.');
}

if (!($user = $this->userProvider->loadUserByUsername($payload['username']))) {
throw new AuthenticationException('User "' . $payload['username'] . '" could not be found.');
}
$user = $this->userProvider->loadUserByUsername($payload['username']);

$authToken = new JWTUserToken($user->getRoles());
$authToken->setUser($user);
Expand Down
2 changes: 2 additions & 0 deletions Security/Http/Authentication/AuthenticationSuccessHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ public function onAuthenticationSuccess(Request $request, TokenInterface $token)
$user = $token->getUser();
$jwt = $this->jwtManager->create($user);

// todo : move that dispatch to the jwt manager

$event = new AuthenticationSuccessEvent(array('token' => $jwt), $user, $request);
$this->dispatcher->dispatch(Events::AUTHENTICATION_SUCCESS, $event);

Expand Down
5 changes: 1 addition & 4 deletions Services/JWTManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,7 @@ public function create(UserInterface $user)
$event = new JWTCreatedEvent($payload, $user, $this->request);
$this->dispatcher->dispatch(Events::JWT_CREATED, $event);

return $this
->jwtEncoder
->encode($event->getData())
->getTokenString();
return $this->jwtEncoder->encode($event->getData());
}

/**
Expand Down
2 changes: 1 addition & 1 deletion Tests/Security/Authentication/Firewall/JWTListenerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,4 @@ protected function getEvent()

return $event;
}
}
}
88 changes: 83 additions & 5 deletions Tests/Security/Authentication/Provider/JWTProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Lexik\Bundle\JWTAuthenticationBundle\Security\Authentication\Provider\JWTProvider;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;

/**
* JWTProviderTest
Expand All @@ -17,7 +18,7 @@ class JWTProviderTest extends \PHPUnit_Framework_TestCase
*/
public function testSupports()
{
$provider = new JWTProvider($this->getUserProviderMock(), $this->getJWTEncoderMock());
$provider = new JWTProvider($this->getUserProviderMock(), $this->getJWTManagerMock());

/** @var TokenInterface $usernamePasswordToken */
$usernamePasswordToken = $this
Expand All @@ -38,17 +39,81 @@ public function testSupports()

/**
* test authenticate method
*
* @expectedException Symfony\Component\Security\Core\Exception\AuthenticationException
*/
public function testAuthenticate()
public function testAuthenticateWithInvalidJWT()
{
/** @var TokenInterface $jwtUserToken */
$jwtUserToken = $this
->getMockBuilder('Lexik\Bundle\JWTAuthenticationBundle\Security\Authentication\Token\JWTUserToken')
->disableOriginalConstructor()
->getMock();

$userProvider = $this->getUserProviderMock();

$jwtManager = $this->getJWTManagerMock();
$jwtManager->expects($this->any())->method('decode')->will($this->returnValue(false));

$provider = new JWTProvider($userProvider, $jwtManager);
$provider->authenticate($jwtUserToken);
}

/**
* test authenticate method
*
* @expectedException Symfony\Component\Security\Core\Exception\AuthenticationException
*/
public function testAuthenticateWithoutUsername()
{
/** @var TokenInterface $jwtUserToken */
$jwtUserToken = $this
->getMockBuilder('Lexik\Bundle\JWTAuthenticationBundle\Security\Authentication\Token\JWTUserToken')
->disableOriginalConstructor()
->getMock();

$jwtEncoder = $this->getJWTEncoderMock();
$jwtEncoder->expects($this->any())->method('decode')->will($this->returnValue(array('username' => 'user')));
$userProvider = $this->getUserProviderMock();

$jwtManager = $this->getJWTManagerMock();
$jwtManager->expects($this->any())->method('decode')->will($this->returnValue(array('foo' => 'bar')));

$provider = new JWTProvider($userProvider, $jwtManager);
$provider->authenticate($jwtUserToken);
}

/**
* test authenticate method
*
* @expectedException Symfony\Component\Security\Core\Exception\UsernameNotFoundException
*/
public function testAuthenticateWithNotExistingUser()
{
/** @var TokenInterface $jwtUserToken */
$jwtUserToken = $this
->getMockBuilder('Lexik\Bundle\JWTAuthenticationBundle\Security\Authentication\Token\JWTUserToken')
->disableOriginalConstructor()
->getMock();

$userProvider = $this->getUserProviderMock();
$userProvider->expects($this->any())->method('loadUserByUsername')->willThrowException(new UsernameNotFoundException());

$jwtManager = $this->getJWTManagerMock();
$jwtManager->expects($this->any())->method('decode')->will($this->returnValue(array('username' => 'user')));

$provider = new JWTProvider($userProvider, $jwtManager);
$provider->authenticate($jwtUserToken);
}

/**
* test authenticate method
*/
public function testAuthenticate()
{
/** @var TokenInterface $jwtUserToken */
$jwtUserToken = $this
->getMockBuilder('Lexik\Bundle\JWTAuthenticationBundle\Security\Authentication\Token\JWTUserToken')
->disableOriginalConstructor()
->getMock();

$user = $this
->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')
Expand All @@ -59,14 +124,27 @@ public function testAuthenticate()
$userProvider = $this->getUserProviderMock();
$userProvider->expects($this->any())->method('loadUserByUsername')->will($this->returnValue($user));

$provider = new JWTProvider($userProvider, $jwtEncoder);
$jwtManager = $this->getJWTManagerMock();
$jwtManager->expects($this->any())->method('decode')->will($this->returnValue(array('username' => 'user')));

$provider = new JWTProvider($userProvider, $jwtManager);

$this->assertInstanceOf(
'Lexik\Bundle\JWTAuthenticationBundle\Security\Authentication\Token\JWTUserToken',
$provider->authenticate($jwtUserToken)
);
}

/**
* @return \PHPUnit_Framework_MockObject_MockObject
*/
protected function getJWTManagerMock()
{
return $this->getMockBuilder('Lexik\Bundle\JWTAuthenticationBundle\Services\JWTManager')
->disableOriginalConstructor()
->getMock();
}

/**
* @return \PHPUnit_Framework_MockObject_MockObject
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Lexik\Bundle\JWTAuthenticationBundle\Tests\Security\Http\Authentication;

use Lexik\Bundle\JWTAuthenticationBundle\Events;
use Lexik\Bundle\JWTAuthenticationBundle\Security\Http\Authentication\AuthenticationSuccessHandler;

/**
Expand All @@ -25,38 +26,36 @@ public function testOnAuthenticationSuccess()

$content = json_decode($response->getContent(), true);
$this->assertArrayHasKey('token', $content);
$this->assertEquals('tokenstring', $content['token']);
$this->assertEquals('secrettoken', $content['token']);
}

/**
* @return AuthenticationSuccessHandler
*/
protected function getHandler()
{
$jws = $this
->getMockBuilder('Namshi\JOSE\JWS')
$jwtManager = $this->getMockBuilder('Lexik\Bundle\JWTAuthenticationBundle\Services\JWTManager')
->disableOriginalConstructor()
->getMock();

$jws
->expects($this->any())
->method('getTokenString')
->will($this->returnValue('tokenstring'));

$creator = $this->getMockBuilder('Lexik\Bundle\JWTAuthenticationBundle\Services\JWTCreator')
->disableOriginalConstructor()
->getMock();

$creator
$jwtManager
->expects($this->any())
->method('create')
->will($this->returnValue($jws->getTokenString()));
->will($this->returnValue('secrettoken'));

$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher')
->disableOriginalConstructor()
->getMock();

return new AuthenticationSuccessHandler($creator, $dispatcher);
$dispatcher
->expects($this->once())
->method('dispatch')
->with(
$this->equalTo(Events::AUTHENTICATION_SUCCESS),
$this->isInstanceOf('Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationSuccessEvent')
);

return new AuthenticationSuccessHandler($jwtManager, $dispatcher);
}

/**
Expand Down
3 changes: 1 addition & 2 deletions Tests/Security/Http/EntryPoint/JWTEntryPointTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

/**
* JWTEntryPointTest
*
* @author Jérémie Augustin <[email protected]>
*/
class JWTEntryPointTest extends \PHPUnit_Framework_TestCase
Expand All @@ -15,11 +16,9 @@ class JWTEntryPointTest extends \PHPUnit_Framework_TestCase
public function testStart()
{
$entryPoint = new JWTEntryPoint();

$this->assertInstanceOf('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface', $entryPoint);

$response = $entryPoint->start($this->getRequest());

$this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $response);
$this->assertEquals(401, $response->getStatusCode(), 'status code should be 401');
}
Expand Down
Loading

0 comments on commit 1dce62e

Please sign in to comment.