vendor/sindrive/sindrive/IpsetBundle/Listener/BruteForceListener.php line 45

Open in your IDE?
  1. <?php
  2. /**
  3.  * Created by PhpStorm.
  4.  * User: bumz
  5.  * Date: 7/9/14
  6.  * Time: 3:30 PM
  7.  */
  8. namespace Sindrive\IpsetBundle\Listener;
  9. use Sindrive\IpsetBundle\Event\BruteForceEvent;
  10. use Sindrive\IpsetBundle\Service\Ban;
  11. use Sindrive\MemcachedBundle\Services\SindriveMemcached;
  12. class BruteForceListener
  13. {
  14.     /**
  15.      * @var string
  16.      */
  17.     private $banKey;
  18.     /**
  19.      * @var \Sindrive\IpsetBundle\Service\Ban
  20.      */
  21.     private $banService;
  22.     /**
  23.      * @var SindriveMemcached|\Memcached
  24.      */
  25.     private $memcached;
  26.     /**
  27.      * @param SindriveMemcached $memcached
  28.      * @param \Sindrive\IpsetBundle\Service\Ban $banService
  29.      * @param string $banKey
  30.      */
  31.     public function __construct(SindriveMemcached $memcachedBan $banServicestring $banKey 'sindrive-ips-brute-force-listener')
  32.     {
  33.         $this->memcached $memcached;
  34.         $this->banService $banService;
  35.         $this->banKey $banKey;
  36.     }
  37.     public function watch(BruteForceEvent $event): bool
  38.     {
  39.         $banKey sprintf('%s-%s'$this->banKey$event->getIp());
  40.         $data $event->getData();
  41.         do {
  42.             $resultStore $this->memcached->getCas($banKey);
  43.             $result $resultStore['value'];
  44.             $cas $resultStore['cas'];
  45.             $currentTime time();
  46.             if ($event->getTimeOffset()) {
  47.                 $time $currentTime $event->getTimeOffset();
  48.             } else {
  49.                 $time 'inf.';
  50.             }
  51.             if ($this->memcached->getResultCode() === \Memcached::RES_NOTFOUND) {
  52.                 $result = array($data => $time);
  53.                 $this->memcached->add($banKey$result$time === 'inf.' $currentTime 365 24 60 60 $time);
  54.             } elseif ($this->memcached->getResultCode() === \Memcached::RES_SUCCESS) {
  55.                 $result array_filter($result, static function($item) use ($currentTime) {
  56.                     return $item === 'inf.' || $item $currentTime;
  57.                 });
  58.                 if (!isset($result[$data]) || $result[$data] !== 'inf.') {
  59.                     $result[$data] = $time;
  60.                 }
  61.                 $this->memcached->cas($cas$banKey$resultin_array('inf.'$resulttrue) ? $currentTime 365 24 60 60 $time);
  62.             } else {
  63.                 return false;
  64.             }
  65.         } while ($this->memcached->getResultCode() !== \Memcached::RES_SUCCESS);
  66.         if (count($result) > $event->getCount()) {
  67.             $this->banService->add($event->getIp());
  68.         }
  69.         // if we do have a bot that is too greedy
  70.         if (count($result) > $event->getCount() + 2) {
  71.             $this->banService->ban();
  72.         }
  73.         return true;
  74.     }
  75.     public function forget(BruteForceEvent $event): void
  76.     {
  77.         $banKey sprintf('%s-%s'$this->banKey$event->getIp());
  78.         $this->memcached->delete($banKey);
  79.     }