aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/AppFramework
diff options
context:
space:
mode:
authorStanimir Bozhilov <stanimir.bozhilov.1998@gmail.com>2022-12-19 09:07:38 +0100
committerGitHub <noreply@github.com>2022-12-19 09:07:38 +0100
commit7dcd6eb561f4bba7ed36ce1178c725278dd9b80e (patch)
tree8de1664f1a18df2e3b7b3dafadb3e0b6c3a8b439 /lib/private/AppFramework
parented902d58b62150a46c745b5e87c895fc3fc67509 (diff)
parente12aaa298861743f798d9adf644d626ac8e89a95 (diff)
downloadnextcloud-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')
-rw-r--r--lib/private/AppFramework/DependencyInjection/DIContainer.php37
-rw-r--r--lib/private/AppFramework/Http/Dispatcher.php2
-rw-r--r--lib/private/AppFramework/Http/Request.php3
-rw-r--r--lib/private/AppFramework/Middleware/PublicShare/PublicShareMiddleware.php22
-rw-r--r--lib/private/AppFramework/Middleware/Security/CORSMiddleware.php4
-rw-r--r--lib/private/AppFramework/Utility/SimpleContainer.php11
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);
}
}