135 lines
2.9 KiB
PHP
135 lines
2.9 KiB
PHP
<?php
|
|
|
|
namespace Illuminate\Cache;
|
|
|
|
use Illuminate\Support\InteractsWithTime;
|
|
use Illuminate\Contracts\Cache\Repository as Cache;
|
|
|
|
class RateLimiter
|
|
{
|
|
use InteractsWithTime;
|
|
|
|
/**
|
|
* The cache store implementation.
|
|
*
|
|
* @var \Illuminate\Contracts\Cache\Repository
|
|
*/
|
|
protected $cache;
|
|
|
|
/**
|
|
* Create a new rate limiter instance.
|
|
*
|
|
* @param \Illuminate\Contracts\Cache\Repository $cache
|
|
* @return void
|
|
*/
|
|
public function __construct(Cache $cache)
|
|
{
|
|
$this->cache = $cache;
|
|
}
|
|
|
|
/**
|
|
* Determine if the given key has been "accessed" too many times.
|
|
*
|
|
* @param string $key
|
|
* @param int $maxAttempts
|
|
* @param float|int $decayMinutes
|
|
* @return bool
|
|
*/
|
|
public function tooManyAttempts($key, $maxAttempts, $decayMinutes = 1)
|
|
{
|
|
if ($this->attempts($key) >= $maxAttempts) {
|
|
if ($this->cache->has($key.':timer')) {
|
|
return true;
|
|
}
|
|
|
|
$this->resetAttempts($key);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Increment the counter for a given key for a given decay time.
|
|
*
|
|
* @param string $key
|
|
* @param float|int $decayMinutes
|
|
* @return int
|
|
*/
|
|
public function hit($key, $decayMinutes = 1)
|
|
{
|
|
$this->cache->add(
|
|
$key.':timer', $this->availableAt($decayMinutes * 60), $decayMinutes
|
|
);
|
|
|
|
$added = $this->cache->add($key, 0, $decayMinutes);
|
|
|
|
$hits = (int) $this->cache->increment($key);
|
|
|
|
if (! $added && $hits == 1) {
|
|
$this->cache->put($key, 1, $decayMinutes);
|
|
}
|
|
|
|
return $hits;
|
|
}
|
|
|
|
/**
|
|
* Get the number of attempts for the given key.
|
|
*
|
|
* @param string $key
|
|
* @return mixed
|
|
*/
|
|
public function attempts($key)
|
|
{
|
|
return $this->cache->get($key, 0);
|
|
}
|
|
|
|
/**
|
|
* Reset the number of attempts for the given key.
|
|
*
|
|
* @param string $key
|
|
* @return mixed
|
|
*/
|
|
public function resetAttempts($key)
|
|
{
|
|
return $this->cache->forget($key);
|
|
}
|
|
|
|
/**
|
|
* Get the number of retries left for the given key.
|
|
*
|
|
* @param string $key
|
|
* @param int $maxAttempts
|
|
* @return int
|
|
*/
|
|
public function retriesLeft($key, $maxAttempts)
|
|
{
|
|
$attempts = $this->attempts($key);
|
|
|
|
return $maxAttempts - $attempts;
|
|
}
|
|
|
|
/**
|
|
* Clear the hits and lockout timer for the given key.
|
|
*
|
|
* @param string $key
|
|
* @return void
|
|
*/
|
|
public function clear($key)
|
|
{
|
|
$this->resetAttempts($key);
|
|
|
|
$this->cache->forget($key.':timer');
|
|
}
|
|
|
|
/**
|
|
* Get the number of seconds until the "key" is accessible again.
|
|
*
|
|
* @param string $key
|
|
* @return int
|
|
*/
|
|
public function availableIn($key)
|
|
{
|
|
return $this->cache->get($key.':timer') - $this->currentTime();
|
|
}
|
|
}
|