diff options
author | Stanimir Bozhilov <stanimir.bozhilov.1998@gmail.com> | 2022-12-19 09:07:38 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-19 09:07:38 +0100 |
commit | 7dcd6eb561f4bba7ed36ce1178c725278dd9b80e (patch) | |
tree | 8de1664f1a18df2e3b7b3dafadb3e0b6c3a8b439 /lib/private/AppFramework | |
parent | ed902d58b62150a46c745b5e87c895fc3fc67509 (diff) | |
parent | e12aaa298861743f798d9adf644d626ac8e89a95 (diff) | |
download | nextcloud-server-7dcd6eb561f4bba7ed36ce1178c725278dd9b80e.tar.gz nextcloud-server-7dcd6eb561f4bba7ed36ce1178c725278dd9b80e.zip |
Merge branch 'master' into add-scim-json-support
Signed-off-by: Stanimir Bozhilov <stanimir.bozhilov.1998@gmail.com>
Diffstat (limited to 'lib/private/AppFramework')
6 files changed, 63 insertions, 16 deletions
diff --git a/lib/private/AppFramework/DependencyInjection/DIContainer.php b/lib/private/AppFramework/DependencyInjection/DIContainer.php index e06d5226a28..462f9b978fd 100644 --- a/lib/private/AppFramework/DependencyInjection/DIContainer.php +++ b/lib/private/AppFramework/DependencyInjection/DIContainer.php @@ -79,6 +79,7 @@ use Psr\Log\LoggerInterface; * @deprecated 20.0.0 */ class DIContainer extends SimpleContainer implements IAppContainer { + private string $appName; /** * @var array @@ -94,9 +95,10 @@ class DIContainer extends SimpleContainer implements IAppContainer { * @param array $urlParams * @param ServerContainer|null $server */ - public function __construct($appName, $urlParams = [], ServerContainer $server = null) { + public function __construct(string $appName, array $urlParams = [], ServerContainer $server = null) { parent::__construct(); - $this['AppName'] = $appName; + $this->appName = $appName; + $this['appName'] = $appName; $this['urlParams'] = $urlParams; $this->registerAlias('Request', IRequest::class); @@ -109,9 +111,12 @@ class DIContainer extends SimpleContainer implements IAppContainer { $this->server->registerAppContainer($appName, $this); // aliases - $this->registerAlias('appName', 'AppName'); - $this->registerAlias('webRoot', 'WebRoot'); - $this->registerAlias('userId', 'UserId'); + /** @deprecated inject $appName */ + $this->registerAlias('AppName', 'appName'); + /** @deprecated inject $webRoot*/ + $this->registerAlias('WebRoot', 'webRoot'); + /** @deprecated inject $userId */ + $this->registerAlias('UserId', 'userId'); /** * Core services @@ -158,11 +163,11 @@ class DIContainer extends SimpleContainer implements IAppContainer { $this->registerAlias(IAppContainer::class, ContainerInterface::class); // commonly used attributes - $this->registerService('UserId', function (ContainerInterface $c) { + $this->registerService('userId', function (ContainerInterface $c) { return $c->get(IUserSession::class)->getSession()->get('user_id'); }); - $this->registerService('WebRoot', function (ContainerInterface $c) { + $this->registerService('webRoot', function (ContainerInterface $c) { return $c->get(IServerContainer::class)->getWebRoot(); }); @@ -301,7 +306,8 @@ class DIContainer extends SimpleContainer implements IAppContainer { new OC\AppFramework\Middleware\PublicShare\PublicShareMiddleware( $c->get(IRequest::class), $c->get(ISession::class), - $c->get(\OCP\IConfig::class) + $c->get(\OCP\IConfig::class), + $c->get(OC\Security\Bruteforce\Throttler::class) ) ); $dispatcher->registerMiddleware( @@ -433,6 +439,15 @@ class DIContainer extends SimpleContainer implements IAppContainer { } public function query(string $name, bool $autoload = true) { + if ($name === 'AppName' || $name === 'appName') { + return $this->appName; + } + + $isServerClass = str_starts_with($name, 'OCP\\') || str_starts_with($name, 'OC\\'); + if ($isServerClass && !$this->has($name)) { + return $this->getServer()->query($name, $autoload); + } + try { return $this->queryNoFallback($name); } catch (QueryException $firstException) { @@ -457,11 +472,11 @@ class DIContainer extends SimpleContainer implements IAppContainer { if ($this->offsetExists($name)) { return parent::query($name); - } elseif ($this['AppName'] === 'settings' && strpos($name, 'OC\\Settings\\') === 0) { + } elseif ($this->appName === 'settings' && str_starts_with($name, 'OC\\Settings\\')) { return parent::query($name); - } elseif ($this['AppName'] === 'core' && strpos($name, 'OC\\Core\\') === 0) { + } elseif ($this->appName === 'core' && str_starts_with($name, 'OC\\Core\\')) { return parent::query($name); - } elseif (strpos($name, \OC\AppFramework\App::buildAppNamespace($this['AppName']) . '\\') === 0) { + } elseif (str_starts_with($name, \OC\AppFramework\App::buildAppNamespace($this->appName) . '\\')) { return parent::query($name); } diff --git a/lib/private/AppFramework/Http/Dispatcher.php b/lib/private/AppFramework/Http/Dispatcher.php index c1a203a7165..aaaf2ba6560 100644 --- a/lib/private/AppFramework/Http/Dispatcher.php +++ b/lib/private/AppFramework/Http/Dispatcher.php @@ -194,7 +194,7 @@ class Dispatcher { $arguments = []; // valid types that will be casted - $types = ['int', 'integer', 'bool', 'boolean', 'float']; + $types = ['int', 'integer', 'bool', 'boolean', 'float', 'double']; foreach ($this->reflector->getParameters() as $param => $default) { diff --git a/lib/private/AppFramework/Http/Request.php b/lib/private/AppFramework/Http/Request.php index 3764ce5c7f8..9f66fd1d3ec 100644 --- a/lib/private/AppFramework/Http/Request.php +++ b/lib/private/AppFramework/Http/Request.php @@ -432,13 +432,12 @@ class Request implements \ArrayAccess, \Countable, IRequest { // 'application/json' and other JSON-related content types must be decoded manually. if (preg_match(self::JSON_CONTENT_TYPE_REGEX, $this->getHeader('Content-Type')) === 1) { $params = json_decode(file_get_contents($this->inputStream), true); - if ($params !== null && \count($params) > 0) { + if (\is_array($params) && \count($params) > 0) { $this->items['params'] = $params; if ($this->method === 'POST') { $this->items['post'] = $params; } } - // Handle application/x-www-form-urlencoded for methods other than GET // or post correctly } elseif ($this->method !== 'GET' diff --git a/lib/private/AppFramework/Middleware/PublicShare/PublicShareMiddleware.php b/lib/private/AppFramework/Middleware/PublicShare/PublicShareMiddleware.php index d3beb4fd3a8..d956ce58912 100644 --- a/lib/private/AppFramework/Middleware/PublicShare/PublicShareMiddleware.php +++ b/lib/private/AppFramework/Middleware/PublicShare/PublicShareMiddleware.php @@ -24,6 +24,7 @@ namespace OC\AppFramework\Middleware\PublicShare; use OC\AppFramework\Middleware\PublicShare\Exceptions\NeedAuthenticationException; +use OC\Security\Bruteforce\Throttler; use OCP\AppFramework\AuthPublicShareController; use OCP\AppFramework\Http\NotFoundResponse; use OCP\AppFramework\Middleware; @@ -34,6 +35,7 @@ use OCP\IRequest; use OCP\ISession; class PublicShareMiddleware extends Middleware { + /** @var IRequest */ private $request; @@ -43,10 +45,14 @@ class PublicShareMiddleware extends Middleware { /** @var IConfig */ private $config; - public function __construct(IRequest $request, ISession $session, IConfig $config) { + /** @var Throttler */ + private $throttler; + + public function __construct(IRequest $request, ISession $session, IConfig $config, Throttler $throttler) { $this->request = $request; $this->session = $session; $this->config = $config; + $this->throttler = $throttler; } public function beforeController($controller, $methodName) { @@ -54,6 +60,11 @@ class PublicShareMiddleware extends Middleware { return; } + $controllerClassPath = explode('\\', get_class($controller)); + $controllerShortClass = end($controllerClassPath); + $bruteforceProtectionAction = $controllerShortClass . '::' . $methodName; + $this->throttler->sleepDelayOrThrowOnMax($this->request->getRemoteAddress(), $bruteforceProtectionAction); + if (!$this->isLinkSharingEnabled()) { throw new NotFoundException('Link sharing is disabled'); } @@ -68,6 +79,8 @@ class PublicShareMiddleware extends Middleware { $controller->setToken($token); if (!$controller->isValidToken()) { + $this->throttle($bruteforceProtectionAction, $token); + $controller->shareNotFound(); throw new NotFoundException(); } @@ -88,6 +101,7 @@ class PublicShareMiddleware extends Middleware { throw new NeedAuthenticationException(); } + $this->throttle($bruteforceProtectionAction, $token); throw new NotFoundException(); } @@ -128,4 +142,10 @@ class PublicShareMiddleware extends Middleware { return true; } + + private function throttle($bruteforceProtectionAction, $token): void { + $ip = $this->request->getRemoteAddress(); + $this->throttler->sleepDelay($ip, $bruteforceProtectionAction); + $this->throttler->registerAttempt($bruteforceProtectionAction, $ip, ['token' => $token]); + } } diff --git a/lib/private/AppFramework/Middleware/Security/CORSMiddleware.php b/lib/private/AppFramework/Middleware/Security/CORSMiddleware.php index 1490b69f534..dd964915006 100644 --- a/lib/private/AppFramework/Middleware/Security/CORSMiddleware.php +++ b/lib/private/AppFramework/Middleware/Security/CORSMiddleware.php @@ -87,6 +87,10 @@ class CORSMiddleware extends Middleware { $user = array_key_exists('PHP_AUTH_USER', $this->request->server) ? $this->request->server['PHP_AUTH_USER'] : null; $pass = array_key_exists('PHP_AUTH_PW', $this->request->server) ? $this->request->server['PHP_AUTH_PW'] : null; + // Allow to use the current session if a CSRF token is provided + if ($this->request->passesCSRFCheck()) { + return; + } $this->session->logout(); try { if ($user === null || $pass === null || !$this->session->logClientIn($user, $pass, $this->request, $this->throttler)) { diff --git a/lib/private/AppFramework/Utility/SimpleContainer.php b/lib/private/AppFramework/Utility/SimpleContainer.php index 429382aa223..925ef67de64 100644 --- a/lib/private/AppFramework/Utility/SimpleContainer.php +++ b/lib/private/AppFramework/Utility/SimpleContainer.php @@ -53,6 +53,15 @@ class SimpleContainer implements ArrayAccess, ContainerInterface, IContainer { $this->container = new Container(); } + /** + * @template T + * @param class-string<T>|string $id + * @return T|mixed + * @psalm-template S as class-string<T>|string + * @psalm-param S $id + * @psalm-return (S is class-string<T> ? T : mixed) + * @throws QueryException + */ public function get(string $id) { return $this->query($id); } @@ -99,7 +108,7 @@ class SimpleContainer implements ArrayAccess, ContainerInterface, IContainer { return $this->query($resolveName); } catch (QueryException $e2) { // don't lose the error we got while trying to query by type - throw new QueryException($e2->getMessage(), (int) $e2->getCode(), $e); + throw new QueryException($e->getMessage(), (int) $e->getCode(), $e); } } |