summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/l10n/ca.js4
-rw-r--r--lib/l10n/ca.json4
-rw-r--r--lib/l10n/he.js5
-rw-r--r--lib/l10n/he.json5
-rw-r--r--lib/l10n/sl.js2
-rw-r--r--lib/l10n/sl.json2
-rw-r--r--lib/l10n/zh_CN.js4
-rw-r--r--lib/l10n/zh_CN.json4
-rw-r--r--lib/private/AllConfig.php6
-rw-r--r--lib/private/AppFramework/Middleware/Security/CORSMiddleware.php9
-rw-r--r--lib/private/Authentication/Exceptions/PasswordLoginForbiddenException.php29
-rw-r--r--lib/private/Authentication/Token/DefaultTokenMapper.php1
-rw-r--r--lib/private/Authentication/TwoFactorAuth/Manager.php13
-rw-r--r--lib/private/Files/Cache/Updater.php18
-rw-r--r--lib/private/Files/Config/LazyStorageMountInfo.php8
-rw-r--r--lib/private/Files/Config/UserMountCache.php33
-rw-r--r--lib/private/IntegrityCheck/Iterator/ExcludeFileByNameFilterIterator.php1
-rw-r--r--lib/private/Preview.php21
-rw-r--r--lib/private/Repair.php4
-rw-r--r--lib/private/Repair/CleanTags.php57
-rw-r--r--lib/private/Repair/RemoveRootShares.php157
-rw-r--r--lib/private/Share20/Manager.php36
-rw-r--r--lib/private/User/Session.php53
-rw-r--r--lib/public/Util.php19
24 files changed, 430 insertions, 65 deletions
diff --git a/lib/l10n/ca.js b/lib/l10n/ca.js
index 3a7f21787ec..d84d7284275 100644
--- a/lib/l10n/ca.js
+++ b/lib/l10n/ca.js
@@ -18,6 +18,7 @@ OC.L10N.register(
"_%n hour ago_::_%n hours ago_" : ["fa %n hora","fa %n hores"],
"_%n minute ago_::_%n minutes ago_" : ["fa %n minut","fa %n minuts"],
"seconds ago" : "segons enrere",
+ "File name contains at least one invalid character" : "El nom del fitxer conté al menys un caràcter invàlid",
"App directory already exists" : "La carpeta de l'aplicació ja existeix",
"Can't create app folder. Please fix permissions. %s" : "No es pot crear la carpeta de l'aplicació. Arregleu els permisos. %s",
"No source specified when installing app" : "No heu especificat la font en instal·lar l'aplicació",
@@ -43,6 +44,7 @@ OC.L10N.register(
"For the best results, please consider using a GNU/Linux server instead." : "Per millors resultats, millor considereu utilitzar un servidor GNU/Linux.",
"Set an admin username." : "Establiu un nom d'usuari per l'administrador.",
"Set an admin password." : "Establiu una contrasenya per l'administrador.",
+ "Invalid Federated Cloud ID" : "ID de núvol federat invàlid",
"%s shared »%s« with you" : "%s ha compartit »%s« amb tu",
"Sharing %s failed, because the file does not exist" : "Ha fallat en compartir %s, perquè el fitxer no existeix",
"You are not allowed to share %s" : "No se us permet compartir %s",
@@ -53,6 +55,8 @@ OC.L10N.register(
"Sharing %s failed, because %s is not a member of the group %s" : "Ha fallat en compartir %s, perquè %s no és membre del grup %s",
"You need to provide a password to create a public link, only protected links are allowed" : "Heu de proporcionar una contrasenya per crear un enllaç públic. Només es permeten enllaços segurs.",
"Sharing %s failed, because sharing with links is not allowed" : "Ha fallat en compartir %s, perquè no es permet compartir amb enllaços",
+ "Not allowed to create a federated share with the same user" : "No està permés crear una compartició federada amb el mateix usuari",
+ "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "La compartició de %s ha fallat, no es pot trobar %s, potser el servidor està actualment innacessible.",
"Share type %s is not valid for %s" : "La compartició tipus %s no és vàlida per %s",
"Setting permissions for %s failed, because the permissions exceed permissions granted to %s" : "Ha fallat en establir els permisos per %s perquè aquests excedeixen els permesos per a %s",
"Setting permissions for %s failed, because the item was not found" : "Ha fallat en establir els permisos per %s, perquè no s'ha trobat l'element",
diff --git a/lib/l10n/ca.json b/lib/l10n/ca.json
index 255f5abbe38..ac6dd35ea1d 100644
--- a/lib/l10n/ca.json
+++ b/lib/l10n/ca.json
@@ -16,6 +16,7 @@
"_%n hour ago_::_%n hours ago_" : ["fa %n hora","fa %n hores"],
"_%n minute ago_::_%n minutes ago_" : ["fa %n minut","fa %n minuts"],
"seconds ago" : "segons enrere",
+ "File name contains at least one invalid character" : "El nom del fitxer conté al menys un caràcter invàlid",
"App directory already exists" : "La carpeta de l'aplicació ja existeix",
"Can't create app folder. Please fix permissions. %s" : "No es pot crear la carpeta de l'aplicació. Arregleu els permisos. %s",
"No source specified when installing app" : "No heu especificat la font en instal·lar l'aplicació",
@@ -41,6 +42,7 @@
"For the best results, please consider using a GNU/Linux server instead." : "Per millors resultats, millor considereu utilitzar un servidor GNU/Linux.",
"Set an admin username." : "Establiu un nom d'usuari per l'administrador.",
"Set an admin password." : "Establiu una contrasenya per l'administrador.",
+ "Invalid Federated Cloud ID" : "ID de núvol federat invàlid",
"%s shared »%s« with you" : "%s ha compartit »%s« amb tu",
"Sharing %s failed, because the file does not exist" : "Ha fallat en compartir %s, perquè el fitxer no existeix",
"You are not allowed to share %s" : "No se us permet compartir %s",
@@ -51,6 +53,8 @@
"Sharing %s failed, because %s is not a member of the group %s" : "Ha fallat en compartir %s, perquè %s no és membre del grup %s",
"You need to provide a password to create a public link, only protected links are allowed" : "Heu de proporcionar una contrasenya per crear un enllaç públic. Només es permeten enllaços segurs.",
"Sharing %s failed, because sharing with links is not allowed" : "Ha fallat en compartir %s, perquè no es permet compartir amb enllaços",
+ "Not allowed to create a federated share with the same user" : "No està permés crear una compartició federada amb el mateix usuari",
+ "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "La compartició de %s ha fallat, no es pot trobar %s, potser el servidor està actualment innacessible.",
"Share type %s is not valid for %s" : "La compartició tipus %s no és vàlida per %s",
"Setting permissions for %s failed, because the permissions exceed permissions granted to %s" : "Ha fallat en establir els permisos per %s perquè aquests excedeixen els permesos per a %s",
"Setting permissions for %s failed, because the item was not found" : "Ha fallat en establir els permisos per %s, perquè no s'ha trobat l'element",
diff --git a/lib/l10n/he.js b/lib/l10n/he.js
index 35d2593ffef..bad99d5c638 100644
--- a/lib/l10n/he.js
+++ b/lib/l10n/he.js
@@ -9,6 +9,7 @@ OC.L10N.register(
"It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "התגלה שדוגמת התצורה הועתקה. דבר זה עלול לשבור את ההתקנה ולא נתמך.יש לקרוא את מסמכי התיעוד לפני שמבצעים שינויים ב- config.php",
"PHP %s or higher is required." : "נדרש PHP בגרסת %s ומעלה.",
"PHP with a version lower than %s is required." : "נדרש PHP בגרסה נמוכה מ- %s.",
+ "%sbit or higher PHP required." : "נדרש PHP בגרסת %s ומעלה.",
"Following databases are supported: %s" : "מסדי הנתונים הבאים נתמכים: %s",
"The command line tool %s could not be found" : "כלי שורת הפקודה %s לא אותר",
"The library %s is not available." : "הספריה %s אינה זמינה.",
@@ -98,6 +99,8 @@ OC.L10N.register(
"Sharing %s failed, because the sharing backend for %s could not find its source" : "השיתוף %s נכשל, כיוון שבצד אחורי לשיתוף עבור %s לא ניתן היה לאתר את מקורו",
"Sharing %s failed, because the file could not be found in the file cache" : "השיתוף %s נכשל, כייון שלא ניתן היה למצוא את הקובץ בזכרון המטמון",
"Cannot increase permissions of %s" : "לא ניתן להגדיל את ההיתרים של %s",
+ "Files can't be shared with delete permissions" : "קובץ לא ניתן לשיתוף בפעולת מחיקת הרשאות",
+ "Files can't be shared with create permissions" : "קובץ לא ניתן לשיתוף בפעולת יצירת הרשאות",
"Expiration date is in the past" : "תאריך תפוגה הנו בעבר",
"Cannot set expiration date more than %s days in the future" : "לא ניתן להגדיר את תאריך התפוגה מעל %s ימים בעתיד",
"Could not find category \"%s\"" : "לא ניתן למצוא את הקטגוריה „%s“",
@@ -107,12 +110,14 @@ OC.L10N.register(
"Username contains whitespace at the beginning or at the end" : "שם המשתמש מכיל רווח בתחילתו או בסופו",
"A valid password must be provided" : "יש לספק ססמה תקנית",
"The username is already being used" : "השם משתמש כבר בשימוש",
+ "Login canceled by app" : "התחברות בוטלה על ידי יישום",
"User disabled" : "משתמש מנוטרל",
"Help" : "עזרה",
"Personal" : "אישי",
"Users" : "משתמשים",
"Admin" : "מנהל",
"Recommended" : "מומלץ",
+ "App \"%s\" cannot be installed because appinfo file cannot be read." : "יישום \"%s\" לא ניתן להתקנה כיוון שקובץ appinfo לא ניתן לקריאה.",
"App \"%s\" cannot be installed because it is not compatible with this version of ownCloud." : "היישום \"%s\" לא ניתן להתקנה כיוון שאינו תואם לגרסה זו של ownCloud.",
"App \"%s\" cannot be installed because the following dependencies are not fulfilled: %s" : "היישום \"%s\" לא ניתן להתקנה כיוון שיחסי התלות הבאים אינם מתקיימים: %s",
"No app name specified" : "לא הוגדר שם יישום",
diff --git a/lib/l10n/he.json b/lib/l10n/he.json
index d60e0486572..73481766e09 100644
--- a/lib/l10n/he.json
+++ b/lib/l10n/he.json
@@ -7,6 +7,7 @@
"It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "התגלה שדוגמת התצורה הועתקה. דבר זה עלול לשבור את ההתקנה ולא נתמך.יש לקרוא את מסמכי התיעוד לפני שמבצעים שינויים ב- config.php",
"PHP %s or higher is required." : "נדרש PHP בגרסת %s ומעלה.",
"PHP with a version lower than %s is required." : "נדרש PHP בגרסה נמוכה מ- %s.",
+ "%sbit or higher PHP required." : "נדרש PHP בגרסת %s ומעלה.",
"Following databases are supported: %s" : "מסדי הנתונים הבאים נתמכים: %s",
"The command line tool %s could not be found" : "כלי שורת הפקודה %s לא אותר",
"The library %s is not available." : "הספריה %s אינה זמינה.",
@@ -96,6 +97,8 @@
"Sharing %s failed, because the sharing backend for %s could not find its source" : "השיתוף %s נכשל, כיוון שבצד אחורי לשיתוף עבור %s לא ניתן היה לאתר את מקורו",
"Sharing %s failed, because the file could not be found in the file cache" : "השיתוף %s נכשל, כייון שלא ניתן היה למצוא את הקובץ בזכרון המטמון",
"Cannot increase permissions of %s" : "לא ניתן להגדיל את ההיתרים של %s",
+ "Files can't be shared with delete permissions" : "קובץ לא ניתן לשיתוף בפעולת מחיקת הרשאות",
+ "Files can't be shared with create permissions" : "קובץ לא ניתן לשיתוף בפעולת יצירת הרשאות",
"Expiration date is in the past" : "תאריך תפוגה הנו בעבר",
"Cannot set expiration date more than %s days in the future" : "לא ניתן להגדיר את תאריך התפוגה מעל %s ימים בעתיד",
"Could not find category \"%s\"" : "לא ניתן למצוא את הקטגוריה „%s“",
@@ -105,12 +108,14 @@
"Username contains whitespace at the beginning or at the end" : "שם המשתמש מכיל רווח בתחילתו או בסופו",
"A valid password must be provided" : "יש לספק ססמה תקנית",
"The username is already being used" : "השם משתמש כבר בשימוש",
+ "Login canceled by app" : "התחברות בוטלה על ידי יישום",
"User disabled" : "משתמש מנוטרל",
"Help" : "עזרה",
"Personal" : "אישי",
"Users" : "משתמשים",
"Admin" : "מנהל",
"Recommended" : "מומלץ",
+ "App \"%s\" cannot be installed because appinfo file cannot be read." : "יישום \"%s\" לא ניתן להתקנה כיוון שקובץ appinfo לא ניתן לקריאה.",
"App \"%s\" cannot be installed because it is not compatible with this version of ownCloud." : "היישום \"%s\" לא ניתן להתקנה כיוון שאינו תואם לגרסה זו של ownCloud.",
"App \"%s\" cannot be installed because the following dependencies are not fulfilled: %s" : "היישום \"%s\" לא ניתן להתקנה כיוון שיחסי התלות הבאים אינם מתקיימים: %s",
"No app name specified" : "לא הוגדר שם יישום",
diff --git a/lib/l10n/sl.js b/lib/l10n/sl.js
index e8e861af3c4..5e0e1fbcdbd 100644
--- a/lib/l10n/sl.js
+++ b/lib/l10n/sl.js
@@ -157,7 +157,7 @@ OC.L10N.register(
"Please check that the data directory contains a file \".ocdata\" in its root." : "Preverite, ali je v korenu podatkovne mape datoteka \".ocdata\".",
"Could not obtain lock type %d on \"%s\"." : "Ni mogoče pridobiti zaklepa %d na \"%s\".",
"Storage unauthorized. %s" : "Dostop do shrambe ni overjen. %s",
- "Storage incomplete configuration. %s" : "Nepopolna konfiguracija shrambe. %s",
+ "Storage incomplete configuration. %s" : "Nepopolna nastavitev shrambe. %s",
"Storage connection error. %s" : "Napaka povezave do shrambe. %s",
"Storage not available" : "Shramba ni na voljo",
"Storage connection timeout. %s" : "Povezava do shrambe je časovno potekla. %s"
diff --git a/lib/l10n/sl.json b/lib/l10n/sl.json
index a05d62b1c39..48c9f69a86d 100644
--- a/lib/l10n/sl.json
+++ b/lib/l10n/sl.json
@@ -155,7 +155,7 @@
"Please check that the data directory contains a file \".ocdata\" in its root." : "Preverite, ali je v korenu podatkovne mape datoteka \".ocdata\".",
"Could not obtain lock type %d on \"%s\"." : "Ni mogoče pridobiti zaklepa %d na \"%s\".",
"Storage unauthorized. %s" : "Dostop do shrambe ni overjen. %s",
- "Storage incomplete configuration. %s" : "Nepopolna konfiguracija shrambe. %s",
+ "Storage incomplete configuration. %s" : "Nepopolna nastavitev shrambe. %s",
"Storage connection error. %s" : "Napaka povezave do shrambe. %s",
"Storage not available" : "Shramba ni na voljo",
"Storage connection timeout. %s" : "Povezava do shrambe je časovno potekla. %s"
diff --git a/lib/l10n/zh_CN.js b/lib/l10n/zh_CN.js
index 8951d48b5c3..a29b4adaa1e 100644
--- a/lib/l10n/zh_CN.js
+++ b/lib/l10n/zh_CN.js
@@ -2,8 +2,12 @@ OC.L10N.register(
"lib",
{
"Cannot write into \"config\" directory!" : "无法写入“config”目录!",
+ "This can usually be fixed by giving the webserver write access to the config directory" : "给 WEB 服务器 Config 目录设置写权限可以修复这个问题。",
"See %s" : "查看 %s",
+ "Sample configuration detected" : "示例配置检测",
"PHP %s or higher is required." : "要求 PHP 版本 %s 或者更高。",
+ "The command line tool %s could not be found" : "命令行工具 %s 未找到",
+ "The library %s is not available." : "库文件 %s 不可用",
"Unknown filetype" : "未知的文件类型",
"Invalid image" : "无效的图像",
"today" : "今天",
diff --git a/lib/l10n/zh_CN.json b/lib/l10n/zh_CN.json
index c502c21ad8a..9b5f0af0742 100644
--- a/lib/l10n/zh_CN.json
+++ b/lib/l10n/zh_CN.json
@@ -1,7 +1,11 @@
{ "translations": {
"Cannot write into \"config\" directory!" : "无法写入“config”目录!",
+ "This can usually be fixed by giving the webserver write access to the config directory" : "给 WEB 服务器 Config 目录设置写权限可以修复这个问题。",
"See %s" : "查看 %s",
+ "Sample configuration detected" : "示例配置检测",
"PHP %s or higher is required." : "要求 PHP 版本 %s 或者更高。",
+ "The command line tool %s could not be found" : "命令行工具 %s 未找到",
+ "The library %s is not available." : "库文件 %s 不可用",
"Unknown filetype" : "未知的文件类型",
"Invalid image" : "无效的图像",
"today" : "今天",
diff --git a/lib/private/AllConfig.php b/lib/private/AllConfig.php
index e082cea3305..c8b2009fcc7 100644
--- a/lib/private/AllConfig.php
+++ b/lib/private/AllConfig.php
@@ -27,6 +27,7 @@
*/
namespace OC;
+use OC\Cache\CappedMemoryCache;
use OCP\IDBConnection;
use OCP\PreConditionNotMetException;
@@ -58,14 +59,15 @@ class AllConfig implements \OCP\IConfig {
* - deleteAllUserValues
* - deleteAppFromAllUsers
*
- * @var array $userCache
+ * @var CappedMemoryCache $userCache
*/
- private $userCache = array();
+ private $userCache;
/**
* @param SystemConfig $systemConfig
*/
function __construct(SystemConfig $systemConfig) {
+ $this->userCache = new CappedMemoryCache();
$this->systemConfig = $systemConfig;
}
diff --git a/lib/private/AppFramework/Middleware/Security/CORSMiddleware.php b/lib/private/AppFramework/Middleware/Security/CORSMiddleware.php
index d84e9963436..32a507623e3 100644
--- a/lib/private/AppFramework/Middleware/Security/CORSMiddleware.php
+++ b/lib/private/AppFramework/Middleware/Security/CORSMiddleware.php
@@ -26,6 +26,7 @@ namespace OC\AppFramework\Middleware\Security;
use OC\AppFramework\Middleware\Security\Exceptions\SecurityException;
use OC\AppFramework\Utility\ControllerMethodReflector;
+use OC\Authentication\Exceptions\PasswordLoginForbiddenException;
use OC\User\Session;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
@@ -89,8 +90,12 @@ class CORSMiddleware extends Middleware {
$pass = $this->request->server['PHP_AUTH_PW'];
$this->session->logout();
- if(!$this->session->logClientIn($user, $pass)) {
- throw new SecurityException('CORS requires basic auth', Http::STATUS_UNAUTHORIZED);
+ try {
+ if (!$this->session->logClientIn($user, $pass, $this->request)) {
+ throw new SecurityException('CORS requires basic auth', Http::STATUS_UNAUTHORIZED);
+ }
+ } catch (PasswordLoginForbiddenException $ex) {
+ throw new SecurityException('Password login forbidden, use token instead', Http::STATUS_UNAUTHORIZED);
}
}
}
diff --git a/lib/private/Authentication/Exceptions/PasswordLoginForbiddenException.php b/lib/private/Authentication/Exceptions/PasswordLoginForbiddenException.php
new file mode 100644
index 00000000000..2e9f9534dbd
--- /dev/null
+++ b/lib/private/Authentication/Exceptions/PasswordLoginForbiddenException.php
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @author Christoph Wurst <christoph@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, 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\Authentication\Exceptions;
+
+use Exception;
+
+class PasswordLoginForbiddenException extends Exception {
+
+}
diff --git a/lib/private/Authentication/Token/DefaultTokenMapper.php b/lib/private/Authentication/Token/DefaultTokenMapper.php
index c56a513b94c..9450ed6b9f3 100644
--- a/lib/private/Authentication/Token/DefaultTokenMapper.php
+++ b/lib/private/Authentication/Token/DefaultTokenMapper.php
@@ -77,6 +77,7 @@ class DefaultTokenMapper extends Mapper {
->execute();
$data = $result->fetch();
+ $result->closeCursor();
if ($data === false) {
throw new DoesNotExistException('token does not exist');
}
diff --git a/lib/private/Authentication/TwoFactorAuth/Manager.php b/lib/private/Authentication/TwoFactorAuth/Manager.php
index 805735bd1b8..6ca4fd065a6 100644
--- a/lib/private/Authentication/TwoFactorAuth/Manager.php
+++ b/lib/private/Authentication/TwoFactorAuth/Manager.php
@@ -24,6 +24,7 @@ namespace OC\Authentication\TwoFactorAuth;
use Exception;
use OC;
use OC\App\AppManager;
+use OC_App;
use OCP\AppFramework\QueryException;
use OCP\Authentication\TwoFactorAuth\IProvider;
use OCP\IConfig;
@@ -110,6 +111,7 @@ class Manager {
$providerClasses = $info['two-factor-providers'];
foreach ($providerClasses as $class) {
try {
+ $this->loadTwoFactorApp($appId);
$provider = OC::$server->query($class);
$providers[$provider->getId()] = $provider;
} catch (QueryException $exc) {
@@ -126,6 +128,17 @@ class Manager {
}
/**
+ * Load an app by ID if it has not been loaded yet
+ *
+ * @param string $appId
+ */
+ protected function loadTwoFactorApp($appId) {
+ if (!OC_App::isAppLoaded($appId)) {
+ OC_App::loadApp($appId);
+ }
+ }
+
+ /**
* Verify the given challenge
*
* @param string $providerId
diff --git a/lib/private/Files/Cache/Updater.php b/lib/private/Files/Cache/Updater.php
index 4e17c4d778d..361db4b3f85 100644
--- a/lib/private/Files/Cache/Updater.php
+++ b/lib/private/Files/Cache/Updater.php
@@ -25,6 +25,8 @@
*/
namespace OC\Files\Cache;
+
+use OCP\Files\Cache\ICacheEntry;
use OCP\Files\Cache\IUpdater;
use OCP\Files\Storage\IStorage;
@@ -150,12 +152,20 @@ class Updater implements IUpdater {
$parent = '';
}
+ $entry = $this->cache->get($path);
+
$this->cache->remove($path);
- if ($this->cache instanceof Cache) {
- $this->cache->correctFolderSize($parent);
- }
+
$this->correctParentStorageMtime($path);
- $this->propagator->propagateChange($path, time());
+ if ($entry instanceof ICacheEntry) {
+ $this->propagator->propagateChange($path, time(), -$entry->getSize());
+ } else {
+ $this->propagator->propagateChange($path, time());
+ if ($this->cache instanceof Cache) {
+ $this->cache->correctFolderSize($parent);
+ }
+ }
+
}
/**
diff --git a/lib/private/Files/Config/LazyStorageMountInfo.php b/lib/private/Files/Config/LazyStorageMountInfo.php
index 654c5b2b23e..5df04c4b78e 100644
--- a/lib/private/Files/Config/LazyStorageMountInfo.php
+++ b/lib/private/Files/Config/LazyStorageMountInfo.php
@@ -28,7 +28,7 @@ use OCP\Files\Node;
use OCP\IUser;
class LazyStorageMountInfo extends CachedMountInfo {
- /** @var IMountPoint */
+ /** @var IMountPoint */
private $mount;
/**
@@ -47,7 +47,11 @@ class LazyStorageMountInfo extends CachedMountInfo {
*/
public function getStorageId() {
if (!$this->storageId) {
- $this->storageId = $this->mount->getStorage()->getStorageCache()->getNumericId();
+ $storage = $this->mount->getStorage();
+ if (!$storage) {
+ return -1;
+ }
+ $this->storageId = $storage->getStorageCache()->getNumericId();
}
return parent::getStorageId();
}
diff --git a/lib/private/Files/Config/UserMountCache.php b/lib/private/Files/Config/UserMountCache.php
index edb1525b276..bc6ad1b34f0 100644
--- a/lib/private/Files/Config/UserMountCache.php
+++ b/lib/private/Files/Config/UserMountCache.php
@@ -36,6 +36,7 @@ use OCP\IDBConnection;
use OCP\ILogger;
use OCP\IUser;
use OCP\IUserManager;
+use OC\Cache\CappedMemoryCache;
/**
* Cache mounts points per user in the cache so we can easilly look them up
@@ -51,15 +52,23 @@ class UserMountCache implements IUserMountCache {
*/
private $userManager;
- /** @var ICachedMountInfo[][] [$userId => [$cachedMountInfo, ....], ...] */
- private $mountsForUsers = [];
+ /**
+ * Cached mount info.
+ * Map of $userId to ICachedMountInfo.
+ *
+ * @var ICache
+ **/
+ private $mountsForUsers;
/**
* @var ILogger
*/
private $logger;
- private $cacheInfoCache = [];
+ /**
+ * @var ICache
+ */
+ private $cacheInfoCache;
/**
* UserMountCache constructor.
@@ -72,6 +81,8 @@ class UserMountCache implements IUserMountCache {
$this->connection = $connection;
$this->userManager = $userManager;
$this->logger = $logger;
+ $this->cacheInfoCache = new CappedMemoryCache();
+ $this->mountsForUsers = new CappedMemoryCache();
}
public function registerMounts(IUser $user, array $mounts) {
@@ -124,12 +135,16 @@ class UserMountCache implements IUserMountCache {
}
private function addToCache(ICachedMountInfo $mount) {
- $this->connection->insertIfNotExist('*PREFIX*mounts', [
- 'storage_id' => $mount->getStorageId(),
- 'root_id' => $mount->getRootId(),
- 'user_id' => $mount->getUser()->getUID(),
- 'mount_point' => $mount->getMountPoint()
- ], ['root_id', 'user_id']);
+ if ($mount->getStorageId() !== -1) {
+ $this->connection->insertIfNotExist('*PREFIX*mounts', [
+ 'storage_id' => $mount->getStorageId(),
+ 'root_id' => $mount->getRootId(),
+ 'user_id' => $mount->getUser()->getUID(),
+ 'mount_point' => $mount->getMountPoint()
+ ], ['root_id', 'user_id']);
+ } else {
+ $this->logger->error('Error getting storage info for mount at ' . $mount->getMountPoint());
+ }
}
private function setMountPoint(ICachedMountInfo $mount) {
diff --git a/lib/private/IntegrityCheck/Iterator/ExcludeFileByNameFilterIterator.php b/lib/private/IntegrityCheck/Iterator/ExcludeFileByNameFilterIterator.php
index 1f31e849446..5c72bfaa57c 100644
--- a/lib/private/IntegrityCheck/Iterator/ExcludeFileByNameFilterIterator.php
+++ b/lib/private/IntegrityCheck/Iterator/ExcludeFileByNameFilterIterator.php
@@ -39,6 +39,7 @@ class ExcludeFileByNameFilterIterator extends \RecursiveFilterIterator {
'.DS_Store', // Mac OS X
'Thumbs.db', // Microsoft Windows
'.directory', // Dolphin (KDE)
+ '.webapp', // Gentoo/Funtoo & derivatives use a tool known as webapp-config to manager wep-apps.
];
/**
diff --git a/lib/private/Preview.php b/lib/private/Preview.php
index f5e2f6b57e1..8bc262d7047 100644
--- a/lib/private/Preview.php
+++ b/lib/private/Preview.php
@@ -136,9 +136,9 @@ class Preview {
//check if there are preview backends
if (!\OC::$server->getPreviewManager()
- ->hasProviders()
+ ->hasProviders()
&& \OC::$server->getConfig()
- ->getSystemValue('enable_previews', true)
+ ->getSystemValue('enable_previews', true)
) {
\OCP\Util::writeLog('core', 'No preview providers exist', \OCP\Util::ERROR);
throw new \Exception('No preview providers');
@@ -410,6 +410,10 @@ class Preview {
* Deletes all previews of a file
*/
public function deleteAllPreviews() {
+ $thumbnailMount = $this->userView->getMount($this->getThumbnailsFolder());
+ $propagator = $thumbnailMount->getStorage()->getPropagator();
+ $propagator->beginBatch();
+
$toDelete = $this->getChildren();
$toDelete[] = $this->getFileInfo();
@@ -422,11 +426,12 @@ class Preview {
// .ocTransferId*.part file from chunked file upload.
if (!empty($fileId)) {
$previewPath = $this->getPreviewPath($fileId);
- $this->userView->deleteAll($previewPath);
$this->userView->rmdir($previewPath);
}
}
}
+
+ $propagator->commitBatch();
}
/**
@@ -573,8 +578,8 @@ class Preview {
* @return integer[]
*/
private function applyAspectRatio($askedWidth, $askedHeight, $originalWidth = 0, $originalHeight = 0) {
- if(!$originalWidth){
- $originalWidth= $this->maxPreviewWidth;
+ if (!$originalWidth) {
+ $originalWidth = $this->maxPreviewWidth;
}
if (!$originalHeight) {
$originalHeight = $this->maxPreviewHeight;
@@ -1113,7 +1118,7 @@ class Preview {
$preview = null;
$previewProviders = \OC::$server->getPreviewManager()
- ->getProviders();
+ ->getProviders();
foreach ($previewProviders as $supportedMimeType => $providers) {
if (!preg_match($supportedMimeType, $this->mimeType)) {
continue;
@@ -1127,7 +1132,7 @@ class Preview {
\OCP\Util::writeLog(
'core', 'Generating preview for "' . $file . '" with "' . get_class($provider)
- . '"', \OCP\Util::DEBUG
+ . '"', \OCP\Util::DEBUG
);
/** @var $provider Provider */
@@ -1261,7 +1266,7 @@ class Preview {
$absPath = Files\Filesystem::normalizePath($view->getAbsolutePath($path));
$fileInfo = $view->getFileInfo($path);
- if($fileInfo === false) {
+ if ($fileInfo === false) {
return;
}
self::addPathToDeleteFileMapper($absPath, $fileInfo);
diff --git a/lib/private/Repair.php b/lib/private/Repair.php
index bb2967d7e6e..2b33dc413b4 100644
--- a/lib/private/Repair.php
+++ b/lib/private/Repair.php
@@ -36,6 +36,7 @@ use OC\Repair\DropOldJobs;
use OC\Repair\OldGroupMembershipShares;
use OC\Repair\RemoveGetETagEntries;
use OC\Repair\RemoveOldShares;
+use OC\Repair\RemoveRootShares;
use OC\Repair\SharePropagation;
use OC\Repair\SqliteAutoincrement;
use OC\Repair\DropOldTables;
@@ -127,7 +128,7 @@ class Repair implements IOutput{
new RepairLegacyStorages(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection()),
new AssetCache(),
new FillETags(\OC::$server->getDatabaseConnection()),
- new CleanTags(\OC::$server->getDatabaseConnection()),
+ new CleanTags(\OC::$server->getDatabaseConnection(), \OC::$server->getUserManager()),
new DropOldTables(\OC::$server->getDatabaseConnection()),
new DropOldJobs(\OC::$server->getJobList()),
new RemoveGetETagEntries(\OC::$server->getDatabaseConnection()),
@@ -136,6 +137,7 @@ class Repair implements IOutput{
new SharePropagation(\OC::$server->getConfig()),
new RemoveOldShares(\OC::$server->getDatabaseConnection()),
new AvatarPermissions(\OC::$server->getDatabaseConnection()),
+ new RemoveRootShares(\OC::$server->getDatabaseConnection(), \OC::$server->getUserManager(), \OC::$server->getLazyRootFolder()),
];
}
diff --git a/lib/private/Repair/CleanTags.php b/lib/private/Repair/CleanTags.php
index 60ddeff08f3..4241fa6da3a 100644
--- a/lib/private/Repair/CleanTags.php
+++ b/lib/private/Repair/CleanTags.php
@@ -25,6 +25,7 @@ namespace OC\Repair;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
+use OCP\IUserManager;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
@@ -38,11 +39,18 @@ class CleanTags implements IRepairStep {
/** @var IDBConnection */
protected $connection;
+ /** @var IUserManager */
+ protected $userManager;
+
+ protected $deletedTags = 0;
+
/**
* @param IDBConnection $connection
+ * @param IUserManager $userManager
*/
- public function __construct(IDBConnection $connection) {
+ public function __construct(IDBConnection $connection, IUserManager $userManager) {
$this->connection = $connection;
+ $this->userManager = $userManager;
}
/**
@@ -56,12 +64,59 @@ class CleanTags implements IRepairStep {
* Updates the configuration after running an update
*/
public function run(IOutput $output) {
+ $this->deleteOrphanTags($output);
$this->deleteOrphanFileEntries($output);
$this->deleteOrphanTagEntries($output);
$this->deleteOrphanCategoryEntries($output);
}
/**
+ * Delete tags for deleted users
+ */
+ protected function deleteOrphanTags(IOutput $output) {
+ $offset = 0;
+ while ($this->checkTags($offset)) {
+ $offset += 50;
+ }
+
+ $output->info(sprintf('%d tags of deleted users have been removed.', $this->deletedTags));
+ }
+
+ protected function checkTags($offset) {
+ $query = $this->connection->getQueryBuilder();
+ $query->select('uid')
+ ->from('vcategory')
+ ->groupBy('uid')
+ ->orderBy('uid')
+ ->setMaxResults(50)
+ ->setFirstResult($offset);
+ $result = $query->execute();
+
+ $users = [];
+ $hadResults = false;
+ while ($row = $result->fetch()) {
+ $hadResults = true;
+ if (!$this->userManager->userExists($row['uid'])) {
+ $users[] = $row['uid'];
+ }
+ }
+ $result->closeCursor();
+
+ if (!$hadResults) {
+ // No more tags, stop looping
+ return false;
+ }
+
+ if (!empty($users)) {
+ $query = $this->connection->getQueryBuilder();
+ $query->delete('vcategory')
+ ->where($query->expr()->in('uid', $query->createNamedParameter($users, IQueryBuilder::PARAM_STR_ARRAY)));
+ $this->deletedTags += $query->execute();
+ }
+ return true;
+ }
+
+ /**
* Delete tag entries for deleted files
*/
protected function deleteOrphanFileEntries(IOutput $output) {
diff --git a/lib/private/Repair/RemoveRootShares.php b/lib/private/Repair/RemoveRootShares.php
new file mode 100644
index 00000000000..89f797e3ef0
--- /dev/null
+++ b/lib/private/Repair/RemoveRootShares.php
@@ -0,0 +1,157 @@
+<?php
+/**
+ * @author Roeland Jago Douma <rullzer@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, 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\Repair;
+
+use OCP\Files\IRootFolder;
+use OCP\IDBConnection;
+use OCP\IUser;
+use OCP\IUserManager;
+use OCP\Migration\IOutput;
+use OCP\Migration\IRepairStep;
+
+/**
+ * Class RemoveRootShares
+ *
+ * @package OC\Repair
+ */
+class RemoveRootShares implements IRepairStep {
+
+ /** @var IDBConnection */
+ protected $connection;
+
+ /** @var IUserManager */
+ protected $userManager;
+
+ /** @var IRootFolder */
+ protected $rootFolder;
+
+ /**
+ * RemoveRootShares constructor.
+ *
+ * @param IDBConnection $connection
+ * @param IUserManager $userManager
+ * @param IRootFolder $rootFolder
+ */
+ public function __construct(IDBConnection $connection,
+ IUserManager $userManager,
+ IRootFolder $rootFolder) {
+ $this->connection = $connection;
+ $this->userManager = $userManager;
+ $this->rootFolder = $rootFolder;
+ }
+
+ /**
+ * @return string
+ */
+ public function getName() {
+ return 'Remove shares of a users root folder';
+ }
+
+ /**
+ * @param IOutput $output
+ */
+ public function run(IOutput $output) {
+ if ($this->rootSharesExist()) {
+ $this->removeRootShares($output);
+ }
+ }
+
+ /**
+ * @param IOutput $output
+ */
+ private function removeRootShares(IOutput $output) {
+ $function = function(IUser $user) use ($output) {
+ $userFolder = $this->rootFolder->getUserFolder($user->getUID());
+ $fileId = $userFolder->getId();
+
+ $qb = $this->connection->getQueryBuilder();
+ $qb->delete('share')
+ ->where($qb->expr()->eq('file_source', $qb->createNamedParameter($fileId)))
+ ->andWhere($qb->expr()->orX(
+ $qb->expr()->eq('item_type', $qb->expr()->literal('file')),
+ $qb->expr()->eq('item_type', $qb->expr()->literal('folder'))
+ ));
+
+ $qb->execute();
+
+ $output->advance();
+ };
+
+ $userCount = $this->countUsers();
+ $output->startProgress($userCount);
+
+ $this->userManager->callForAllUsers($function);
+
+ $output->finishProgress();
+ }
+
+ /**
+ * Count all the users
+ *
+ * @return int
+ */
+ private function countUsers() {
+ $allCount = $this->userManager->countUsers();
+
+ $totalCount = 0;
+ foreach ($allCount as $backend => $count) {
+ $totalCount += $count;
+ }
+
+ return $totalCount;
+ }
+
+ /**
+ * Verify if this repair steps is required
+ * It *should* not be necessary in most cases and it can be very
+ * costly.
+ *
+ * @return bool
+ */
+ private function rootSharesExist() {
+ $qb = $this->connection->getQueryBuilder();
+ $qb2 = $this->connection->getQueryBuilder();
+
+ $qb->select('fileid')
+ ->from('filecache')
+ ->where($qb->expr()->eq('path', $qb->expr()->literal('files')));
+
+ $qb2->select('id')
+ ->from('share')
+ ->where($qb2->expr()->in('file_source', $qb2->createFunction($qb->getSQL())))
+ ->andWhere($qb2->expr()->orX(
+ $qb2->expr()->eq('item_type', $qb->expr()->literal('file')),
+ $qb2->expr()->eq('item_type', $qb->expr()->literal('folder'))
+ ))
+ ->setMaxResults(1);
+
+ $cursor = $qb2->execute();
+ $data = $cursor->fetch();
+ $cursor->closeCursor();
+
+ if ($data === false) {
+ return false;
+ }
+
+ return true;
+ }
+}
+
diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php
index 5921bbc44c8..2857a394e1e 100644
--- a/lib/private/Share20/Manager.php
+++ b/lib/private/Share20/Manager.php
@@ -24,25 +24,24 @@
namespace OC\Share20;
+use OC\Cache\CappedMemoryCache;
use OC\Files\Mount\MoveableMount;
+use OCP\Files\File;
+use OCP\Files\Folder;
use OCP\Files\IRootFolder;
+use OCP\Files\Mount\IMountManager;
use OCP\Files\NotFoundException;
-use OCP\IUserManager;
-use OCP\Share\IManager;
-use OCP\Share\IProviderFactory;
-use OC\Share20\Exception\BackendError;
use OCP\IConfig;
+use OCP\IGroupManager;
use OCP\IL10N;
use OCP\ILogger;
-use OCP\Security\ISecureRandom;
+use OCP\IUserManager;
use OCP\Security\IHasher;
-use OCP\Files\Mount\IMountManager;
-use OCP\IGroupManager;
-use OCP\Files\File;
-use OCP\Files\Folder;
-
-use OCP\Share\Exceptions\ShareNotFound;
+use OCP\Security\ISecureRandom;
use OCP\Share\Exceptions\GenericShareException;
+use OCP\Share\Exceptions\ShareNotFound;
+use OCP\Share\IManager;
+use OCP\Share\IProviderFactory;
/**
* This class is the communication hub for all sharing related operations.
@@ -69,6 +68,9 @@ class Manager implements IManager {
private $userManager;
/** @var IRootFolder */
private $rootFolder;
+ /** @var CappedMemoryCache */
+ private $sharingDisabledForUsersCache;
+
/**
* Manager constructor.
@@ -106,6 +108,7 @@ class Manager implements IManager {
$this->factory = $factory;
$this->userManager = $userManager;
$this->rootFolder = $rootFolder;
+ $this->sharingDisabledForUsersCache = new CappedMemoryCache();
}
/**
@@ -1212,6 +1215,14 @@ class Manager implements IManager {
* @return bool
*/
public function sharingDisabledForUser($userId) {
+ if ($userId === null) {
+ return false;
+ }
+
+ if (isset($this->sharingDisabledForUsersCache[$userId])) {
+ return $this->sharingDisabledForUsersCache[$userId];
+ }
+
if ($this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
$groupsList = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
$excludedGroups = json_decode($groupsList);
@@ -1227,10 +1238,13 @@ class Manager implements IManager {
// if the user is only in groups which are disabled for sharing then
// sharing is also disabled for the user
if (empty($remainingGroups)) {
+ $this->sharingDisabledForUsersCache[$userId] = true;
return true;
}
}
}
+
+ $this->sharingDisabledForUsersCache[$userId] = false;
return false;
}
diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php
index f560bb4bfc0..4e9c827448d 100644
--- a/lib/private/User/Session.php
+++ b/lib/private/User/Session.php
@@ -33,6 +33,7 @@ namespace OC\User;
use OC;
use OC\Authentication\Exceptions\InvalidTokenException;
use OC\Authentication\Exceptions\PasswordlessTokenException;
+use OC\Authentication\Exceptions\PasswordLoginForbiddenException;
use OC\Authentication\Token\IProvider;
use OC\Authentication\Token\IToken;
use OC\Hooks\Emitter;
@@ -348,18 +349,18 @@ class Session implements IUserSession, Emitter {
*
* @param string $user
* @param string $password
+ * @param IRequest $request
* @throws LoginException
+ * @throws PasswordLoginForbiddenException
* @return boolean
*/
- public function logClientIn($user, $password) {
+ public function logClientIn($user, $password, IRequest $request) {
$isTokenPassword = $this->isTokenPassword($password);
if (!$isTokenPassword && $this->isTokenAuthEnforced()) {
- // TODO: throw LoginException instead (https://github.com/owncloud/core/pull/24616)
- return false;
+ throw new PasswordLoginForbiddenException();
}
if (!$isTokenPassword && $this->isTwoFactorEnforced($user)) {
- // TODO: throw LoginException instead (https://github.com/owncloud/core/pull/24616)
- return false;
+ throw new PasswordLoginForbiddenException();
}
if (!$this->login($user, $password) ) {
$users = $this->manager->getByEmail($user);
@@ -368,9 +369,22 @@ class Session implements IUserSession, Emitter {
}
return false;
}
+
+ if ($this->supportsCookies($request)) {
+ $this->createSessionToken($request, $this->getUser()->getUID(), $user, $password);
+ }
+
return true;
}
+ protected function supportsCookies(IRequest $request) {
+ if (!is_null($request->getCookie('cookie_test'))) {
+ return true;
+ }
+ setcookie('cookie_test', 'test', $this->timeFacory->getTime() + 3600);
+ return false;
+ }
+
private function isTokenAuthEnforced() {
return $this->config->getSystemValue('token_auth_enforced', false);
}
@@ -428,19 +442,22 @@ class Session implements IUserSession, Emitter {
*/
public function tryBasicAuthLogin(IRequest $request) {
if (!empty($request->server['PHP_AUTH_USER']) && !empty($request->server['PHP_AUTH_PW'])) {
- $result = $this->logClientIn($request->server['PHP_AUTH_USER'], $request->server['PHP_AUTH_PW']);
- if ($result === true) {
- /**
- * Add DAV authenticated. This should in an ideal world not be
- * necessary but the iOS App reads cookies from anywhere instead
- * only the DAV endpoint.
- * This makes sure that the cookies will be valid for the whole scope
- * @see https://github.com/owncloud/core/issues/22893
- */
- $this->session->set(
- Auth::DAV_AUTHENTICATED, $this->getUser()->getUID()
- );
- return true;
+ try {
+ if ($this->logClientIn($request->server['PHP_AUTH_USER'], $request->server['PHP_AUTH_PW'], $request)) {
+ /**
+ * Add DAV authenticated. This should in an ideal world not be
+ * necessary but the iOS App reads cookies from anywhere instead
+ * only the DAV endpoint.
+ * This makes sure that the cookies will be valid for the whole scope
+ * @see https://github.com/owncloud/core/issues/22893
+ */
+ $this->session->set(
+ Auth::DAV_AUTHENTICATED, $this->getUser()->getUID()
+ );
+ return true;
+ }
+ } catch (PasswordLoginForbiddenException $ex) {
+ // Nothing to do
}
}
return false;
diff --git a/lib/public/Util.php b/lib/public/Util.php
index eb573168e10..687f4e78f69 100644
--- a/lib/public/Util.php
+++ b/lib/public/Util.php
@@ -63,6 +63,9 @@ class Util {
const ERROR=3;
const FATAL=4;
+ /** \OCP\Share\IManager */
+ private static $shareManager;
+
/**
* get the current installed version of ownCloud
* @return array
@@ -171,13 +174,19 @@ class Util {
*
* @return boolean
* @since 7.0.0
+ * @deprecated 9.1.0 Use \OC::$server->getShareManager()->sharingDisabledForUser
*/
public static function isSharingDisabledForUser() {
- return \OC_Util::isSharingDisabledForUser(
- \OC::$server->getConfig(),
- \OC::$server->getGroupManager(),
- \OC::$server->getUserSession()->getUser()
- );
+ if (self::$shareManager === null) {
+ self::$shareManager = \OC::$server->getShareManager();
+ }
+
+ $user = \OC::$server->getUserSession()->getUser();
+ if ($user !== null) {
+ $user = $user->getUID();
+ }
+
+ return self::$shareManager->sharingDisabledForUser($user);
}
/**