Skip to content

Commit a70a240

Browse files
authored
Adjusted code structure, added translations, adjusted documentation, added basic tests, adjusted dependencies and package naming (#3)
Adjusted code structure, added translations, adjusted documentation, added basic tests, adjusted dependencies and package naming
1 parent e4fbaff commit a70a240

27 files changed

+331
-171
lines changed

.travis-memcached.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
extension="memcached.so"

.travis.yml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
language: php
2+
23
php:
3-
- 5.5
4-
- 5.6
54
- 7.0
65
- 7.1
6+
- 7.2
7+
- 7.3
78

89
before_script:
10+
- phpenv config-add .travis-memcached.ini
11+
- composer self-update
912
- composer install
1013

1114
script:
12-
- vendor/bin/phpunit
15+
- ./vendor/bin/phpunit

Command/MySQLProviderSetupCommand.php

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,42 @@
33
namespace NV\RequestLimitBundle\Command;
44

55
use Doctrine\DBAL\Connection;
6+
use Doctrine\DBAL\DBALException;
67
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
78
use Symfony\Component\Console\Input\InputInterface;
89
use Symfony\Component\Console\Output\OutputInterface;
910

11+
/**
12+
* Class MySQLProviderSetupCommand
13+
* @package NV\RequestLimitBundle\Command
14+
* @author Novikov Viktor
15+
*/
1016
class MySQLProviderSetupCommand extends ContainerAwareCommand
1117
{
18+
/**
19+
* {@inheritdoc}
20+
*/
1221
protected function configure()
1322
{
1423
$this
1524
->setName('nv:request-limit:mysql-init')
1625
->setDescription('Creates a table in your project database to store keys')
17-
->setHelp('This command initialize MySQL provider workflow')
18-
;
26+
->setHelp('This command initializes MySQL provider workflow');
1927
}
2028

2129
/**
2230
* @param InputInterface $input
2331
* @param OutputInterface $output
2432
* @return int|null|void
25-
* @throws \Doctrine\DBAL\DBALException
33+
* @throws DBALException
2634
*/
2735
protected function execute(InputInterface $input, OutputInterface $output)
2836
{
2937
/** @var Connection $connection */
3038
$connection = $this->getContainer()->get('doctrine.orm.default_entity_manager')->getConnection();
31-
$connection->exec('CREATE TABLE nv_request_limit_items (
32-
item_key VARCHAR(30) PRIMARY KEY,
33-
expires_at TIMESTAMP
34-
);');
39+
$connection->exec(
40+
'CREATE TABLE nv_request_limit_items (item_key VARCHAR(30) PRIMARY KEY, expires_at TIMESTAMP);'
41+
);
3542
$connection->close();
3643
}
3744
}

DataCollector/RestrictionsCollector.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
use Symfony\Component\HttpFoundation\Response;
88
use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;
99

10+
/**
11+
* Class RestrictionsCollector
12+
* @package NV\RequestLimitBundle\DataCollector
13+
* @author Novikov Viktor
14+
*/
1015
class RestrictionsCollector implements DataCollectorInterface
1116
{
1217
/**
@@ -18,7 +23,7 @@ class RestrictionsCollector implements DataCollectorInterface
1823
private $storageManager;
1924

2025
/**
21-
* @inheritdoc
26+
* {@inheritdoc}
2227
*/
2328
public function collect(Request $request, Response $response, \Exception $exception = null)
2429
{
@@ -69,7 +74,7 @@ public function __sleep()
6974
}
7075

7176
/**
72-
* @inheritdoc
77+
* {@inheritdoc}
7378
*/
7479
public function reset()
7580
{

DependencyInjection/Compiler/StoragePass.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,16 @@
55
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
66
use Symfony\Component\DependencyInjection\ContainerBuilder;
77

8+
/**
9+
* Class StoragePass
10+
* @package NV\RequestLimitBundle\DependencyInjection\Compiler
11+
* @author Novikov Viktor
12+
*/
813
class StoragePass implements CompilerPassInterface
914
{
1015
/**
16+
* {@inheritdoc}
17+
*
1118
* @param ContainerBuilder $container
1219
*/
1320
public function process(ContainerBuilder $container)

DependencyInjection/Configuration.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,22 @@
55
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
66
use Symfony\Component\Config\Definition\ConfigurationInterface;
77

8+
/**
9+
* Class Configuration
10+
* @package NV\RequestLimitBundle\DependencyInjection
11+
* @author Novikov Viktor
12+
*/
813
class Configuration implements ConfigurationInterface
914
{
1015
/**
11-
* @inheritdoc
16+
* {@inheritdoc}
17+
*
18+
* @return TreeBuilder
1219
*/
1320
public function getConfigTreeBuilder()
1421
{
1522
$treeBuilder = new TreeBuilder();
1623
$rootNode = $treeBuilder->root('request_limit');
17-
1824
$rootNode
1925
->children()
2026
->integerNode('restriction_time')->end()

DependencyInjection/NVRequestLimitExtension.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,32 @@
66
use Symfony\Component\Config\FileLocator;
77
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
88
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
9+
use \Exception;
910

11+
/**
12+
* Class NVRequestLimitExtension
13+
* @package NV\RequestLimitBundle\DependencyInjection
14+
* @author Novikov Viktor
15+
*/
1016
class NVRequestLimitExtension extends Extension
1117
{
1218
/**
1319
* Loads a specific configuration.
1420
*
1521
* @param array $configs
1622
* @param ContainerBuilder $container
17-
* @throws \Exception
23+
* @throws Exception
1824
*/
19-
public function load(array $configs, ContainerBuilder $container) {
25+
public function load(array $configs, ContainerBuilder $container)
26+
{
2027
$loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
2128
$loader->load('services.xml');
2229

23-
$configuration = new Configuration();
24-
$config = $this->processConfiguration($configuration, $configs);
25-
$providerType = $config['provider_type'];
30+
$configuration = new Configuration();
31+
$config = $this->processConfiguration($configuration, $configs);
32+
$providerType = $config['provider_type'];
2633
$providerConfiguration = $config['provider_configuration'];
27-
$restrictionTime = $config['restriction_time'];
34+
$restrictionTime = $config['restriction_time'];
2835

2936
$container->setParameter('nv_request_limit.provider_type', $providerType);
3037
$container->setParameter('nv_request_limit.provider_configuration', $providerConfiguration);

Exception/RequestLimitReachedException.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,18 @@
44

55
use Throwable;
66

7+
/**
8+
* Class RequestLimitReachedException
9+
* @package NV\RequestLimitBundle\Exception
10+
* @author Novikov Viktor
11+
*/
712
class RequestLimitReachedException extends \Exception
813
{
914
/**
10-
* @inheritdoc
15+
* {@inheritdoc}
1116
*/
1217
public function __construct(
13-
$message = "You reached defined requests limit, please try again later",
18+
$message = "You reached the defined requests limit. Please, try again later.",
1419
$code = 403,
1520
Throwable $previous = null
1621
) {

NVRequestLimitBundle.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,19 @@
66
use Symfony\Component\HttpKernel\Bundle\Bundle;
77
use Symfony\Component\DependencyInjection\ContainerBuilder;
88

9+
/**
10+
* Class NVRequestLimitBundle
11+
* @package NV\RequestLimitBundle
12+
* @author Novikov Viktor
13+
*/
914
class NVRequestLimitBundle extends Bundle
1015
{
1116
/**
12-
* @inheritdoc
17+
* {@inheritdoc}
1318
*/
1419
public function build(ContainerBuilder $container)
1520
{
1621
parent::build($container);
17-
1822
$container->addCompilerPass(new StoragePass());
1923
}
2024
}

README.md

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,56 +6,64 @@ RequestLimitBundle
66
This bundle is a simple solution to restrict user access
77
to some controller for a specified timeline.
88

9-
This could be used for different cases when you need to pre
10-
9+
This functionality could be used for different cases when you need to:
1110
- prevent flood - pushing users of irrelevant data;
12-
- prevent user to visit page very often, etc.
11+
- prevent a user from accessing the certain endpoint very often, etc.
1312

1413
Installation
1514
=============
1615

17-
1) Require bundle with:
16+
1) Install package via:
1817
```bash
19-
composer require
18+
composer require nv/request-limit-bundle
19+
```
20+
21+
2) Register bundle :
22+
23+
In `app/AppKernel.php` prior to Symfony version `4.0`:
24+
```php
25+
public function registerBundles()
26+
{
27+
$bundles = [
28+
// ... ,
29+
new NV\RequestLimitBundle\NVRequestLimitBundle()
30+
];
31+
32+
// ...
33+
return $bundles;
34+
}
2035
```
2136

22-
2) Register bundle in AppKernel:
37+
In `config/bundles.php` when Symfony version is `4.0` and higher
2338
```php
24-
public function registerBundles()
25-
{
26-
$bundles = [
27-
... ,
28-
new NV\RequestLimitBundle\NVRequestLimitBundle()
29-
];
30-
...
31-
}
39+
return [
40+
//... other bundles
41+
NV\RequestLimitBundle\NVRequestLimitBundle::class => ['all' => true]
42+
];
3243
```
3344

34-
3) Configure bundle according to provider you use:
35-
- [Memcached](https://github.com/NovikovViktor/RequestLimitBundle/blob/master/Resources/docs/memcached.md)
36-
- [MySQL](https://github.com/NovikovViktor/RequestLimitBundle/blob/master/Resources/docs/mysql.md)
45+
3) Configure the bundle according to the provider you would like to use.
46+
Out of the box, we provide the Memcached and MySQL providers. To see configuration options, see the docs below.
47+
48+
- [Memcached provider configuration](https://github.com/NovikovViktor/RequestLimitBundle/blob/master/Resources/docs/memcached.md)
49+
- [MySQL provider configuration](https://github.com/NovikovViktor/RequestLimitBundle/blob/master/Resources/docs/mysql.md)
50+
51+
If you want to use other storage, you can implement your provider.
3752

3853
4) Specify `restriction_time` in seconds:
3954
```yml
4055
nv_request_limit:
41-
restriction_time: 5
56+
#... options for provider configuration
57+
restriction_time: 5 # 5 seconds
4258
```
4359
4460
Usage
4561
=============
4662
47-
In your controller action add following line to restrict user access by user id:
48-
```php
49-
$this->get('nv.request_limit.request_restrictor')->restrictRequestByUserId($userId);
50-
```
51-
or following to restrict by user IP:
63+
In your action, add the following line to restrict access by some specific application user artifact (e.g., user id, user IP, etc.):
5264
```php
53-
$this->get('nv.request_limit.request_restrictor')->restrictRequestByIp($userIp);
65+
$artifact = 'e.g. get user id or IP here';
66+
$this->get('nv.request_limit.restrictor')->blockBy($artifact);
5467
```
5568

56-
These will restrict user access to the action for 10 minutes.
57-
58-
TODO
59-
=========
60-
61-
1) Write tests
69+
These will restrict user access for a time frame specified in your configuration (5 seconds accordingly to).

0 commit comments

Comments
 (0)