Skip to content

Commit

Permalink
Merge pull request #72 from thewilkybarkid/user-provider
Browse files Browse the repository at this point in the history
Add simple user provider
  • Loading branch information
weaverryan authored Jan 8, 2018
2 parents 463e9d4 + 3abd308 commit d71a55f
Show file tree
Hide file tree
Showing 6 changed files with 226 additions and 0 deletions.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,28 @@ ciricular reference issues and degrades performance (because autheticators are i
on every request, even though you *rarely* need the `FacebookClient` to be created).
The `ClientRegistry` lazily creates the client objects.

### Authenticating any OAuth user

If you don't need to fetch/persist any information about the user, you can use the `OAuthUserProvider` service to quickly authenticate them into your application.

Firstly define the user provider in your `security.yml` file:

```yml
security:
providers:
oauth:
id: knpu.oauth2.user_provider
```

Then in your Guard authenticator use the user provider to log the user in to your application:

```php
public function getUser($credentials, UserProviderInterface $userProvider) : UserInterface
{
return $userProvider->loadUserByUsername($this->getClient()->fetchUserFromToken($credentials)->getId());
}
```

## Configuration

Below is the configuration for *all* of the supported OAuth2 providers.
Expand Down
2 changes: 2 additions & 0 deletions src/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
<argument type="service" id="service_container" />
<argument /> <!-- argument added dynamically -->
</service>

<service id="knpu.oauth2.user_provider" class="KnpU\OAuth2ClientBundle\Security\User\OAuthUserProvider" public="false" />

<!-- Add service alias for autowiring -->
<service id="KnpU\OAuth2ClientBundle\Client\ClientRegistry" alias="knpu.oauth2.registry" public="false" />
Expand Down
50 changes: 50 additions & 0 deletions src/Security/User/OAuthUser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

/*
* OAuth2 Client Bundle
* Copyright (c) KnpUniversity <http://knpuniversity.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace KnpU\OAuth2ClientBundle\Security\User;

use Symfony\Component\Security\Core\User\UserInterface;

class OAuthUser implements UserInterface
{
private $username;
private $roles;

public function __construct($username, array $roles)
{
$this->username = $username;
$this->roles = $roles;
}

public function getRoles()
{
return $this->roles;
}

public function getPassword()
{
return '';
}

public function getSalt()
{
return null;
}

public function getUsername()
{
return $this->username;
}

public function eraseCredentials()
{
// Do nothing.
}
}
44 changes: 44 additions & 0 deletions src/Security/User/OAuthUserProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

/*
* OAuth2 Client Bundle
* Copyright (c) KnpUniversity <http://knpuniversity.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace KnpU\OAuth2ClientBundle\Security\User;

use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;

class OAuthUserProvider implements UserProviderInterface
{
private $roles;

public function __construct(array $roles = ['ROLE_USER', 'ROLE_OAUTH_USER'])
{
$this->roles = $roles;
}

public function loadUserByUsername($username)
{
return new OAuthUser($username, $this->roles);
}

public function refreshUser(UserInterface $user)
{
if (!$user instanceof OAuthUser) {
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));
}

return $this->loadUserByUsername($user->getUsername());
}

public function supportsClass($class)
{
return OAuthUser::class === $class;
}
}
64 changes: 64 additions & 0 deletions tests/Security/User/OAuthUserProviderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

/*
* OAuth2 Client Bundle
* Copyright (c) KnpUniversity <http://knpuniversity.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace KnpU\OAuth2ClientBundle\Tests\Security\User;

use KnpU\OAuth2ClientBundle\Security\User\OAuthUser;
use KnpU\OAuth2ClientBundle\Security\User\OAuthUserProvider;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\User\User;
use Symfony\Component\Security\Core\User\UserInterface;

class OAuthUserProviderTest extends \PHPUnit_Framework_TestCase
{
public function testLoadUserByUsername()
{
$userProvider = new OAuthUserProvider(['role 1', 'role 2']);

$expected = new OAuthUser('username', ['role 1', 'role 2']);

$this->assertEquals($expected, $userProvider->loadUserByUsername('username'));
}

public function testRefreshUser()
{
$userProvider = new OAuthUserProvider(['role 1', 'role 2']);

$user = new OAuthUser('username', ['role 3']);
$expected = new OAuthUser('username', ['role 1', 'role 2']);

$this->assertEquals($expected, $userProvider->refreshUser($user));
}

public function testRefreshOtherUser()
{
$userProvider = new OAuthUserProvider();

$this->setExpectedException(UnsupportedUserException::class);

$userProvider->refreshUser($this->getMock(UserInterface::class));
}

/**
* @dataProvider supportsClassProvider
*/
public function testSupportsClass($class, $supports)
{
$userProvider = new OAuthUserProvider();

$this->assertSame($supports, $userProvider->supportsClass($class));
}

public function supportsClassProvider()
{
yield 'OAuthUser' => [OAuthUser::class, true];
yield 'other user' => [User::class, false];
}
}
44 changes: 44 additions & 0 deletions tests/Security/User/OAuthUserTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

/*
* OAuth2 Client Bundle
* Copyright (c) KnpUniversity <http://knpuniversity.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace KnpU\OAuth2ClientBundle\Tests\Security\User;

use KnpU\OAuth2ClientBundle\Security\User\OAuthUser;

class OAuthUserTest extends \PHPUnit_Framework_TestCase
{
public function testRoles()
{
$user = new OAuthUser('username', ['role 1', 'role 2']);

$this->assertSame(['role 1', 'role 2'], $user->getRoles());
}

public function testPassword()
{
$user = new OAuthUser('username', ['role 1', 'role 2']);

$this->assertSame('', $user->getPassword());
}

public function testSalt()
{
$user = new OAuthUser('username', ['role 1', 'role 2']);

$this->assertNull($user->getSalt());
}

public function testUsername()
{
$user = new OAuthUser('username', ['role 1', 'role 2']);

$this->assertSame('username', $user->getUsername());
}
}

0 comments on commit d71a55f

Please sign in to comment.