diff options
author | Marvin Borner | 2018-06-08 20:03:25 +0200 |
---|---|---|
committer | Marvin Borner | 2018-06-08 20:03:25 +0200 |
commit | 92b7dd3335a6572debeacfb5faa82c63a5e67888 (patch) | |
tree | 7ebbca22595d542ec5e2912a24a0400ac8f6b113 /main/app/sprinkles/core/src/Throttle | |
parent | 22a1bb27f94ea33042b0bdd35bef1a5cfa96cc0d (diff) |
Some minor fixes
Diffstat (limited to 'main/app/sprinkles/core/src/Throttle')
3 files changed, 324 insertions, 324 deletions
diff --git a/main/app/sprinkles/core/src/Throttle/ThrottleRule.php b/main/app/sprinkles/core/src/Throttle/ThrottleRule.php index c5e0c82..5840027 100644 --- a/main/app/sprinkles/core/src/Throttle/ThrottleRule.php +++ b/main/app/sprinkles/core/src/Throttle/ThrottleRule.php @@ -1,133 +1,133 @@ -<?php -/** - * UserFrosting (http://www.userfrosting.com) - * - * @link https://github.com/userfrosting/UserFrosting - * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License) - */ - -namespace UserFrosting\Sprinkle\Core\Throttle; - -/** - * ThrottleRule Class - * - * Represents a request throttling rule. - * @author Alex Weissman (https://alexanderweissman.com) - */ -class ThrottleRule -{ - /** @var string Set to 'ip' for ip-based throttling, 'data' for request-data-based throttling. */ - protected $method; - - /** @var int The amount of time, in seconds, to look back in determining attempts to consider. */ - protected $interval; - - /** - * @var int[] A mapping of minimum observation counts (x) to delays (y), in seconds. - * Any throttleable event that has occurred more than x times in this rule's interval, - * must wait y seconds after the last occurrence before another attempt is permitted. - */ - protected $delays; - - /** - * Create a new ThrottleRule object. - * - * @param string $method Set to 'ip' for ip-based throttling, 'data' for request-data-based throttling. - * @param int $interval The amount of time, in seconds, to look back in determining attempts to consider. - * @param int[] $delays A mapping of minimum observation counts (x) to delays (y), in seconds. - */ - public function __construct($method, $interval, $delays) { - $this->setMethod($method); - $this->setInterval($interval); - $this->setDelays($delays); - } - - /** - * Get the current delay on this rule for a particular number of event counts. - * - * @param Carbon\Carbon $lastEventTime The timestamp for the last countable event. - * @param int $count The total number of events which have occurred in an interval. - */ - public function getDelay($lastEventTime, $count) { - // Zero occurrences always maps to a delay of 0 seconds. - if ($count == 0) { - return 0; - } - - foreach ($this->delays as $observations => $delay) { - // Skip any delay rules for which we haven't met the requisite number of observations - if ($count < $observations) { - continue; - } - - // If this rule meets the observed number of events, and violates the required delay, then return the remaining time left - if ($lastEventTime->diffInSeconds() < $delay) { - return $lastEventTime->addSeconds($delay)->diffInSeconds(); - } - } - - return 0; - } - - /** - * Gets the current mapping of attempts (int) to delays (seconds). - * - * @return int[] - */ - public function getDelays() { - return $this->delays; - } - - /** - * Gets the current throttling interval (seconds). - * - * @return int - */ - public function getInterval() { - return $this->interval; - } - - /** - * Gets the current throttling method ('ip' or 'data'). - * - * @return string - */ - public function getMethod() { - return $this->method; - } - - /** - * Sets the current mapping of attempts (int) to delays (seconds). - * - * @param int[] A mapping of minimum observation counts (x) to delays (y), in seconds. - */ - public function setDelays($delays) { - // Sort the array by key, from highest to lowest value - $this->delays = $delays; - krsort($this->delays); - - return $this; - } - - /** - * Sets the current throttling interval (seconds). - * - * @param int The amount of time, in seconds, to look back in determining attempts to consider. - */ - public function setInterval($interval) { - $this->interval = $interval; - - return $this; - } - - /** - * Sets the current throttling method ('ip' or 'data'). - * - * @param string Set to 'ip' for ip-based throttling, 'data' for request-data-based throttling. - */ - public function setMethod($method) { - $this->method = $method; - - return $this; - } -} +<?php
+/**
+ * UserFrosting (http://www.userfrosting.com)
+ *
+ * @link https://github.com/userfrosting/UserFrosting
+ * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
+ */
+
+namespace UserFrosting\Sprinkle\Core\Throttle;
+
+/**
+ * ThrottleRule Class
+ *
+ * Represents a request throttling rule.
+ * @author Alex Weissman (https://alexanderweissman.com)
+ */
+class ThrottleRule
+{
+ /** @var string Set to 'ip' for ip-based throttling, 'data' for request-data-based throttling. */
+ protected $method;
+
+ /** @var int The amount of time, in seconds, to look back in determining attempts to consider. */
+ protected $interval;
+
+ /**
+ * @var int[] A mapping of minimum observation counts (x) to delays (y), in seconds.
+ * Any throttleable event that has occurred more than x times in this rule's interval,
+ * must wait y seconds after the last occurrence before another attempt is permitted.
+ */
+ protected $delays;
+
+ /**
+ * Create a new ThrottleRule object.
+ *
+ * @param string $method Set to 'ip' for ip-based throttling, 'data' for request-data-based throttling.
+ * @param int $interval The amount of time, in seconds, to look back in determining attempts to consider.
+ * @param int[] $delays A mapping of minimum observation counts (x) to delays (y), in seconds.
+ */
+ public function __construct($method, $interval, $delays) {
+ $this->setMethod($method);
+ $this->setInterval($interval);
+ $this->setDelays($delays);
+ }
+
+ /**
+ * Get the current delay on this rule for a particular number of event counts.
+ *
+ * @param Carbon\Carbon $lastEventTime The timestamp for the last countable event.
+ * @param int $count The total number of events which have occurred in an interval.
+ */
+ public function getDelay($lastEventTime, $count) {
+ // Zero occurrences always maps to a delay of 0 seconds.
+ if ($count == 0) {
+ return 0;
+ }
+
+ foreach ($this->delays as $observations => $delay) {
+ // Skip any delay rules for which we haven't met the requisite number of observations
+ if ($count < $observations) {
+ continue;
+ }
+
+ // If this rule meets the observed number of events, and violates the required delay, then return the remaining time left
+ if ($lastEventTime->diffInSeconds() < $delay) {
+ return $lastEventTime->addSeconds($delay)->diffInSeconds();
+ }
+ }
+
+ return 0;
+ }
+
+ /**
+ * Gets the current mapping of attempts (int) to delays (seconds).
+ *
+ * @return int[]
+ */
+ public function getDelays() {
+ return $this->delays;
+ }
+
+ /**
+ * Gets the current throttling interval (seconds).
+ *
+ * @return int
+ */
+ public function getInterval() {
+ return $this->interval;
+ }
+
+ /**
+ * Gets the current throttling method ('ip' or 'data').
+ *
+ * @return string
+ */
+ public function getMethod() {
+ return $this->method;
+ }
+
+ /**
+ * Sets the current mapping of attempts (int) to delays (seconds).
+ *
+ * @param int[] A mapping of minimum observation counts (x) to delays (y), in seconds.
+ */
+ public function setDelays($delays) {
+ // Sort the array by key, from highest to lowest value
+ $this->delays = $delays;
+ krsort($this->delays);
+
+ return $this;
+ }
+
+ /**
+ * Sets the current throttling interval (seconds).
+ *
+ * @param int The amount of time, in seconds, to look back in determining attempts to consider.
+ */
+ public function setInterval($interval) {
+ $this->interval = $interval;
+
+ return $this;
+ }
+
+ /**
+ * Sets the current throttling method ('ip' or 'data').
+ *
+ * @param string Set to 'ip' for ip-based throttling, 'data' for request-data-based throttling.
+ */
+ public function setMethod($method) {
+ $this->method = $method;
+
+ return $this;
+ }
+}
diff --git a/main/app/sprinkles/core/src/Throttle/Throttler.php b/main/app/sprinkles/core/src/Throttle/Throttler.php index 4ab9dd6..f7d1cc7 100644 --- a/main/app/sprinkles/core/src/Throttle/Throttler.php +++ b/main/app/sprinkles/core/src/Throttle/Throttler.php @@ -1,172 +1,172 @@ -<?php -/** - * UserFrosting (http://www.userfrosting.com) - * - * @link https://github.com/userfrosting/UserFrosting - * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License) - */ - -namespace UserFrosting\Sprinkle\Core\Throttle; - -use Carbon\Carbon; -use UserFrosting\Sprinkle\Core\Util\ClassMapper; - -/** - * Handles throttling (rate limiting) of specific types of requests. - * - * @author Alex Weissman (https://alexanderweissman.com) - */ -class Throttler -{ - /** - * @var UserFrosting\Sprinkle\Core\Util\ClassMapper - */ - protected $classMapper; - - /** - * @var ThrottleRule[] An array mapping throttle names to throttle rules. - */ - protected $throttleRules; - - /** - * Create a new Throttler object. - * - * @param ClassMapper $classMapper Maps generic class identifiers to specific class names. - */ - public function __construct(ClassMapper $classMapper) { - $this->classMapper = $classMapper; - $this->throttleRules = []; - } - - /** - * Add a throttling rule for a particular throttle event type. - * - * @param string $type The type of throttle event to check against. - * @param ThrottleRule $rule The rule to use when throttling this type of event. - */ - public function addThrottleRule($type, $rule) { - if (!($rule instanceof ThrottleRule || ($rule === NULL))) { - throw new ThrottlerException('$rule must be of type ThrottleRule (or null).'); - } - - $this->throttleRules[$type] = $rule; - - return $this; - } - - /** - * Check the current request against a specified throttle rule. - * - * @param string $type The type of throttle event to check against. - * @param mixed[] $requestData Any additional request parameters to use in checking the throttle. - * @return bool - */ - public function getDelay($type, $requestData = []) { - $throttleRule = $this->getRule($type); - - if (is_null($throttleRule)) { - return 0; - } - - // Get earliest time to start looking for throttleable events - $startTime = Carbon::now() - ->subSeconds($throttleRule->getInterval()); - - // Fetch all throttle events of the specified type, that match the specified rule - if ($throttleRule->getMethod() == 'ip') { - $events = $this->classMapper->staticMethod('throttle', 'where', 'type', $type) - ->where('created_at', '>', $startTime) - ->where('ip', $_SERVER['REMOTE_ADDR']) - ->get(); - } else { - $events = $this->classMapper->staticMethod('throttle', 'where', 'type', $type) - ->where('created_at', '>', $startTime) - ->get(); - - // Filter out only events that match the required JSON data - $events = $events->filter(function ($item, $key) use ($requestData) { - $data = json_decode($item->request_data); - - // If a field is not specified in the logged data, or it doesn't match the value we're searching for, - // then filter out this event from the collection. - foreach ($requestData as $name => $value) { - if (!isset($data->$name) || ($data->$name != $value)) { - return FALSE; - } - } - - return TRUE; - }); - } - - // Check the collection of events against the specified throttle rule. - return $this->computeDelay($events, $throttleRule); - } - - /** - * Get a registered rule of a particular type. - * - * @param string $type - * @throws ThrottlerException - * @return ThrottleRule[] - */ - public function getRule($type) { - if (!array_key_exists($type, $this->throttleRules)) { - throw new ThrottlerException("The throttling rule for '$type' could not be found."); - } - - return $this->throttleRules[$type]; - } - - /** - * Get the current throttling rules. - * - * @return ThrottleRule[] - */ - public function getThrottleRules() { - return $this->throttleRules; - } - - /** - * Log a throttleable event to the database. - * - * @param string $type the type of event - * @param string[] $requestData an array of field names => values that are relevant to throttling for this event (e.g. username, email, etc). - */ - public function logEvent($type, $requestData = []) { - // Just a check to make sure the rule exists - $throttleRule = $this->getRule($type); - - if (is_null($throttleRule)) { - return $this; - } - - $event = $this->classMapper->createInstance('throttle', [ - 'type' => $type, - 'ip' => $_SERVER['REMOTE_ADDR'], - 'request_data' => json_encode($requestData) - ]); - - $event->save(); - - return $this; - } - - /** - * Returns the current delay for a specified throttle rule. - * - * @param Throttle[] $events a Collection of throttle events. - * @param ThrottleRule $throttleRule a rule representing the strategy to use for throttling a particular type of event. - * @return int seconds remaining until a particular event is permitted to be attempted again. - */ - protected function computeDelay($events, $throttleRule) { - // If no matching events found, then there is no delay - if (!$events->count()) { - return 0; - } - - // Great, now we compare our delay against the most recent attempt - $lastEvent = $events->last(); - return $throttleRule->getDelay($lastEvent->created_at, $events->count()); - } -} +<?php
+/**
+ * UserFrosting (http://www.userfrosting.com)
+ *
+ * @link https://github.com/userfrosting/UserFrosting
+ * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
+ */
+
+namespace UserFrosting\Sprinkle\Core\Throttle;
+
+use Carbon\Carbon;
+use UserFrosting\Sprinkle\Core\Util\ClassMapper;
+
+/**
+ * Handles throttling (rate limiting) of specific types of requests.
+ *
+ * @author Alex Weissman (https://alexanderweissman.com)
+ */
+class Throttler
+{
+ /**
+ * @var UserFrosting\Sprinkle\Core\Util\ClassMapper
+ */
+ protected $classMapper;
+
+ /**
+ * @var ThrottleRule[] An array mapping throttle names to throttle rules.
+ */
+ protected $throttleRules;
+
+ /**
+ * Create a new Throttler object.
+ *
+ * @param ClassMapper $classMapper Maps generic class identifiers to specific class names.
+ */
+ public function __construct(ClassMapper $classMapper) {
+ $this->classMapper = $classMapper;
+ $this->throttleRules = [];
+ }
+
+ /**
+ * Add a throttling rule for a particular throttle event type.
+ *
+ * @param string $type The type of throttle event to check against.
+ * @param ThrottleRule $rule The rule to use when throttling this type of event.
+ */
+ public function addThrottleRule($type, $rule) {
+ if (!($rule instanceof ThrottleRule || ($rule === NULL))) {
+ throw new ThrottlerException('$rule must be of type ThrottleRule (or null).');
+ }
+
+ $this->throttleRules[$type] = $rule;
+
+ return $this;
+ }
+
+ /**
+ * Check the current request against a specified throttle rule.
+ *
+ * @param string $type The type of throttle event to check against.
+ * @param mixed[] $requestData Any additional request parameters to use in checking the throttle.
+ * @return bool
+ */
+ public function getDelay($type, $requestData = []) {
+ $throttleRule = $this->getRule($type);
+
+ if (is_null($throttleRule)) {
+ return 0;
+ }
+
+ // Get earliest time to start looking for throttleable events
+ $startTime = Carbon::now()
+ ->subSeconds($throttleRule->getInterval());
+
+ // Fetch all throttle events of the specified type, that match the specified rule
+ if ($throttleRule->getMethod() == 'ip') {
+ $events = $this->classMapper->staticMethod('throttle', 'where', 'type', $type)
+ ->where('created_at', '>', $startTime)
+ ->where('ip', $_SERVER['REMOTE_ADDR'])
+ ->get();
+ } else {
+ $events = $this->classMapper->staticMethod('throttle', 'where', 'type', $type)
+ ->where('created_at', '>', $startTime)
+ ->get();
+
+ // Filter out only events that match the required JSON data
+ $events = $events->filter(function ($item, $key) use ($requestData) {
+ $data = json_decode($item->request_data);
+
+ // If a field is not specified in the logged data, or it doesn't match the value we're searching for,
+ // then filter out this event from the collection.
+ foreach ($requestData as $name => $value) {
+ if (!isset($data->$name) || ($data->$name != $value)) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+ });
+ }
+
+ // Check the collection of events against the specified throttle rule.
+ return $this->computeDelay($events, $throttleRule);
+ }
+
+ /**
+ * Get a registered rule of a particular type.
+ *
+ * @param string $type
+ * @throws ThrottlerException
+ * @return ThrottleRule[]
+ */
+ public function getRule($type) {
+ if (!array_key_exists($type, $this->throttleRules)) {
+ throw new ThrottlerException("The throttling rule for '$type' could not be found.");
+ }
+
+ return $this->throttleRules[$type];
+ }
+
+ /**
+ * Get the current throttling rules.
+ *
+ * @return ThrottleRule[]
+ */
+ public function getThrottleRules() {
+ return $this->throttleRules;
+ }
+
+ /**
+ * Log a throttleable event to the database.
+ *
+ * @param string $type the type of event
+ * @param string[] $requestData an array of field names => values that are relevant to throttling for this event (e.g. username, email, etc).
+ */
+ public function logEvent($type, $requestData = []) {
+ // Just a check to make sure the rule exists
+ $throttleRule = $this->getRule($type);
+
+ if (is_null($throttleRule)) {
+ return $this;
+ }
+
+ $event = $this->classMapper->createInstance('throttle', [
+ 'type' => $type,
+ 'ip' => $_SERVER['REMOTE_ADDR'],
+ 'request_data' => json_encode($requestData)
+ ]);
+
+ $event->save();
+
+ return $this;
+ }
+
+ /**
+ * Returns the current delay for a specified throttle rule.
+ *
+ * @param Throttle[] $events a Collection of throttle events.
+ * @param ThrottleRule $throttleRule a rule representing the strategy to use for throttling a particular type of event.
+ * @return int seconds remaining until a particular event is permitted to be attempted again.
+ */
+ protected function computeDelay($events, $throttleRule) {
+ // If no matching events found, then there is no delay
+ if (!$events->count()) {
+ return 0;
+ }
+
+ // Great, now we compare our delay against the most recent attempt
+ $lastEvent = $events->last();
+ return $throttleRule->getDelay($lastEvent->created_at, $events->count());
+ }
+}
diff --git a/main/app/sprinkles/core/src/Throttle/ThrottlerException.php b/main/app/sprinkles/core/src/Throttle/ThrottlerException.php index 08f2919..af29bc8 100644 --- a/main/app/sprinkles/core/src/Throttle/ThrottlerException.php +++ b/main/app/sprinkles/core/src/Throttle/ThrottlerException.php @@ -1,19 +1,19 @@ -<?php -/** - * UserFrosting (http://www.userfrosting.com) - * - * @link https://github.com/userfrosting/UserFrosting - * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License) - */ - -namespace UserFrosting\Sprinkle\Core\Throttle; - -/** - * Throttler exception. Used when there is a problem with the request throttler. - * - * @author Alex Weissman (https://alexanderweissman.com) - */ -class ThrottlerException extends \RuntimeException -{ - -} +<?php
+/**
+ * UserFrosting (http://www.userfrosting.com)
+ *
+ * @link https://github.com/userfrosting/UserFrosting
+ * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
+ */
+
+namespace UserFrosting\Sprinkle\Core\Throttle;
+
+/**
+ * Throttler exception. Used when there is a problem with the request throttler.
+ *
+ * @author Alex Weissman (https://alexanderweissman.com)
+ */
+class ThrottlerException extends \RuntimeException
+{
+
+}
|