@@ -51,101 +51,101 @@ |
||
| 51 | 51 | * @package OC\AppFramework\Middleware\Security |
| 52 | 52 | */ |
| 53 | 53 | class BruteForceMiddleware extends Middleware { |
| 54 | - public function __construct( |
|
| 55 | - protected ControllerMethodReflector $reflector, |
|
| 56 | - protected Throttler $throttler, |
|
| 57 | - protected IRequest $request, |
|
| 58 | - protected LoggerInterface $logger, |
|
| 59 | - ) { |
|
| 60 | - } |
|
| 61 | - |
|
| 62 | - /** |
|
| 63 | - * {@inheritDoc} |
|
| 64 | - */ |
|
| 65 | - public function beforeController($controller, $methodName) { |
|
| 66 | - parent::beforeController($controller, $methodName); |
|
| 67 | - |
|
| 68 | - if ($this->reflector->hasAnnotation('BruteForceProtection')) { |
|
| 69 | - $action = $this->reflector->getAnnotationParameter('BruteForceProtection', 'action'); |
|
| 70 | - $this->throttler->sleepDelayOrThrowOnMax($this->request->getRemoteAddress(), $action); |
|
| 71 | - } else { |
|
| 72 | - $reflectionMethod = new ReflectionMethod($controller, $methodName); |
|
| 73 | - $attributes = $reflectionMethod->getAttributes(BruteForceProtection::class); |
|
| 74 | - |
|
| 75 | - if (!empty($attributes)) { |
|
| 76 | - $remoteAddress = $this->request->getRemoteAddress(); |
|
| 77 | - |
|
| 78 | - foreach ($attributes as $attribute) { |
|
| 79 | - /** @var BruteForceProtection $protection */ |
|
| 80 | - $protection = $attribute->newInstance(); |
|
| 81 | - $action = $protection->getAction(); |
|
| 82 | - $this->throttler->sleepDelayOrThrowOnMax($remoteAddress, $action); |
|
| 83 | - } |
|
| 84 | - } |
|
| 85 | - } |
|
| 86 | - } |
|
| 87 | - |
|
| 88 | - /** |
|
| 89 | - * {@inheritDoc} |
|
| 90 | - */ |
|
| 91 | - public function afterController($controller, $methodName, Response $response) { |
|
| 92 | - if ($response->isThrottled()) { |
|
| 93 | - try { |
|
| 94 | - if ($this->reflector->hasAnnotation('BruteForceProtection')) { |
|
| 95 | - $action = $this->reflector->getAnnotationParameter('BruteForceProtection', 'action'); |
|
| 96 | - $ip = $this->request->getRemoteAddress(); |
|
| 97 | - $this->throttler->registerAttempt($action, $ip, $response->getThrottleMetadata()); |
|
| 98 | - $this->throttler->sleepDelayOrThrowOnMax($ip, $action); |
|
| 99 | - } else { |
|
| 100 | - $reflectionMethod = new ReflectionMethod($controller, $methodName); |
|
| 101 | - $attributes = $reflectionMethod->getAttributes(BruteForceProtection::class); |
|
| 102 | - |
|
| 103 | - if (!empty($attributes)) { |
|
| 104 | - $ip = $this->request->getRemoteAddress(); |
|
| 105 | - $metaData = $response->getThrottleMetadata(); |
|
| 106 | - |
|
| 107 | - foreach ($attributes as $attribute) { |
|
| 108 | - /** @var BruteForceProtection $protection */ |
|
| 109 | - $protection = $attribute->newInstance(); |
|
| 110 | - $action = $protection->getAction(); |
|
| 111 | - |
|
| 112 | - if (!isset($metaData['action']) || $metaData['action'] === $action) { |
|
| 113 | - $this->throttler->registerAttempt($action, $ip, $metaData); |
|
| 114 | - $this->throttler->sleepDelayOrThrowOnMax($ip, $action); |
|
| 115 | - } |
|
| 116 | - } |
|
| 117 | - } else { |
|
| 118 | - $this->logger->debug('Response for ' . get_class($controller) . '::' . $methodName . ' got bruteforce throttled but has no annotation nor attribute defined.'); |
|
| 119 | - } |
|
| 120 | - } |
|
| 121 | - } catch (MaxDelayReached $e) { |
|
| 122 | - if ($controller instanceof OCSController) { |
|
| 123 | - throw new OCSException($e->getMessage(), Http::STATUS_TOO_MANY_REQUESTS); |
|
| 124 | - } |
|
| 125 | - |
|
| 126 | - return new TooManyRequestsResponse(); |
|
| 127 | - } |
|
| 128 | - } |
|
| 129 | - |
|
| 130 | - return parent::afterController($controller, $methodName, $response); |
|
| 131 | - } |
|
| 132 | - |
|
| 133 | - /** |
|
| 134 | - * @param Controller $controller |
|
| 135 | - * @param string $methodName |
|
| 136 | - * @param \Exception $exception |
|
| 137 | - * @throws \Exception |
|
| 138 | - * @return Response |
|
| 139 | - */ |
|
| 140 | - public function afterException($controller, $methodName, \Exception $exception): Response { |
|
| 141 | - if ($exception instanceof MaxDelayReached) { |
|
| 142 | - if ($controller instanceof OCSController) { |
|
| 143 | - throw new OCSException($exception->getMessage(), Http::STATUS_TOO_MANY_REQUESTS); |
|
| 144 | - } |
|
| 145 | - |
|
| 146 | - return new TooManyRequestsResponse(); |
|
| 147 | - } |
|
| 148 | - |
|
| 149 | - throw $exception; |
|
| 150 | - } |
|
| 54 | + public function __construct( |
|
| 55 | + protected ControllerMethodReflector $reflector, |
|
| 56 | + protected Throttler $throttler, |
|
| 57 | + protected IRequest $request, |
|
| 58 | + protected LoggerInterface $logger, |
|
| 59 | + ) { |
|
| 60 | + } |
|
| 61 | + |
|
| 62 | + /** |
|
| 63 | + * {@inheritDoc} |
|
| 64 | + */ |
|
| 65 | + public function beforeController($controller, $methodName) { |
|
| 66 | + parent::beforeController($controller, $methodName); |
|
| 67 | + |
|
| 68 | + if ($this->reflector->hasAnnotation('BruteForceProtection')) { |
|
| 69 | + $action = $this->reflector->getAnnotationParameter('BruteForceProtection', 'action'); |
|
| 70 | + $this->throttler->sleepDelayOrThrowOnMax($this->request->getRemoteAddress(), $action); |
|
| 71 | + } else { |
|
| 72 | + $reflectionMethod = new ReflectionMethod($controller, $methodName); |
|
| 73 | + $attributes = $reflectionMethod->getAttributes(BruteForceProtection::class); |
|
| 74 | + |
|
| 75 | + if (!empty($attributes)) { |
|
| 76 | + $remoteAddress = $this->request->getRemoteAddress(); |
|
| 77 | + |
|
| 78 | + foreach ($attributes as $attribute) { |
|
| 79 | + /** @var BruteForceProtection $protection */ |
|
| 80 | + $protection = $attribute->newInstance(); |
|
| 81 | + $action = $protection->getAction(); |
|
| 82 | + $this->throttler->sleepDelayOrThrowOnMax($remoteAddress, $action); |
|
| 83 | + } |
|
| 84 | + } |
|
| 85 | + } |
|
| 86 | + } |
|
| 87 | + |
|
| 88 | + /** |
|
| 89 | + * {@inheritDoc} |
|
| 90 | + */ |
|
| 91 | + public function afterController($controller, $methodName, Response $response) { |
|
| 92 | + if ($response->isThrottled()) { |
|
| 93 | + try { |
|
| 94 | + if ($this->reflector->hasAnnotation('BruteForceProtection')) { |
|
| 95 | + $action = $this->reflector->getAnnotationParameter('BruteForceProtection', 'action'); |
|
| 96 | + $ip = $this->request->getRemoteAddress(); |
|
| 97 | + $this->throttler->registerAttempt($action, $ip, $response->getThrottleMetadata()); |
|
| 98 | + $this->throttler->sleepDelayOrThrowOnMax($ip, $action); |
|
| 99 | + } else { |
|
| 100 | + $reflectionMethod = new ReflectionMethod($controller, $methodName); |
|
| 101 | + $attributes = $reflectionMethod->getAttributes(BruteForceProtection::class); |
|
| 102 | + |
|
| 103 | + if (!empty($attributes)) { |
|
| 104 | + $ip = $this->request->getRemoteAddress(); |
|
| 105 | + $metaData = $response->getThrottleMetadata(); |
|
| 106 | + |
|
| 107 | + foreach ($attributes as $attribute) { |
|
| 108 | + /** @var BruteForceProtection $protection */ |
|
| 109 | + $protection = $attribute->newInstance(); |
|
| 110 | + $action = $protection->getAction(); |
|
| 111 | + |
|
| 112 | + if (!isset($metaData['action']) || $metaData['action'] === $action) { |
|
| 113 | + $this->throttler->registerAttempt($action, $ip, $metaData); |
|
| 114 | + $this->throttler->sleepDelayOrThrowOnMax($ip, $action); |
|
| 115 | + } |
|
| 116 | + } |
|
| 117 | + } else { |
|
| 118 | + $this->logger->debug('Response for ' . get_class($controller) . '::' . $methodName . ' got bruteforce throttled but has no annotation nor attribute defined.'); |
|
| 119 | + } |
|
| 120 | + } |
|
| 121 | + } catch (MaxDelayReached $e) { |
|
| 122 | + if ($controller instanceof OCSController) { |
|
| 123 | + throw new OCSException($e->getMessage(), Http::STATUS_TOO_MANY_REQUESTS); |
|
| 124 | + } |
|
| 125 | + |
|
| 126 | + return new TooManyRequestsResponse(); |
|
| 127 | + } |
|
| 128 | + } |
|
| 129 | + |
|
| 130 | + return parent::afterController($controller, $methodName, $response); |
|
| 131 | + } |
|
| 132 | + |
|
| 133 | + /** |
|
| 134 | + * @param Controller $controller |
|
| 135 | + * @param string $methodName |
|
| 136 | + * @param \Exception $exception |
|
| 137 | + * @throws \Exception |
|
| 138 | + * @return Response |
|
| 139 | + */ |
|
| 140 | + public function afterException($controller, $methodName, \Exception $exception): Response { |
|
| 141 | + if ($exception instanceof MaxDelayReached) { |
|
| 142 | + if ($controller instanceof OCSController) { |
|
| 143 | + throw new OCSException($exception->getMessage(), Http::STATUS_TOO_MANY_REQUESTS); |
|
| 144 | + } |
|
| 145 | + |
|
| 146 | + return new TooManyRequestsResponse(); |
|
| 147 | + } |
|
| 148 | + |
|
| 149 | + throw $exception; |
|
| 150 | + } |
|
| 151 | 151 | } |
@@ -115,7 +115,7 @@ |
||
| 115 | 115 | } |
| 116 | 116 | } |
| 117 | 117 | } else { |
| 118 | - $this->logger->debug('Response for ' . get_class($controller) . '::' . $methodName . ' got bruteforce throttled but has no annotation nor attribute defined.'); |
|
| 118 | + $this->logger->debug('Response for '.get_class($controller).'::'.$methodName.' got bruteforce throttled but has no annotation nor attribute defined.'); |
|
| 119 | 119 | } |
| 120 | 120 | } |
| 121 | 121 | } catch (MaxDelayReached $e) { |