Вход Регистрация
Файл: gapps/vendor/cartalyst/sentinel/src/Throttling/IlluminateThrottleRepository.php
Строк: 390
<?php

/**
 * Part of the Sentinel package.
 *
 * NOTICE OF LICENSE
 *
 * Licensed under the 3-clause BSD License.
 *
 * This source file is subject to the 3-clause BSD License that is
 * bundled with this package in the LICENSE file.
 *
 * @package    Sentinel
 * @version    2.0.15
 * @author     Cartalyst LLC
 * @license    BSD License (3-clause)
 * @copyright  (c) 2011-2017, Cartalyst LLC
 * @link       http://cartalyst.com
 */

namespace CartalystSentinelThrottling;

use 
CarbonCarbon;
use 
CartalystSentinelUsersUserInterface;
use 
CartalystSupportTraitsRepositoryTrait;

class 
IlluminateThrottleRepository implements ThrottleRepositoryInterface
{
    use 
RepositoryTrait;

    
/**
     * The interval which failed logins are checked, to prevent brute force.
     *
     * @var int
     */
    
protected $globalInterval 900;

    
/**
     * The global thresholds configuration array.
     *
     * If an array is set, the key is the number of failed login attempts
     * and the value is the delay in seconds before another login can
     * occur.
     *
     * If an integer is set, it represents the number of attempts
     * before throttling locks out in the current interval.
     *
     * @var int|array
     */
    
protected $globalThresholds = [
        
10 => 1,
        
20 => 2,
        
30 => 4,
        
40 => 8,
        
50 => 16,
        
60 => 32,
    ];

    
/**
     * Cached global throttles collection within the interval.
     *
     * @var IlluminateDatabaseEloquentCollection
     */
    
protected $globalThrottles;

    
/**
     * The interval at which point one IP address' failed logins are checked.
     *
     * @var int
     */
    
protected $ipInterval 900;

    
/**
     * Works identical to global thresholds, except specific to an IP address.
     *
     * @var int|array
     */
    
protected $ipThresholds 5;

    
/**
     * The cached IP address throttle collections within the interval.
     *
     * @var array
     */
    
protected $ipThrottles = [];

    
/**
     * The interval at which point failed logins for one user are checked.
     *
     * @var int
     */
    
protected $userInterval 900;

    
/**
     * Works identical to global and IP address thresholds, regarding a user.
     *
     * @var int|array
     */
    
protected $userThresholds 5;

    
/**
     * The cached user throttle collections within the interval.
     *
     * @var IlluminateDatabaseEloquentCollection
     */
    
protected $userThrottles = [];

    
/**
     * Create a new Illuminate throttle repository.
     *
     * @param  string  $model
     * @param  int  $globalInterval
     * @param  int|array  $globalThresholds
     * @param  int  $ipInterval
     * @param  int|array  $ipThresholds
     * @param  int  $userInterval
     * @param  int|array  $userThresholds
     * @return void
     */
    
public function __construct(
        
$model 'CartalystSentinelThrottlingEloquentThrottle',
        
$globalInterval null,
        
$globalThresholds null,
        
$ipInterval null,
        
$ipThresholds null,
        
$userInterval null,
        
$userThresholds null
    
) {
        
$this->model $model;

        if (isset(
$globalInterval)) {
            
$this->setGlobalInterval($globalInterval);
        }

        if (isset(
$globalThresholds)) {
            
$this->setGlobalThresholds($globalThresholds);
        }

        if (isset(
$ipInterval)) {
            
$this->setIpInterval($ipInterval);
        }

        if (isset(
$ipThresholds)) {
            
$this->setIpThresholds($ipThresholds);
        }

        if (isset(
$userInterval)) {
            
$this->setUserInterval($userInterval);
        }

        if (isset(
$userThresholds)) {
            
$this->setUserThresholds($userThresholds);
        }
    }

    
/**
     * {@inheritDoc}
     */
    
public function globalDelay()
    {
        return 
$this->delay('global');
    }

    
/**
     * {@inheritDoc}
     */
    
public function ipDelay($ipAddress)
    {
        return 
$this->delay('ip'$ipAddress);
    }

    
/**
     * {@inheritDoc}
     */
    
public function userDelay(UserInterface $user)
    {
        return 
$this->delay('user'$user);
    }

    
/**
     * {@inheritDoc}
     */
    
public function log($ipAddress nullUserInterface $user null)
    {
        
$global $this->createModel();
        
$global->fill([
            
'type' => 'global',
        ]);
        
$global->save();

        if (
$ipAddress !== null) {
            
$ipAddressThrottle $this->createModel();
            
$ipAddressThrottle->fill([
                
'type' => 'ip',
                
'ip'   => $ipAddress,
            ]);
            
$ipAddressThrottle->save();
        }

        if (
$user !== null) {
            
$userThrottle $this->createModel();
            
$userThrottle->fill([
                
'type' => 'user',
            ]);
            
$userThrottle->user_id $user->getUserId();
            
$userThrottle->save();
        }
    }

    
/**
     * Returns the global interval.
     *
     * @return int
     */
    
public function getGlobalInterval()
    {
        return 
$this->globalInterval;
    }

    
/**
     * Sets the global interval.
     *
     * @param  int  $globalInterval
     * @return void
     */
    
public function setGlobalInterval($globalInterval)
    {
        
$this->globalInterval = (int) $globalInterval;
    }

    
/**
     * Returns the global thresholds.
     *
     * @return int|array
     */
    
public function getGlobalThresholds()
    {
        return 
$this->globalThresholds;
    }

    
/**
     * Sets the global thresholds.
     *
     * @param  int|array  $globalThresholds
     * @return void
     */
    
public function setGlobalThresholds($globalThresholds)
    {
        
$this->globalThresholds is_array($globalThresholds) ? $globalThresholds : (int) $globalThresholds;
    }

    
/**
     * Returns the IP address interval.
     *
     * @return int
     */
    
public function getIpInterval()
    {
        return 
$this->ipInterval;
    }

    
/**
     * Sets the IP address interval.
     *
     * @param  int  $ipInterval
     * @return void
     */
    
public function setIpInterval($ipInterval)
    {
        
$this->ipInterval = (int) $ipInterval;
    }

    
/**
     * Returns the IP address thresholds.
     *
     * @return int|array
     */
    
public function getIpThresholds()
    {
        return 
$this->ipThresholds;
    }

    
/**
     * Sets the IP address thresholds.
     *
     * @param  int|array  $ipThresholds
     * @return void
     */
    
public function setIpThresholds($ipThresholds)
    {
        
$this->ipThresholds is_array($ipThresholds) ? $ipThresholds : (int) $ipThresholds;
    }

    
/**
     * Returns the user interval.
     *
     * @return int
     */
    
public function getUserInterval()
    {
        return 
$this->userInterval;
    }

    
/**
     * Sets the user interval.
     *
     * @param  int  $userInterval
     * @return void
     */
    
public function setUserInterval($userInterval)
    {
        
$this->userInterval = (int) $userInterval;
    }

    
/**
     * Returns the user thresholds.
     *
     * @return int|array
     */
    
public function getUserThresholds()
    {
        return 
$this->userThresholds;
    }

    
/**
     * Sets the user thresholds.
     *
     * @param  int|array  $userThresholds
     * @return void
     */
    
public function setUserThresholds($userThresholds)
    {
        
$this->userThresholds is_array($userThresholds) ? $userThresholds : (int) $userThresholds;
    }

    
/**
     * Returns a delay for the given type.
     *
     * @param  string  $type
     * @param  mixed  $argument
     * @return int
     */
    
protected function delay($type$argument null)
    {
        
// Based on the given type, we will generate method and property names
        
$method 'get'.studly_case($type).'Throttles';

        
$thresholds $type.'Thresholds';

        
$throttles $this->{$method}($argument);

        if (! 
$throttles->count()) {
            return 
0;
        }

        if (
is_array($this->$thresholds)) {
            
// Great, now we compare our delay against the most recent attempt
            
$last $throttles->last();

            foreach (
array_reverse($this->$thresholdstrue) as $attempts => $delay) {
                if (
$throttles->count() <= $attempts) {
                    continue;
                }

                if (
$last->created_at->diffInSeconds() < $delay) {
                    return 
$this->secondsToFree($last$delay);
                }
            }
        } elseif (
$throttles->count() > $this->$thresholds) {
            
$interval $type.'Interval';

            
$first $throttles->first();

            return 
$this->secondsToFree($first$this->{$interval});
        }

        return 
0;
    }

    
/**
     * Returns the global throttles collection.
     *
     * @return IlluminateDatabaseEloquentCollection
     */
    
protected function getGlobalThrottles()
    {
        if (
$this->globalThrottles === null) {
            
$this->globalThrottles $this->loadGlobalThrottles();
        }

        return 
$this->globalThrottles;
    }

    
/**
     * Loads and returns the global throttles collection.
     *
     * @return IlluminateDatabaseEloquentCollection
     */
    
protected function loadGlobalThrottles()
    {
        
$interval Carbon::now()
            ->
subSeconds($this->globalInterval);

        return 
$this->createModel()
            ->
newQuery()
            ->
where('type''global')
            ->
where('created_at''>'$interval)
            ->
get();
    }

    
/**
     * Returns the IP address throttles collection.
     *
     * @param  string  $ipAddress
     * @return IlluminateDatabaseEloquentCollection
     */
    
protected function getIpThrottles($ipAddress)
    {
        if (! 
array_key_exists($ipAddress$this->ipThrottles)) {
            
$this->ipThrottles[$ipAddress] = $this->loadIpThrottles($ipAddress);
        }

        return 
$this->ipThrottles[$ipAddress];
    }

    
/**
     * Loads and returns the IP address throttles collection.
     *
     * @param  string  $ipAddress
     * @return IlluminateDatabaseEloquentCollection
     */
    
protected function loadIpThrottles($ipAddress)
    {
        
$interval Carbon::now()
            ->
subSeconds($this->ipInterval);

        return 
$this
            
->createModel()
            ->
newQuery()
            ->
where('type''ip')
            ->
where('ip'$ipAddress)
            ->
where('created_at''>'$interval)
            ->
get();
    }

    
/**
     * Returns the user throttles collection.
     *
     * @param  CartalystSentinelUsersUserInterface  $user
     * @return IlluminateDatabaseEloquentCollection
     */
    
protected function getUserThrottles(UserInterface $user)
    {
        
$key $user->getUserId();

        if (! 
array_key_exists($key$this->userThrottles)) {
            
$this->userThrottles[$key] = $this->loadUserThrottles($user);
        }

        return 
$this->userThrottles[$key];
    }

    
/**
     * Loads and returns the user throttles collection.
     *
     * @param  CartalystSentinelUsersUserInterface  $user
     * @return IlluminateDatabaseEloquentCollection
     */
    
protected function loadUserThrottles(UserInterface $user)
    {
        
$interval Carbon::now()
            ->
subSeconds($this->userInterval);

        return 
$this
            
->createModel()
            ->
newQuery()
            ->
where('type''user')
            ->
where('user_id'$user->getUserId())
            ->
where('created_at''>'$interval)
            ->
get();
    }

    
/**
     * Returns the seconds to free based on the given throttle and
     * the presented delay in seconds, by comparing it to now.
     *
     * @param  CartalystSentinelThrottlingEloquentThrottle  $throttle
     * @param  int  $interval
     * @return int
     */
    
protected function secondsToFree(EloquentThrottle $throttle$interval)
    {
        return 
$throttle->created_at->addSeconds($interval)->diffInSeconds();
    }
}
Онлайн: 0
Реклама