Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcos Gómez committed Jul 6, 2016
0 parents commit 8c6b56b
Show file tree
Hide file tree
Showing 48 changed files with 3,422 additions and 0 deletions.
21 changes: 21 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
clover.xml
html/
vendor/*
.vagrant
tmp
build/*
!build/*.xml
introspective
cookbooks
.idea
.env
.chef/*.pem
.generatorrc
npm-debug.log
node_modules
temp
dump
npm-debug.log
*.xcodeproj
*.xcworkspace
RELEASE
15 changes: 15 additions & 0 deletions .scrutinizer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
inherit: true

tools:
external_code_coverage: true
sensiolabs_security_checker:
enabled: true

filter:
excluded_paths:
- 'vendor/*'
- 'tests/*'
- 'app/*'
- 'bin/*'
- 'library/*'
- 'Tests/*'
72 changes: 72 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
language: php

php:
- 5.3
- 5.4
- 5.5
- 5.6
- 7.0
- hhvm

sudo: false

matrix:
fast_finish: true
include:
- php: 5.3
env: COMPOSER_FLAGS="--prefer-lowest"
- php: 5.4
env: COMPOSER_FLAGS="--prefer-lowest"
- php: 5.5
env: COMPOSER_FLAGS="--prefer-lowest"
- php: 5.6
env: SYMFONY_VERSION=2.3.*
- php: 5.6
env: SYMFONY_VERSION=2.6.*
- php: 5.6
env: SYMFONY_VERSION=2.7.*
- php: 5.6
env: SYMFONY_VERSION=2.8.*
- php: 5.6
env: SYMFONY_VERSION=3.0.*
- php: 7.0
env: COMPOSER_FLAGS="--prefer-lowest"
- php: 7.0
env: SYMFONY_VERSION=2.3.*
- php: 7.0
env: SYMFONY_VERSION=2.6.*
- php: 7.0
env: SYMFONY_VERSION=2.7.*
- php: 7.0
env: SYMFONY_VERSION=2.8.*
- php: 7.0
env: SYMFONY_VERSION=3.0.*
- php: hhvm
env: COMPOSER_FLAGS="--prefer-lowest"
- php: hhvm
env: SYMFONY_VERSION=2.3.*
- php: hhvm
env: SYMFONY_VERSION=2.6.*
- php: hhvm
env: SYMFONY_VERSION=2.7.*
- php: hhvm
env: SYMFONY_VERSION=2.8.*
- php: hhvm
env: SYMFONY_VERSION=3.0.*
allow_failures:
- env: SYMFONY_VERSION=3.0.*
- env: SYMFONY_VERSION=dev-master

before_script:
- wget https://phar.phpunit.de/phpunit-4.1.1.phar
- composer self-update
- if [ "$SYMFONY_VERSION" != "" ]; then composer require "symfony/symfony:${SYMFONY_VERSION}" --no-update; fi;
- composer require predis/predis:0.8.x --dev --no-update
- composer require friendsofsymfony/oauth-server-bundle:1.4.x --dev --no-update
- composer update --prefer-dist --no-interaction $COMPOSER_FLAGS

script: php phpunit-4.1.1.phar --coverage-text --coverage-clover=coverage.clover

after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- php ocular.phar code-coverage:upload --format=php-clover coverage.clover
96 changes: 96 additions & 0 deletions Annotation/RateLimit.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<?php

namespace Instasent\RateLimitBundle\Annotation;

use Doctrine\Common\Annotations\Annotation;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationAnnotation;

/**
* @Annotation
* @Target({"METHOD", "CLASS"})
*/
class RateLimit extends ConfigurationAnnotation
{
/**
* @var array HTTP Methods protected by this annotation. Defaults to all method
*/
protected $methods = array();

/**
* @var int Number of calls per period
*/
protected $limit = -1;

/**
* @var int Number of seconds of the time period in which the calls can be made
*/
protected $period = 3600;

/**
* Returns the alias name for an annotated configuration.
*
* @return string
*/
public function getAliasName()
{
return "x-rate-limit";
}

/**
* Returns whether multiple annotations of this type are allowed
*
* @return Boolean
*/
public function allowArray()
{
return true;
}

/**
* @return int
*/
public function getLimit()
{
return $this->limit;
}

/**
* @param int $limit
*/
public function setLimit($limit)
{
$this->limit = $limit;
}

/**
* @return array
*/
public function getMethods()
{
return $this->methods;
}

/**
* @param array $methods
*/
public function setMethods($methods)
{
$this->methods = $methods;
}

/**
* @return int
*/
public function getPeriod()
{
return $this->period;
}

/**
* @param int $period
*/
public function setPeriod($period)
{
$this->period = $period;
}
}
45 changes: 45 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
## 1.5.0

2015-04-10 Sam Van der Borght <[email protected]>
[Security] Prevent ratelimit bypassing by encoding url paths

2015-01-05 Jonathan McLean <[email protected]>
Fix rate_response_exception

## 1.4

2014-12-10 Koen Vlaswinkel <[email protected]>

Add Doctrine Cache storage engine

## 1.3

2014-11-17 Joshua Thijssen <[email protected]>

Ratelimit can trigger exceptions

## 1.2
2014-07-15 Dan Spencer <[email protected]>

Added global rate limits

## 1.1
2014-07-08 Joshua Thijssen <[email protected]>

Added changelog to reflect changes in the different releases

2014-07-07 Tobias Berchtold <[email protected]>

removed dependency to constant used in Symfony > 2.3

2014-07-05 Alberto Fernández <[email protected]>

Improved README, added enabled configuration

## 1.0.1
2014-06-23 Joshua Thijssen <[email protected]>

Fixed installation documentation for 1.x

## 1.0 - Initial release

110 changes: 110 additions & 0 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<?php

namespace Instasent\RateLimitBundle\DependencyInjection;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;

/**
* This is the class that validates and merges configuration from your app/config files
*
*/
class Configuration implements ConfigurationInterface
{
const HTTP_TOO_MANY_REQUESTS = 429;

/**
* {@inheritDoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$treeBuilder->root('instasent_rate_limit')
->canBeDisabled()
->children()
->enumNode('storage_engine')
->values(array('redis','memcache','doctrine'))
->defaultValue('redis')
->info('The storage engine where all the rates will be stored')
->end()
->scalarNode('redis_client')
->defaultValue('default_client')
->info('The redis client to use for the redis storage engine')
->end()
->scalarNode('memcache_client')
->defaultValue('default')
->info('The memcache client to use for the memcache storage engine')
->end()
->scalarNode('doctrine_provider')
->defaultNull()
->info('The Doctrine Cache provider to use for the doctrine storage engine')
->example('my_apc_cache')
->end()
->integerNode('rate_response_code')
->min(400)
->max(499)
->defaultValue(static::HTTP_TOO_MANY_REQUESTS)
->info('The HTTP status code to return when a client hits the rate limit')
->end()
->scalarNode('rate_response_exception')
->defaultNull()
->info('Optional exception class that will be returned when a client hits the rate limit')
->validate()
->always(function ($item) {
if (! is_subclass_of($item, '\Exception')) {
throw new InvalidConfigurationException(sprintf("'%s' must inherit the \\Exception class", $item));
}
return $item;
})
->end()
->end()
->scalarNode('rate_response_message')
->defaultValue('You exceeded the rate limit')
->info('The HTTP message to return when a client hits the rate limit')
->end()
->booleanNode('display_headers')
->defaultTrue()
->info('Should the ratelimit headers be automatically added to the response?')
->end()
->arrayNode('headers')
->addDefaultsIfNotSet()
->info('What are the different header names to add')
->children()
->scalarNode('limit')->defaultValue('X-RateLimit-Limit')->end()
->scalarNode('remaining')->defaultValue('X-RateLimit-Remaining')->end()
->scalarNode('reset')->defaultValue('X-RateLimit-Reset')->end()
->end()
->end()
->arrayNode('path_limits')
->defaultValue(array())
->info('Rate limits for paths')
->prototype('array')
->children()
->scalarNode('path')
->isRequired()
->end()
->arrayNode('methods')
->prototype('enum')
->values(array('*', 'GET', 'POST', 'PUT', 'DELETE', 'PATCH'))
->end()
->requiresAtLeastOneElement()
->defaultValue(array('*'))
->end()
->integerNode('limit')
->isRequired()
->min(0)
->end()
->integerNode('period')
->isRequired()
->min(0)
->end()
->end()
->end()
->end()
->end()
;

return $treeBuilder;
}
}
Loading

0 comments on commit 8c6b56b

Please sign in to comment.