summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/autoloader.php35
-rw-r--r--lib/base.php19
-rw-r--r--lib/l10n/cs_CZ.js1
-rw-r--r--lib/l10n/cs_CZ.json1
-rw-r--r--lib/l10n/da.js1
-rw-r--r--lib/l10n/da.json1
-rw-r--r--lib/l10n/el.js1
-rw-r--r--lib/l10n/el.json1
-rw-r--r--lib/l10n/es.js1
-rw-r--r--lib/l10n/es.json1
-rw-r--r--lib/l10n/fi_FI.js1
-rw-r--r--lib/l10n/fi_FI.json1
-rw-r--r--lib/l10n/fr.js1
-rw-r--r--lib/l10n/fr.json1
-rw-r--r--lib/l10n/id.js1
-rw-r--r--lib/l10n/id.json1
-rw-r--r--lib/l10n/it.js1
-rw-r--r--lib/l10n/it.json1
-rw-r--r--lib/l10n/nl.js1
-rw-r--r--lib/l10n/nl.json1
-rw-r--r--lib/l10n/pt_BR.js1
-rw-r--r--lib/l10n/pt_BR.json1
-rw-r--r--lib/l10n/th_TH.js1
-rw-r--r--lib/l10n/th_TH.json1
-rw-r--r--lib/private/activitymanager.php14
-rw-r--r--lib/private/app.php3
-rw-r--r--lib/private/appconfig.php219
-rw-r--r--lib/private/appframework/http.php2
-rw-r--r--lib/private/appframework/http/request.php83
-rw-r--r--lib/private/backgroundjob/joblist.php22
-rw-r--r--lib/private/encryption/keys/storage.php25
-rw-r--r--lib/private/encryption/manager.php53
-rw-r--r--lib/private/encryption/util.php42
-rw-r--r--lib/private/files.php58
-rw-r--r--lib/private/files/cache/cache.php96
-rw-r--r--lib/private/files/storage/storagefactory.php3
-rw-r--r--lib/private/files/type/detection.php30
-rw-r--r--lib/private/files/type/loader.php165
-rw-r--r--lib/private/json.php2
-rw-r--r--lib/private/preview.php74
-rw-r--r--lib/private/route/router.php5
-rw-r--r--lib/private/security/certificatemanager.php15
-rw-r--r--lib/private/server.php49
-rw-r--r--lib/private/share/share.php16
-rw-r--r--lib/private/util.php10
-rw-r--r--lib/public/appframework/http/jsonresponse.php2
-rw-r--r--lib/public/autoloadnotallowedexception.php36
-rw-r--r--lib/public/files/imimetypeloader.php59
-rw-r--r--lib/public/iservercontainer.php8
49 files changed, 814 insertions, 353 deletions
diff --git a/lib/autoloader.php b/lib/autoloader.php
index 23285f61e73..41a040b3f54 100644
--- a/lib/autoloader.php
+++ b/lib/autoloader.php
@@ -27,6 +27,8 @@
namespace OC;
+use \OCP\AutoloadNotAllowedException;
+
class Autoloader {
private $useGlobalClassPath = true;
@@ -34,13 +36,34 @@ class Autoloader {
private $classPaths = array();
+ private $validRoots = [];
+
/**
* Optional low-latency memory cache for class to path mapping.
+ *
* @var \OC\Memcache\Cache
*/
protected $memoryCache;
/**
+ * Autoloader constructor.
+ *
+ * @param string[] $validRoots
+ */
+ public function __construct(array $validRoots) {
+ $this->validRoots = $validRoots;
+ }
+
+ /**
+ * Add a path to the list of valid php roots for auto loading
+ *
+ * @param string $root
+ */
+ public function addValidRoot($root) {
+ $this->validRoots[] = stream_resolve_include_path($root);
+ }
+
+ /**
* disable the usage of the global classpath \OC::$CLASSPATH
*/
public function disableGlobalClassPath() {
@@ -102,6 +125,15 @@ class Autoloader {
return $paths;
}
+ protected function isValidPath($fullPath) {
+ foreach ($this->validRoots as $root) {
+ if (substr($fullPath, 0, strlen($root) + 1) === $root . '/') {
+ return true;
+ }
+ }
+ throw new AutoloadNotAllowedException($fullPath);
+ }
+
/**
* Load the specified class
*
@@ -119,7 +151,7 @@ class Autoloader {
$pathsToRequire = array();
foreach ($this->findClass($class) as $path) {
$fullPath = stream_resolve_include_path($path);
- if ($fullPath) {
+ if ($fullPath && $this->isValidPath($fullPath)) {
$pathsToRequire[] = $fullPath;
}
}
@@ -138,6 +170,7 @@ class Autoloader {
/**
* Sets the optional low-latency cache for class to path mapping.
+ *
* @param \OC\Memcache\Cache $memoryCache Instance of memory cache.
*/
public function setMemoryCache(\OC\Memcache\Cache $memoryCache = null) {
diff --git a/lib/base.php b/lib/base.php
index aceac2e53c3..a4b5e9e01bf 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -115,9 +115,6 @@ class OC {
* the app path list is empty or contains an invalid path
*/
public static function initPaths() {
- // calculate the root directories
- OC::$SERVERROOT = str_replace("\\", '/', substr(__DIR__, 0, -4));
-
// ensure we can find OC_Config
set_include_path(
OC::$SERVERROOT . '/lib' . PATH_SEPARATOR .
@@ -519,10 +516,20 @@ class OC {
}
public static function init() {
+ // calculate the root directories
+ OC::$SERVERROOT = str_replace("\\", '/', substr(__DIR__, 0, -4));
+
// register autoloader
$loaderStart = microtime(true);
require_once __DIR__ . '/autoloader.php';
- self::$loader = new \OC\Autoloader();
+ self::$loader = new \OC\Autoloader([
+ OC::$SERVERROOT . '/lib',
+ OC::$SERVERROOT . '/core',
+ OC::$SERVERROOT . '/settings',
+ OC::$SERVERROOT . '/ocs',
+ OC::$SERVERROOT . '/ocs-provider',
+ OC::$SERVERROOT . '/3rdparty'
+ ]);
spl_autoload_register(array(self::$loader, 'load'));
$loaderEnd = microtime(true);
@@ -533,7 +540,7 @@ class OC {
// setup 3rdparty autoloader
$vendorAutoLoad = OC::$THIRDPARTYROOT . '/3rdparty/autoload.php';
if (!file_exists($vendorAutoLoad)) {
- throw new \RuntimeException('Composer autoloader not found, unable to continue. Check the folder "3rdparty".');
+ throw new \RuntimeException('Composer autoloader not found, unable to continue. Check the folder "3rdparty". Running "git submodule update --init" will initialize the git submodule that handles the subfolder "3rdparty".');
}
require_once $vendorAutoLoad;
@@ -663,7 +670,7 @@ class OC {
self::registerCacheHooks();
self::registerFilesystemHooks();
- if (\OC::$server->getSystemConfig()->getValue('enable_previews', true)) {
+ if ($systemConfig->getValue('enable_previews', true)) {
self::registerPreviewHooks();
}
self::registerShareHooks();
diff --git a/lib/l10n/cs_CZ.js b/lib/l10n/cs_CZ.js
index 8885ecd6e10..715b834d2bf 100644
--- a/lib/l10n/cs_CZ.js
+++ b/lib/l10n/cs_CZ.js
@@ -49,6 +49,7 @@ OC.L10N.register(
"Can't read file" : "Nelze přečíst soubor",
"App directory already exists" : "Adresář aplikace již existuje",
"Can't create app folder. Please fix permissions. %s" : "Nelze vytvořit složku aplikace. Opravte práva souborů. %s",
+ "Archive does not contain a directory named %s" : "Archiv neobsahuje adresář pojmenovaný %s",
"No source specified when installing app" : "Nebyl zadán zdroj při instalaci aplikace",
"No href specified when installing app from http" : "Nebyl zadán odkaz pro instalaci aplikace z HTTP",
"No path specified when installing app from local file" : "Nebyla zadána cesta pro instalaci aplikace z místního souboru",
diff --git a/lib/l10n/cs_CZ.json b/lib/l10n/cs_CZ.json
index c5f50a73848..891b30850ab 100644
--- a/lib/l10n/cs_CZ.json
+++ b/lib/l10n/cs_CZ.json
@@ -47,6 +47,7 @@
"Can't read file" : "Nelze přečíst soubor",
"App directory already exists" : "Adresář aplikace již existuje",
"Can't create app folder. Please fix permissions. %s" : "Nelze vytvořit složku aplikace. Opravte práva souborů. %s",
+ "Archive does not contain a directory named %s" : "Archiv neobsahuje adresář pojmenovaný %s",
"No source specified when installing app" : "Nebyl zadán zdroj při instalaci aplikace",
"No href specified when installing app from http" : "Nebyl zadán odkaz pro instalaci aplikace z HTTP",
"No path specified when installing app from local file" : "Nebyla zadána cesta pro instalaci aplikace z místního souboru",
diff --git a/lib/l10n/da.js b/lib/l10n/da.js
index 42f367d21c2..d644d7d3426 100644
--- a/lib/l10n/da.js
+++ b/lib/l10n/da.js
@@ -91,6 +91,7 @@ OC.L10N.register(
"Sharing %s failed, because the user %s does not exist" : "Der skete en fejl ved deling af %s, brugeren %s eksistere ikke",
"Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Der skete en fejl ved deling af %s, brugeren %s er ikke medlem af nogle grupper som %s er medlem af",
"Sharing %s failed, because this item is already shared with %s" : "Der skete en fejl ved deling af %s, objektet er allerede delt med %s",
+ "Sharing %s failed, because this item is already shared with user %s" : "Deling af %s mislykkedes, fordi dette element allerede er delt med brugeren %s",
"Sharing %s failed, because the group %s does not exist" : "Der skete en fejl ved deling af %s, gruppen %s eksistere ikke",
"Sharing %s failed, because %s is not a member of the group %s" : "Der skete en fejl ved deling af %s, fordi %s ikke er medlem af gruppen %s",
"You need to provide a password to create a public link, only protected links are allowed" : "Du skal angive et kodeord for at oprette et offentligt link - kun beskyttede links er tilladt",
diff --git a/lib/l10n/da.json b/lib/l10n/da.json
index 0e20adc31bf..d57ea2a92ae 100644
--- a/lib/l10n/da.json
+++ b/lib/l10n/da.json
@@ -89,6 +89,7 @@
"Sharing %s failed, because the user %s does not exist" : "Der skete en fejl ved deling af %s, brugeren %s eksistere ikke",
"Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Der skete en fejl ved deling af %s, brugeren %s er ikke medlem af nogle grupper som %s er medlem af",
"Sharing %s failed, because this item is already shared with %s" : "Der skete en fejl ved deling af %s, objektet er allerede delt med %s",
+ "Sharing %s failed, because this item is already shared with user %s" : "Deling af %s mislykkedes, fordi dette element allerede er delt med brugeren %s",
"Sharing %s failed, because the group %s does not exist" : "Der skete en fejl ved deling af %s, gruppen %s eksistere ikke",
"Sharing %s failed, because %s is not a member of the group %s" : "Der skete en fejl ved deling af %s, fordi %s ikke er medlem af gruppen %s",
"You need to provide a password to create a public link, only protected links are allowed" : "Du skal angive et kodeord for at oprette et offentligt link - kun beskyttede links er tilladt",
diff --git a/lib/l10n/el.js b/lib/l10n/el.js
index b47cc7e36d2..ee9ad8efd42 100644
--- a/lib/l10n/el.js
+++ b/lib/l10n/el.js
@@ -88,6 +88,7 @@ OC.L10N.register(
"Sharing %s failed, because the user %s does not exist" : "Ο διαμοιρασμός του %s απέτυχε, γιατί ο χρήστης %s δεν υπάρχει",
"Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Ο διαμοιρασμός του %s απέτυχε, γιατί ο χρήστης %s δεν είναι μέλος καμίας ομάδας στην οποία ο χρήστης %s είναι μέλος",
"Sharing %s failed, because this item is already shared with %s" : "Ο διαμοιρασμός του %s απέτυχε, γιατί το αντικείμενο είναι διαμοιρασμένο ήδη με τον χρήστη %s",
+ "Sharing %s failed, because this item is already shared with user %s" : "Αποτυχία διαμοιρασμού με %s, διότι αυτό το αντικείμενο διαμοιράζεται ήδη με τον χρήστη %s",
"Sharing %s failed, because the group %s does not exist" : "Ο διαμοιρασμός του %s απέτυχε, γιατί η ομάδα χρηστών %s δεν υπάρχει",
"Sharing %s failed, because %s is not a member of the group %s" : "Ο διαμοιρασμός του %s απέτυχε, γιατί ο χρήστης %s δεν είναι μέλος της ομάδας %s",
"You need to provide a password to create a public link, only protected links are allowed" : "Πρέπει να εισάγετε έναν κωδικό για να δημιουργήσετε έναν δημόσιο σύνδεσμο. Μόνο προστατευμένοι σύνδεσμοι επιτρέπονται",
diff --git a/lib/l10n/el.json b/lib/l10n/el.json
index d82aec00129..d0235598f7e 100644
--- a/lib/l10n/el.json
+++ b/lib/l10n/el.json
@@ -86,6 +86,7 @@
"Sharing %s failed, because the user %s does not exist" : "Ο διαμοιρασμός του %s απέτυχε, γιατί ο χρήστης %s δεν υπάρχει",
"Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Ο διαμοιρασμός του %s απέτυχε, γιατί ο χρήστης %s δεν είναι μέλος καμίας ομάδας στην οποία ο χρήστης %s είναι μέλος",
"Sharing %s failed, because this item is already shared with %s" : "Ο διαμοιρασμός του %s απέτυχε, γιατί το αντικείμενο είναι διαμοιρασμένο ήδη με τον χρήστη %s",
+ "Sharing %s failed, because this item is already shared with user %s" : "Αποτυχία διαμοιρασμού με %s, διότι αυτό το αντικείμενο διαμοιράζεται ήδη με τον χρήστη %s",
"Sharing %s failed, because the group %s does not exist" : "Ο διαμοιρασμός του %s απέτυχε, γιατί η ομάδα χρηστών %s δεν υπάρχει",
"Sharing %s failed, because %s is not a member of the group %s" : "Ο διαμοιρασμός του %s απέτυχε, γιατί ο χρήστης %s δεν είναι μέλος της ομάδας %s",
"You need to provide a password to create a public link, only protected links are allowed" : "Πρέπει να εισάγετε έναν κωδικό για να δημιουργήσετε έναν δημόσιο σύνδεσμο. Μόνο προστατευμένοι σύνδεσμοι επιτρέπονται",
diff --git a/lib/l10n/es.js b/lib/l10n/es.js
index e08ed66f1b5..3f1d751fc1e 100644
--- a/lib/l10n/es.js
+++ b/lib/l10n/es.js
@@ -91,6 +91,7 @@ OC.L10N.register(
"Sharing %s failed, because the user %s does not exist" : "Se ha fallado al compartir %s, ya que el usuario %s no existe",
"Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Se ha fallado al compartir %s, ya que el usuario %s no es miembro de ningún grupo del que %s sea miembro",
"Sharing %s failed, because this item is already shared with %s" : "Se falló al compartir %s, ya que este elemento ya está compartido con %s",
+ "Sharing %s failed, because this item is already shared with user %s" : "Compartiendo %s falló, porque este objeto ya se comparte con el usuario %s",
"Sharing %s failed, because the group %s does not exist" : "Se falló al compartir %s, ya que el grupo %s no existe",
"Sharing %s failed, because %s is not a member of the group %s" : "Se falló al compartir %s, ya que %s no es miembro del grupo %s",
"You need to provide a password to create a public link, only protected links are allowed" : "Es necesario definir una contraseña para crear un enlace publico. Solo los enlaces protegidos están permitidos",
diff --git a/lib/l10n/es.json b/lib/l10n/es.json
index f9bca103231..75b8060b819 100644
--- a/lib/l10n/es.json
+++ b/lib/l10n/es.json
@@ -89,6 +89,7 @@
"Sharing %s failed, because the user %s does not exist" : "Se ha fallado al compartir %s, ya que el usuario %s no existe",
"Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Se ha fallado al compartir %s, ya que el usuario %s no es miembro de ningún grupo del que %s sea miembro",
"Sharing %s failed, because this item is already shared with %s" : "Se falló al compartir %s, ya que este elemento ya está compartido con %s",
+ "Sharing %s failed, because this item is already shared with user %s" : "Compartiendo %s falló, porque este objeto ya se comparte con el usuario %s",
"Sharing %s failed, because the group %s does not exist" : "Se falló al compartir %s, ya que el grupo %s no existe",
"Sharing %s failed, because %s is not a member of the group %s" : "Se falló al compartir %s, ya que %s no es miembro del grupo %s",
"You need to provide a password to create a public link, only protected links are allowed" : "Es necesario definir una contraseña para crear un enlace publico. Solo los enlaces protegidos están permitidos",
diff --git a/lib/l10n/fi_FI.js b/lib/l10n/fi_FI.js
index d82d26645db..6960162e0ab 100644
--- a/lib/l10n/fi_FI.js
+++ b/lib/l10n/fi_FI.js
@@ -82,6 +82,7 @@ OC.L10N.register(
"Sharing %s failed, because the user %s is the item owner" : "Kohteen %s jakaminen epäonnistui, koska käyttäjä %s on kohteen omistaja",
"Sharing %s failed, because the user %s does not exist" : "Kohteen %s jakaminen epäonnistui, koska käyttäjää %s ei ole olemassa",
"Sharing %s failed, because this item is already shared with %s" : "Kohteen %s jakaminen epäonnistui, koska kohde on jo jaettu käyttäjän %s kanssa",
+ "Sharing %s failed, because this item is already shared with user %s" : "Kohteen %s jakaminen epäonnistui, koska kohde on jo jaettu käyttäjän %s kanssa",
"Sharing %s failed, because the group %s does not exist" : "Kohteen %s jakaminen epäonnistui, koska ryhmää %s ei ole olemassa",
"Sharing %s failed, because %s is not a member of the group %s" : "Kohteen %s jakaminen epäonnistui, koska käyttäjä %s ei ole ryhmän %s jäsen",
"You need to provide a password to create a public link, only protected links are allowed" : "Anna salasana luodaksesi julkisen linkin. Vain suojatut linkit ovat sallittuja",
diff --git a/lib/l10n/fi_FI.json b/lib/l10n/fi_FI.json
index de6d474e467..7d23189b358 100644
--- a/lib/l10n/fi_FI.json
+++ b/lib/l10n/fi_FI.json
@@ -80,6 +80,7 @@
"Sharing %s failed, because the user %s is the item owner" : "Kohteen %s jakaminen epäonnistui, koska käyttäjä %s on kohteen omistaja",
"Sharing %s failed, because the user %s does not exist" : "Kohteen %s jakaminen epäonnistui, koska käyttäjää %s ei ole olemassa",
"Sharing %s failed, because this item is already shared with %s" : "Kohteen %s jakaminen epäonnistui, koska kohde on jo jaettu käyttäjän %s kanssa",
+ "Sharing %s failed, because this item is already shared with user %s" : "Kohteen %s jakaminen epäonnistui, koska kohde on jo jaettu käyttäjän %s kanssa",
"Sharing %s failed, because the group %s does not exist" : "Kohteen %s jakaminen epäonnistui, koska ryhmää %s ei ole olemassa",
"Sharing %s failed, because %s is not a member of the group %s" : "Kohteen %s jakaminen epäonnistui, koska käyttäjä %s ei ole ryhmän %s jäsen",
"You need to provide a password to create a public link, only protected links are allowed" : "Anna salasana luodaksesi julkisen linkin. Vain suojatut linkit ovat sallittuja",
diff --git a/lib/l10n/fr.js b/lib/l10n/fr.js
index 873abd44ad0..d0abd693e0c 100644
--- a/lib/l10n/fr.js
+++ b/lib/l10n/fr.js
@@ -90,6 +90,7 @@ OC.L10N.register(
"Sharing %s failed, because the user %s does not exist" : "Le partage de %s a échoué car l'utilisateur %s n'existe pas",
"Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Le partage de %s a échoué car l'utilisateur %s n'est membre d'aucun groupe auquel %s appartient",
"Sharing %s failed, because this item is already shared with %s" : "Le partage de %s a échoué car cet objet est déjà partagé avec %s",
+ "Sharing %s failed, because this item is already shared with user %s" : "Le partage de %s a échoué car cet élément est déjà partagé avec l'utilisateur %s",
"Sharing %s failed, because the group %s does not exist" : "Le partage de %s a échoué car le groupe %s n'existe pas",
"Sharing %s failed, because %s is not a member of the group %s" : "Le partage de %s a échoué car %s n'est pas membre du groupe %s",
"You need to provide a password to create a public link, only protected links are allowed" : "Vous devez fournir un mot de passe pour créer un lien public, seuls les liens protégés sont autorisées.",
diff --git a/lib/l10n/fr.json b/lib/l10n/fr.json
index 440f2ddd84d..d0a90797df9 100644
--- a/lib/l10n/fr.json
+++ b/lib/l10n/fr.json
@@ -88,6 +88,7 @@
"Sharing %s failed, because the user %s does not exist" : "Le partage de %s a échoué car l'utilisateur %s n'existe pas",
"Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Le partage de %s a échoué car l'utilisateur %s n'est membre d'aucun groupe auquel %s appartient",
"Sharing %s failed, because this item is already shared with %s" : "Le partage de %s a échoué car cet objet est déjà partagé avec %s",
+ "Sharing %s failed, because this item is already shared with user %s" : "Le partage de %s a échoué car cet élément est déjà partagé avec l'utilisateur %s",
"Sharing %s failed, because the group %s does not exist" : "Le partage de %s a échoué car le groupe %s n'existe pas",
"Sharing %s failed, because %s is not a member of the group %s" : "Le partage de %s a échoué car %s n'est pas membre du groupe %s",
"You need to provide a password to create a public link, only protected links are allowed" : "Vous devez fournir un mot de passe pour créer un lien public, seuls les liens protégés sont autorisées.",
diff --git a/lib/l10n/id.js b/lib/l10n/id.js
index 432ea5c0192..2114b34eddd 100644
--- a/lib/l10n/id.js
+++ b/lib/l10n/id.js
@@ -49,6 +49,7 @@ OC.L10N.register(
"Can't read file" : "Tidak dapat membaca berkas",
"App directory already exists" : "Direktori Apl sudah ada",
"Can't create app folder. Please fix permissions. %s" : "Tidak dapat membuat folder apl. Silakan perbaiki perizinan. %s",
+ "Archive does not contain a directory named %s" : "Arsip tidak berisi direktori yang bernama %s",
"No source specified when installing app" : "Tidak ada sumber yang ditentukan saat menginstal apl",
"No href specified when installing app from http" : "Href tidak ditentukan saat menginstal apl dari http",
"No path specified when installing app from local file" : "Lokasi tidak ditentukan saat menginstal apl dari berkas lokal",
diff --git a/lib/l10n/id.json b/lib/l10n/id.json
index 6aeffa363da..cdc17b6ce8e 100644
--- a/lib/l10n/id.json
+++ b/lib/l10n/id.json
@@ -47,6 +47,7 @@
"Can't read file" : "Tidak dapat membaca berkas",
"App directory already exists" : "Direktori Apl sudah ada",
"Can't create app folder. Please fix permissions. %s" : "Tidak dapat membuat folder apl. Silakan perbaiki perizinan. %s",
+ "Archive does not contain a directory named %s" : "Arsip tidak berisi direktori yang bernama %s",
"No source specified when installing app" : "Tidak ada sumber yang ditentukan saat menginstal apl",
"No href specified when installing app from http" : "Href tidak ditentukan saat menginstal apl dari http",
"No path specified when installing app from local file" : "Lokasi tidak ditentukan saat menginstal apl dari berkas lokal",
diff --git a/lib/l10n/it.js b/lib/l10n/it.js
index d0c0022fd06..d0cf725013b 100644
--- a/lib/l10n/it.js
+++ b/lib/l10n/it.js
@@ -91,6 +91,7 @@ OC.L10N.register(
"Sharing %s failed, because the user %s does not exist" : "Condivisione di %s non riuscita, poiché l'utente %s non esiste",
"Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Condivisione di %s non riuscita, poiché l'utente %s non appartiene ad alcun gruppo di cui %s è membro",
"Sharing %s failed, because this item is already shared with %s" : "Condivisione di %s non riuscita, poiché l'oggetto è già condiviso con %s",
+ "Sharing %s failed, because this item is already shared with user %s" : "Condivisione di %s non riuscita, poiché l'oggetto è già condiviso con l'utente %s",
"Sharing %s failed, because the group %s does not exist" : "Condivisione di %s non riuscita, poiché il gruppo %s non esiste",
"Sharing %s failed, because %s is not a member of the group %s" : "Condivisione di %s non riuscita, poiché %s non appartiene al gruppo %s",
"You need to provide a password to create a public link, only protected links are allowed" : "Devi fornire una password per creare un collegamento pubblico, sono consentiti solo i collegamenti protetti",
diff --git a/lib/l10n/it.json b/lib/l10n/it.json
index 1183b588eb2..81038c0e425 100644
--- a/lib/l10n/it.json
+++ b/lib/l10n/it.json
@@ -89,6 +89,7 @@
"Sharing %s failed, because the user %s does not exist" : "Condivisione di %s non riuscita, poiché l'utente %s non esiste",
"Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Condivisione di %s non riuscita, poiché l'utente %s non appartiene ad alcun gruppo di cui %s è membro",
"Sharing %s failed, because this item is already shared with %s" : "Condivisione di %s non riuscita, poiché l'oggetto è già condiviso con %s",
+ "Sharing %s failed, because this item is already shared with user %s" : "Condivisione di %s non riuscita, poiché l'oggetto è già condiviso con l'utente %s",
"Sharing %s failed, because the group %s does not exist" : "Condivisione di %s non riuscita, poiché il gruppo %s non esiste",
"Sharing %s failed, because %s is not a member of the group %s" : "Condivisione di %s non riuscita, poiché %s non appartiene al gruppo %s",
"You need to provide a password to create a public link, only protected links are allowed" : "Devi fornire una password per creare un collegamento pubblico, sono consentiti solo i collegamenti protetti",
diff --git a/lib/l10n/nl.js b/lib/l10n/nl.js
index d08e8294dfb..5abae786d34 100644
--- a/lib/l10n/nl.js
+++ b/lib/l10n/nl.js
@@ -91,6 +91,7 @@ OC.L10N.register(
"Sharing %s failed, because the user %s does not exist" : "Delen van %s is mislukt, omdat gebruiker %s niet bestaat",
"Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Delen van %s is mislukt, omdat gebruiker %s geen lid is van een groep waar %s lid van is",
"Sharing %s failed, because this item is already shared with %s" : "Delen van %s is mislukt, omdat het object al wordt gedeeld met %s",
+ "Sharing %s failed, because this item is already shared with user %s" : "Delen van %s is mislukt, omdat het object al wordt gedeeld met gebruiker %s",
"Sharing %s failed, because the group %s does not exist" : "Delen van %s is mislukt, omdat groep %s niet bestaat",
"Sharing %s failed, because %s is not a member of the group %s" : "Delen van %s is mislukt, omdat %s geen lid is van groep %s",
"You need to provide a password to create a public link, only protected links are allowed" : "U moet een wachtwoord verstrekken om een openbare koppeling te maken, alleen beschermde links zijn toegestaan",
diff --git a/lib/l10n/nl.json b/lib/l10n/nl.json
index 8d0b5dc7169..4e4eaf8b52a 100644
--- a/lib/l10n/nl.json
+++ b/lib/l10n/nl.json
@@ -89,6 +89,7 @@
"Sharing %s failed, because the user %s does not exist" : "Delen van %s is mislukt, omdat gebruiker %s niet bestaat",
"Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Delen van %s is mislukt, omdat gebruiker %s geen lid is van een groep waar %s lid van is",
"Sharing %s failed, because this item is already shared with %s" : "Delen van %s is mislukt, omdat het object al wordt gedeeld met %s",
+ "Sharing %s failed, because this item is already shared with user %s" : "Delen van %s is mislukt, omdat het object al wordt gedeeld met gebruiker %s",
"Sharing %s failed, because the group %s does not exist" : "Delen van %s is mislukt, omdat groep %s niet bestaat",
"Sharing %s failed, because %s is not a member of the group %s" : "Delen van %s is mislukt, omdat %s geen lid is van groep %s",
"You need to provide a password to create a public link, only protected links are allowed" : "U moet een wachtwoord verstrekken om een openbare koppeling te maken, alleen beschermde links zijn toegestaan",
diff --git a/lib/l10n/pt_BR.js b/lib/l10n/pt_BR.js
index a53e5f01a16..402a7cbc51a 100644
--- a/lib/l10n/pt_BR.js
+++ b/lib/l10n/pt_BR.js
@@ -91,6 +91,7 @@ OC.L10N.register(
"Sharing %s failed, because the user %s does not exist" : "Compartilhamento %s falhou, porque o usuário %s não existe",
"Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Compartilhamento %s falhou, porque o usuário %s não é membro de nenhum grupo que o usuário %s pertença",
"Sharing %s failed, because this item is already shared with %s" : "Compartilhamento %s falhou, porque este ítem já está compartilhado com %s",
+ "Sharing %s failed, because this item is already shared with user %s" : "Compartilhamento de %s falhou, porque esse item já é compartilhada com o usuário %s",
"Sharing %s failed, because the group %s does not exist" : "Compartilhamento %s falhou, porque o grupo %s não existe",
"Sharing %s failed, because %s is not a member of the group %s" : "Compartilhamento %s falhou, porque %s não é membro do grupo %s",
"You need to provide a password to create a public link, only protected links are allowed" : "Você precisa fornecer uma senha para criar um link público, apenas links protegidos são permitidos",
diff --git a/lib/l10n/pt_BR.json b/lib/l10n/pt_BR.json
index cef167c2098..255272b8cb8 100644
--- a/lib/l10n/pt_BR.json
+++ b/lib/l10n/pt_BR.json
@@ -89,6 +89,7 @@
"Sharing %s failed, because the user %s does not exist" : "Compartilhamento %s falhou, porque o usuário %s não existe",
"Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Compartilhamento %s falhou, porque o usuário %s não é membro de nenhum grupo que o usuário %s pertença",
"Sharing %s failed, because this item is already shared with %s" : "Compartilhamento %s falhou, porque este ítem já está compartilhado com %s",
+ "Sharing %s failed, because this item is already shared with user %s" : "Compartilhamento de %s falhou, porque esse item já é compartilhada com o usuário %s",
"Sharing %s failed, because the group %s does not exist" : "Compartilhamento %s falhou, porque o grupo %s não existe",
"Sharing %s failed, because %s is not a member of the group %s" : "Compartilhamento %s falhou, porque %s não é membro do grupo %s",
"You need to provide a password to create a public link, only protected links are allowed" : "Você precisa fornecer uma senha para criar um link público, apenas links protegidos são permitidos",
diff --git a/lib/l10n/th_TH.js b/lib/l10n/th_TH.js
index 2ff86f599e9..6092f348cb5 100644
--- a/lib/l10n/th_TH.js
+++ b/lib/l10n/th_TH.js
@@ -91,6 +91,7 @@ OC.L10N.register(
"Sharing %s failed, because the user %s does not exist" : "การแชร์ %s ล้มเหลวเนื่องจากไม่ได้มีผู้ใช้ %s อยู่",
"Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "การแชร์ %s ล้มเหลวเนื่องจากผู้ใช้ %s ไม่ได้เป็นสมาชิกของกลุ่มใดๆ %s เป็นสมาชิกของ",
"Sharing %s failed, because this item is already shared with %s" : "การแชร์ %s ล้มเหลวเพราะรายการนี้ถูกแชร์กับ %s",
+ "Sharing %s failed, because this item is already shared with user %s" : "%s ที่กำลังแชร์ล้มเหลว เพราะรายการนี้ได้ถูกแชร์กับผู้ใช้ %s",
"Sharing %s failed, because the group %s does not exist" : "การแชร์ %s ล้มเหลวเพราะไม่มีกลุ่ม %s อยู่",
"Sharing %s failed, because %s is not a member of the group %s" : "การแชร์ %s ล้มเหลวเพราะ %s ไม่ได้เป็นสมาชิกของกลุ่ม %s",
"You need to provide a password to create a public link, only protected links are allowed" : "คุณจำเป็นต้องระบุรหัสผ่านเพื่อสร้างลิงค์สาธารณะ, ลิงค์ที่มีการป้องกันเท่านั้นที่ได้รับอนุญาต",
diff --git a/lib/l10n/th_TH.json b/lib/l10n/th_TH.json
index a215b67a180..a872236a70d 100644
--- a/lib/l10n/th_TH.json
+++ b/lib/l10n/th_TH.json
@@ -89,6 +89,7 @@
"Sharing %s failed, because the user %s does not exist" : "การแชร์ %s ล้มเหลวเนื่องจากไม่ได้มีผู้ใช้ %s อยู่",
"Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "การแชร์ %s ล้มเหลวเนื่องจากผู้ใช้ %s ไม่ได้เป็นสมาชิกของกลุ่มใดๆ %s เป็นสมาชิกของ",
"Sharing %s failed, because this item is already shared with %s" : "การแชร์ %s ล้มเหลวเพราะรายการนี้ถูกแชร์กับ %s",
+ "Sharing %s failed, because this item is already shared with user %s" : "%s ที่กำลังแชร์ล้มเหลว เพราะรายการนี้ได้ถูกแชร์กับผู้ใช้ %s",
"Sharing %s failed, because the group %s does not exist" : "การแชร์ %s ล้มเหลวเพราะไม่มีกลุ่ม %s อยู่",
"Sharing %s failed, because %s is not a member of the group %s" : "การแชร์ %s ล้มเหลวเพราะ %s ไม่ได้เป็นสมาชิกของกลุ่ม %s",
"You need to provide a password to create a public link, only protected links are allowed" : "คุณจำเป็นต้องระบุรหัสผ่านเพื่อสร้างลิงค์สาธารณะ, ลิงค์ที่มีการป้องกันเท่านั้นที่ได้รับอนุญาต",
diff --git a/lib/private/activitymanager.php b/lib/private/activitymanager.php
index a973db7206f..fc250173536 100644
--- a/lib/private/activitymanager.php
+++ b/lib/private/activitymanager.php
@@ -244,15 +244,27 @@ class ActivityManager implements IManager {
* @return array
*/
public function getNotificationTypes($languageCode) {
+ $filesNotificationTypes = [];
+ $sharingNotificationTypes = [];
+
$notificationTypes = array();
foreach ($this->getExtensions() as $c) {
$result = $c->getNotificationTypes($languageCode);
if (is_array($result)) {
+ if (class_exists('\OCA\Files\Activity') && $c instanceof \OCA\Files\Activity) {
+ $filesNotificationTypes = $result;
+ continue;
+ }
+ if (class_exists('\OCA\Files_Sharing\Activity') && $c instanceof \OCA\Files_Sharing\Activity) {
+ $sharingNotificationTypes = $result;
+ continue;
+ }
+
$notificationTypes = array_merge($notificationTypes, $result);
}
}
- return $notificationTypes;
+ return array_merge($filesNotificationTypes, $sharingNotificationTypes, $notificationTypes);
}
/**
diff --git a/lib/private/app.php b/lib/private/app.php
index f1a1d27ae66..f6a81f9945f 100644
--- a/lib/private/app.php
+++ b/lib/private/app.php
@@ -105,7 +105,6 @@ class OC_App {
ob_start();
foreach ($apps as $app) {
if ((is_null($types) or self::isType($app, $types)) && !in_array($app, self::$loadedApps)) {
- self::$loadedApps[] = $app;
self::loadApp($app);
}
}
@@ -122,6 +121,8 @@ class OC_App {
* @throws \OC\NeedsUpdateException
*/
public static function loadApp($app, $checkUpgrade = true) {
+ self::$loadedApps[] = $app;
+ \OC::$loader->addValidRoot(self::getAppPath($app));
if (is_file(self::getAppPath($app) . '/appinfo/app.php')) {
\OC::$server->getEventLogger()->start('load_app_' . $app, 'Load app: ' . $app);
if ($checkUpgrade and self::shouldUpgrade($app)) {
diff --git a/lib/private/appconfig.php b/lib/private/appconfig.php
index b88df10dddd..7ee64980fd0 100644
--- a/lib/private/appconfig.php
+++ b/lib/private/appconfig.php
@@ -28,23 +28,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
-/*
- *
- * The following SQL statement is just a help for developers and will not be
- * executed!
- *
- * CREATE TABLE `appconfig` (
- * `appid` VARCHAR( 255 ) NOT NULL ,
- * `configkey` VARCHAR( 255 ) NOT NULL ,
- * `configvalue` VARCHAR( 255 ) NOT NULL
- * )
- *
- */
namespace OC;
-use OC\DB\Connection;
use OCP\IAppConfig;
+use OCP\IDBConnection;
/**
* This class provides an easy way for apps to store config values in the
@@ -52,54 +40,32 @@ use OCP\IAppConfig;
*/
class AppConfig implements IAppConfig {
/**
- * @var \OC\DB\Connection $conn
+ * @var \OCP\IDBConnection $conn
*/
protected $conn;
private $cache = array();
- private $appsLoaded = array();
-
- /**
- * @var string[]
- */
- private $apps = null;
-
/**
- * @param Connection $conn
+ * @param IDBConnection $conn
*/
- public function __construct(Connection $conn) {
+ public function __construct(IDBConnection $conn) {
$this->conn = $conn;
+ $this->configLoaded = false;
}
/**
* @param string $app
- * @return string[]
- */
- private function getAppCache($app) {
- if (!isset($this->cache[$app])) {
- $this->cache[$app] = array();
- }
- return $this->cache[$app];
- }
-
- /**
- * @param string $app
- * @return \string[]
+ * @return array
*/
private function getAppValues($app) {
- $appCache = $this->getAppCache($app);
- if (array_search($app, $this->appsLoaded) === false) {
- $query = 'SELECT `configvalue`, `configkey` FROM `*PREFIX*appconfig`'
- . ' WHERE `appid` = ?';
- $result = $this->conn->executeQuery($query, array($app));
- while ($row = $result->fetch()) {
- $appCache[$row['configkey']] = $row['configvalue'];
- }
- $this->appsLoaded[] = $app;
+ $this->loadConfigValues();
+
+ if (isset($this->cache[$app])) {
+ return $this->cache[$app];
}
- $this->cache[$app] = $appCache;
- return $appCache;
+
+ return [];
}
/**
@@ -111,18 +77,9 @@ class AppConfig implements IAppConfig {
* entry in the appconfig table.
*/
public function getApps() {
- if (is_array($this->apps)) {
- return $this->apps;
- }
- $query = 'SELECT DISTINCT `appid` FROM `*PREFIX*appconfig` ORDER BY `appid`';
- $result = $this->conn->executeQuery($query);
+ $this->loadConfigValues();
- $apps = array();
- while ($appid = $result->fetchColumn()) {
- $apps[] = $appid;
- }
- $this->apps = $apps;
- return $apps;
+ return $this->getSortedKeys($this->cache);
}
/**
@@ -135,8 +92,17 @@ class AppConfig implements IAppConfig {
* not returned.
*/
public function getKeys($app) {
- $values = $this->getAppValues($app);
- $keys = array_keys($values);
+ $this->loadConfigValues();
+
+ if (isset($this->cache[$app])) {
+ return $this->getSortedKeys($this->cache[$app]);
+ }
+
+ return [];
+ }
+
+ public function getSortedKeys($data) {
+ $keys = array_keys($data);
sort($keys);
return $keys;
}
@@ -153,12 +119,13 @@ class AppConfig implements IAppConfig {
* not exist the default value will be returned
*/
public function getValue($app, $key, $default = null) {
- $values = $this->getAppValues($app);
- if (isset($values[$key])) {
- return $values[$key];
- } else {
- return $default;
+ $this->loadConfigValues();
+
+ if ($this->hasKey($app, $key)) {
+ return $this->cache[$app][$key];
}
+
+ return $default;
}
/**
@@ -169,8 +136,9 @@ class AppConfig implements IAppConfig {
* @return bool
*/
public function hasKey($app, $key) {
- $values = $this->getAppValues($app);
- return array_key_exists($key, $values);
+ $this->loadConfigValues();
+
+ return isset($this->cache[$app][$key]);
}
/**
@@ -179,11 +147,9 @@ class AppConfig implements IAppConfig {
* @param string $app app
* @param string $key key
* @param string $value value
- * @return void
+ * @return bool True if the value was inserted or updated, false if the value was the same
*/
public function setValue($app, $key, $value) {
- $inserted = false;
- // Does the key exist? no: insert, yes: update.
if (!$this->hasKey($app, $key)) {
$inserted = (bool) $this->conn->insertIfNotExist('*PREFIX*appconfig', [
'appid' => $app,
@@ -193,29 +159,32 @@ class AppConfig implements IAppConfig {
'appid',
'configkey',
]);
- }
- if (!$inserted) {
- $oldValue = $this->getValue($app, $key);
- if($oldValue === strval($value)) {
- return;
+ if ($inserted) {
+ if (!isset($this->cache[$app])) {
+ $this->cache[$app] = [];
+ }
+
+ $this->cache[$app][$key] = $value;
+ return true;
}
- $data = array(
- 'configvalue' => $value,
- );
- $where = array(
- 'appid' => $app,
- 'configkey' => $key,
- );
- $this->conn->update('*PREFIX*appconfig', $data, $where);
- }
- if (!isset($this->cache[$app])) {
- $this->cache[$app] = array();
- }
- if (is_array($this->apps) and array_search($app, $this->apps) === false) {
- $this->apps[$app] = $app;
}
+
+ $sql = $this->conn->getQueryBuilder();
+ $sql->update('appconfig')
+ ->set('configvalue', $sql->createParameter('configvalue'))
+ ->where($sql->expr()->eq('appid', $sql->createParameter('app')))
+ ->andWhere($sql->expr()->eq('configkey', $sql->createParameter('configkey')))
+ ->andWhere($sql->expr()->neq('configvalue', $sql->createParameter('configvalue')))
+ ->setParameter('configvalue', $value)
+ ->setParameter('app', $app)
+ ->setParameter('configkey', $key)
+ ->setParameter('configvalue', $value);
+ $changedRow = (bool) $sql->execute();
+
$this->cache[$app][$key] = $value;
+
+ return $changedRow;
}
/**
@@ -226,14 +195,17 @@ class AppConfig implements IAppConfig {
* @return boolean|null
*/
public function deleteKey($app, $key) {
- $where = array(
- 'appid' => $app,
- 'configkey' => $key,
- );
- $this->conn->delete('*PREFIX*appconfig', $where);
- if (isset($this->cache[$app]) and isset($this->cache[$app][$key])) {
- unset($this->cache[$app][$key]);
- }
+ $this->loadConfigValues();
+
+ $sql = $this->conn->getQueryBuilder();
+ $sql->delete('appconfig')
+ ->where($sql->expr()->eq('appid', $sql->createParameter('app')))
+ ->andWhere($sql->expr()->eq('configkey', $sql->createParameter('configkey')))
+ ->setParameter('app', $app)
+ ->setParameter('configkey', $key);
+ $sql->execute();
+
+ unset($this->cache[$app][$key]);
}
/**
@@ -245,38 +217,65 @@ class AppConfig implements IAppConfig {
* Removes all keys in appconfig belonging to the app.
*/
public function deleteApp($app) {
- $where = array(
- 'appid' => $app,
- );
- $this->conn->delete('*PREFIX*appconfig', $where);
+ $this->loadConfigValues();
+
+ $sql = $this->conn->getQueryBuilder();
+ $sql->delete('appconfig')
+ ->where($sql->expr()->eq('appid', $sql->createParameter('app')))
+ ->setParameter('app', $app);
+ $sql->execute();
+
unset($this->cache[$app]);
- unset($this->apps[$app]);
}
/**
- * get multiply values, either the app or key can be used as wildcard by setting it to false
+ * get multiple values, either the app or key can be used as wildcard by setting it to false
*
* @param string|false $app
* @param string|false $key
* @return array|false
*/
public function getValues($app, $key) {
- if (($app !== false) == ($key !== false)) {
+ if (($app !== false) === ($key !== false)) {
return false;
}
- if ($app !== false) {
+ if ($key === false) {
return $this->getAppValues($app);
} else {
- $query = 'SELECT `configvalue`, `appid` FROM `*PREFIX*appconfig` WHERE `configkey` = ?';
- $result = $this->conn->executeQuery($query, array($key));
+ $configs = [];
+ foreach ($this->getApps() as $appId) {
+ if ($this->hasKey($appId, $key)) {
+ $configs[$appId] = $this->getValue($appId, $key);
+ }
+ }
+
+ return $configs;
+ }
+ }
- $values = array();
- while ($row = $result->fetch((\PDO::FETCH_ASSOC))) {
- $values[$row['appid']] = $row['configvalue'];
+ /**
+ * Load all the app config values
+ */
+ protected function loadConfigValues() {
+ if ($this->configLoaded) return;
+
+ $this->cache = [];
+
+ $sql = $this->conn->getQueryBuilder();
+ $sql->select('*')
+ ->from('appconfig');
+ $result = $sql->execute();
+
+ while ($row = $result->fetch()) {
+ if (!isset($this->cache[$row['appid']])) {
+ $this->cache[$row['appid']] = [];
}
- return $values;
+ $this->cache[$row['appid']][$row['configkey']] = $row['configvalue'];
}
+ $result->closeCursor();
+
+ $this->configLoaded = true;
}
}
diff --git a/lib/private/appframework/http.php b/lib/private/appframework/http.php
index e7b0d1e2cab..dee9818f4bc 100644
--- a/lib/private/appframework/http.php
+++ b/lib/private/appframework/http.php
@@ -121,7 +121,7 @@ class Http extends BaseHttp {
// if etag or lastmodified have not changed, return a not modified
if ((isset($this->server['HTTP_IF_NONE_MATCH'])
- && trim($this->server['HTTP_IF_NONE_MATCH']) === $ETag)
+ && trim(trim($this->server['HTTP_IF_NONE_MATCH']), '"') === (string)$ETag)
||
diff --git a/lib/private/appframework/http/request.php b/lib/private/appframework/http/request.php
index a2109439177..b430673f9a9 100644
--- a/lib/private/appframework/http/request.php
+++ b/lib/private/appframework/http/request.php
@@ -9,6 +9,7 @@
* @author Thomas Müller <thomas.mueller@tmit.eu>
* @author Thomas Tanghus <thomas@tanghus.net>
* @author Vincent Petry <pvince81@owncloud.com>
+ * @author Robin McCorkell <rmccorkell@owncloud.com>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
* @license AGPL-3.0
@@ -71,6 +72,9 @@ class Request implements \ArrayAccess, \Countable, IRequest {
/** @var ICrypto */
protected $crypto;
+ /** @var bool */
+ protected $contentDecoded = false;
+
/**
* @param array $vars An associative array with the following optional values:
* - array 'urlParams' the parameters which were matched from the URL
@@ -109,27 +113,6 @@ class Request implements \ArrayAccess, \Countable, IRequest {
: array();
}
- // 'application/json' must be decoded manually.
- if (strpos($this->getHeader('Content-Type'), 'application/json') !== false) {
- $params = json_decode(file_get_contents($this->inputStream), true);
- if(count($params) > 0) {
- $this->items['params'] = $params;
- if($vars['method'] === 'POST') {
- $this->items['post'] = $params;
- }
- }
- // Handle application/x-www-form-urlencoded for methods other than GET
- // or post correctly
- } elseif($vars['method'] !== 'GET'
- && $vars['method'] !== 'POST'
- && strpos($this->getHeader('Content-Type'), 'application/x-www-form-urlencoded') !== false) {
-
- parse_str(file_get_contents($this->inputStream), $params);
- if(is_array($params)) {
- $this->items['params'] = $params;
- }
- }
-
$this->items['parameters'] = array_merge(
$this->items['get'],
$this->items['post'],
@@ -237,24 +220,19 @@ class Request implements \ArrayAccess, \Countable, IRequest {
if($this->method !== strtoupper($name)) {
throw new \LogicException(sprintf('%s cannot be accessed in a %s request.', $name, $this->method));
}
+ return $this->getContent();
case 'files':
case 'server':
case 'env':
case 'cookies':
- case 'parameters':
- case 'params':
case 'urlParams':
- if(in_array($name, array('put', 'patch'))) {
- return $this->getContent();
- } else {
- return isset($this->items[$name])
- ? $this->items[$name]
- : null;
- }
- break;
case 'method':
- return $this->items['method'];
- break;
+ return isset($this->items[$name])
+ ? $this->items[$name]
+ : null;
+ case 'parameters':
+ case 'params':
+ return $this->getContent();
default;
return isset($this[$name])
? $this[$name]
@@ -396,11 +374,48 @@ class Request implements \ArrayAccess, \Countable, IRequest {
$this->content = false;
return fopen($this->inputStream, 'rb');
} else {
- return $this->parameters;
+ $this->decodeContent();
+ return $this->items['parameters'];
}
}
/**
+ * Attempt to decode the content and populate parameters
+ */
+ protected function decodeContent() {
+ if ($this->contentDecoded) {
+ return;
+ }
+ $params = [];
+
+ // 'application/json' must be decoded manually.
+ if (strpos($this->getHeader('Content-Type'), 'application/json') !== false) {
+ $params = json_decode(file_get_contents($this->inputStream), true);
+ if(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'
+ && $this->method !== 'POST'
+ && strpos($this->getHeader('Content-Type'), 'application/x-www-form-urlencoded') !== false) {
+
+ parse_str(file_get_contents($this->inputStream), $params);
+ if(is_array($params)) {
+ $this->items['params'] = $params;
+ }
+ }
+
+ $this->items['parameters'] = array_merge($this->items['parameters'], $params);
+ $this->contentDecoded = true;
+ }
+
+
+ /**
* Checks if the CSRF check was correct
* @return bool true if CSRF check passed
* @see OC_Util::callRegister()
diff --git a/lib/private/backgroundjob/joblist.php b/lib/private/backgroundjob/joblist.php
index f297bccbc7d..deadadfb77e 100644
--- a/lib/private/backgroundjob/joblist.php
+++ b/lib/private/backgroundjob/joblist.php
@@ -26,6 +26,7 @@
namespace OC\BackgroundJob;
use OCP\BackgroundJob\IJobList;
+use OCP\AutoloadNotAllowedException;
class JobList implements IJobList {
/**
@@ -185,15 +186,20 @@ class JobList implements IJobList {
/**
* @var Job $job
*/
- if (!class_exists($class)) {
- // job from disabled app or old version of an app, no need to do anything
- return null;
+ try {
+ if (!class_exists($class)) {
+ // job from disabled app or old version of an app, no need to do anything
+ return null;
+ }
+ $job = new $class();
+ $job->setId($row['id']);
+ $job->setLastRun($row['last_run']);
+ $job->setArgument(json_decode($row['argument'], true));
+ return $job;
+ } catch (AutoloadNotAllowedException $e) {
+ // job is from a disabled app, ignore
}
- $job = new $class();
- $job->setId($row['id']);
- $job->setLastRun($row['last_run']);
- $job->setArgument(json_decode($row['argument'], true));
- return $job;
+ return null;
}
/**
diff --git a/lib/private/encryption/keys/storage.php b/lib/private/encryption/keys/storage.php
index b754462d9b0..d0c094538b0 100644
--- a/lib/private/encryption/keys/storage.php
+++ b/lib/private/encryption/keys/storage.php
@@ -27,11 +27,13 @@ namespace OC\Encryption\Keys;
use OC\Encryption\Util;
use OC\Files\Filesystem;
use OC\Files\View;
-use OCP\Encryption\Exceptions\GenericEncryptionException;
use OCP\Encryption\Keys\IStorage;
class Storage implements IStorage {
+ // hidden file which indicate that the folder is a valid key storage
+ const KEY_STORAGE_MARKER = '.oc_key_storage';
+
/** @var View */
private $view;
@@ -42,6 +44,10 @@ class Storage implements IStorage {
/** @var string */
private $keys_base_dir;
+ // root of the key storage default is empty which means that we use the data folder
+ /** @var string */
+ private $root_dir;
+
/** @var string */
private $encryption_base_dir;
@@ -58,6 +64,7 @@ class Storage implements IStorage {
$this->encryption_base_dir = '/files_encryption';
$this->keys_base_dir = $this->encryption_base_dir .'/keys';
+ $this->root_dir = $this->util->getKeyStorageRoot();
}
/**
@@ -162,13 +169,13 @@ class Storage implements IStorage {
protected function constructUserKeyPath($encryptionModuleId, $keyId, $uid) {
if ($uid === null) {
- $path = $this->encryption_base_dir . '/' . $encryptionModuleId . '/' . $keyId;
+ $path = $this->root_dir . '/' . $this->encryption_base_dir . '/' . $encryptionModuleId . '/' . $keyId;
} else {
- $path = '/' . $uid . $this->encryption_base_dir . '/'
+ $path = $this->root_dir . '/' . $uid . $this->encryption_base_dir . '/'
. $encryptionModuleId . '/' . $uid . '.' . $keyId;
}
- return $path;
+ return \OC\Files\Filesystem::normalizePath($path);
}
/**
@@ -227,9 +234,9 @@ class Storage implements IStorage {
// in case of system wide mount points the keys are stored directly in the data directory
if ($this->util->isSystemWideMountPoint($filename, $owner)) {
- $keyPath = $this->keys_base_dir . $filename . '/';
+ $keyPath = $this->root_dir . '/' . $this->keys_base_dir . $filename . '/';
} else {
- $keyPath = '/' . $owner . $this->keys_base_dir . $filename . '/';
+ $keyPath = $this->root_dir . '/' . $owner . $this->keys_base_dir . $filename . '/';
}
return Filesystem::normalizePath($keyPath . $encryptionModuleId . '/', false);
@@ -290,12 +297,12 @@ class Storage implements IStorage {
$systemWideMountPoint = $this->util->isSystemWideMountPoint($relativePath, $owner);
if ($systemWideMountPoint) {
- $systemPath = $this->keys_base_dir . $relativePath . '/';
+ $systemPath = $this->root_dir . '/' . $this->keys_base_dir . $relativePath . '/';
} else {
- $systemPath = '/' . $owner . $this->keys_base_dir . $relativePath . '/';
+ $systemPath = $this->root_dir . '/' . $owner . $this->keys_base_dir . $relativePath . '/';
}
- return $systemPath;
+ return Filesystem::normalizePath($systemPath, false);
}
/**
diff --git a/lib/private/encryption/manager.php b/lib/private/encryption/manager.php
index 1e0a065e25a..c004dfda0d9 100644
--- a/lib/private/encryption/manager.php
+++ b/lib/private/encryption/manager.php
@@ -25,14 +25,12 @@
namespace OC\Encryption;
+use OC\Encryption\Keys\Storage;
use OC\Files\Filesystem;
-use OC\Files\Storage\Shared;
-use OC\Files\Storage\Wrapper\Encryption;
use OC\Files\View;
-use OC\Search\Provider\File;
+use OC\ServiceUnavailableException;
use OCP\Encryption\IEncryptionModule;
use OCP\Encryption\IManager;
-use OCP\Files\Mount\IMountPoint;
use OCP\IConfig;
use OCP\IL10N;
use OCP\ILogger;
@@ -51,16 +49,26 @@ class Manager implements IManager {
/** @var Il10n */
protected $l;
+ /** @var View */
+ protected $rootView;
+
+ /** @var Util */
+ protected $util;
+
/**
* @param IConfig $config
* @param ILogger $logger
* @param IL10N $l10n
+ * @param View $rootView
+ * @param Util $util
*/
- public function __construct(IConfig $config, ILogger $logger, IL10N $l10n) {
+ public function __construct(IConfig $config, ILogger $logger, IL10N $l10n, View $rootView, Util $util) {
$this->encryptionModules = array();
$this->config = $config;
$this->logger = $logger;
$this->l = $l10n;
+ $this->rootView = $rootView;
+ $this->util = $util;
}
/**
@@ -82,7 +90,8 @@ class Manager implements IManager {
/**
* check if new encryption is ready
*
- * @return boolean
+ * @return bool
+ * @throws ServiceUnavailableException
*/
public function isReady() {
// check if we are still in transit between the old and the new encryption
@@ -94,6 +103,11 @@ class Manager implements IManager {
$this->logger->warning($warning);
return false;
}
+
+ if ($this->isKeyStorageReady() === false) {
+ throw new ServiceUnavailableException('Key Storage is not ready');
+ }
+
return true;
}
@@ -221,6 +235,31 @@ class Manager implements IManager {
\OC::$server->getGroupManager(),
\OC::$server->getConfig()
);
- \OC\Files\Filesystem::addStorageWrapper('oc_encryption', array($util, 'wrapStorage'), 2);
+ Filesystem::addStorageWrapper('oc_encryption', array($util, 'wrapStorage'), 2);
}
+
+
+ /**
+ * check if key storage is ready
+ *
+ * @return bool
+ */
+ protected function isKeyStorageReady() {
+
+ $rootDir = $this->util->getKeyStorageRoot();
+
+ // the default root is always valid
+ if ($rootDir === '') {
+ return true;
+ }
+
+ // check if key storage is mounted correctly
+ if ($this->rootView->file_exists($rootDir . '/' . Storage::KEY_STORAGE_MARKER)) {
+ return true;
+ }
+
+ return false;
+ }
+
+
}
diff --git a/lib/private/encryption/util.php b/lib/private/encryption/util.php
index d0733941a35..90ae8259972 100644
--- a/lib/private/encryption/util.php
+++ b/lib/private/encryption/util.php
@@ -59,7 +59,7 @@ class Util {
protected $blockSize = 8192;
/** @var View */
- protected $view;
+ protected $rootView;
/** @var array */
protected $ocHeaderKeys;
@@ -78,13 +78,13 @@ class Util {
/**
*
- * @param \OC\Files\View $view
+ * @param View $rootView
* @param \OC\User\Manager $userManager
* @param \OC\Group\Manager $groupManager
* @param IConfig $config
*/
public function __construct(
- \OC\Files\View $view,
+ View $rootView,
\OC\User\Manager $userManager,
\OC\Group\Manager $groupManager,
IConfig $config) {
@@ -93,7 +93,7 @@ class Util {
self::HEADER_ENCRYPTION_MODULE_KEY
];
- $this->view = $view;
+ $this->rootView = $rootView;
$this->userManager = $userManager;
$this->groupManager = $groupManager;
$this->config = $config;
@@ -167,7 +167,7 @@ class Util {
while ($dirList) {
$dir = array_pop($dirList);
- $content = $this->view->getDirectoryContent($dir);
+ $content = $this->rootView->getDirectoryContent($dir);
foreach ($content as $c) {
if ($c->getType() === 'dir') {
@@ -332,10 +332,22 @@ class Util {
* @return boolean
*/
public function isExcluded($path) {
- $normalizedPath = \OC\Files\Filesystem::normalizePath($path);
+ $normalizedPath = Filesystem::normalizePath($path);
$root = explode('/', $normalizedPath, 4);
if (count($root) > 1) {
+ // detect alternative key storage root
+ $rootDir = $this->getKeyStorageRoot();
+ if ($rootDir !== '' &&
+ 0 === strpos(
+ Filesystem::normalizePath($path),
+ Filesystem::normalizePath($rootDir)
+ )
+ ) {
+ return true;
+ }
+
+
//detect system wide folders
if (in_array($root[1], $this->excludedPaths)) {
return true;
@@ -364,6 +376,24 @@ class Util {
}
/**
+ * set new key storage root
+ *
+ * @param string $root new key store root relative to the data folder
+ */
+ public function setKeyStorageRoot($root) {
+ $this->config->setAppValue('core', 'encryption_key_storage_root', $root);
+ }
+
+ /**
+ * get key storage root
+ *
+ * @return string key storage root
+ */
+ public function getKeyStorageRoot() {
+ return $this->config->getAppValue('core', 'encryption_key_storage_root', '');
+ }
+
+ /**
* Wraps the given storage when it is not a shared storage
*
* @param string $mountPoint
diff --git a/lib/private/files.php b/lib/private/files.php
index 6268bf8a129..0172f1ca6af 100644
--- a/lib/private/files.php
+++ b/lib/private/files.php
@@ -86,15 +86,6 @@ class OC_Files {
*/
public static function get($dir, $files, $only_header = false) {
$view = \OC\Files\Filesystem::getView();
- $xsendfile = false;
- if (\OC::$server->getLockingProvider() instanceof NoopLockingProvider) {
- if (isset($_SERVER['MOD_X_SENDFILE_ENABLED']) ||
- isset($_SERVER['MOD_X_SENDFILE2_ENABLED']) ||
- isset($_SERVER['MOD_X_ACCEL_REDIRECT_ENABLED'])
- ) {
- $xsendfile = true;
- }
- }
if (is_array($files) && count($files) === 1) {
$files = $files[0];
@@ -129,9 +120,6 @@ class OC_Files {
if ($get_type === self::FILE) {
$zip = false;
- if ($xsendfile && \OC::$server->getEncryptionManager()->isEnabled()) {
- $xsendfile = false;
- }
} else {
$zip = new ZipStreamer(false);
}
@@ -176,17 +164,7 @@ class OC_Files {
$zip->finalize();
set_time_limit($executionTime);
} else {
- if ($xsendfile) {
- /** @var $storage \OC\Files\Storage\Storage */
- list($storage) = $view->resolvePath($filename);
- if ($storage->isLocal()) {
- self::addSendfileHeader($filename);
- } else {
- \OC\Files\Filesystem::readfile($filename);
- }
- } else {
- \OC\Files\Filesystem::readfile($filename);
- }
+ \OC\Files\Filesystem::readfile($filename);
}
if ($get_type === self::FILE) {
$view->unlockFile($filename, ILockingProvider::LOCK_SHARED);
@@ -203,40 +181,6 @@ class OC_Files {
}
/**
- * @param false|string $filename
- */
- private static function addSendfileHeader($filename) {
- if (isset($_SERVER['MOD_X_SENDFILE_ENABLED'])) {
- $filename = \OC\Files\Filesystem::getLocalFile($filename);
- header("X-Sendfile: " . $filename);
- }
- if (isset($_SERVER['MOD_X_SENDFILE2_ENABLED'])) {
- $filename = \OC\Files\Filesystem::getLocalFile($filename);
- if (isset($_SERVER['HTTP_RANGE']) &&
- preg_match("/^bytes=([0-9]+)-([0-9]*)$/", $_SERVER['HTTP_RANGE'], $range)) {
- $filelength = filesize($filename);
- if ($range[2] === "") {
- $range[2] = $filelength - 1;
- }
- header("Content-Range: bytes $range[1]-$range[2]/" . $filelength);
- header("HTTP/1.1 206 Partial content");
- header("X-Sendfile2: " . str_replace(",", "%2c", rawurlencode($filename)) . " $range[1]-$range[2]");
- } else {
- header("X-Sendfile: " . $filename);
- }
- }
-
- if (isset($_SERVER['MOD_X_ACCEL_REDIRECT_ENABLED'])) {
- if (isset($_SERVER['MOD_X_ACCEL_REDIRECT_PREFIX'])) {
- $filename = $_SERVER['MOD_X_ACCEL_REDIRECT_PREFIX'] . \OC\Files\Filesystem::getLocalFile($filename);
- } else {
- $filename = \OC::$WEBROOT . '/data' . \OC\Files\Filesystem::getRoot() . $filename;
- }
- header("X-Accel-Redirect: " . $filename);
- }
- }
-
- /**
* @param string $dir
* @param ZipStreamer $zip
* @param string $internalDir
diff --git a/lib/private/files/cache/cache.php b/lib/private/files/cache/cache.php
index 8cf097421d4..5c04da1f0d5 100644
--- a/lib/private/files/cache/cache.php
+++ b/lib/private/files/cache/cache.php
@@ -35,6 +35,8 @@
namespace OC\Files\Cache;
+use \OCP\Files\IMimeTypeLoader;
+
/**
* Metadata cache for a storage
*
@@ -66,8 +68,8 @@ class Cache {
*/
protected $storageCache;
- protected static $mimetypeIds = array();
- protected static $mimetypes = array();
+ /** @var IMimeTypeLoader */
+ protected $mimetypeLoader;
/**
* @param \OC\Files\Storage\Storage|string $storage
@@ -83,6 +85,7 @@ class Cache {
}
$this->storageCache = new Storage($storage);
+ $this->mimetypeLoader = \OC::$server->getMimeTypeLoader();
}
/**
@@ -95,72 +98,6 @@ class Cache {
}
/**
- * Get the numeric id for a mimetype
- *
- * Mimetypes are stored as integers in the cache to prevent duplicated data of the (usually) fairly limited amount of unique mimetypes
- * If the supplied mimetype does not yet have a numeric id a new one will be generated
- *
- * @param string $mime
- * @return int
- */
- public function getMimetypeId($mime) {
- if (empty($mime)) {
- // Can not insert empty string into Oracle NOT NULL column.
- $mime = 'application/octet-stream';
- }
- if (empty(self::$mimetypeIds)) {
- $this->loadMimetypes();
- }
-
- if (!isset(self::$mimetypeIds[$mime])) {
- try {
- $connection = \OC_DB::getConnection();
- $connection->insertIfNotExist('*PREFIX*mimetypes', [
- 'mimetype' => $mime,
- ]);
- $this->loadMimetypes();
- } catch (\Doctrine\DBAL\DBALException $e) {
- \OCP\Util::writeLog('core', 'Exception during mimetype insertion: ' . $e->getmessage(), \OCP\Util::DEBUG);
- return -1;
- }
- }
-
- return self::$mimetypeIds[$mime];
- }
-
-
- /**
- * Get the mimetype (as string) from a mimetype id
- *
- * @param int $id
- * @return string | null the mimetype for the id or null if the id is not known
- */
- public function getMimetype($id) {
- if (empty(self::$mimetypes)) {
- $this->loadMimetypes();
- }
-
- return isset(self::$mimetypes[$id]) ? self::$mimetypes[$id] : null;
- }
-
- /**
- * Load all known mimetypes and mimetype ids from the database
- *
- * @throws \OC\DatabaseException
- */
- public function loadMimetypes() {
- self::$mimetypeIds = self::$mimetypes = array();
-
- $result = \OC_DB::executeAudited('SELECT `id`, `mimetype` FROM `*PREFIX*mimetypes`', array());
- if ($result) {
- while ($row = $result->fetchRow()) {
- self::$mimetypeIds[$row['mimetype']] = $row['id'];
- self::$mimetypes[$row['id']] = $row['mimetype'];
- }
- }
- }
-
- /**
* get the stored metadata of a file or folder
*
* the returned cache entry contains at least the following values:
@@ -222,8 +159,8 @@ class Cache {
$data['storage_mtime'] = (int)$data['storage_mtime'];
$data['encrypted'] = (bool)$data['encrypted'];
$data['storage'] = $this->storageId;
- $data['mimetype'] = $this->getMimetype($data['mimetype']);
- $data['mimepart'] = $this->getMimetype($data['mimepart']);
+ $data['mimetype'] = $this->mimetypeLoader->getMimetypeById($data['mimetype']);
+ $data['mimepart'] = $this->mimetypeLoader->getMimetypeById($data['mimepart']);
if ($data['storage_mtime'] == 0) {
$data['storage_mtime'] = $data['mtime'];
}
@@ -258,8 +195,8 @@ class Cache {
$result = \OC_DB::executeAudited($sql, array($fileId));
$files = $result->fetchAll();
foreach ($files as &$file) {
- $file['mimetype'] = $this->getMimetype($file['mimetype']);
- $file['mimepart'] = $this->getMimetype($file['mimepart']);
+ $file['mimetype'] = $this->mimetypeLoader->getMimetypeById($file['mimetype']);
+ $file['mimepart'] = $this->mimetypeLoader->getMimetypeById($file['mimepart']);
if ($file['storage_mtime'] == 0) {
$file['storage_mtime'] = $file['mtime'];
}
@@ -385,9 +322,9 @@ class Cache {
$params[] = md5($value);
$queryParts[] = '`path_hash`';
} elseif ($name === 'mimetype') {
- $params[] = $this->getMimetypeId(substr($value, 0, strpos($value, '/')));
+ $params[] = $this->mimetypeLoader->getId(substr($value, 0, strpos($value, '/')));
$queryParts[] = '`mimepart`';
- $value = $this->getMimetypeId($value);
+ $value = $this->mimetypeLoader->getId($value);
} elseif ($name === 'storage_mtime') {
if (!isset($data['mtime'])) {
$params[] = $value;
@@ -613,7 +550,6 @@ class Cache {
* @return array an array of cache entries where the name matches the search pattern
*/
public function search($pattern) {
-
// normalize pattern
$pattern = $this->normalize($pattern);
@@ -630,8 +566,8 @@ class Cache {
$files = array();
while ($row = $result->fetchRow()) {
- $row['mimetype'] = $this->getMimetype($row['mimetype']);
- $row['mimepart'] = $this->getMimetype($row['mimepart']);
+ $row['mimetype'] = $this->mimetypeLoader->getMimetypeById($row['mimetype']);
+ $row['mimepart'] = $this->mimetypeLoader->getMimetypeById($row['mimepart']);
$files[] = $row;
}
return $files;
@@ -652,12 +588,12 @@ class Cache {
}
$sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag`, `permissions`
FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?';
- $mimetype = $this->getMimetypeId($mimetype);
+ $mimetype = $this->mimetypeLoader->getId($mimetype);
$result = \OC_DB::executeAudited($sql, array($mimetype, $this->getNumericStorageId()));
$files = array();
while ($row = $result->fetchRow()) {
- $row['mimetype'] = $this->getMimetype($row['mimetype']);
- $row['mimepart'] = $this->getMimetype($row['mimepart']);
+ $row['mimetype'] = $this->mimetypeLoader->getMimetypeById($row['mimetype']);
+ $row['mimepart'] = $this->mimetypeLoader->getMimetypeById($row['mimepart']);
$files[] = $row;
}
return $files;
diff --git a/lib/private/files/storage/storagefactory.php b/lib/private/files/storage/storagefactory.php
index 62b393c845c..e8df5090f09 100644
--- a/lib/private/files/storage/storagefactory.php
+++ b/lib/private/files/storage/storagefactory.php
@@ -99,6 +99,9 @@ class StorageFactory implements IStorageFactory {
}, $wrappers);
foreach ($wrappers as $wrapper) {
$storage = $wrapper($mountPoint->getMountPoint(), $storage, $mountPoint);
+ if (!($storage instanceof \OCP\Files\Storage)) {
+ throw new \Exception('Invalid result from storage wrapper');
+ }
}
return $storage;
}
diff --git a/lib/private/files/type/detection.php b/lib/private/files/type/detection.php
index ba286637df3..3dc3975fb2a 100644
--- a/lib/private/files/type/detection.php
+++ b/lib/private/files/type/detection.php
@@ -6,6 +6,7 @@
* @author Robin Appelman <icewind@owncloud.com>
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Thomas Tanghus <thomas@tanghus.net>
+ * @author Robin McCorkell <rmccorkell@owncloud.com>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
* @license AGPL-3.0
@@ -101,16 +102,23 @@ class Detection implements IMimeTypeDetector {
return;
}
- $file = file_get_contents($this->configDir . '/mimetypealiases.dist.json');
- $this->mimeTypeAlias = get_object_vars(json_decode($file));
+ $this->mimeTypeAlias = json_decode(file_get_contents($this->configDir . '/mimetypealiases.dist.json'), true);
if (file_exists($this->configDir . '/mimetypealiases.json')) {
- $custom = get_object_vars(json_decode(file_get_contents($this->configDir . '/mimetypealiases.json')));
+ $custom = json_decode(file_get_contents($this->configDir . '/mimetypealiases.json'), true);
$this->mimeTypeAlias = array_merge($this->mimeTypeAlias, $custom);
}
}
/**
+ * @return array
+ */
+ public function getAllAliases() {
+ $this->loadAliases();
+ return $this->mimeTypeAlias;
+ }
+
+ /**
* Add mimetype mappings if they are not yet present
*/
private function loadMappings() {
@@ -118,20 +126,26 @@ class Detection implements IMimeTypeDetector {
return;
}
- $dist = file_get_contents($this->configDir . '/mimetypemapping.dist.json');
- $mimetypemapping = get_object_vars(json_decode($dist));
+ $mimetypemapping = json_decode(file_get_contents($this->configDir . '/mimetypemapping.dist.json'), true);
//Check if need to load custom mappings
if (file_exists($this->configDir . '/mimetypemapping.json')) {
- $custom = file_get_contents($this->configDir . '/mimetypemapping.json');
- $custom_mapping = get_object_vars(json_decode($custom));
- $mimetypemapping = array_merge($mimetypemapping, $custom_mapping);
+ $custom = json_decode(file_get_contents($this->configDir . '/mimetypemapping.json'), true);
+ $mimetypemapping = array_merge($mimetypemapping, $custom);
}
$this->registerTypeArray($mimetypemapping);
}
/**
+ * @return array
+ */
+ public function getAllMappings() {
+ $this->loadMappings();
+ return $this->mimetypes;
+ }
+
+ /**
* detect mimetype only based on filename, content of file is not used
*
* @param string $path
diff --git a/lib/private/files/type/loader.php b/lib/private/files/type/loader.php
new file mode 100644
index 00000000000..df893306615
--- /dev/null
+++ b/lib/private/files/type/loader.php
@@ -0,0 +1,165 @@
+<?php
+/**
+ * @author Robin McCorkell <rmccorkell@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Files\Type;
+
+use OCP\Files\IMimeTypeLoader;
+use OCP\IDBConnection;
+
+use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
+
+/**
+ * Mimetype database loader
+ *
+ * @package OC\Files\Type
+ */
+class Loader implements IMimeTypeLoader {
+
+ /** @var IDBConnection */
+ private $dbConnection;
+
+ /** @var array [id => mimetype] */
+ protected $mimetypes;
+
+ /** @var array [mimetype => id] */
+ protected $mimetypeIds;
+
+ /**
+ * @param IDBConnection $dbConnection
+ */
+ public function __construct(IDBConnection $dbConnection) {
+ $this->dbConnection = $dbConnection;
+ $this->mimetypes = [];
+ $this->mimetypeIds = [];
+ }
+
+ /**
+ * Get a mimetype from its ID
+ *
+ * @param int $id
+ * @return string|null
+ */
+ public function getMimetypeById($id) {
+ if (!$this->mimetypes) {
+ $this->loadMimetypes();
+ }
+ if (isset($this->mimetypes[$id])) {
+ return $this->mimetypes[$id];
+ }
+ return null;
+ }
+
+ /**
+ * Get a mimetype ID, adding the mimetype to the DB if it does not exist
+ *
+ * @param string $mimetype
+ * @return int
+ */
+ public function getId($mimetype) {
+ if (!$this->mimetypeIds) {
+ $this->loadMimetypes();
+ }
+ if (isset($this->mimetypeIds[$mimetype])) {
+ return $this->mimetypeIds[$mimetype];
+ }
+ return $this->store($mimetype);
+ }
+
+ /**
+ * Test if a mimetype exists in the database
+ *
+ * @param string $mimetype
+ * @return bool
+ */
+ public function exists($mimetype) {
+ if (!$this->mimetypeIds) {
+ $this->loadMimetypes();
+ }
+ return isset($this->mimetypeIds[$mimetype]);
+ }
+
+ /**
+ * Store a mimetype in the DB
+ *
+ * @param string $mimetype
+ * @param int inserted ID
+ */
+ protected function store($mimetype) {
+ try {
+ $qb = $this->dbConnection->getQueryBuilder();
+ $qb->insert('mimetypes')
+ ->values([
+ 'mimetype' => $qb->createNamedParameter($mimetype)
+ ]);
+ $qb->execute();
+ } catch (UniqueConstraintViolationException $e) {
+ // something inserted it before us
+ }
+
+ $fetch = $this->dbConnection->getQueryBuilder();
+ $fetch->select('id')
+ ->from('mimetypes')
+ ->where(
+ $fetch->expr()->eq('mimetype', $fetch->createNamedParameter($mimetype)
+ ));
+ $row = $fetch->execute()->fetch();
+
+ $this->mimetypes[$row['id']] = $mimetype;
+ $this->mimetypeIds[$mimetype] = $row['id'];
+ return $row['id'];
+ }
+
+ /**
+ * Load all mimetypes from DB
+ */
+ private function loadMimetypes() {
+ $qb = $this->dbConnection->getQueryBuilder();
+ $qb->select('id', 'mimetype')
+ ->from('mimetypes');
+ $results = $qb->execute()->fetchAll();
+
+ foreach ($results as $row) {
+ $this->mimetypes[$row['id']] = $row['mimetype'];
+ $this->mimetypeIds[$row['mimetype']] = $row['id'];
+ }
+ }
+
+ /**
+ * Update filecache mimetype based on file extension
+ *
+ * @param string $ext file extension
+ * @param int $mimetypeId
+ * @return int number of changed rows
+ */
+ public function updateFilecache($ext, $mimetypeId) {
+ $update = $this->dbConnection->getQueryBuilder();
+ $update->update('filecache')
+ ->set('mimetype', $update->createNamedParameter($mimetypeId))
+ ->where($update->expr()->neq(
+ 'mimetype', $update->createNamedParameter($mimetypeId)
+ ))
+ ->andWhere($update->expr()->like(
+ $update->createFunction('LOWER(`name`)'), $update->createNamedParameter($ext)
+ ));
+ return $update->execute();
+ }
+
+}
diff --git a/lib/private/json.php b/lib/private/json.php
index e32e937c01a..ac72f02f609 100644
--- a/lib/private/json.php
+++ b/lib/private/json.php
@@ -167,6 +167,6 @@ class OC_JSON{
if (is_array($data)) {
array_walk_recursive($data, array('OC_JSON', 'to_string'));
}
- return json_encode($data);
+ return json_encode($data, JSON_HEX_TAG);
}
}
diff --git a/lib/private/preview.php b/lib/private/preview.php
index 5dcab476a4f..978da1161c2 100644
--- a/lib/private/preview.php
+++ b/lib/private/preview.php
@@ -38,6 +38,9 @@ class Preview {
//the thumbnail folder
const THUMBNAILS_FOLDER = 'thumbnails';
+ const MODE_FILL = 'fill';
+ const MODE_COVER = 'cover';
+
//config
private $maxScaleFactor;
/** @var int maximum width allowed for a preview */
@@ -56,6 +59,7 @@ class Preview {
private $scalingUp;
private $mimeType;
private $keepAspect = false;
+ private $mode = self::MODE_FILL;
//used to calculate the size of the preview to generate
/** @var int $maxPreviewWidth max width a preview can have */
@@ -332,6 +336,19 @@ class Preview {
}
/**
+ * Set whether to cover or fill the specified dimensions
+ *
+ * @param string $mode
+ *
+ * @return \OC\Preview
+ */
+ public function setMode($mode) {
+ $this->mode = $mode;
+
+ return $this;
+ }
+
+ /**
* Sets whether we need to generate a preview which keeps the aspect ratio of the original file
*
* @param bool $keepAspect
@@ -531,14 +548,22 @@ class Preview {
* @param int $askedWidth
* @param int $askedHeight
*
+ * @param int $originalWidth
+ * @param int $originalHeight
* @return \int[]
*/
- private function applyAspectRatio($askedWidth, $askedHeight) {
- $originalRatio = $this->maxPreviewWidth / $this->maxPreviewHeight;
+ private function applyAspectRatio($askedWidth, $askedHeight, $originalWidth = 0, $originalHeight = 0) {
+ if(!$originalWidth){
+ $originalWidth= $this->maxPreviewWidth;
+ }
+ if (!$originalHeight) {
+ $originalHeight = $this->maxPreviewHeight;
+ }
+ $originalRatio = $originalWidth / $originalHeight;
// Defines the box in which the preview has to fit
$scaleFactor = $this->scalingUp ? $this->maxScaleFactor : 1;
- $askedWidth = min($askedWidth, $this->maxPreviewWidth * $scaleFactor);
- $askedHeight = min($askedHeight, $this->maxPreviewHeight * $scaleFactor);
+ $askedWidth = min($askedWidth, $originalWidth * $scaleFactor);
+ $askedHeight = min($askedHeight, $originalHeight * $scaleFactor);
if ($askedWidth / $originalRatio < $askedHeight) {
// width restricted
@@ -551,6 +576,32 @@ class Preview {
}
/**
+ * Resizes the boundaries to cover the area
+ *
+ * @param int $askedWidth
+ * @param int $askedHeight
+ * @param int $previewWidth
+ * @param int $previewHeight
+ * @return \int[]
+ */
+ private function applyCover($askedWidth, $askedHeight, $previewWidth, $previewHeight) {
+ $originalRatio = $previewWidth / $previewHeight;
+ // Defines the box in which the preview has to fit
+ $scaleFactor = $this->scalingUp ? $this->maxScaleFactor : 1;
+ $askedWidth = min($askedWidth, $previewWidth * $scaleFactor);
+ $askedHeight = min($askedHeight, $previewHeight * $scaleFactor);
+
+ if ($askedWidth / $originalRatio > $askedHeight) {
+ // height restricted
+ $askedHeight = round($askedWidth / $originalRatio);
+ } else {
+ $askedWidth = round($askedHeight * $originalRatio);
+ }
+
+ return [(int)$askedWidth, (int)$askedHeight];
+ }
+
+ /**
* Makes sure an upscaled preview doesn't end up larger than the max dimensions defined in the
* config
*
@@ -791,7 +842,15 @@ class Preview {
*/
if ($this->keepAspect) {
list($askedWidth, $askedHeight) =
- $this->applyAspectRatio($askedWidth, $askedHeight);
+ $this->applyAspectRatio($askedWidth, $askedHeight, $previewWidth, $previewHeight);
+ }
+
+ if ($this->mode === self::MODE_COVER) {
+ list($scaleWidth, $scaleHeight) =
+ $this->applyCover($askedWidth, $askedHeight, $previewWidth, $previewHeight);
+ } else {
+ $scaleWidth = $askedWidth;
+ $scaleHeight = $askedHeight;
}
/**
@@ -799,7 +858,7 @@ class Preview {
* Takes the scaling ratio into consideration
*/
list($newPreviewWidth, $newPreviewHeight) = $this->scale(
- $image, $askedWidth, $askedHeight, $previewWidth, $previewHeight
+ $image, $scaleWidth, $scaleHeight, $previewWidth, $previewHeight
);
// The preview has been resized and should now have the asked dimensions
@@ -1000,6 +1059,9 @@ class Preview {
if ($this->keepAspect && !$isMaxPreview) {
$previewPath .= '-with-aspect';
}
+ if ($this->mode === self::MODE_COVER) {
+ $previewPath .= '-cover';
+ }
$previewPath .= '.png';
return $previewPath;
diff --git a/lib/private/route/router.php b/lib/private/route/router.php
index 33669452f2d..7b7849a6da0 100644
--- a/lib/private/route/router.php
+++ b/lib/private/route/router.php
@@ -169,8 +169,9 @@ class Router implements IRouter {
$this->useCollection('root');
require_once 'settings/routes.php';
require_once 'core/routes.php';
-
- // include ocs routes
+ }
+ if ($this->loaded) {
+ // include ocs routes, must be loaded last for /ocs prefix
require_once 'ocs/routes.php';
$collection = $this->getCollection('ocs');
$collection->addPrefix('/ocs');
diff --git a/lib/private/security/certificatemanager.php b/lib/private/security/certificatemanager.php
index d61c7f29327..4d470f69a66 100644
--- a/lib/private/security/certificatemanager.php
+++ b/lib/private/security/certificatemanager.php
@@ -27,6 +27,7 @@ namespace OC\Security;
use OC\Files\Filesystem;
use OCP\ICertificateManager;
+use OCP\IConfig;
/**
* Manage trusted certificates for users
@@ -43,12 +44,19 @@ class CertificateManager implements ICertificateManager {
protected $view;
/**
+ * @var IConfig
+ */
+ protected $config;
+
+ /**
* @param string $uid
* @param \OC\Files\View $view relative zu data/
+ * @param IConfig $config
*/
- public function __construct($uid, \OC\Files\View $view) {
+ public function __construct($uid, \OC\Files\View $view, IConfig $config) {
$this->uid = $uid;
$this->view = $view;
+ $this->config = $config;
}
/**
@@ -57,6 +65,11 @@ class CertificateManager implements ICertificateManager {
* @return \OCP\ICertificate[]
*/
public function listCertificates() {
+
+ if (!$this->config->getSystemValue('installed', false)) {
+ return array();
+ }
+
$path = $this->getPathToCertificates() . 'uploads/';
if (!$this->view->is_dir($path)) {
return array();
diff --git a/lib/private/server.php b/lib/private/server.php
index a47fa2e43f9..393c1840973 100644
--- a/lib/private/server.php
+++ b/lib/private/server.php
@@ -91,12 +91,25 @@ class Server extends SimpleContainer implements IServerContainer {
});
$this->registerService('EncryptionManager', function (Server $c) {
- return new Encryption\Manager($c->getConfig(), $c->getLogger(), $c->getL10N('core'));
+ $view = new View();
+ $util = new Encryption\Util(
+ $view,
+ $c->getUserManager(),
+ $c->getGroupManager(),
+ $c->getConfig()
+ );
+ return new Encryption\Manager(
+ $c->getConfig(),
+ $c->getLogger(),
+ $c->getL10N('core'),
+ new View(),
+ $util
+ );
});
$this->registerService('EncryptionFileHelper', function (Server $c) {
- $util = new \OC\Encryption\Util(
- new \OC\Files\View(),
+ $util = new Encryption\Util(
+ new View(),
$c->getUserManager(),
$c->getGroupManager(),
$c->getConfig()
@@ -105,8 +118,8 @@ class Server extends SimpleContainer implements IServerContainer {
});
$this->registerService('EncryptionKeyStorage', function (Server $c) {
- $view = new \OC\Files\View();
- $util = new \OC\Encryption\Util(
+ $view = new View();
+ $util = new Encryption\Util(
$view,
$c->getUserManager(),
$c->getGroupManager(),
@@ -326,7 +339,7 @@ class Server extends SimpleContainer implements IServerContainer {
$uid = $user ? $user : null;
return new ClientService(
$c->getConfig(),
- new \OC\Security\CertificateManager($uid, new \OC\Files\View())
+ new \OC\Security\CertificateManager($uid, new View(), $c->getConfig())
);
});
$this->registerService('EventLogger', function (Server $c) {
@@ -438,13 +451,13 @@ class Server extends SimpleContainer implements IServerContainer {
);
});
$this->registerService('LockingProvider', function (Server $c) {
- if ($c->getConfig()->getSystemValue('filelocking.enabled', false) or (defined('PHPUNIT_RUN') && PHPUNIT_RUN)) {
+ if ($c->getConfig()->getSystemValue('filelocking.enabled', true) or (defined('PHPUNIT_RUN') && PHPUNIT_RUN)) {
/** @var \OC\Memcache\Factory $memcacheFactory */
$memcacheFactory = $c->getMemCacheFactory();
$memcache = $memcacheFactory->createLocking('lock');
-// if (!($memcache instanceof \OC\Memcache\NullCache)) {
-// return new MemcacheLockingProvider($memcache);
-// }
+ if (!($memcache instanceof \OC\Memcache\NullCache)) {
+ return new MemcacheLockingProvider($memcache);
+ }
return new DBLockingProvider($c->getDatabaseConnection(), $c->getLogger());
}
return new NoopLockingProvider();
@@ -457,6 +470,11 @@ class Server extends SimpleContainer implements IServerContainer {
$c->getURLGenerator(),
\OC::$configDir);
});
+ $this->registerService('MimeTypeLoader', function(Server $c) {
+ return new \OC\Files\Type\Loader(
+ $c->getDatabaseConnection()
+ );
+ });
$this->registerService('CapabilitiesManager', function (Server $c) {
$manager = new \OC\CapabilitiesManager();
$manager->registerCapability(function() use ($c) {
@@ -839,7 +857,7 @@ class Server extends SimpleContainer implements IServerContainer {
}
$userId = $user->getUID();
}
- return new CertificateManager($userId, new \OC\Files\View());
+ return new CertificateManager($userId, new View(), $this->getConfig());
}
/**
@@ -998,6 +1016,15 @@ class Server extends SimpleContainer implements IServerContainer {
}
/**
+ * Get the MimeTypeLoader
+ *
+ * @return \OCP\Files\IMimeTypeLoader
+ */
+ public function getMimeTypeLoader() {
+ return $this->query('MimeTypeLoader');
+ }
+
+ /**
* Get the manager of all the capabilities
*
* @return \OC\CapabilitiesManager
diff --git a/lib/private/share/share.php b/lib/private/share/share.php
index d0c69badb46..6ad36d60fe8 100644
--- a/lib/private/share/share.php
+++ b/lib/private/share/share.php
@@ -37,6 +37,7 @@
namespace OC\Share;
+use OC\Files\Filesystem;
use OCP\IUserSession;
use OCP\IDBConnection;
use OCP\IConfig;
@@ -120,6 +121,7 @@ class Share extends Constants {
*/
public static function getUsersSharingFile($path, $ownerUser, $includeOwner = false, $returnUserPaths = false) {
+ Filesystem::initMountPoints($ownerUser);
$shares = $sharePaths = $fileTargets = array();
$publicShare = false;
$remoteShare = false;
@@ -701,6 +703,18 @@ class Share extends Constants {
throw new \Exception($message_t);
}
}
+ if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_USER,
+ $shareWith, null, self::FORMAT_NONE, null, 1, true, true)) {
+ // Only allow the same share to occur again if it is the same
+ // owner and is not a user share, this use case is for increasing
+ // permissions for a specific user
+ if ($checkExists['uid_owner'] != $uidOwner || $checkExists['share_type'] == $shareType) {
+ $message = 'Sharing %s failed, because this item is already shared with user %s';
+ $message_t = $l->t('Sharing %s failed, because this item is already shared with user %s', array($itemSourceName, $shareWith));
+ \OC_Log::write('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OC_Log::ERROR);
+ throw new \Exception($message_t);
+ }
+ }
} else if ($shareType === self::SHARE_TYPE_GROUP) {
if (!\OC_Group::groupExists($shareWith)) {
$message = 'Sharing %s failed, because the group %s does not exist';
@@ -751,7 +765,7 @@ class Share extends Constants {
}
// Generate hash of password - same method as user passwords
- if (!empty($shareWith)) {
+ if (is_string($shareWith) && $shareWith !== '') {
self::verifyPassword($shareWith);
$shareWith = \OC::$server->getHasher()->hash($shareWith);
} else {
diff --git a/lib/private/util.php b/lib/private/util.php
index 47e42d8b7d3..eb1de5be5a4 100644
--- a/lib/private/util.php
+++ b/lib/private/util.php
@@ -1054,6 +1054,7 @@ class OC_Util {
return $id;
}
+ protected static $encryptedToken;
/**
* Register an get/post call. Important to prevent CSRF attacks.
*
@@ -1066,6 +1067,11 @@ class OC_Util {
* @see OC_Util::isCallRegistered()
*/
public static function callRegister() {
+ // Use existing token if function has already been called
+ if(isset(self::$encryptedToken)) {
+ return self::$encryptedToken;
+ }
+
// Check if a token exists
if (!\OC::$server->getSession()->exists('requesttoken')) {
// No valid token found, generate a new one.
@@ -1078,7 +1084,8 @@ class OC_Util {
// Encrypt the token to mitigate breach-like attacks
$sharedSecret = \OC::$server->getSecureRandom()->getMediumStrengthGenerator()->generate(10);
- return \OC::$server->getCrypto()->encrypt($requestToken, $sharedSecret) . ':' . $sharedSecret;
+ self::$encryptedToken = \OC::$server->getCrypto()->encrypt($requestToken, $sharedSecret) . ':' . $sharedSecret;
+ return self::$encryptedToken;
}
/**
@@ -1145,6 +1152,7 @@ class OC_Util {
* @throws \OC\HintException If the test file can't get written.
*/
public function isHtaccessWorking(\OCP\IConfig $config) {
+
if (\OC::$CLI || !$config->getSystemValue('check_for_working_htaccess', true)) {
return true;
}
diff --git a/lib/public/appframework/http/jsonresponse.php b/lib/public/appframework/http/jsonresponse.php
index 456a5616d4d..1a509200dd7 100644
--- a/lib/public/appframework/http/jsonresponse.php
+++ b/lib/public/appframework/http/jsonresponse.php
@@ -64,7 +64,7 @@ class JSONResponse extends Response {
* @throws \Exception If data could not get encoded
*/
public function render() {
- $response = json_encode($this->data);
+ $response = json_encode($this->data, JSON_HEX_TAG);
if($response === false) {
throw new \Exception(sprintf('Could not json_encode due to invalid ' .
'non UTF-8 characters in the array: %s', var_export($this->data, true)));
diff --git a/lib/public/autoloadnotallowedexception.php b/lib/public/autoloadnotallowedexception.php
new file mode 100644
index 00000000000..edb7121c065
--- /dev/null
+++ b/lib/public/autoloadnotallowedexception.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * @author Robin McCorkell <rmccorkell@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ */
+
+namespace OCP;
+
+/**
+ * Exception for when a not allowed path is attempted to be autoloaded
+ * @since 8.2.0
+ */
+class AutoloadNotAllowedException extends \DomainException {
+ /**
+ * @param string $path
+ * @since 8.2.0
+ */
+ public function __construct($path) {
+ parent::__construct('Autoload path not allowed: '.$path);
+ }
+}
+
diff --git a/lib/public/files/imimetypeloader.php b/lib/public/files/imimetypeloader.php
new file mode 100644
index 00000000000..24937ea9b86
--- /dev/null
+++ b/lib/public/files/imimetypeloader.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * @author Robin McCorkell <rmccorkell@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCP\Files;
+
+/**
+ * Interface IMimeTypeLoader
+ * @package OCP\Files
+ * @since 8.2.0
+ *
+ * Interface to load mimetypes
+ **/
+interface IMimeTypeLoader {
+
+ /**
+ * Get a mimetype from its ID
+ *
+ * @param int $id
+ * @return string|null
+ * @since 8.2.0
+ */
+ public function getMimetypeById($id);
+
+ /**
+ * Get a mimetype ID, adding the mimetype to the DB if it does not exist
+ *
+ * @param string $mimetype
+ * @return int
+ * @since 8.2.0
+ */
+ public function getId($mimetype);
+
+ /**
+ * Test if a mimetype exists in the database
+ *
+ * @param string $mimetype
+ * @return bool
+ * @since 8.2.0
+ */
+ public function exists($mimetype);
+}
diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php
index a6d83156de3..81724cb4967 100644
--- a/lib/public/iservercontainer.php
+++ b/lib/public/iservercontainer.php
@@ -440,6 +440,14 @@ interface IServerContainer {
*/
public function getMimeTypeDetector();
+ /**
+ * Get the MimeTypeLoader
+ *
+ * @return \OCP\Files\IMimeTypeLoader
+ * @since 8.2.0
+ */
+ public function getMimeTypeLoader();
+
/**
* Get the EventDispatcher