Skip to content

Commit

Permalink
Merge pull request FriendsOfSymfony#137 from Koc/add-provider-key-to-…
Browse files Browse the repository at this point in the history
…authentication-provider

Add provider key to authentication provider
  • Loading branch information
stof committed Apr 17, 2012
2 parents f20178a + 69dfa94 commit e78236d
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 33 deletions.
16 changes: 8 additions & 8 deletions DependencyInjection/Security/Factory/FacebookFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,22 @@ protected function getListenerId()

protected function createAuthProvider(ContainerBuilder $container, $id, $config, $userProviderId)
{
$authProviderId = 'fos_facebook.auth.'.$id;

$definition = $container
->setDefinition($authProviderId, new DefinitionDecorator('fos_facebook.auth'))
->replaceArgument(0, $id);

// with user provider
if (isset($config['provider'])) {
$authProviderId = 'fos_facebook.auth.'.$id;

$container
->setDefinition($authProviderId, new DefinitionDecorator('fos_facebook.auth'))
$definition
->addArgument(new Reference($userProviderId))
->addArgument(new Reference('security.user_checker'))
->addArgument($config['create_user_if_not_exists'])
;

return $authProviderId;
}

// without user provider
return 'fos_facebook.auth';
return $authProviderId;
}

protected function createEntryPoint($container, $id, $config, $defaultEntryPointId)
Expand Down
3 changes: 2 additions & 1 deletion Resources/config/security.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@

<services>
<service id="fos_facebook.auth" class="FOS\FacebookBundle\Security\Authentication\Provider\FacebookProvider" public="false">
<argument /> <!-- Provider-shared Key -->
<argument type="service" id="fos_facebook.api" />
</service>

<service id="fos_facebook.logout_handler" class="FOS\FacebookBundle\Security\Logout\FacebookHandler" public="false">
<argument type="service" id="fos_facebook.api" />
</service>
Expand Down
12 changes: 7 additions & 5 deletions Security/Authentication/Provider/FacebookProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@ class FacebookProvider implements AuthenticationProviderInterface
* @var \BaseFacebook
*/
protected $facebook;
protected $providerKey;
protected $userProvider;
protected $userChecker;
protected $createIfNotExists;

public function __construct(\BaseFacebook $facebook, UserProviderInterface $userProvider = null, UserCheckerInterface $userChecker = null, $createIfNotExists = false)
public function __construct($providerKey, \BaseFacebook $facebook, UserProviderInterface $userProvider = null, UserCheckerInterface $userChecker = null, $createIfNotExists = false)
{
if (null !== $userProvider && null === $userChecker) {
throw new \InvalidArgumentException('$userChecker cannot be null, if $userProvider is not null.');
Expand All @@ -44,6 +45,7 @@ public function __construct(\BaseFacebook $facebook, UserProviderInterface $user
throw new \InvalidArgumentException('The $userProvider must implement UserManagerInterface if $createIfNotExists is true.');
}

$this->providerKey = $providerKey;
$this->facebook = $facebook;
$this->userProvider = $userProvider;
$this->userChecker = $userChecker;
Expand All @@ -60,7 +62,7 @@ public function authenticate(TokenInterface $token)
if ($user instanceof UserInterface) {
$this->userChecker->checkPostAuth($user);

$newToken = new FacebookUserToken($user, $user->getRoles());
$newToken = new FacebookUserToken($this->providerKey, $user, $user->getRoles());
$newToken->setAttributes($token->getAttributes());

return $newToken;
Expand All @@ -84,13 +86,13 @@ public function authenticate(TokenInterface $token)

public function supports(TokenInterface $token)
{
return $token instanceof FacebookUserToken;
return $token instanceof FacebookUserToken && $this->providerKey === $token->getProviderKey();
}

protected function createAuthenticatedToken($uid)
{
if (null === $this->userProvider) {
return new FacebookUserToken($uid);
return new FacebookUserToken($this->providerKey, $uid);
}

try {
Expand All @@ -108,6 +110,6 @@ protected function createAuthenticatedToken($uid)
throw new \RuntimeException('User provider did not return an implementation of user interface.');
}

return new FacebookUserToken($user, $user->getRoles());
return new FacebookUserToken($this->providerKey, $user, $user->getRoles());
}
}
22 changes: 21 additions & 1 deletion Security/Authentication/Token/FacebookUserToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@

class FacebookUserToken extends AbstractToken
{
public function __construct($uid = '', array $roles = array())
private $providerKey;

public function __construct($providerKey, $uid = '', array $roles = array())
{
parent::__construct($roles);

Expand All @@ -24,10 +26,28 @@ public function __construct($uid = '', array $roles = array())
if (!empty($uid)) {
$this->setAuthenticated(true);
}

$this->providerKey = $providerKey;
}

public function getCredentials()
{
return '';
}

public function getProviderKey()
{
return $this->providerKey;
}

public function serialize()
{
return serialize(array($this->providerKey, parent::serialize()));
}

public function unserialize($str)
{
list($this->providerKey, $parentStr) = unserialize($str);
parent::unserialize($parentStr);
}
}
2 changes: 1 addition & 1 deletion Security/Firewall/FacebookListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ class FacebookListener extends AbstractAuthenticationListener
{
protected function attemptAuthentication(Request $request)
{
return $this->authenticationManager->authenticate(new FacebookUserToken());
return $this->authenticationManager->authenticate(new FacebookUserToken($this->providerKey));
}
}
20 changes: 16 additions & 4 deletions Tests/DependencyInjection/Security/Factory/FacebookFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,22 @@ public function testThatCreateUserAuthProviderWhenDefinedInConfig()
/**
* @covers FOS\FacebookBundle\DependencyInjection\Security\Factory\FacebookFactory::createAuthProvider
*/
public function testThatDoNotCreateUserAuthProviderWhenNotDefinedInConfig()
public function testThatCreateUserAuthProviderEvenWhenNotDefinedInConfig()
{
$idsArray = $this->facebookFactoryCreate(array('remember_me' => false));
$this->assertEquals('fos_facebook.auth', $idsArray[0]);
$this->assertEquals('fos_facebook.auth.l3l0', $idsArray[0]);
}

/**
* @covers FOS\FacebookBundle\DependencyInjection\Security\Factory\FacebookFactory::createAuthProvider
*/
public function testThatCreateDifferentUserAuthProviderForDifferentFirewalls()
{
$idsArray = $this->facebookFactoryCreate(array('remember_me' => false));
$this->assertEquals('fos_facebook.auth.l3l0', $idsArray[0]);

$idsArray = $this->facebookFactoryCreate(array('remember_me' => false), 'main');
$this->assertEquals('fos_facebook.auth.main', $idsArray[0]);
}

/**
Expand All @@ -75,7 +87,7 @@ public function testThatListenerForListenerId()
* @param array $config
* @return array
*/
private function facebookFactoryCreate($config = array())
private function facebookFactoryCreate($config = array(), $id = 'l3l0')
{
$definition = $this->getMock('Symfony\Component\DependencyInjection\Definition', array('addArgument', 'replaceArgument'));
$definition->expects($this->any())
Expand All @@ -89,6 +101,6 @@ private function facebookFactoryCreate($config = array())
->method('setDefinition')
->will($this->returnValue($definition));

return $this->factory->create($container, 'l3l0', $config, 'l3l0.user.provider', null);
return $this->factory->create($container, $id, $config, 'l3l0.user.provider', null);
}
}
73 changes: 61 additions & 12 deletions Tests/Security/Authentication/Provider/FacebookProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,35 +21,63 @@ class FacebookProviderTest extends \PHPUnit_Framework_TestCase
*/
public function testThatUserCheckerCannotBeNullWhenUserProviderIsNotNull()
{
$facebookProvider = new FacebookProvider($this->getMock('\BaseFacebook'), $this->getMock('Symfony\Component\Security\Core\User\UserProviderInterface'));
$facebookProvider = new FacebookProvider('main', $this->getMock('\BaseFacebook'), $this->getMock('Symfony\Component\Security\Core\User\UserProviderInterface'));
}

/**
* @covers FOS\FacebookBundle\Security\Authentication\Provider\FacebookProvider::authenticate
*/
public function testThatCannotAuthenticateWhenTokenIsNotFacebookUserToken()
{
$facebookProvider = new FacebookProvider($this->getMock('\BaseFacebook'));
$facebookProvider = new FacebookProvider('main', $this->getMock('\BaseFacebook'));
$this->assertNull($facebookProvider->authenticate($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')));
}

/**
* @covers FOS\FacebookBundle\Security\Authentication\Provider\FacebookProvider::authenticate
* @covers FOS\FacebookBundle\Security\Authentication\Provider\FacebookProvider::supports
*/
public function testThatCannotAuthenticateWhenTokenFromOtherFirewall()
{
$providerKeyForProvider = 'main';
$providerKeyForToken = 'connect';

$facebookProvider = new FacebookProvider($providerKeyForProvider, $this->getMock('\BaseFacebook'));

$tokenMock = $this->getMock('FOS\FacebookBundle\Security\Authentication\Token\FacebookUserToken', array('getProviderKey'), array($providerKeyForToken));
$tokenMock->expects($this->any())
->method('getProviderKey')
->will($this->returnValue($providerKeyForToken));

$this->assertFalse($facebookProvider->supports($tokenMock));
$this->assertNull($facebookProvider->authenticate($tokenMock));
}

/**
* @covers FOS\FacebookBundle\Security\Authentication\Provider\FacebookProvider::authenticate
* @covers FOS\FacebookBundle\Security\Authentication\Provider\FacebookProvider::supports
* @covers FOS\FacebookBundle\Security\Authentication\Provider\FacebookProvider::createAuthenticatedToken
*/
public function testThatCanAuthenticateUserWithoutUserProvider()
{
$providerKey = 'main';

$facebookMock = $this->getMock('\BaseFacebook', array('getUser'));
$facebookMock->expects($this->once())
->method('getUser')
->will($this->returnValue('123'));

$facebookProvider = new FacebookProvider($facebookMock);
$tokenMock = $this->getMock('FOS\FacebookBundle\Security\Authentication\Token\FacebookUserToken');
$facebookProvider = new FacebookProvider($providerKey, $facebookMock);

$tokenMock = $this->getMock('FOS\FacebookBundle\Security\Authentication\Token\FacebookUserToken', array('getAttributes', 'getProviderKey'), array($providerKey));
$tokenMock->expects($this->once())
->method('getAttributes')
->will($this->returnValue(array()));
$tokenMock->expects($this->any())
->method('getProviderKey')
->will($this->returnValue($providerKey));

$this->assertTrue($facebookProvider->supports($tokenMock));
$this->assertEquals('123', $facebookProvider->authenticate($tokenMock)->getUser());
}

Expand All @@ -58,6 +86,8 @@ public function testThatCanAuthenticateUserWithoutUserProvider()
*/
public function testThatCannotAuthenticateWhenUserProviderThrowsAuthenticationException()
{
$providerKey = 'main';

$facebookMock = $this->getMock('\BaseFacebook', array('getUser'));
$facebookMock->expects($this->once())
->method('getUser')
Expand All @@ -70,9 +100,12 @@ public function testThatCannotAuthenticateWhenUserProviderThrowsAuthenticationEx
->will($this->throwException(new AuthenticationException('test')));

$userCheckerMock = $this->getMock('Symfony\Component\Security\Core\User\UserCheckerInterface');
$tokenMock = $this->getMock('FOS\FacebookBundle\Security\Authentication\Token\FacebookUserToken');
$tokenMock = $this->getMock('FOS\FacebookBundle\Security\Authentication\Token\FacebookUserToken', array('getProviderKey'), array($providerKey));
$tokenMock->expects($this->any())
->method('getProviderKey')
->will($this->returnValue($providerKey));

$facebookProvider = new FacebookProvider($facebookMock, $userProviderMock, $userCheckerMock);
$facebookProvider = new FacebookProvider($providerKey, $facebookMock, $userProviderMock, $userCheckerMock);
$facebookProvider->authenticate($tokenMock);
}

Expand All @@ -81,6 +114,8 @@ public function testThatCannotAuthenticateWhenUserProviderThrowsAuthenticationEx
*/
public function testThatCannotAuthenticateWhenUserProviderDoesNotReturnUsetInterface()
{
$providerKey = 'main';

$facebookMock = $this->getMock('\BaseFacebook', array('getUser'));
$facebookMock->expects($this->once())
->method('getUser')
Expand All @@ -93,9 +128,12 @@ public function testThatCannotAuthenticateWhenUserProviderDoesNotReturnUsetInter
->will($this->returnValue('234'));

$userCheckerMock = $this->getMock('Symfony\Component\Security\Core\User\UserCheckerInterface');
$tokenMock = $this->getMock('FOS\FacebookBundle\Security\Authentication\Token\FacebookUserToken');
$tokenMock = $this->getMock('FOS\FacebookBundle\Security\Authentication\Token\FacebookUserToken', array('getProviderKey'), array($providerKey));
$tokenMock->expects($this->any())
->method('getProviderKey')
->will($this->returnValue($providerKey));

$facebookProvider = new FacebookProvider($facebookMock, $userProviderMock, $userCheckerMock);
$facebookProvider = new FacebookProvider($providerKey, $facebookMock, $userProviderMock, $userCheckerMock);
$facebookProvider->authenticate($tokenMock);
}

Expand All @@ -104,16 +142,22 @@ public function testThatCannotAuthenticateWhenUserProviderDoesNotReturnUsetInter
*/
public function testThatCannotAuthenticateWhenCannotRetrieveFacebookUserFromSession()
{
$providerKey = 'main';

$facebookMock = $this->getMock('\BaseFacebook', array('getUser'));
$facebookMock->expects($this->once())
->method('getUser')
->will($this->returnValue(false));

$userProviderMock = $this->getMock('Symfony\Component\Security\Core\User\UserProviderInterface');
$userCheckerMock = $this->getMock('Symfony\Component\Security\Core\User\UserCheckerInterface');
$tokenMock = $this->getMock('FOS\FacebookBundle\Security\Authentication\Token\FacebookUserToken');

$facebookProvider = new FacebookProvider($facebookMock, $userProviderMock, $userCheckerMock);
$tokenMock = $this->getMock('FOS\FacebookBundle\Security\Authentication\Token\FacebookUserToken', array('getProviderKey'), array($providerKey));
$tokenMock->expects($this->any())
->method('getProviderKey')
->will($this->returnValue($providerKey));

$facebookProvider = new FacebookProvider($providerKey, $facebookMock, $userProviderMock, $userCheckerMock);
$facebookProvider->authenticate($tokenMock);
}

Expand All @@ -123,6 +167,8 @@ public function testThatCannotAuthenticateWhenCannotRetrieveFacebookUserFromSess
*/
public function testThatCanAutenticateUsingUserProvider()
{
$providerKey = 'main';

$userMock = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
$userMock->expects($this->once())
->method('getUsername')
Expand All @@ -146,12 +192,15 @@ public function testThatCanAutenticateUsingUserProvider()
$userCheckerMock->expects($this->once())
->method('checkPostAuth');

$tokenMock = $this->getMock('FOS\FacebookBundle\Security\Authentication\Token\FacebookUserToken');
$tokenMock = $this->getMock('FOS\FacebookBundle\Security\Authentication\Token\FacebookUserToken', array('getAttributes', 'getProviderKey'), array($providerKey));
$tokenMock->expects($this->once())
->method('getAttributes')
->will($this->returnValue(array()));
$tokenMock->expects($this->any())
->method('getProviderKey')
->will($this->returnValue($providerKey));

$facebookProvider = new FacebookProvider($facebookMock, $userProviderMock, $userCheckerMock);
$facebookProvider = new FacebookProvider($providerKey, $facebookMock, $userProviderMock, $userCheckerMock);
$this->assertEquals('l3l0', $facebookProvider->authenticate($tokenMock)->getUsername());
}
}
10 changes: 9 additions & 1 deletion Tests/Security/Authentication/Token/FacebookUserTokenTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class FacebookUserTokenTest extends \PHPUnit_Framework_TestCase
*/
public function testThatAlwaysReturnEmptyCredentials($uid, $roles)
{
$token = new FacebookUserToken($uid, $roles);
$token = new FacebookUserToken('main', $uid, $roles);

$this->assertEquals('', $token->getCredentials());
}
Expand All @@ -37,4 +37,12 @@ public static function provider()
array('l3l0', array('role1', 'role2'))
);
}

public function testThatProviderKeyIsNotEmptyAfterDeserialization()
{
$providerKey = 'main';
$token = unserialize(serialize(new FacebookUserToken($providerKey)));

$this->assertEquals($providerKey, $token->getProviderKey());
}
}

0 comments on commit e78236d

Please sign in to comment.