Skip to content

Commit e0b8c8a

Browse files
committed
Merge pull request #22 from gepo/extendability
Allows user to use custom user provider
2 parents b7a55bb + e89cfb7 commit e0b8c8a

File tree

8 files changed

+106
-28
lines changed

8 files changed

+106
-28
lines changed

README.md

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ ApiKey Bundle
33

44
Creates an avenue for using ApiKey authentication for Symfony2. Requires FOSUserBundle.
55

6-
## Installation
6+
# Installation
77

88
Requires composer, install as follows
99

1010
```sh
1111
composer require uecode/api-key-bundle dev-master
1212
```
1313

14-
#### Enable Bundle
14+
## Enable Bundle
1515

1616
Place in your `AppKernel.php` to enable the bundle
1717

@@ -36,14 +36,23 @@ uecode_api_key:
3636
parameter_name: some_value # defaults to `api_key`
3737
```
3838
39+
### Update user provider
40+
41+
This bundle provides two ways to work with User model:
42+
43+
1. use model and user provider provided by this bundle
44+
2. use custom user provider
45+
46+
### Use model provided by this bundle
47+
3948
#### Entities
4049
4150
Assuming you already have a `User` class that extends the `FOSUserBundle`'s base user model,
4251
change that extend, so its extending `Uecode\Bundle\ApiKeyBundle\Model\ApiKeyUser`
4352

4453
Then update your schema.
4554

46-
#### Set up security
55+
#### Change used user provider
4756

4857
In your security, change your provider to the service `uecode.api_key.provider.user_provider`
4958

@@ -64,7 +73,30 @@ security:
6473
id: uecode.api_key.provider.user_provider
6574
```
6675

67-
After adding that, you can now add `api_key: true`, and `stateless: true` to any of your firewalls.
76+
77+
### Use custom user provider
78+
79+
To work with this bundle your user provider should implement ```ApiKeyUserProviderInterface```.
80+
It consist of one method for loading user by their apiKey.
81+
You should implement this interface for user provider which used in your api firewall:
82+
83+
```php
84+
use Uecode\Bundle\ApiKeyBundle\Security\Authentication\Provider\ApiKeyUserProviderInterface;
85+
86+
class MyCustomUserProvider implements ApiKeyUserProviderInterface {
87+
// ...
88+
89+
public function loadUserByApiKey($apiKey)
90+
{
91+
return $this->userManager->findUserBy(array('apiKey' => $apiKey));
92+
}
93+
94+
}
95+
```
96+
97+
## Change security settings
98+
99+
You can now add `api_key: true`, and `stateless: true` to any of your firewalls.
68100

69101
For Example:
70102

src/Uecode/Bundle/ApiKeyBundle/Model/ApiKeyUser.php

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,44 +6,31 @@
66
use FOS\UserBundle\Model\UserInterface;
77
use Symfony\Component\Security\Core\User\UserInterface as BaseUserInterface;
88
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
9+
use Uecode\Bundle\ApiKeyBundle\Util\ApiKeyGenerator;
910

1011
class ApiKeyUser extends BaseUser implements UserInterface, AdvancedUserInterface, BaseUserInterface
1112
{
1213
protected $apiKey;
1314

1415
public function __construct()
1516
{
16-
$this->generateApiKey();
1717
parent::__construct();
18+
$this->setApiKey(ApiKeyGenerator::generate());
1819
}
1920

2021
/**
21-
* @param mixed $apiKey
22+
* @param string $apiKey
2223
*/
2324
public function setApiKey($apiKey)
2425
{
2526
$this->apiKey = $apiKey;
2627
}
2728

2829
/**
29-
* @return mixed
30+
* @return string
3031
*/
3132
public function getApiKey()
3233
{
3334
return $this->apiKey;
3435
}
35-
36-
/**
37-
* Generates an API Key
38-
*/
39-
public function generateApiKey()
40-
{
41-
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
42-
$apikey = '';
43-
for ($i = 0; $i < 64; $i++) {
44-
$apikey .= $characters[rand(0, strlen($characters) - 1)];
45-
}
46-
$apikey = base64_encode(sha1(uniqid('ue' . rand(rand(), rand())) . $apikey));
47-
$this->apiKey = $apikey;
48-
}
4936
}

src/Uecode/Bundle/ApiKeyBundle/Resources/config/services.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ parameters:
55

66
uecode.api_key.extractor.query.class: Uecode\Bundle\ApiKeyBundle\Extractor\QueryExtractor
77
uecode.api_key.extractor.header.class: Uecode\Bundle\ApiKeyBundle\Extractor\HeaderExtractor
8-
8+
9+
uecode.api_key.generator.class: Uecode\Bundle\ApiKeyBundle\Util\ApiKeyGenerator
10+
911
services:
1012
uecode.api_key.provider.user_provider:
1113
class: %uecode.api_key.provider.user_provider.class%
@@ -25,3 +27,6 @@ services:
2527
class: %uecode.api_key.extractor.header.class%
2628
arguments: [%uecode.api_key.parameter_name%]
2729
public: false
30+
uecode.api_key.generator:
31+
class: %uecode.api_key.generator.class%
32+
public: false

src/Uecode/Bundle/ApiKeyBundle/Security/Authentication/Provider/ApiKeyProvider.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Symfony\Component\Security\Core\User\UserProviderInterface;
1010
use FOS\UserBundle\Model\UserInterface;
1111
use Uecode\Bundle\ApiKeyBundle\Security\Authentication\Token\ApiKeyUserToken;
12+
use Uecode\Bundle\ApiKeyBundle\Security\Authentication\Provider\ApiKeyUserProviderInterface;
1213

1314
/**
1415
* @author Aaron Scherer <[email protected]>
@@ -58,9 +59,9 @@ public function authenticate(TokenInterface $token)
5859
* @return bool|ApiKeyUserToken
5960
* @throws AuthenticationException
6061
*/
61-
protected function doAuth(UserProviderInterface $provider, TokenInterface $token)
62+
protected function doAuth($provider, TokenInterface $token)
6263
{
63-
if (!method_exists($provider, 'loadUserByApiKey')) {
64+
if (! $provider instanceof ApiKeyUserProviderInterface) {
6465
return false;
6566
}
6667

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
namespace Uecode\Bundle\ApiKeyBundle\Security\Authentication\Provider;
3+
4+
/**
5+
* @author Gennady Telegin <[email protected]>
6+
*/
7+
interface ApiKeyUserProviderInterface
8+
{
9+
/**
10+
* @param string $apiKey
11+
*
12+
* @return UserInterface
13+
*/
14+
public function loadUserByApiKey($apiKey);
15+
}

src/Uecode/Bundle/ApiKeyBundle/Security/Authentication/Provider/UserProvider.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,15 @@
88
/**
99
* @author Aaron Scherer <[email protected]>
1010
*/
11-
class UserProvider extends FOSUserProvider
11+
class UserProvider extends FOSUserProvider implements ApiKeyUserProviderInterface
1212
{
1313
/**
1414
* @var bool Stateless Authentication?
1515
*/
1616
private $stateless = false;
1717

1818
/**
19-
* @param $apiKey
20-
*
21-
* @return UserInterface
19+
* {@inheritdoc}
2220
*/
2321
public function loadUserByApiKey($apiKey)
2422
{
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace Uecode\Bundle\ApiKeyBundle\Util;
4+
5+
/**
6+
* @author Gennady Telegin <[email protected]>
7+
*/
8+
class ApiKeyGenerator implements ApiKeyGeneratorInterface
9+
{
10+
private $characterSet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
11+
private $apiKeyLength = 64;
12+
13+
public function generateApiKey()
14+
{
15+
return self::generate($this->characterSet, $this->apiKeyLength);
16+
}
17+
18+
public static function generate($characterSet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', $apiKeyLength = 64)
19+
{
20+
$characterSetLength = strlen($characterSet);
21+
22+
$apikey = '';
23+
for ($i = 0; $i < $apiKeyLength; ++$i) {
24+
$apikey .= $characterSet[rand(0, $characterSetLength - 1)];
25+
}
26+
27+
return rtrim(base64_encode(sha1(uniqid('ue' . rand(rand(), rand())) . $apikey)), '=');
28+
}
29+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Uecode\Bundle\ApiKeyBundle\Util;
4+
5+
/**
6+
* @author Gennady Telegin <[email protected]>
7+
*/
8+
interface ApiKeyGeneratorInterface
9+
{
10+
public function generateApiKey();
11+
}

0 commit comments

Comments
 (0)