summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorRobin McCorkell <rmccorkell@owncloud.com>2015-09-14 19:50:52 +0100
committerRobin McCorkell <rmccorkell@owncloud.com>2015-09-14 19:50:52 +0100
commit35d4851af2733515a1c81d4c0b78c4c14bf570e6 (patch)
tree7adde58609d8de5d7b64774f4339cdc4dd0c7449 /lib
parent227868fe168529a638dcf2dbff4ff8f44cadc519 (diff)
parentfb9e75edb6d01729a27c84f6f11399a1b0fde9f3 (diff)
downloadnextcloud-server-35d4851af2733515a1c81d4c0b78c4c14bf570e6.tar.gz
nextcloud-server-35d4851af2733515a1c81d4c0b78c4c14bf570e6.zip
Merge branch 'master' into fix-app-disable-route
Diffstat (limited to 'lib')
-rw-r--r--lib/autoloader.php6
-rw-r--r--lib/base.php21
-rw-r--r--lib/l10n/cs_CZ.js1
-rw-r--r--lib/l10n/cs_CZ.json1
-rw-r--r--lib/l10n/da.js3
-rw-r--r--lib/l10n/da.json3
-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/ko.js2
-rw-r--r--lib/l10n/ko.json2
-rw-r--r--lib/l10n/nb_NO.js2
-rw-r--r--lib/l10n/nb_NO.json2
-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/app.php3
-rw-r--r--lib/private/appconfig.php16
-rw-r--r--lib/private/appframework/utility/simplecontainer.php2
-rw-r--r--lib/private/backgroundjob/joblist.php22
-rw-r--r--lib/private/eventsource.php11
-rw-r--r--lib/private/files.php58
-rw-r--r--lib/private/files/cache/cache.php96
-rw-r--r--lib/private/files/cache/scanner.php2
-rw-r--r--lib/private/files/storage/dav.php93
-rw-r--r--lib/private/files/type/detection.php30
-rw-r--r--lib/private/files/type/loader.php173
-rw-r--r--lib/private/http/client/client.php3
-rw-r--r--lib/private/http/client/response.php15
-rw-r--r--lib/private/memcache/memcached.php5
-rw-r--r--lib/private/notification/action.php167
-rw-r--r--lib/private/notification/iaction.php109
-rw-r--r--lib/private/notification/iapp.php56
-rw-r--r--lib/private/notification/imanager.php56
-rw-r--r--lib/private/notification/inotification.php241
-rw-r--r--lib/private/notification/inotifier.php43
-rw-r--r--lib/private/notification/manager.php191
-rw-r--r--lib/private/notification/notification.php446
-rw-r--r--lib/private/server.php69
-rw-r--r--lib/private/session/cryptosessiondata.php62
-rw-r--r--lib/private/session/cryptowrapper.php6
-rw-r--r--lib/private/session/internal.php8
-rw-r--r--lib/private/share/share.php2
-rw-r--r--lib/private/tempmanager.php86
-rw-r--r--lib/private/updater.php28
-rw-r--r--lib/private/util.php15
-rw-r--r--lib/public/autoloadnotallowedexception.php36
-rw-r--r--lib/public/files/imimetypeloader.php66
-rw-r--r--lib/public/http/client/iresponse.php2
-rw-r--r--lib/public/icontainer.php10
-rw-r--r--lib/public/iservercontainer.php15
-rw-r--r--lib/public/itempmanager.php8
64 files changed, 2022 insertions, 290 deletions
diff --git a/lib/autoloader.php b/lib/autoloader.php
index d7649781ea1..41a040b3f54 100644
--- a/lib/autoloader.php
+++ b/lib/autoloader.php
@@ -27,6 +27,8 @@
namespace OC;
+use \OCP\AutoloadNotAllowedException;
+
class Autoloader {
private $useGlobalClassPath = true;
@@ -58,7 +60,7 @@ class Autoloader {
* @param string $root
*/
public function addValidRoot($root) {
- $this->validRoots[] = $root;
+ $this->validRoots[] = stream_resolve_include_path($root);
}
/**
@@ -129,7 +131,7 @@ class Autoloader {
return true;
}
}
- throw new \Exception('Path not allowed: '. $fullPath);
+ throw new AutoloadNotAllowedException($fullPath);
}
/**
diff --git a/lib/base.php b/lib/base.php
index 63aad4518ab..5f8a7ed0f19 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -552,10 +552,6 @@ class OC {
exit();
}
- foreach(OC::$APPSROOTS as $appRoot) {
- self::$loader->addValidRoot($appRoot['path']);
- }
-
// setup the basic server
self::$server = new \OC\Server(\OC::$WEBROOT);
\OC::$server->getEventLogger()->log('autoloader', 'Autoloader', $loaderStart, $loaderEnd);
@@ -1119,27 +1115,16 @@ class OC {
}
return true;
}
-}
-if (!function_exists('get_temp_dir')) {
/**
* Get the temporary dir to store uploaded data
* @return null|string Path to the temporary directory or null
*/
function get_temp_dir() {
- if ($temp = ini_get('upload_tmp_dir')) return $temp;
- if ($temp = getenv('TMP')) return $temp;
- if ($temp = getenv('TEMP')) return $temp;
- if ($temp = getenv('TMPDIR')) return $temp;
- $temp = tempnam(__FILE__, '');
- if (file_exists($temp)) {
- unlink($temp);
- return dirname($temp);
- }
- if ($temp = sys_get_temp_dir()) return $temp;
-
- return null;
+ return \OC::$server->getTempManager()->t_get_temp_dir();
}
+
}
+
OC::init();
diff --git a/lib/l10n/cs_CZ.js b/lib/l10n/cs_CZ.js
index 715b834d2bf..65ff43b4f23 100644
--- a/lib/l10n/cs_CZ.js
+++ b/lib/l10n/cs_CZ.js
@@ -91,6 +91,7 @@ OC.L10N.register(
"Sharing %s failed, because the user %s does not exist" : "Sdílení položky %s selhalo, protože uživatel %s neexistuje",
"Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Sdílení položky %s selhalo, protože uživatel %s není členem žádné skupiny společné s uživatelem %s",
"Sharing %s failed, because this item is already shared with %s" : "Sdílení položky %s selhalo, protože položka již je s uživatelem %s sdílena",
+ "Sharing %s failed, because this item is already shared with user %s" : "Sdílení položky %s selhalo, protože ta je již s uživatelem %s sdílena",
"Sharing %s failed, because the group %s does not exist" : "Sdílení položky %s selhalo, protože skupina %s neexistuje",
"Sharing %s failed, because %s is not a member of the group %s" : "Sdílení položky %s selhalo, protože uživatel %s není členem skupiny %s",
"You need to provide a password to create a public link, only protected links are allowed" : "Pro vytvoření veřejného odkazu je nutné zadat heslo, jsou povoleny pouze chráněné odkazy",
diff --git a/lib/l10n/cs_CZ.json b/lib/l10n/cs_CZ.json
index 891b30850ab..501210dd0f8 100644
--- a/lib/l10n/cs_CZ.json
+++ b/lib/l10n/cs_CZ.json
@@ -89,6 +89,7 @@
"Sharing %s failed, because the user %s does not exist" : "Sdílení položky %s selhalo, protože uživatel %s neexistuje",
"Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Sdílení položky %s selhalo, protože uživatel %s není členem žádné skupiny společné s uživatelem %s",
"Sharing %s failed, because this item is already shared with %s" : "Sdílení položky %s selhalo, protože položka již je s uživatelem %s sdílena",
+ "Sharing %s failed, because this item is already shared with user %s" : "Sdílení položky %s selhalo, protože ta je již s uživatelem %s sdílena",
"Sharing %s failed, because the group %s does not exist" : "Sdílení položky %s selhalo, protože skupina %s neexistuje",
"Sharing %s failed, because %s is not a member of the group %s" : "Sdílení položky %s selhalo, protože uživatel %s není členem skupiny %s",
"You need to provide a password to create a public link, only protected links are allowed" : "Pro vytvoření veřejného odkazu je nutné zadat heslo, jsou povoleny pouze chráněné odkazy",
diff --git a/lib/l10n/da.js b/lib/l10n/da.js
index 42f367d21c2..285e9ac55d1 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",
@@ -131,7 +132,7 @@ OC.L10N.register(
"PHP setting \"%s\" is not set to \"%s\"." : "PHP-indstillingen \"%s\" er ikke angivet til \"%s\".",
"Adjusting this setting in php.ini will make ownCloud run again" : "Justeres denne indstilling i php.ini, så vil ownCloud kunne køre igen",
"mbstring.func_overload is set to \"%s\" instead of the expected value \"0\"" : "mbstring.func_overload er angivet til \"%s\", i stedet for den forventede værdi \"0\"",
- "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "For at rette dette problem, så angiv\n<code>mbstring.func_overload</code> til <code>0</code> i din php.ini",
+ "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "For at rette dette problem, angiv\n<code>mbstring.func_overload</code> til <code>0</code> i din php.ini",
"PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible." : "PHP er tilsyneladende sat op til at fjerne indlejrede doc-blokke. Dette vil gøre adskillige kerneprogrammer utilgængelige.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Dette er sansynligvis forårsaget af et accelerator eller cache som Zend OPcache eller eAccelerator",
"PHP modules have been installed, but they are still listed as missing?" : "Der er installeret PHP-moduler, men de fremstår stadig som fraværende?",
diff --git a/lib/l10n/da.json b/lib/l10n/da.json
index 0e20adc31bf..1b9ed304596 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",
@@ -129,7 +130,7 @@
"PHP setting \"%s\" is not set to \"%s\"." : "PHP-indstillingen \"%s\" er ikke angivet til \"%s\".",
"Adjusting this setting in php.ini will make ownCloud run again" : "Justeres denne indstilling i php.ini, så vil ownCloud kunne køre igen",
"mbstring.func_overload is set to \"%s\" instead of the expected value \"0\"" : "mbstring.func_overload er angivet til \"%s\", i stedet for den forventede værdi \"0\"",
- "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "For at rette dette problem, så angiv\n<code>mbstring.func_overload</code> til <code>0</code> i din php.ini",
+ "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "For at rette dette problem, angiv\n<code>mbstring.func_overload</code> til <code>0</code> i din php.ini",
"PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible." : "PHP er tilsyneladende sat op til at fjerne indlejrede doc-blokke. Dette vil gøre adskillige kerneprogrammer utilgængelige.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Dette er sansynligvis forårsaget af et accelerator eller cache som Zend OPcache eller eAccelerator",
"PHP modules have been installed, but they are still listed as missing?" : "Der er installeret PHP-moduler, men de fremstår stadig som fraværende?",
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 2114b34eddd..0de6a4124fb 100644
--- a/lib/l10n/id.js
+++ b/lib/l10n/id.js
@@ -91,6 +91,7 @@ OC.L10N.register(
"Sharing %s failed, because the user %s does not exist" : "Gagal membagikan %s, karena pengguna %s tidak ada",
"Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Gagal membagikan %s, karena pengguna %s bukan merupakan anggota dari grup yang %s ikuti",
"Sharing %s failed, because this item is already shared with %s" : "Gagal membagkan %s, karena item ini sudah dibagikan dengan %s",
+ "Sharing %s failed, because this item is already shared with user %s" : "Berbagi %s gagal karena item ini sudah dibagikan dengan pengguna %s",
"Sharing %s failed, because the group %s does not exist" : "Gagal membagikan %s, karena grup %s tidak ada",
"Sharing %s failed, because %s is not a member of the group %s" : "Gagal membagikan %s, karena %s bukan anggota dari grup %s",
"You need to provide a password to create a public link, only protected links are allowed" : "Anda perlu memberikan sandi untuk membuat tautan publik, hanya tautan yang terlindungi yang diizinkan",
diff --git a/lib/l10n/id.json b/lib/l10n/id.json
index cdc17b6ce8e..e1b3a9f93b0 100644
--- a/lib/l10n/id.json
+++ b/lib/l10n/id.json
@@ -89,6 +89,7 @@
"Sharing %s failed, because the user %s does not exist" : "Gagal membagikan %s, karena pengguna %s tidak ada",
"Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Gagal membagikan %s, karena pengguna %s bukan merupakan anggota dari grup yang %s ikuti",
"Sharing %s failed, because this item is already shared with %s" : "Gagal membagkan %s, karena item ini sudah dibagikan dengan %s",
+ "Sharing %s failed, because this item is already shared with user %s" : "Berbagi %s gagal karena item ini sudah dibagikan dengan pengguna %s",
"Sharing %s failed, because the group %s does not exist" : "Gagal membagikan %s, karena grup %s tidak ada",
"Sharing %s failed, because %s is not a member of the group %s" : "Gagal membagikan %s, karena %s bukan anggota dari grup %s",
"You need to provide a password to create a public link, only protected links are allowed" : "Anda perlu memberikan sandi untuk membuat tautan publik, hanya tautan yang terlindungi yang diizinkan",
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/ko.js b/lib/l10n/ko.js
index a2ec230d59f..bb143bdd527 100644
--- a/lib/l10n/ko.js
+++ b/lib/l10n/ko.js
@@ -49,6 +49,7 @@ OC.L10N.register(
"Can't read file" : "파일을 읽을 수 없음",
"App directory already exists" : "앱 디렉터리가 이미 존재합니다.",
"Can't create app folder. Please fix permissions. %s" : "앱 폴더를 만들 수 없습니다. 권한을 수정하십시오. %s",
+ "Archive does not contain a directory named %s" : "압축 파일에 디렉터리 %s이(가) 없습니다",
"No source specified when installing app" : "앱을 설치할 때 소스가 지정되지 않았습니다.",
"No href specified when installing app from http" : "http에서 앱을 설치할 때 href가 지정되지 않았습니다.",
"No path specified when installing app from local file" : "로컬 파일에서 앱을 설치할 때 경로가 지정되지 않았습니다.",
@@ -90,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/ko.json b/lib/l10n/ko.json
index fa52b9a8f05..8fea07402ca 100644
--- a/lib/l10n/ko.json
+++ b/lib/l10n/ko.json
@@ -47,6 +47,7 @@
"Can't read file" : "파일을 읽을 수 없음",
"App directory already exists" : "앱 디렉터리가 이미 존재합니다.",
"Can't create app folder. Please fix permissions. %s" : "앱 폴더를 만들 수 없습니다. 권한을 수정하십시오. %s",
+ "Archive does not contain a directory named %s" : "압축 파일에 디렉터리 %s이(가) 없습니다",
"No source specified when installing app" : "앱을 설치할 때 소스가 지정되지 않았습니다.",
"No href specified when installing app from http" : "http에서 앱을 설치할 때 href가 지정되지 않았습니다.",
"No path specified when installing app from local file" : "로컬 파일에서 앱을 설치할 때 경로가 지정되지 않았습니다.",
@@ -88,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/l10n/nb_NO.js b/lib/l10n/nb_NO.js
index d09fa5ca6e8..af629c5ef34 100644
--- a/lib/l10n/nb_NO.js
+++ b/lib/l10n/nb_NO.js
@@ -49,6 +49,7 @@ OC.L10N.register(
"Can't read file" : "Kan ikke lese fil",
"App directory already exists" : "App-mappe finnes allerede",
"Can't create app folder. Please fix permissions. %s" : "Kan ikke opprette app-mappe. Vennligst ordne opp i tillatelser. %s",
+ "Archive does not contain a directory named %s" : "Arkivet inneholder ikke en mappe med navn %s",
"No source specified when installing app" : "Ingen kilde spesifisert ved installering av app",
"No href specified when installing app from http" : "Ingen href spesifisert ved installering av app fra http",
"No path specified when installing app from local file" : "Ingen sti spesifisert ved installering av app fra lokal fil",
@@ -90,6 +91,7 @@ OC.L10N.register(
"Sharing %s failed, because the user %s does not exist" : "Deling av %s feilet, fordi brukeren %s ikke finnes",
"Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Deling av %s feilet, fordi brukeren %s ikke er medlem av noen grupper som %s er medlem av",
"Sharing %s failed, because this item is already shared with %s" : "Deling av %s feilet, fordi dette elementet allerede er delt med %s",
+ "Sharing %s failed, because this item is already shared with user %s" : "Deling av %s feilet, fordi dette elementet allerede er delt med bruker %s",
"Sharing %s failed, because the group %s does not exist" : "Deling av %s feilet, fordi gruppen %s ikke finnes",
"Sharing %s failed, because %s is not a member of the group %s" : "Deling av %s feilet, fordi %s ikke er medlem av gruppen %s",
"You need to provide a password to create a public link, only protected links are allowed" : "Du må oppgi et passord for å lage en offentlig lenke. Bare beskyttede lenker er tillatt",
diff --git a/lib/l10n/nb_NO.json b/lib/l10n/nb_NO.json
index 665ae866969..29f9e7f1365 100644
--- a/lib/l10n/nb_NO.json
+++ b/lib/l10n/nb_NO.json
@@ -47,6 +47,7 @@
"Can't read file" : "Kan ikke lese fil",
"App directory already exists" : "App-mappe finnes allerede",
"Can't create app folder. Please fix permissions. %s" : "Kan ikke opprette app-mappe. Vennligst ordne opp i tillatelser. %s",
+ "Archive does not contain a directory named %s" : "Arkivet inneholder ikke en mappe med navn %s",
"No source specified when installing app" : "Ingen kilde spesifisert ved installering av app",
"No href specified when installing app from http" : "Ingen href spesifisert ved installering av app fra http",
"No path specified when installing app from local file" : "Ingen sti spesifisert ved installering av app fra lokal fil",
@@ -88,6 +89,7 @@
"Sharing %s failed, because the user %s does not exist" : "Deling av %s feilet, fordi brukeren %s ikke finnes",
"Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Deling av %s feilet, fordi brukeren %s ikke er medlem av noen grupper som %s er medlem av",
"Sharing %s failed, because this item is already shared with %s" : "Deling av %s feilet, fordi dette elementet allerede er delt med %s",
+ "Sharing %s failed, because this item is already shared with user %s" : "Deling av %s feilet, fordi dette elementet allerede er delt med bruker %s",
"Sharing %s failed, because the group %s does not exist" : "Deling av %s feilet, fordi gruppen %s ikke finnes",
"Sharing %s failed, because %s is not a member of the group %s" : "Deling av %s feilet, fordi %s ikke er medlem av gruppen %s",
"You need to provide a password to create a public link, only protected links are allowed" : "Du må oppgi et passord for å lage en offentlig lenke. Bare beskyttede lenker er tillatt",
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/app.php b/lib/private/app.php
index d5415834fa4..6eba215ee27 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 7ee64980fd0..cf2a057f224 100644
--- a/lib/private/appconfig.php
+++ b/lib/private/appconfig.php
@@ -175,11 +175,21 @@ class AppConfig implements IAppConfig {
->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);
+ ->setParameter('configkey', $key);
+
+ /*
+ * Only limit to the existing value for non-Oracle DBs:
+ * http://docs.oracle.com/cd/E11882_01/server.112/e26088/conditions002.htm#i1033286
+ * > Large objects (LOBs) are not supported in comparison conditions.
+ */
+ if (!($this->conn instanceof \OC\DB\OracleConnection)) {
+ // Only update the value when it is not the same
+ $sql->andWhere($sql->expr()->neq('configvalue', $sql->createParameter('configvalue')))
+ ->setParameter('configvalue', $value);
+ }
+
$changedRow = (bool) $sql->execute();
$this->cache[$app][$key] = $value;
diff --git a/lib/private/appframework/utility/simplecontainer.php b/lib/private/appframework/utility/simplecontainer.php
index 83a08acde26..5d7ea48752b 100644
--- a/lib/private/appframework/utility/simplecontainer.php
+++ b/lib/private/appframework/utility/simplecontainer.php
@@ -77,7 +77,7 @@ class SimpleContainer extends Container implements IContainer {
* @return stdClass
* @throws QueryException if the class could not be found or instantiated
*/
- private function resolve($name) {
+ public function resolve($name) {
$baseMsg = 'Could not resolve ' . $name . '!';
try {
$class = new ReflectionClass($name);
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/eventsource.php b/lib/private/eventsource.php
index c69671c1a75..e2be808e726 100644
--- a/lib/private/eventsource.php
+++ b/lib/private/eventsource.php
@@ -59,6 +59,17 @@ class OC_EventSource implements \OCP\IEventSource {
$this->fallback = isset($_GET['fallback']) and $_GET['fallback'] == 'true';
if ($this->fallback) {
$this->fallBackId = (int)$_GET['fallback_id'];
+ /**
+ * FIXME: The default content-security-policy of ownCloud forbids inline
+ * JavaScript for security reasons. IE starting on Windows 10 will
+ * however also obey the CSP which will break the event source fallback.
+ *
+ * As a workaround thus we set a custom policy which allows the execution
+ * of inline JavaScript.
+ *
+ * @link https://github.com/owncloud/core/issues/14286
+ */
+ header("Content-Security-Policy: default-src 'none'; script-src 'unsafe-inline'");
header("Content-Type: text/html");
echo str_repeat('<span></span>' . PHP_EOL, 10); //dummy data to keep IE happy
} else {
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/cache/scanner.php b/lib/private/files/cache/scanner.php
index f76ef5ba0dd..fb60ee5aa53 100644
--- a/lib/private/files/cache/scanner.php
+++ b/lib/private/files/cache/scanner.php
@@ -377,7 +377,7 @@ class Scanner extends BasicEmitter {
// inserted mimetypes but those weren't available yet inside the transaction
// To make sure to have the updated mime types in such cases,
// we reload them here
- $this->cache->loadMimetypes();
+ \OC::$server->getMimeTypeLoader()->reset();
}
foreach ($childQueue as $child => $childData) {
diff --git a/lib/private/files/storage/dav.php b/lib/private/files/storage/dav.php
index 6e89dcccbcd..c1cf17abdee 100644
--- a/lib/private/files/storage/dav.php
+++ b/lib/private/files/storage/dav.php
@@ -40,6 +40,7 @@ use OC\Files\Filesystem;
use OC\Files\Stream\Close;
use Icewind\Streams\IteratorDirectory;
use OC\MemCache\ArrayCache;
+use OCP\AppFramework\Http;
use OCP\Constants;
use OCP\Files;
use OCP\Files\FileInfo;
@@ -77,6 +78,8 @@ class DAV extends Common {
private $statCache;
/** @var array */
private static $tempFiles = [];
+ /** @var \OCP\Http\Client\IClientService */
+ private $httpClientService;
/**
* @param array $params
@@ -84,6 +87,7 @@ class DAV extends Common {
*/
public function __construct($params) {
$this->statCache = new ArrayCache();
+ $this->httpClientService = \OC::$server->getHTTPClientService();
if (isset($params['host']) && isset($params['user']) && isset($params['password'])) {
$host = $params['host'];
//remove leading http[s], will be generated in createBaseUri()
@@ -232,7 +236,7 @@ class DAV extends Common {
* If not, request it from the server then store to cache.
*
* @param string $path path to propfind
- *
+ *
* @return array propfind response
*
* @throws NotFound
@@ -337,38 +341,22 @@ class DAV extends Common {
if (!$this->file_exists($path)) {
return false;
}
- //straight up curl instead of sabredav here, sabredav put's the entire get result in memory
- $curl = curl_init();
- $fp = fopen('php://temp', 'r+');
- curl_setopt($curl, CURLOPT_USERPWD, $this->user . ':' . $this->password);
- curl_setopt($curl, CURLOPT_URL, $this->createBaseUri() . $this->encodePath($path));
- curl_setopt($curl, CURLOPT_FILE, $fp);
- curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
- if(defined('CURLOPT_PROTOCOLS')) {
- curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
- }
- if(defined('CURLOPT_REDIR_PROTOCOLS')) {
- curl_setopt($curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
- }
- if ($this->secure === true) {
- curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
- curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
- if ($this->certPath) {
- curl_setopt($curl, CURLOPT_CAINFO, $this->certPath);
- }
- }
-
- curl_exec($curl);
- $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
- if ($statusCode !== 200) {
- Util::writeLog("webdav client", 'curl GET ' . curl_getinfo($curl, CURLINFO_EFFECTIVE_URL) . ' returned status code ' . $statusCode, Util::ERROR);
- if ($statusCode === 423) {
+ $response = $this->httpClientService
+ ->newClient()
+ ->get($this->createBaseUri() . $this->encodePath($path), [
+ 'auth' => [$this->user, $this->password],
+ 'stream' => true
+ ]);
+
+ if ($response->getStatusCode() !== Http::STATUS_OK) {
+ if ($response->getStatusCode() === Http::STATUS_LOCKED) {
throw new \OCP\Lock\LockedException($path);
+ } else {
+ Util::writeLog("webdav client", 'Guzzle get returned status code ' . $response->getStatusCode(), Util::ERROR);
}
}
- curl_close($curl);
- rewind($fp);
- return $fp;
+
+ return $response->getBody();
case 'w':
case 'wb':
case 'a':
@@ -478,38 +466,19 @@ class DAV extends Common {
*/
protected function uploadFile($path, $target) {
$this->init();
+
// invalidate
$target = $this->cleanPath($target);
$this->statCache->remove($target);
$source = fopen($path, 'r');
- $curl = curl_init();
- curl_setopt($curl, CURLOPT_USERPWD, $this->user . ':' . $this->password);
- curl_setopt($curl, CURLOPT_URL, $this->createBaseUri() . $this->encodePath($target));
- curl_setopt($curl, CURLOPT_BINARYTRANSFER, true);
- curl_setopt($curl, CURLOPT_INFILE, $source); // file pointer
- curl_setopt($curl, CURLOPT_INFILESIZE, filesize($path));
- curl_setopt($curl, CURLOPT_PUT, true);
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
- curl_setopt($curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
- if ($this->secure === true) {
- curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
- curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
- if ($this->certPath) {
- curl_setopt($curl, CURLOPT_CAINFO, $this->certPath);
- }
- }
- curl_exec($curl);
- $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
- if ($statusCode !== 200) {
- Util::writeLog("webdav client", 'curl GET ' . curl_getinfo($curl, CURLINFO_EFFECTIVE_URL) . ' returned status code ' . $statusCode, Util::ERROR);
- if ($statusCode === 423) {
- throw new \OCP\Lock\LockedException($path);
- }
- }
- curl_close($curl);
- fclose($source);
+ $this->httpClientService
+ ->newClient()
+ ->put($this->createBaseUri() . $this->encodePath($target), [
+ 'body' => $source,
+ 'auth' => [$this->user, $this->password]
+ ]);
+
$this->removeCachedFile($target);
}
@@ -768,7 +737,7 @@ class DAV extends Common {
if ($e->getHttpStatus() === 404 || $e->getHttpStatus() === 405) {
if ($path === '') {
// if root is gone it means the storage is not available
- throw new StorageNotAvailableException(get_class($e).': '.$e->getMessage());
+ throw new StorageNotAvailableException(get_class($e) . ': ' . $e->getMessage());
}
return false;
}
@@ -802,19 +771,19 @@ class DAV extends Common {
}
if ($e->getHttpStatus() === 401) {
// either password was changed or was invalid all along
- throw new StorageInvalidException(get_class($e).': '.$e->getMessage());
+ throw new StorageInvalidException(get_class($e) . ': ' . $e->getMessage());
} else if ($e->getHttpStatus() === 405) {
// ignore exception for MethodNotAllowed, false will be returned
return;
}
- throw new StorageNotAvailableException(get_class($e).': '.$e->getMessage());
+ throw new StorageNotAvailableException(get_class($e) . ': ' . $e->getMessage());
} else if ($e instanceof ClientException) {
// connection timeout or refused, server could be temporarily down
- throw new StorageNotAvailableException(get_class($e).': '.$e->getMessage());
+ throw new StorageNotAvailableException(get_class($e) . ': ' . $e->getMessage());
} else if ($e instanceof \InvalidArgumentException) {
// parse error because the server returned HTML instead of XML,
// possibly temporarily down
- throw new StorageNotAvailableException(get_class($e).': '.$e->getMessage());
+ throw new StorageNotAvailableException(get_class($e) . ': ' . $e->getMessage());
} else if (($e instanceof StorageNotAvailableException) || ($e instanceof StorageInvalidException)) {
// rethrow
throw $e;
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..78bfcf60bff
--- /dev/null
+++ b/lib/private/files/type/loader.php
@@ -0,0 +1,173 @@
+<?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]);
+ }
+
+ /**
+ * Clear all loaded mimetypes, allow for re-loading
+ */
+ public function reset() {
+ $this->mimetypes = [];
+ $this->mimetypeIds = [];
+ }
+
+ /**
+ * 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/http/client/client.php b/lib/private/http/client/client.php
index 323fc0d324f..b0aff10a413 100644
--- a/lib/private/http/client/client.php
+++ b/lib/private/http/client/client.php
@@ -120,7 +120,8 @@ class Client implements IClient {
*/
public function get($uri, array $options = []) {
$response = $this->client->get($uri, $options);
- return new Response($response);
+ $isStream = isset($options['stream']) && $options['stream'];
+ return new Response($response, $isStream);
}
/**
diff --git a/lib/private/http/client/response.php b/lib/private/http/client/response.php
index 4e9df51d77f..558482491d1 100644
--- a/lib/private/http/client/response.php
+++ b/lib/private/http/client/response.php
@@ -34,17 +34,26 @@ class Response implements IResponse {
private $response;
/**
+ * @var bool
+ */
+ private $stream;
+
+ /**
* @param GuzzleResponse $response
+ * @param bool $stream
*/
- public function __construct(GuzzleResponse $response) {
+ public function __construct(GuzzleResponse $response, $stream = false) {
$this->response = $response;
+ $this->stream = $stream;
}
/**
- * @return string
+ * @return string|resource
*/
public function getBody() {
- return $this->response->getBody()->getContents();
+ return $this->stream ?
+ $this->response->getBody()->detach():
+ $this->response->getBody()->getContents();
}
/**
diff --git a/lib/private/memcache/memcached.php b/lib/private/memcache/memcached.php
index 1503851fd73..e99303ecc15 100644
--- a/lib/private/memcache/memcached.php
+++ b/lib/private/memcache/memcached.php
@@ -89,6 +89,11 @@ class Memcached extends Cache implements IMemcache {
public function clear($prefix = '') {
$prefix = $this->getNamespace() . $prefix;
$allKeys = self::$cache->getAllKeys();
+ if ($allKeys === false) {
+ // newer Memcached doesn't like getAllKeys(), flush everything
+ self::$cache->flush();
+ return true;
+ }
$keys = array();
$prefixLength = strlen($prefix);
foreach ($allKeys as $key) {
diff --git a/lib/private/notification/action.php b/lib/private/notification/action.php
new file mode 100644
index 00000000000..6de8a1a4bbc
--- /dev/null
+++ b/lib/private/notification/action.php
@@ -0,0 +1,167 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@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\Notification;
+
+
+class Action implements IAction {
+
+ /** @var string */
+ protected $label;
+
+ /** @var string */
+ protected $labelParsed;
+
+ /** @var string */
+ protected $link;
+
+ /** @var string */
+ protected $requestType;
+
+ /** @var string */
+ protected $icon;
+
+ /**
+ * Constructor
+ */
+ public function __construct() {
+ $this->label = '';
+ $this->labelParsed = '';
+ $this->link = '';
+ $this->requestType = '';
+ $this->icon = '';
+ }
+
+ /**
+ * @param string $label
+ * @return $this
+ * @throws \InvalidArgumentException if the label is invalid
+ * @since 8.2.0
+ */
+ public function setLabel($label) {
+ if (!is_string($label) || $label === '' || isset($label[32])) {
+ throw new \InvalidArgumentException('The given label is invalid');
+ }
+ $this->label = $label;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getLabel() {
+ return $this->label;
+ }
+
+ /**
+ * @param string $label
+ * @return $this
+ * @throws \InvalidArgumentException if the label is invalid
+ * @since 8.2.0
+ */
+ public function setParsedLabel($label) {
+ if (!is_string($label) || $label === '') {
+ throw new \InvalidArgumentException('The given parsed label is invalid');
+ }
+ $this->labelParsed = $label;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getParsedLabel() {
+ return $this->labelParsed;
+ }
+
+ /**
+ * @param string $link
+ * @param string $requestType
+ * @return $this
+ * @throws \InvalidArgumentException if the link is invalid
+ * @since 8.2.0
+ */
+ public function setLink($link, $requestType) {
+ if (!is_string($link) || $link === '' || isset($link[256])) {
+ throw new \InvalidArgumentException('The given link is invalid');
+ }
+ if (!in_array($requestType, ['GET', 'POST', 'PUT', 'DELETE'], true)) {
+ throw new \InvalidArgumentException('The given request type is invalid');
+ }
+ $this->link = $link;
+ $this->requestType = $requestType;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getLink() {
+ return $this->link;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getRequestType() {
+ return $this->requestType;
+ }
+
+ /**
+ * @param string $icon
+ * @return $this
+ * @throws \InvalidArgumentException if the icon is invalid
+ * @since 8.2.0
+ */
+ public function setIcon($icon) {
+ if (!is_string($icon) || $icon === '' || isset($icon[64])) {
+ throw new \InvalidArgumentException('The given icon is invalid');
+ }
+ $this->icon = $icon;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getIcon() {
+ return $this->icon;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isValid() {
+ return $this->label !== '' && $this->link !== '';
+ }
+
+ /**
+ * @return bool
+ */
+ public function isValidParsed() {
+ return $this->labelParsed !== '' && $this->link !== '';
+ }
+}
diff --git a/lib/private/notification/iaction.php b/lib/private/notification/iaction.php
new file mode 100644
index 00000000000..da6728f5c52
--- /dev/null
+++ b/lib/private/notification/iaction.php
@@ -0,0 +1,109 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@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\Notification;
+
+/**
+ * Interface IAction
+ *
+ * @package OC\Notification
+ * @since 8.2.0
+ *
+ * DEVELOPER NOTE:
+ * The notification api is experimental only in 8.2.0! Do not start using it,
+ * if you can not prepare an update for the next version afterwards.
+ */
+interface IAction {
+ /**
+ * @param string $label
+ * @return $this
+ * @throws \InvalidArgumentException if the label is invalid
+ * @since 8.2.0
+ */
+ public function setLabel($label);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getLabel();
+
+ /**
+ * @param string $label
+ * @return $this
+ * @throws \InvalidArgumentException if the label is invalid
+ * @since 8.2.0
+ */
+ public function setParsedLabel($label);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getParsedLabel();
+
+ /**
+ * @param string $link
+ * @param string $requestType
+ * @return $this
+ * @throws \InvalidArgumentException if the link is invalid
+ * @since 8.2.0
+ */
+ public function setLink($link, $requestType);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getLink();
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getRequestType();
+
+ /**
+ * @param string $icon
+ * @return $this
+ * @throws \InvalidArgumentException if the icon is invalid
+ * @since 8.2.0
+ */
+ public function setIcon($icon);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getIcon();
+
+ /**
+ * @return bool
+ * @since 8.2.0
+ */
+ public function isValid();
+
+ /**
+ * @return bool
+ * @since 8.2.0
+ */
+ public function isValidParsed();
+}
diff --git a/lib/private/notification/iapp.php b/lib/private/notification/iapp.php
new file mode 100644
index 00000000000..eda66423f3a
--- /dev/null
+++ b/lib/private/notification/iapp.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@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\Notification;
+
+/**
+ * Interface IApp
+ *
+ * @package OC\Notification
+ * @since 8.2.0
+ *
+ * DEVELOPER NOTE:
+ * The notification api is experimental only in 8.2.0! Do not start using it,
+ * if you can not prepare an update for the next version afterwards.
+ */
+interface IApp {
+ /**
+ * @param INotification $notification
+ * @return null
+ * @throws \InvalidArgumentException When the notification is not valid
+ * @since 8.2.0
+ */
+ public function notify(INotification $notification);
+
+ /**
+ * @param INotification $notification
+ * @return null
+ * @since 8.2.0
+ */
+ public function markProcessed(INotification $notification);
+
+ /**
+ * @param INotification $notification
+ * @return int
+ * @since 8.2.0
+ */
+ public function getCount(INotification $notification);
+}
diff --git a/lib/private/notification/imanager.php b/lib/private/notification/imanager.php
new file mode 100644
index 00000000000..0cd92b33251
--- /dev/null
+++ b/lib/private/notification/imanager.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@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\Notification;
+
+/**
+ * Interface IManager
+ *
+ * @package OC\Notification
+ * @since 8.2.0
+ *
+ * DEVELOPER NOTE:
+ * The notification api is experimental only in 8.2.0! Do not start using it,
+ * if you can not prepare an update for the next version afterwards.
+ */
+interface IManager extends IApp, INotifier {
+ /**
+ * @param \Closure $service The service must implement IApp, otherwise a
+ * \InvalidArgumentException is thrown later
+ * @return null
+ * @since 8.2.0
+ */
+ public function registerApp(\Closure $service);
+
+ /**
+ * @param \Closure $service The service must implement INotifier, otherwise a
+ * \InvalidArgumentException is thrown later
+ * @return null
+ * @since 8.2.0
+ */
+ public function registerNotifier(\Closure $service);
+
+ /**
+ * @return INotification
+ * @since 8.2.0
+ */
+ public function createNotification();
+}
diff --git a/lib/private/notification/inotification.php b/lib/private/notification/inotification.php
new file mode 100644
index 00000000000..faf5db1d24c
--- /dev/null
+++ b/lib/private/notification/inotification.php
@@ -0,0 +1,241 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@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\Notification;
+
+/**
+ * Interface INotification
+ *
+ * @package OC\Notification
+ * @since 8.2.0
+ *
+ * DEVELOPER NOTE:
+ * The notification api is experimental only in 8.2.0! Do not start using it,
+ * if you can not prepare an update for the next version afterwards.
+ */
+interface INotification {
+ /**
+ * @param string $app
+ * @return $this
+ * @throws \InvalidArgumentException if the app id are invalid
+ * @since 8.2.0
+ */
+ public function setApp($app);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getApp();
+
+ /**
+ * @param string $user
+ * @return $this
+ * @throws \InvalidArgumentException if the user id are invalid
+ * @since 8.2.0
+ */
+ public function setUser($user);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getUser();
+
+ /**
+ * @param int $timestamp
+ * @return $this
+ * @throws \InvalidArgumentException if the timestamp are invalid
+ * @since 8.2.0
+ */
+ public function setTimestamp($timestamp);
+
+ /**
+ * @return int
+ * @since 8.2.0
+ */
+ public function getTimestamp();
+
+ /**
+ * @param string $type
+ * @param int $id
+ * @return $this
+ * @throws \InvalidArgumentException if the object type or id are invalid
+ * @since 8.2.0
+ */
+ public function setObject($type, $id);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getObjectType();
+
+ /**
+ * @return int
+ * @since 8.2.0
+ */
+ public function getObjectId();
+
+ /**
+ * @param string $subject
+ * @param array $parameters
+ * @return $this
+ * @throws \InvalidArgumentException if the subject or parameters are invalid
+ * @since 8.2.0
+ */
+ public function setSubject($subject, array $parameters = []);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getSubject();
+
+ /**
+ * @return string[]
+ * @since 8.2.0
+ */
+ public function getSubjectParameters();
+
+ /**
+ * @param string $subject
+ * @return $this
+ * @throws \InvalidArgumentException if the subject are invalid
+ * @since 8.2.0
+ */
+ public function setParsedSubject($subject);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getParsedSubject();
+
+ /**
+ * @param string $message
+ * @param array $parameters
+ * @return $this
+ * @throws \InvalidArgumentException if the message or parameters are invalid
+ * @since 8.2.0
+ */
+ public function setMessage($message, array $parameters = []);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getMessage();
+
+ /**
+ * @return string[]
+ * @since 8.2.0
+ */
+ public function getMessageParameters();
+
+ /**
+ * @param string $message
+ * @return $this
+ * @throws \InvalidArgumentException if the message are invalid
+ * @since 8.2.0
+ */
+ public function setParsedMessage($message);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getParsedMessage();
+
+ /**
+ * @param string $link
+ * @return $this
+ * @throws \InvalidArgumentException if the link are invalid
+ * @since 8.2.0
+ */
+ public function setLink($link);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getLink();
+
+ /**
+ * @param string $icon
+ * @return $this
+ * @throws \InvalidArgumentException if the icon are invalid
+ * @since 8.2.0
+ */
+ public function setIcon($icon);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getIcon();
+
+ /**
+ * @return IAction
+ * @since 8.2.0
+ */
+ public function createAction();
+
+ /**
+ * @param IAction $action
+ * @return $this
+ * @throws \InvalidArgumentException if the action are invalid
+ * @since 8.2.0
+ */
+ public function addAction(IAction $action);
+
+ /**
+ * @return IAction[]
+ * @since 8.2.0
+ */
+ public function getActions();
+
+ /**
+ * @param IAction $action
+ * @return $this
+ * @throws \InvalidArgumentException if the action are invalid
+ * @since 8.2.0
+ */
+ public function addParsedAction(IAction $action);
+
+ /**
+ * @return IAction[]
+ * @since 8.2.0
+ */
+ public function getParsedActions();
+
+ /**
+ * @return bool
+ * @since 8.2.0
+ */
+ public function isValid();
+
+ /**
+ * @return bool
+ * @since 8.2.0
+ */
+ public function isValidParsed();
+}
diff --git a/lib/private/notification/inotifier.php b/lib/private/notification/inotifier.php
new file mode 100644
index 00000000000..22531229e3f
--- /dev/null
+++ b/lib/private/notification/inotifier.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@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\Notification;
+
+/**
+ * Interface INotifier
+ *
+ * @package OC\Notification
+ * @since 8.2.0
+ *
+ * DEVELOPER NOTE:
+ * The notification api is experimental only in 8.2.0! Do not start using it,
+ * if you can not prepare an update for the next version afterwards.
+ */
+interface INotifier {
+ /**
+ * @param INotification $notification
+ * @param string $languageCode The code of the language that should be used to prepare the notification
+ * @return INotification
+ * @throws \InvalidArgumentException When the notification was not prepared by a notifier
+ * @since 8.2.0
+ */
+ public function prepare(INotification $notification, $languageCode);
+}
diff --git a/lib/private/notification/manager.php b/lib/private/notification/manager.php
new file mode 100644
index 00000000000..9635925e38e
--- /dev/null
+++ b/lib/private/notification/manager.php
@@ -0,0 +1,191 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@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\Notification;
+
+
+class Manager implements IManager {
+ /** @var IApp */
+ protected $apps;
+
+ /** @var INotifier */
+ protected $notifiers;
+
+ /** @var \Closure */
+ protected $appsClosures;
+
+ /** @var \Closure */
+ protected $notifiersClosures;
+
+ public function __construct() {
+ $this->apps = [];
+ $this->notifiers = [];
+ $this->appsClosures = [];
+ $this->notifiersClosures = [];
+ }
+
+ /**
+ * @param \Closure $service The service must implement IApp, otherwise a
+ * \InvalidArgumentException is thrown later
+ * @return null
+ * @since 8.2.0
+ */
+ public function registerApp(\Closure $service) {
+ $this->appsClosures[] = $service;
+ $this->apps = [];
+ }
+
+ /**
+ * @param \Closure $service The service must implement INotifier, otherwise a
+ * \InvalidArgumentException is thrown later
+ * @return null
+ * @since 8.2.0
+ */
+ public function registerNotifier(\Closure $service) {
+ $this->notifiersClosures[] = $service;
+ $this->notifiers = [];
+ }
+
+ /**
+ * @return IApp[]
+ */
+ protected function getApps() {
+ if (!empty($this->apps)) {
+ return $this->apps;
+ }
+
+ $this->apps = [];
+ foreach ($this->appsClosures as $closure) {
+ $app = $closure();
+ if (!($app instanceof IApp)) {
+ throw new \InvalidArgumentException('The given notification app does not implement the IApp interface');
+ }
+ $this->apps[] = $app;
+ }
+
+ return $this->apps;
+ }
+
+ /**
+ * @return INotifier[]
+ */
+ protected function getNotifiers() {
+ if (!empty($this->notifiers)) {
+ return $this->notifiers;
+ }
+
+ $this->notifiers = [];
+ foreach ($this->notifiersClosures as $closure) {
+ $notifier = $closure();
+ if (!($notifier instanceof INotifier)) {
+ throw new \InvalidArgumentException('The given notification app does not implement the INotifier interface');
+ }
+ $this->notifiers[] = $notifier;
+ }
+
+ return $this->notifiers;
+ }
+
+ /**
+ * @return INotification
+ * @since 8.2.0
+ */
+ public function createNotification() {
+ return new Notification();
+ }
+
+ /**
+ * @param INotification $notification
+ * @return null
+ * @throws \InvalidArgumentException When the notification is not valid
+ * @since 8.2.0
+ */
+ public function notify(INotification $notification) {
+ if (!$notification->isValid()) {
+ throw new \InvalidArgumentException('The given notification is invalid');
+ }
+
+ $apps = $this->getApps();
+
+ foreach ($apps as $app) {
+ try {
+ $app->notify($notification);
+ } catch (\InvalidArgumentException $e) {
+ }
+ }
+ }
+
+ /**
+ * @param INotification $notification
+ * @param string $languageCode The code of the language that should be used to prepare the notification
+ * @return INotification
+ * @throws \InvalidArgumentException When the notification was not prepared by a notifier
+ * @since 8.2.0
+ */
+ public function prepare(INotification $notification, $languageCode) {
+ $notifiers = $this->getNotifiers();
+
+ foreach ($notifiers as $notifier) {
+ try {
+ $notification = $notifier->prepare($notification, $languageCode);
+ } catch (\InvalidArgumentException $e) {
+ continue;
+ }
+
+ if (!($notification instanceof INotification) || !$notification->isValidParsed()) {
+ throw new \InvalidArgumentException('The given notification has not been handled');
+ }
+ }
+
+ if (!($notification instanceof INotification) || !$notification->isValidParsed()) {
+ throw new \InvalidArgumentException('The given notification has not been handled');
+ }
+
+ return $notification;
+ }
+
+ /**
+ * @param INotification $notification
+ * @return null
+ */
+ public function markProcessed(INotification $notification) {
+ $apps = $this->getApps();
+
+ foreach ($apps as $app) {
+ $app->markProcessed($notification);
+ }
+ }
+
+ /**
+ * @param INotification $notification
+ * @return int
+ */
+ public function getCount(INotification $notification) {
+ $apps = $this->getApps();
+
+ $count = 0;
+ foreach ($apps as $app) {
+ $count += $app->getCount($notification);
+ }
+
+ return $count;
+ }
+}
diff --git a/lib/private/notification/notification.php b/lib/private/notification/notification.php
new file mode 100644
index 00000000000..40fe39a956e
--- /dev/null
+++ b/lib/private/notification/notification.php
@@ -0,0 +1,446 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@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\Notification;
+
+
+class Notification implements INotification {
+ /** @var string */
+ protected $app;
+
+ /** @var string */
+ protected $user;
+
+ /** @var int */
+ protected $timestamp;
+
+ /** @var string */
+ protected $objectType;
+
+ /** @var int */
+ protected $objectId;
+
+ /** @var string */
+ protected $subject;
+
+ /** @var array */
+ protected $subjectParameters;
+
+ /** @var string */
+ protected $subjectParsed;
+
+ /** @var string */
+ protected $message;
+
+ /** @var array */
+ protected $messageParameters;
+
+ /** @var string */
+ protected $messageParsed;
+
+ /** @var string */
+ protected $link;
+
+ /** @var string */
+ protected $icon;
+
+ /** @var array */
+ protected $actions;
+
+ /** @var array */
+ protected $actionsParsed;
+
+ /**
+ * Constructor
+ */
+ public function __construct() {
+ $this->app = '';
+ $this->user = '';
+ $this->timestamp = 0;
+ $this->objectType = '';
+ $this->objectId = 0;
+ $this->subject = '';
+ $this->subjectParameters = [];
+ $this->subjectParsed = '';
+ $this->message = '';
+ $this->messageParameters = [];
+ $this->messageParsed = '';
+ $this->link = '';
+ $this->icon = '';
+ $this->actions = [];
+ $this->actionsParsed = [];
+ }
+
+ /**
+ * @param string $app
+ * @return $this
+ * @throws \InvalidArgumentException if the app id is invalid
+ * @since 8.2.0
+ */
+ public function setApp($app) {
+ if (!is_string($app) || $app === '' || isset($app[32])) {
+ throw new \InvalidArgumentException('The given app name is invalid');
+ }
+ $this->app = $app;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getApp() {
+ return $this->app;
+ }
+
+ /**
+ * @param string $user
+ * @return $this
+ * @throws \InvalidArgumentException if the user id is invalid
+ * @since 8.2.0
+ */
+ public function setUser($user) {
+ if (!is_string($user) || $user === '' || isset($user[64])) {
+ throw new \InvalidArgumentException('The given user id is invalid');
+ }
+ $this->user = $user;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getUser() {
+ return $this->user;
+ }
+
+ /**
+ * @param int $timestamp
+ * @return $this
+ * @throws \InvalidArgumentException if the timestamp is invalid
+ * @since 8.2.0
+ */
+ public function setTimestamp($timestamp) {
+ if (!is_int($timestamp)) {
+ throw new \InvalidArgumentException('The given timestamp is invalid');
+ }
+ $this->timestamp = $timestamp;
+ return $this;
+ }
+
+ /**
+ * @return int
+ * @since 8.2.0
+ */
+ public function getTimestamp() {
+ return $this->timestamp;
+ }
+
+ /**
+ * @param string $type
+ * @param int $id
+ * @return $this
+ * @throws \InvalidArgumentException if the object type or id is invalid
+ * @since 8.2.0
+ */
+ public function setObject($type, $id) {
+ if (!is_string($type) || $type === '' || isset($type[64])) {
+ throw new \InvalidArgumentException('The given object type is invalid');
+ }
+ $this->objectType = $type;
+
+ if (!is_int($id)) {
+ throw new \InvalidArgumentException('The given object id is invalid');
+ }
+ $this->objectId = $id;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getObjectType() {
+ return $this->objectType;
+ }
+
+ /**
+ * @return int
+ * @since 8.2.0
+ */
+ public function getObjectId() {
+ return $this->objectId;
+ }
+
+ /**
+ * @param string $subject
+ * @param array $parameters
+ * @return $this
+ * @throws \InvalidArgumentException if the subject or parameters are invalid
+ * @since 8.2.0
+ */
+ public function setSubject($subject, array $parameters = []) {
+ if (!is_string($subject) || $subject === '' || isset($subject[64])) {
+ throw new \InvalidArgumentException('The given subject is invalid');
+ }
+ $this->subject = $subject;
+
+ if (!is_array($parameters)) {
+ throw new \InvalidArgumentException('The given subject parameters are invalid');
+ }
+ $this->subjectParameters = $parameters;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getSubject() {
+ return $this->subject;
+ }
+
+ /**
+ * @return string[]
+ * @since 8.2.0
+ */
+ public function getSubjectParameters() {
+ return $this->subjectParameters;
+ }
+
+ /**
+ * @param string $subject
+ * @return $this
+ * @throws \InvalidArgumentException if the subject are invalid
+ * @since 8.2.0
+ */
+ public function setParsedSubject($subject) {
+ if (!is_string($subject) || $subject === '') {
+ throw new \InvalidArgumentException('The given parsed subject is invalid');
+ }
+ $this->subjectParsed = $subject;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getParsedSubject() {
+ return $this->subjectParsed;
+ }
+
+ /**
+ * @param string $message
+ * @param array $parameters
+ * @return $this
+ * @throws \InvalidArgumentException if the message or parameters are invalid
+ * @since 8.2.0
+ */
+ public function setMessage($message, array $parameters = []) {
+ if (!is_string($message) || $message === '' || isset($message[64])) {
+ throw new \InvalidArgumentException('The given message is invalid');
+ }
+ $this->message = $message;
+
+ if (!is_array($parameters)) {
+ throw new \InvalidArgumentException('The given message parameters are invalid');
+ }
+ $this->messageParameters = $parameters;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getMessage() {
+ return $this->message;
+ }
+
+ /**
+ * @return string[]
+ * @since 8.2.0
+ */
+ public function getMessageParameters() {
+ return $this->messageParameters;
+ }
+
+ /**
+ * @param string $message
+ * @return $this
+ * @throws \InvalidArgumentException if the message are invalid
+ * @since 8.2.0
+ */
+ public function setParsedMessage($message) {
+ if (!is_string($message) || $message === '') {
+ throw new \InvalidArgumentException('The given parsed message is invalid');
+ }
+ $this->messageParsed = $message;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getParsedMessage() {
+ return $this->messageParsed;
+ }
+
+ /**
+ * @param string $link
+ * @return $this
+ * @throws \InvalidArgumentException if the link are invalid
+ * @since 8.2.0
+ */
+ public function setLink($link) {
+ if (!is_string($link) || $link === '' || isset($link[4000])) {
+ throw new \InvalidArgumentException('The given link is invalid');
+ }
+ $this->link = $link;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getLink() {
+ return $this->link;
+ }
+
+ /**
+ * @param string $icon
+ * @return $this
+ * @throws \InvalidArgumentException if the icon are invalid
+ * @since 8.2.0
+ */
+ public function setIcon($icon) {
+ if (!is_string($icon) || $icon === '' || isset($icon[64])) {
+ throw new \InvalidArgumentException('The given icon is invalid');
+ }
+ $this->icon = $icon;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getIcon() {
+ return $this->icon;
+ }
+
+ /**
+ * @return IAction
+ * @since 8.2.0
+ */
+ public function createAction() {
+ return new Action();
+ }
+
+ /**
+ * @param IAction $action
+ * @return $this
+ * @throws \InvalidArgumentException if the action are invalid
+ * @since 8.2.0
+ */
+ public function addAction(IAction $action) {
+ if (!$action->isValid()) {
+ throw new \InvalidArgumentException('The given action is invalid');
+ }
+ $this->actions[] = $action;
+ return $this;
+ }
+
+ /**
+ * @return IAction[]
+ * @since 8.2.0
+ */
+ public function getActions() {
+ return $this->actions;
+ }
+
+ /**
+ * @param IAction $action
+ * @return $this
+ * @throws \InvalidArgumentException if the action are invalid
+ * @since 8.2.0
+ */
+ public function addParsedAction(IAction $action) {
+ if (!$action->isValidParsed()) {
+ throw new \InvalidArgumentException('The given parsed action is invalid');
+ }
+ $this->actionsParsed[] = $action;
+ return $this;
+ }
+
+ /**
+ * @return IAction[]
+ * @since 8.2.0
+ */
+ public function getParsedActions() {
+ return $this->actionsParsed;
+ }
+
+ /**
+ * @return bool
+ * @since 8.2.0
+ */
+ public function isValid() {
+ return
+ $this->isValidCommon()
+ &&
+ $this->getSubject() !== ''
+ ;
+ }
+
+ /**
+ * @return bool
+ * @since 8.2.0
+ */
+ public function isValidParsed() {
+ return
+ $this->isValidCommon()
+ &&
+ $this->getParsedSubject() !== ''
+ ;
+ }
+
+ /**
+ * @return bool
+ */
+ protected function isValidCommon() {
+ return
+ $this->getApp() !== ''
+ &&
+ $this->getUser() !== ''
+ &&
+ $this->getTimestamp() !== 0
+ &&
+ $this->getObjectType() !== ''
+ &&
+ $this->getObjectId() !== 0
+ ;
+ }
+}
diff --git a/lib/private/server.php b/lib/private/server.php
index 24674d2e3c7..9657afbdaec 100644
--- a/lib/private/server.php
+++ b/lib/private/server.php
@@ -53,6 +53,7 @@ use OC\Lock\DBLockingProvider;
use OC\Lock\MemcacheLockingProvider;
use OC\Lock\NoopLockingProvider;
use OC\Mail\Mailer;
+use OC\Notification\Manager;
use OC\Security\CertificateManager;
use OC\Security\Crypto;
use OC\Security\Hasher;
@@ -177,8 +178,6 @@ class Server extends SimpleContainer implements IServerContainer {
$manager = $c->getUserManager();
$session = new \OC\Session\Memory('');
- $cryptoWrapper = $c->getSessionCryptoWrapper();
- $session = $cryptoWrapper->wrapSession($session);
$userSession = new \OC\User\Session($manager, $session);
$userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) {
@@ -252,7 +251,7 @@ class Server extends SimpleContainer implements IServerContainer {
if($config->getSystemValue('installed', false) && !(defined('PHPUNIT_RUN') && PHPUNIT_RUN)) {
$v = \OC_App::getAppVersions();
- $v['core'] = implode('.', \OC_Util::getVersion());
+ $v['core'] = md5(file_get_contents(\OC::$SERVERROOT . '/version.php'));
$version = implode(',', $v);
$instanceId = \OC_Util::getInstanceId();
$path = \OC::$SERVERROOT;
@@ -357,7 +356,10 @@ class Server extends SimpleContainer implements IServerContainer {
}
});
$this->registerService('TempManager', function (Server $c) {
- return new TempManager(get_temp_dir(), $c->getLogger());
+ return new TempManager(
+ $c->getLogger(),
+ $c->getConfig()
+ );
});
$this->registerService('AppManager', function(Server $c) {
return new \OC\App\AppManager(
@@ -470,6 +472,14 @@ 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('NotificationManager', function() {
+ return new Manager();
+ });
$this->registerService('CapabilitiesManager', function (Server $c) {
$manager = new \OC\CapabilitiesManager();
$manager->registerCapability(function() use ($c) {
@@ -1011,6 +1021,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
@@ -1030,9 +1049,51 @@ class Server extends SimpleContainer implements IServerContainer {
}
/**
+ * Get the Notification Manager
+ *
+ * @return \OC\Notification\IManager
+ * @since 8.2.0
+ */
+ public function getNotificationManager() {
+ return $this->query('NotificationManager');
+ }
+
+ /**
* @return \OC\Session\CryptoWrapper
*/
public function getSessionCryptoWrapper() {
return $this->query('CryptoWrapper');
}
+
+ /**
+ * Not a public API as of 8.2, wait for 9.0
+ * @return \OCA\Files_External\Service\BackendService
+ */
+ public function getStoragesBackendService() {
+ return \OC_Mount_Config::$app->getContainer()->query('OCA\\Files_External\\Service\\BackendService');
+ }
+
+ /**
+ * Not a public API as of 8.2, wait for 9.0
+ * @return \OCA\Files_External\Service\GlobalStoragesService
+ */
+ public function getGlobalStoragesService() {
+ return \OC_Mount_Config::$app->getContainer()->query('OCA\\Files_External\\Service\\GlobalStoragesService');
+ }
+
+ /**
+ * Not a public API as of 8.2, wait for 9.0
+ * @return \OCA\Files_External\Service\UserGlobalStoragesService
+ */
+ public function getUserGlobalStoragesService() {
+ return \OC_Mount_Config::$app->getContainer()->query('OCA\\Files_External\\Service\\UserGlobalStoragesService');
+ }
+
+ /**
+ * Not a public API as of 8.2, wait for 9.0
+ * @return \OCA\Files_External\Service\UserStoragesService
+ */
+ public function getUserStoragesService() {
+ return \OC_Mount_Config::$app->getContainer()->query('OCA\\Files_External\\Service\\UserStoragesService');
+ }
}
diff --git a/lib/private/session/cryptosessiondata.php b/lib/private/session/cryptosessiondata.php
index 60d22b25e97..6826ede5e33 100644
--- a/lib/private/session/cryptosessiondata.php
+++ b/lib/private/session/cryptosessiondata.php
@@ -32,22 +32,47 @@ use OCP\Security\ICrypto;
class CryptoSessionData implements \ArrayAccess, ISession {
/** @var ISession */
protected $session;
-
/** @var \OCP\Security\ICrypto */
protected $crypto;
-
/** @var string */
protected $passphrase;
+ /** @var array */
+ protected $sessionValues;
+ /** @var bool */
+ protected $isModified = false;
+ CONST encryptedSessionName = 'encrypted_session_data';
/**
* @param ISession $session
* @param ICrypto $crypto
* @param string $passphrase
*/
- public function __construct(ISession $session, ICrypto $crypto, $passphrase) {
+ public function __construct(ISession $session,
+ ICrypto $crypto,
+ $passphrase) {
$this->crypto = $crypto;
$this->session = $session;
$this->passphrase = $passphrase;
+ $this->initializeSession();
+ }
+
+ /**
+ * Close session if class gets destructed
+ */
+ public function __destruct() {
+ $this->close();
+ }
+
+ protected function initializeSession() {
+ $encryptedSessionData = $this->session->get(self::encryptedSessionName);
+ try {
+ $this->sessionValues = json_decode(
+ $this->crypto->decrypt($encryptedSessionData, $this->passphrase),
+ true
+ );
+ } catch (\Exception $e) {
+ $this->sessionValues = [];
+ }
}
/**
@@ -57,8 +82,8 @@ class CryptoSessionData implements \ArrayAccess, ISession {
* @param mixed $value
*/
public function set($key, $value) {
- $encryptedValue = $this->crypto->encrypt(json_encode($value), $this->passphrase);
- $this->session->set($key, $encryptedValue);
+ $this->sessionValues[$key] = $value;
+ $this->isModified = true;
}
/**
@@ -68,17 +93,11 @@ class CryptoSessionData implements \ArrayAccess, ISession {
* @return string|null Either the value or null
*/
public function get($key) {
- $encryptedValue = $this->session->get($key);
- if ($encryptedValue === null) {
- return null;
+ if(isset($this->sessionValues[$key])) {
+ return $this->sessionValues[$key];
}
- try {
- $value = $this->crypto->decrypt($encryptedValue, $this->passphrase);
- return json_decode($value);
- } catch (\Exception $e) {
- return null;
- }
+ return null;
}
/**
@@ -88,7 +107,7 @@ class CryptoSessionData implements \ArrayAccess, ISession {
* @return bool
*/
public function exists($key) {
- return $this->session->exists($key);
+ return isset($this->sessionValues[$key]);
}
/**
@@ -97,20 +116,29 @@ class CryptoSessionData implements \ArrayAccess, ISession {
* @param string $key
*/
public function remove($key) {
- $this->session->remove($key);
+ $this->isModified = true;
+ unset($this->sessionValues[$key]);
+ $this->session->remove(self::encryptedSessionName);
}
/**
* Reset and recreate the session
*/
public function clear() {
+ $this->sessionValues = [];
+ $this->isModified = true;
$this->session->clear();
}
/**
- * Close the session and release the lock
+ * Close the session and release the lock, also writes all changed data in batch
*/
public function close() {
+ if($this->isModified) {
+ $encryptedValue = $this->crypto->encrypt(json_encode($this->sessionValues), $this->passphrase);
+ $this->session->set(self::encryptedSessionName, $encryptedValue);
+ $this->isModified = false;
+ }
$this->session->close();
}
diff --git a/lib/private/session/cryptowrapper.php b/lib/private/session/cryptowrapper.php
index 62bdcbfb719..261514d683e 100644
--- a/lib/private/session/cryptowrapper.php
+++ b/lib/private/session/cryptowrapper.php
@@ -77,7 +77,11 @@ class CryptoWrapper {
$secureCookie = $request->getServerProtocol() === 'https';
// FIXME: Required for CI
if (!defined('PHPUNIT_RUN')) {
- setcookie(self::COOKIE_NAME, $this->passphrase, 0, \OC::$WEBROOT, '', $secureCookie, true);
+ $webRoot = \OC::$WEBROOT;
+ if($webRoot === '') {
+ $webRoot = '/';
+ }
+ setcookie(self::COOKIE_NAME, $this->passphrase, 0, $webRoot, '', $secureCookie, true);
}
}
}
diff --git a/lib/private/session/internal.php b/lib/private/session/internal.php
index 77197887754..8ee21272104 100644
--- a/lib/private/session/internal.php
+++ b/lib/private/session/internal.php
@@ -32,6 +32,10 @@ namespace OC\Session;
* @package OC\Session
*/
class Internal extends Session {
+ /**
+ * @param string $name
+ * @throws \Exception
+ */
public function __construct($name) {
session_name($name);
set_error_handler(array($this, 'trapError'));
@@ -42,10 +46,6 @@ class Internal extends Session {
}
}
- public function __destruct() {
- $this->close();
- }
-
/**
* @param string $key
* @param integer $value
diff --git a/lib/private/share/share.php b/lib/private/share/share.php
index 70ed26c0b27..6ad36d60fe8 100644
--- a/lib/private/share/share.php
+++ b/lib/private/share/share.php
@@ -765,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/tempmanager.php b/lib/private/tempmanager.php
index b8cef8e036e..cc7c51d8568 100644
--- a/lib/private/tempmanager.php
+++ b/lib/private/tempmanager.php
@@ -25,6 +25,7 @@
namespace OC;
use OCP\ILogger;
+use OCP\IConfig;
use OCP\ITempManager;
class TempManager implements ITempManager {
@@ -34,16 +35,20 @@ class TempManager implements ITempManager {
protected $tmpBaseDir;
/** @var ILogger */
protected $log;
+ /** @var IConfig */
+ protected $config;
+
/** Prefix */
const TMP_PREFIX = 'oc_tmp_';
/**
- * @param string $baseDir
* @param \OCP\ILogger $logger
+ * @param \OCP\IConfig $config
*/
- public function __construct($baseDir, ILogger $logger) {
- $this->tmpBaseDir = $baseDir;
+ public function __construct(ILogger $logger, IConfig $config) {
$this->log = $logger;
+ $this->config = $config;
+ $this->tmpBaseDir = $this->getTempBaseDir();
}
/**
@@ -190,4 +195,79 @@ class TempManager implements ITempManager {
}
return $files;
}
+
+ /**
+ * Get the temporary base directory configured on the server
+ *
+ * @return string Path to the temporary directory or null
+ * @throws \UnexpectedValueException
+ */
+ public function getTempBaseDir() {
+ if ($this->tmpBaseDir) {
+ return $this->tmpBaseDir;
+ }
+
+ $directories = [];
+ if ($temp = $this->config->getSystemValue('tempdirectory', null)) {
+ $directories[] = $temp;
+ }
+ if ($temp = ini_get('upload_tmp_dir')) {
+ $directories[] = $temp;
+ }
+ if ($temp = getenv('TMP')) {
+ $directories[] = $temp;
+ }
+ if ($temp = getenv('TEMP')) {
+ $directories[] = $temp;
+ }
+ if ($temp = getenv('TMPDIR')) {
+ $directories[] = $temp;
+ }
+ $temp = tempnam(__FILE__, '');
+ if (file_exists($temp)) {
+ unlink($temp);
+ $directories[] = dirname($temp);
+ }
+ if ($temp = sys_get_temp_dir()) {
+ $directories[] = $temp;
+ }
+
+ foreach ($directories as $dir) {
+ if ($this->checkTemporaryDirectory($dir)) {
+ return $dir;
+ }
+ }
+ throw new \UnexpectedValueException('Unable to detect system temporary directory');
+ }
+
+ /**
+ * Check if a temporary directory is ready for use
+ *
+ * @param mixed $directory
+ * @return bool
+ */
+ private function checkTemporaryDirectory($directory) {
+ // surpress any possible errors caused by is_writable
+ // checks missing or invalid path or characters, wrong permissions ect
+ try {
+ if (is_writeable($directory)) {
+ return true;
+ }
+ } catch (Exception $e) {
+ }
+ $this->log->warning('Temporary directory {dir} is not present or writable',
+ ['dir' => $directory]
+ );
+ return false;
+ }
+
+ /**
+ * Override the temporary base directory
+ *
+ * @param string $directory
+ */
+ public function overrideTempBaseDir($directory) {
+ $this->tmpBaseDir = $directory;
+ }
+
}
diff --git a/lib/private/updater.php b/lib/private/updater.php
index f73fa8ff655..71e9732c307 100644
--- a/lib/private/updater.php
+++ b/lib/private/updater.php
@@ -212,19 +212,26 @@ class Updater extends BasicEmitter {
}
/**
+ * Return version from which this version is allowed to upgrade from
+ *
+ * @return string allowed previous version
+ */
+ private function getAllowedPreviousVersion() {
+ // this should really be a JSON file
+ require \OC::$SERVERROOT . '/version.php';
+ return implode('.', $OC_VersionCanBeUpgradedFrom);
+ }
+
+ /**
* Whether an upgrade to a specified version is possible
* @param string $oldVersion
* @param string $newVersion
+ * @param string $allowedPreviousVersion
* @return bool
*/
- public function isUpgradePossible($oldVersion, $newVersion) {
- $oldVersion = explode('.', $oldVersion);
- $newVersion = explode('.', $newVersion);
-
- if($newVersion[0] > ($oldVersion[0] + 1) || $oldVersion[0] > $newVersion[0]) {
- return false;
- }
- return true;
+ public function isUpgradePossible($oldVersion, $newVersion, $allowedPreviousVersion) {
+ return (version_compare($allowedPreviousVersion, $oldVersion, '<=')
+ && version_compare($oldVersion, $newVersion, '<='));
}
/**
@@ -259,8 +266,9 @@ class Updater extends BasicEmitter {
*/
private function doUpgrade($currentVersion, $installedVersion) {
// Stop update if the update is over several major versions
- if (!self::isUpgradePossible($installedVersion, $currentVersion)) {
- throw new \Exception('Updates between multiple major versions are unsupported.');
+ $allowedPreviousVersion = $this->getAllowedPreviousVersion();
+ if (!self::isUpgradePossible($installedVersion, $currentVersion, $allowedPreviousVersion)) {
+ throw new \Exception('Updates between multiple major versions and downgrades are unsupported.');
}
// Update .htaccess files
diff --git a/lib/private/util.php b/lib/private/util.php
index 0fda55496dc..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;
}
/**
@@ -1449,8 +1456,12 @@ class OC_Util {
if ($config->getSystemValue('installed', false)) {
$installedVersion = $config->getSystemValue('version', '0.0.0');
$currentVersion = implode('.', OC_Util::getVersion());
- if (version_compare($currentVersion, $installedVersion, '>')) {
+ $versionDiff = version_compare($currentVersion, $installedVersion);
+ if ($versionDiff > 0) {
return true;
+ } else if ($versionDiff < 0) {
+ // downgrade attempt, throw exception
+ throw new \OC\HintException('Downgrading is not supported and is likely to cause unpredictable issues (from ' . $installedVersion . ' to ' . $currentVersion . ')');
}
// also check for upgrades for apps (independently from the user)
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..6d00c4a0b31
--- /dev/null
+++ b/lib/public/files/imimetypeloader.php
@@ -0,0 +1,66 @@
+<?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);
+
+ /**
+ * Clear all loaded mimetypes, allow for re-loading
+ *
+ * @since 8.2.0
+ */
+ public function reset();
+}
diff --git a/lib/public/http/client/iresponse.php b/lib/public/http/client/iresponse.php
index 0e0ef4c5014..92bb7af82dd 100644
--- a/lib/public/http/client/iresponse.php
+++ b/lib/public/http/client/iresponse.php
@@ -30,7 +30,7 @@ namespace OCP\Http\Client;
*/
interface IResponse {
/**
- * @return string
+ * @return string|resource
* @since 8.1.0
*/
public function getBody();
diff --git a/lib/public/icontainer.php b/lib/public/icontainer.php
index 75ff5e97b69..ffd1d16c97e 100644
--- a/lib/public/icontainer.php
+++ b/lib/public/icontainer.php
@@ -44,6 +44,16 @@ use Closure;
interface IContainer {
/**
+ * If a parameter is not registered in the container try to instantiate it
+ * by using reflection to find out how to build the class
+ * @param string $name the class name to resolve
+ * @return \stdClass
+ * @since 8.2.0
+ * @throws QueryException if the class could not be found or instantiated
+ */
+ public function resolve($name);
+
+ /**
* Look up a service for a given name in the container.
*
* @param string $name
diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php
index a6d83156de3..8be23dff214 100644
--- a/lib/public/iservercontainer.php
+++ b/lib/public/iservercontainer.php
@@ -440,6 +440,13 @@ interface IServerContainer {
*/
public function getMimeTypeDetector();
+ /**
+ * Get the MimeTypeLoader
+ *
+ * @return \OCP\Files\IMimeTypeLoader
+ * @since 8.2.0
+ */
+ public function getMimeTypeLoader();
/**
* Get the EventDispatcher
@@ -448,4 +455,12 @@ interface IServerContainer {
* @since 8.2.0
*/
public function getEventDispatcher();
+
+ /**
+ * Get the Notification Manager
+ *
+ * @return \OC\Notification\IManager
+ * @since 8.2.0
+ */
+ public function getNotificationManager();
}
diff --git a/lib/public/itempmanager.php b/lib/public/itempmanager.php
index 7ba5b1e7bff..6364fa71913 100644
--- a/lib/public/itempmanager.php
+++ b/lib/public/itempmanager.php
@@ -58,4 +58,12 @@ interface ITempManager {
* @since 8.0.0
*/
public function cleanOld();
+
+ /**
+ * Get the temporary base directory
+ *
+ * @return string
+ * @since 8.2.0
+ */
+ public function getTempBaseDir();
}