').addClass('size').text(humanFileSize(elem.size)));
tbody.append(newtr);
if (elem.type === 'dir') {
newtr.find('td.filename').attr('style','background-image:url('+OC.imagePath('core', 'filetypes/folder.png')+')');
@@ -865,9 +655,9 @@ var dragOptions={
}
}
// sane browsers support using the distance option
-if ( ! $.browser.msie) {
+if ( $('html.ie').length === 0) {
dragOptions['distance'] = 20;
-}
+}
var folderDropOptions={
drop: function( event, ui ) {
@@ -900,7 +690,7 @@ var folderDropOptions={
$('#notification').fadeIn();
}
} else {
- OC.dialogs.alert(t('Error moving file'));
+ OC.dialogs.alert(t('Error moving file'), t('core', 'Error'));
}
});
});
@@ -938,7 +728,7 @@ var crumbDropOptions={
$('#notification').fadeIn();
}
} else {
- OC.dialogs.alert(t('Error moving file'));
+ OC.dialogs.alert(t('Error moving file'), t('core', 'Error'));
}
});
});
diff --git a/apps/files/l10n/ar.php b/apps/files/l10n/ar.php
index ce8a34acedb3ef8462d1659bde80f0145b526d14..e000bc966c150b5c4168ec4f50a39d61e3671568 100644
--- a/apps/files/l10n/ar.php
+++ b/apps/files/l10n/ar.php
@@ -1,24 +1,71 @@
"فشل في نقل الملف %s - يوجد ملف بنفس هذا الاسم",
+"Could not move %s" => "فشل في نقل %s",
+"No file was uploaded. Unknown error" => "لم يتم رفع أي ملف , خطأ غير معروف",
"There is no error, the file uploaded with success" => "تم ترفيع الملفات بنجاح.",
+"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "حجم الملف المرفوع تجاوز قيمة upload_max_filesize الموجودة في ملف php.ini ",
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "حجم الملف الذي تريد ترفيعه أعلى مما MAX_FILE_SIZE يسمح به في واجهة ال HTML.",
"The uploaded file was only partially uploaded" => "تم ترفيع جزء من الملفات الذي تريد ترفيعها فقط",
"No file was uploaded" => "لم يتم ترفيع أي من الملفات",
"Missing a temporary folder" => "المجلد المؤقت غير موجود",
+"Failed to write to disk" => "خطأ في الكتابة على القرص الصلب",
+"Not enough storage available" => "لا يوجد مساحة تخزينية كافية",
+"Invalid directory." => "مسار غير صحيح.",
"Files" => "الملفات",
-"Delete" => "محذوف",
-"Close" => "إغلق",
-"Name" => "الاسم",
+"Unable to upload your file as it is a directory or has 0 bytes" => "فشل في رفع ملفاتك , إما أنها مجلد أو حجمها 0 بايت",
+"Upload cancelled." => "تم إلغاء عملية رفع الملفات .",
+"File upload is in progress. Leaving the page now will cancel the upload." => "عملية رفع الملفات قيد التنفيذ. اغلاق الصفحة سوف يلغي عملية رفع الملفات.",
+"URL cannot be empty." => "عنوان ال URL لا يجوز أن يكون فارغا.",
+"Error" => "خطأ",
+"Share" => "شارك",
+"Delete permanently" => "حذف بشكل دائم",
+"Delete" => "إلغاء",
+"Rename" => "إعادة تسميه",
+"Pending" => "قيد الانتظار",
+"{new_name} already exists" => "{new_name} موجود مسبقا",
+"replace" => "استبدال",
+"suggest name" => "اقترح إسم",
+"cancel" => "إلغاء",
+"replaced {new_name} with {old_name}" => "استبدل {new_name} بـ {old_name}",
+"undo" => "تراجع",
+"perform delete operation" => "جاري تنفيذ عملية الحذف",
+"1 file uploading" => "جاري رفع 1 ملف",
+"'.' is an invalid file name." => "\".\" اسم ملف غير صحيح.",
+"File name cannot be empty." => "اسم الملف لا يجوز أن يكون فارغا",
+"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "اسم غير صحيح , الرموز '\\', '/', '<', '>', ':', '\"', '|', '?' و \"*\" غير مسموح استخدامها",
+"Your storage is full, files can not be updated or synced anymore!" => "مساحتك التخزينية ممتلئة, لا يمكم تحديث ملفاتك أو مزامنتها بعد الآن !",
+"Your storage is almost full ({usedSpacePercent}%)" => "مساحتك التخزينية امتلأت تقريبا ",
+"Your download is being prepared. This might take some time if the files are big." => "جاري تجهيز عملية التحميل. قد تستغرق بعض الوقت اذا كان حجم الملفات كبير.",
+"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "إسم مجلد غير صحيح. استخدام مصطلح \"Shared\" محجوز للنظام",
+"Name" => "اسم",
"Size" => "حجم",
"Modified" => "معدل",
-"Upload" => "إرفع",
+"1 folder" => "مجلد عدد 1",
+"{count} folders" => "{count} مجلدات",
+"1 file" => "ملف واحد",
+"{count} files" => "{count} ملفات",
+"Upload" => "رفع",
+"File handling" => "التعامل مع الملف",
"Maximum upload size" => "الحد الأقصى لحجم الملفات التي يمكن رفعها",
+"max. possible: " => "الحد الأقصى المسموح به",
+"Needed for multi-file and folder downloads." => "اجباري للسماح بالتحميل المتعدد للمجلدات والملفات",
+"Enable ZIP-download" => "تفعيل خاصية تحميل ملفات ZIP",
+"0 is unlimited" => "0 = غير محدود",
+"Maximum input size for ZIP files" => "الحد الأقصى المسموح به لملفات ZIP",
"Save" => "حفظ",
"New" => "جديد",
"Text file" => "ملف",
"Folder" => "مجلد",
+"From link" => "من رابط",
+"Deleted files" => "حذف الملفات",
+"Cancel upload" => "إلغاء رفع الملفات",
+"You don’t have write permissions here." => "لا تملك صلاحيات الكتابة هنا.",
"Nothing in here. Upload something!" => "لا يوجد شيء هنا. إرفع بعض الملفات!",
"Download" => "تحميل",
"Unshare" => "إلغاء مشاركة",
"Upload too large" => "حجم الترفيع أعلى من المسموح",
-"The files you are trying to upload exceed the maximum size for file uploads on this server." => "حجم الملفات التي تريد ترفيعها أعلى من المسموح على الخادم."
+"The files you are trying to upload exceed the maximum size for file uploads on this server." => "حجم الملفات التي تريد ترفيعها أعلى من المسموح على الخادم.",
+"Files are being scanned, please wait." => "يرجى الانتظار , جاري فحص الملفات .",
+"Current scanning" => "الفحص الحالي",
+"Upgrading filesystem cache..." => "تحديث ذاكرة التخزين المؤقت(الكاش) الخاصة بملفات النظام ..."
);
diff --git a/apps/files/l10n/bg_BG.php b/apps/files/l10n/bg_BG.php
index a4d23e5afb54e317b8a7b15ddd8aea2f343de914..f4424f925774b5c8d5ca9381c14e0b94a119249d 100644
--- a/apps/files/l10n/bg_BG.php
+++ b/apps/files/l10n/bg_BG.php
@@ -1,8 +1,15 @@
"Файлът е качен успешно",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Файлът който се опитвате да качите надвишава стойностите в MAX_FILE_SIZE в HTML формата.",
+"The uploaded file was only partially uploaded" => "Файлът е качен частично",
+"No file was uploaded" => "Фахлът не бе качен",
"Missing a temporary folder" => "Липсва временна папка",
"Failed to write to disk" => "Възникна проблем при запис в диска",
"Invalid directory." => "Невалидна директория.",
"Files" => "Файлове",
+"Upload cancelled." => "Качването е спряно.",
+"Error" => "Грешка",
+"Share" => "Споделяне",
"Delete permanently" => "Изтриване завинаги",
"Delete" => "Изтриване",
"Rename" => "Преименуване",
@@ -10,9 +17,6 @@
"replace" => "препокриване",
"cancel" => "отказ",
"undo" => "възтановяване",
-"Upload Error" => "Възникна грешка при качването",
-"Close" => "Затвори",
-"Upload cancelled." => "Качването е спряно.",
"Name" => "Име",
"Size" => "Размер",
"Modified" => "Променено",
@@ -30,5 +34,8 @@
"Cancel upload" => "Спри качването",
"Nothing in here. Upload something!" => "Няма нищо тук. Качете нещо.",
"Download" => "Изтегляне",
-"Upload too large" => "Файлът който сте избрали за качване е прекалено голям"
+"Upload too large" => "Файлът който сте избрали за качване е прекалено голям",
+"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Файловете които се опитвате да качите са по-големи от позволеното за сървъра.",
+"Files are being scanned, please wait." => "Файловете се претърсват, изчакайте.",
+"file" => "файл"
);
diff --git a/apps/files/l10n/bn_BD.php b/apps/files/l10n/bn_BD.php
index aec5d7f9d9215e934c10358d6e782ad844d5c4b4..6d755bccc8af45e3305e6bf20f1173ac9e2861db 100644
--- a/apps/files/l10n/bn_BD.php
+++ b/apps/files/l10n/bn_BD.php
@@ -1,18 +1,24 @@
"%s কে স্থানান্তর করা সম্ভব হলো না - এই নামের ফাইল বিদ্যমান",
"Could not move %s" => "%s কে স্থানান্তর করা সম্ভব হলো না",
-"Unable to rename file" => "ফাইলের নাম পরিবর্তন করা সম্ভব হলো না",
-"No file was uploaded. Unknown error" => "কোন ফাইল আপলোড করা হয় নি। সমস্যা অজ্ঞাত।",
-"There is no error, the file uploaded with success" => "কোন সমস্যা নেই, ফাইল আপলোড সুসম্পন্ন হয়েছে",
+"No file was uploaded. Unknown error" => "কোন ফাইল আপলোড করা হয় নি। সমস্যার কারণটি অজ্ঞাত।",
+"There is no error, the file uploaded with success" => "কোন সমস্যা হয় নি, ফাইল আপলোড সুসম্পন্ন হয়েছে।",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "আপলোড করা ফাইলটি php.ini তে বর্ণিত upload_max_filesize নির্দেশিত আয়তন অতিক্রম করছেঃ",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "আপলোড করা ফাইলটি HTML ফর্মে নির্ধারিত MAX_FILE_SIZE নির্দেশিত সর্বোচ্চ আকার অতিক্রম করেছে ",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "আপলোড করা ফাইলটি HTML ফর্মে উল্লিখিত MAX_FILE_SIZE নির্ধারিত ফাইলের সর্বোচ্চ আকার অতিক্রম করতে চলেছে ",
"The uploaded file was only partially uploaded" => "আপলোড করা ফাইলটি আংশিক আপলোড করা হয়েছে",
"No file was uploaded" => "কোন ফাইল আপলোড করা হয় নি",
-"Missing a temporary folder" => "অস্থায়ী ফোল্ডার খোয়া গিয়েছে",
+"Missing a temporary folder" => "অস্থায়ী ফোল্ডারটি হারানো গিয়েছে",
"Failed to write to disk" => "ডিস্কে লিখতে ব্যর্থ",
"Invalid directory." => "ভুল ডিরেক্টরি",
"Files" => "ফাইল",
-"Delete" => "মুছে ফেল",
+"Unable to upload your file as it is a directory or has 0 bytes" => "আপনার ফাইলটি আপলোড করা সম্ভব হলো না, কেননা এটি হয় একটি ফোল্ডার কিংবা এর আকার ০ বাইট",
+"Not enough space available" => "যথেষ্ঠ পরিমাণ স্থান নেই",
+"Upload cancelled." => "আপলোড বাতিল করা হয়েছে।",
+"File upload is in progress. Leaving the page now will cancel the upload." => "ফাইল আপলোড চলমান। এই পৃষ্ঠা পরিত্যাগ করলে আপলোড বাতিল করা হবে।",
+"URL cannot be empty." => "URL ফাঁকা রাখা যাবে না।",
+"Error" => "সমস্যা",
+"Share" => "ভাগাভাগি কর",
+"Delete" => "মুছে",
"Rename" => "পূনঃনামকরণ",
"Pending" => "মুলতুবি",
"{new_name} already exists" => "{new_name} টি বিদ্যমান",
@@ -21,19 +27,12 @@
"cancel" => "বাতিল",
"replaced {new_name} with {old_name}" => "{new_name} কে {old_name} নামে প্রতিস্থাপন করা হয়েছে",
"undo" => "ক্রিয়া প্রত্যাহার",
+"1 file uploading" => "১টি ফাইল আপলোড করা হচ্ছে",
"'.' is an invalid file name." => "টি একটি অননুমোদিত নাম।",
"File name cannot be empty." => "ফাইলের নামটি ফাঁকা রাখা যাবে না।",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "নামটি সঠিক নয়, '\\', '/', '<', '>', ':', '\"', '|', '?' এবং '*' অনুমোদিত নয়।",
-"Unable to upload your file as it is a directory or has 0 bytes" => "আপনার ফাইলটি আপলোড করা সম্ভব হলো না, কেননা এটি হয় একটি ফোল্ডার কিংবা এর আকার ০ বাইট",
-"Upload Error" => "আপলোড করতে সমস্যা ",
-"Close" => "বন্ধ",
-"1 file uploading" => "১টি ফাইল আপলোড করা হচ্ছে",
-"{count} files uploading" => "{count} টি ফাইল আপলোড করা হচ্ছে",
-"Upload cancelled." => "আপলোড বাতিল করা হয়েছে।",
-"File upload is in progress. Leaving the page now will cancel the upload." => "ফাইল আপলোড চলমান। এই পৃষ্ঠা পরিত্যাগ করলে আপলোড বাতিল করা হবে।",
-"URL cannot be empty." => "URL ফাঁকা রাখা যাবে না।",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "ফোল্ডারের নামটি সঠিক নয়। 'ভাগাভাগি করা' শুধুমাত্র Owncloud এর জন্য সংরক্ষিত।",
-"Name" => "নাম",
+"Name" => "রাম",
"Size" => "আকার",
"Modified" => "পরিবর্তিত",
"1 folder" => "১টি ফোল্ডার",
@@ -48,7 +47,7 @@
"Enable ZIP-download" => "ZIP ডাউনলোড সক্রিয় কর",
"0 is unlimited" => "০ এর অর্থ অসীম",
"Maximum input size for ZIP files" => "ZIP ফাইলের ইনপুটের সর্বোচ্চ আকার",
-"Save" => "সংরক্ষন কর",
+"Save" => "সংরক্ষণ",
"New" => "নতুন",
"Text file" => "টেক্সট ফাইল",
"Folder" => "ফোল্ডার",
diff --git a/apps/files/l10n/ca.php b/apps/files/l10n/ca.php
index 43aaea31e8a722e7268338990b0e9fe610752ef7..51d450b4f68ef5faa9a2dcb14b8bbd2a73e9b08c 100644
--- a/apps/files/l10n/ca.php
+++ b/apps/files/l10n/ca.php
@@ -1,22 +1,31 @@
"No s'ha pogut moure %s - Ja hi ha un fitxer amb aquest nom",
"Could not move %s" => " No s'ha pogut moure %s",
-"Unable to rename file" => "No es pot canviar el nom del fitxer",
+"Unable to set upload directory." => "No es pot establir la carpeta de pujada.",
+"Invalid Token" => "Testimoni no vàlid",
"No file was uploaded. Unknown error" => "No s'ha carregat cap fitxer. Error desconegut",
-"There is no error, the file uploaded with success" => "El fitxer s'ha pujat correctament",
+"There is no error, the file uploaded with success" => "No hi ha errors, el fitxer s'ha carregat correctament",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "L’arxiu que voleu carregar supera el màxim definit en la directiva upload_max_filesize del php.ini:",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "El fitxer de pujada excedeix la directiva MAX_FILE_SIZE especificada al formulari HTML",
-"The uploaded file was only partially uploaded" => "El fitxer només s'ha pujat parcialment",
-"No file was uploaded" => "El fitxer no s'ha pujat",
-"Missing a temporary folder" => "S'ha perdut un fitxer temporal",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "El fitxer carregat supera la directiva MAX_FILE_SIZE especificada al formulari HTML",
+"The uploaded file was only partially uploaded" => "El fitxer només s'ha carregat parcialment",
+"No file was uploaded" => "No s'ha carregat cap fitxer",
+"Missing a temporary folder" => "Falta un fitxer temporal",
"Failed to write to disk" => "Ha fallat en escriure al disc",
"Not enough storage available" => "No hi ha prou espai disponible",
"Invalid directory." => "Directori no vàlid.",
"Files" => "Fitxers",
+"Unable to upload your file as it is a directory or has 0 bytes" => "No es pot pujar el fitxer perquè és una carpeta o té 0 bytes",
+"Not enough space available" => "No hi ha prou espai disponible",
+"Upload cancelled." => "La pujada s'ha cancel·lat.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Hi ha una pujada en curs. Si abandoneu la pàgina la pujada es cancel·larà.",
+"URL cannot be empty." => "La URL no pot ser buida",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Nom de carpeta no vàlid. L'ús de 'Shared' està reservat per Owncloud",
+"Error" => "Error",
+"Share" => "Comparteix",
"Delete permanently" => "Esborra permanentment",
-"Delete" => "Suprimeix",
+"Delete" => "Esborra",
"Rename" => "Reanomena",
-"Pending" => "Pendents",
+"Pending" => "Pendent",
"{new_name} already exists" => "{new_name} ja existeix",
"replace" => "substitueix",
"suggest name" => "sugereix un nom",
@@ -24,20 +33,14 @@
"replaced {new_name} with {old_name}" => "s'ha substituït {old_name} per {new_name}",
"undo" => "desfés",
"perform delete operation" => "executa d'operació d'esborrar",
+"1 file uploading" => "1 fitxer pujant",
+"files uploading" => "fitxers pujant",
"'.' is an invalid file name." => "'.' és un nom no vàlid per un fitxer.",
"File name cannot be empty." => "El nom del fitxer no pot ser buit.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "El nóm no és vàlid, '\\', '/', '<', '>', ':', '\"', '|', '?' i '*' no estan permesos.",
"Your storage is full, files can not be updated or synced anymore!" => "El vostre espai d'emmagatzemament és ple, els fitxers ja no es poden actualitzar o sincronitzar!",
"Your storage is almost full ({usedSpacePercent}%)" => "El vostre espai d'emmagatzemament és gairebé ple ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "S'està preparant la baixada. Pot trigar una estona si els fitxers són grans.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "No es pot pujar el fitxer perquè és una carpeta o té 0 bytes",
-"Upload Error" => "Error en la pujada",
-"Close" => "Tanca",
-"1 file uploading" => "1 fitxer pujant",
-"{count} files uploading" => "{count} fitxers en pujada",
-"Upload cancelled." => "La pujada s'ha cancel·lat.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Hi ha una pujada en curs. Si abandoneu la pàgina la pujada es cancel·larà.",
-"URL cannot be empty." => "La URL no pot ser buida",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Nom de carpeta no vàlid. L'ús de 'Shared' està reservat per Owncloud",
"Name" => "Nom",
"Size" => "Mida",
@@ -46,6 +49,7 @@
"{count} folders" => "{count} carpetes",
"1 file" => "1 fitxer",
"{count} files" => "{count} fitxers",
+"%s could not be renamed" => "%s no es pot canviar el nom",
"Upload" => "Puja",
"File handling" => "Gestió de fitxers",
"Maximum upload size" => "Mida màxima de pujada",
@@ -64,10 +68,15 @@
"You don’t have write permissions here." => "No teniu permisos d'escriptura aquí.",
"Nothing in here. Upload something!" => "Res per aquí. Pugeu alguna cosa!",
"Download" => "Baixa",
+"Size (MB)" => "Mida (MB)",
"Unshare" => "Deixa de compartir",
"Upload too large" => "La pujada és massa gran",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Els fitxers que esteu intentant pujar excedeixen la mida màxima de pujada del servidor",
"Files are being scanned, please wait." => "S'estan escanejant els fitxers, espereu",
"Current scanning" => "Actualment escanejant",
+"directory" => "directori",
+"directories" => "directoris",
+"file" => "fitxer",
+"files" => "fitxers",
"Upgrading filesystem cache..." => "Actualitzant la memòria de cau del sistema de fitxers..."
);
diff --git a/apps/files/l10n/cs_CZ.php b/apps/files/l10n/cs_CZ.php
index 48b60bfb7118c7f8e3cb82e1118369bdf8682930..c16d32e9c28e81e505f755b5ef8400b4141ede43 100644
--- a/apps/files/l10n/cs_CZ.php
+++ b/apps/files/l10n/cs_CZ.php
@@ -1,7 +1,8 @@
"Nelze přesunout %s - existuje soubor se stejným názvem",
"Could not move %s" => "Nelze přesunout %s",
-"Unable to rename file" => "Nelze přejmenovat soubor",
+"Unable to set upload directory." => "Nelze nastavit adresář pro nahrané soubory.",
+"Invalid Token" => "Neplatný token",
"No file was uploaded. Unknown error" => "Soubor nebyl odeslán. Neznámá chyba",
"There is no error, the file uploaded with success" => "Soubor byl odeslán úspěšně",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Odesílaný soubor přesahuje velikost upload_max_filesize povolenou v php.ini:",
@@ -13,10 +14,18 @@
"Not enough storage available" => "Nedostatek dostupného úložného prostoru",
"Invalid directory." => "Neplatný adresář",
"Files" => "Soubory",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Nelze odeslat Váš soubor, protože je to adresář, nebo je jeho velikost 0 bajtů",
+"Not enough space available" => "Nedostatek dostupného místa",
+"Upload cancelled." => "Odesílání zrušeno.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Probíhá odesílání souboru. Opuštění stránky vyústí ve zrušení nahrávání.",
+"URL cannot be empty." => "URL nemůže být prázdná",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Název složky nelze použít. Použití názvu 'Shared' je ownCloudem rezervováno",
+"Error" => "Chyba",
+"Share" => "Sdílet",
"Delete permanently" => "Trvale odstranit",
"Delete" => "Smazat",
"Rename" => "Přejmenovat",
-"Pending" => "Čekající",
+"Pending" => "Nevyřízené",
"{new_name} already exists" => "{new_name} již existuje",
"replace" => "nahradit",
"suggest name" => "navrhnout název",
@@ -24,24 +33,18 @@
"replaced {new_name} with {old_name}" => "nahrazeno {new_name} s {old_name}",
"undo" => "zpět",
"perform delete operation" => "provést smazání",
+"1 file uploading" => "odesílá se 1 soubor",
+"files uploading" => "soubory se odesílají",
"'.' is an invalid file name." => "'.' je neplatným názvem souboru.",
"File name cannot be empty." => "Název souboru nemůže být prázdný řetězec.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Neplatný název, znaky '\\', '/', '<', '>', ':', '\"', '|', '?' a '*' nejsou povoleny.",
"Your storage is full, files can not be updated or synced anymore!" => "Vaše úložiště je plné, nelze aktualizovat ani synchronizovat soubory.",
"Your storage is almost full ({usedSpacePercent}%)" => "Vaše úložiště je téměř plné ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "Vaše soubory ke stažení se připravují. Pokud jsou velké může to chvíli trvat.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Nelze odeslat Váš soubor, protože je to adresář nebo má velikost 0 bajtů",
-"Upload Error" => "Chyba odesílání",
-"Close" => "Zavřít",
-"1 file uploading" => "odesílá se 1 soubor",
-"{count} files uploading" => "odesílám {count} souborů",
-"Upload cancelled." => "Odesílání zrušeno.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Probíhá odesílání souboru. Opuštění stránky vyústí ve zrušení nahrávání.",
-"URL cannot be empty." => "URL nemůže být prázdná",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Neplatný název složky. Použití 'Shared' je rezervováno pro vnitřní potřeby Owncloud",
"Name" => "Název",
"Size" => "Velikost",
-"Modified" => "Změněno",
+"Modified" => "Upraveno",
"1 folder" => "1 složka",
"{count} folders" => "{count} složky",
"1 file" => "1 soubor",
@@ -65,9 +68,11 @@
"Nothing in here. Upload something!" => "Žádný obsah. Nahrajte něco.",
"Download" => "Stáhnout",
"Unshare" => "Zrušit sdílení",
-"Upload too large" => "Odeslaný soubor je příliš velký",
+"Upload too large" => "Odesílaný soubor je příliš velký",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Soubory, které se snažíte odeslat, překračují limit velikosti odesílání na tomto serveru.",
"Files are being scanned, please wait." => "Soubory se prohledávají, prosím čekejte.",
"Current scanning" => "Aktuální prohledávání",
+"file" => "soubor",
+"files" => "soubory",
"Upgrading filesystem cache..." => "Aktualizuji mezipaměť souborového systému..."
);
diff --git a/apps/files/l10n/cy_GB.php b/apps/files/l10n/cy_GB.php
new file mode 100644
index 0000000000000000000000000000000000000000..0aab1a18bc5da97120d00d1b941973a82f77871d
--- /dev/null
+++ b/apps/files/l10n/cy_GB.php
@@ -0,0 +1,73 @@
+ "Methwyd symud %s - Mae ffeil gyda'r enw hwn eisoes yn bodoli",
+"Could not move %s" => "Methwyd symud %s",
+"No file was uploaded. Unknown error" => "Ni lwythwyd ffeil i fyny. Gwall anhysbys.",
+"There is no error, the file uploaded with success" => "Does dim gwall, llwythodd y ffeil i fyny'n llwyddiannus",
+"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Mae'r ffeil lwythwyd i fyny'n fwy na chyfarwyddeb upload_max_filesize yn php.ini:",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Mae'r ffeil lwythwyd i fyny'n fwy na chyfarwyddeb MAX_FILE_SIZE bennwyd yn y ffurflen HTML",
+"The uploaded file was only partially uploaded" => "Dim ond yn rhannol y llwythwyd y ffeil i fyny",
+"No file was uploaded" => "Ni lwythwyd ffeil i fyny",
+"Missing a temporary folder" => "Plygell dros dro yn eisiau",
+"Failed to write to disk" => "Methwyd ysgrifennu i'r ddisg",
+"Not enough storage available" => "Dim digon o le storio ar gael",
+"Invalid directory." => "Cyfeiriadur annilys.",
+"Files" => "Ffeiliau",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Methu llwytho'ch ffeil i fyny gan ei fod yn gyferiadur neu'n cynnwys 0 beit",
+"Not enough space available" => "Dim digon o le ar gael",
+"Upload cancelled." => "Diddymwyd llwytho i fyny.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Mae ffeiliau'n cael eu llwytho i fyny. Bydd gadael y dudalen hon nawr yn diddymu'r broses.",
+"URL cannot be empty." => "Does dim hawl cael URL gwag.",
+"Error" => "Gwall",
+"Share" => "Rhannu",
+"Delete permanently" => "Dileu'n barhaol",
+"Delete" => "Dileu",
+"Rename" => "Ailenwi",
+"Pending" => "I ddod",
+"{new_name} already exists" => "{new_name} yn bodoli'n barod",
+"replace" => "amnewid",
+"suggest name" => "awgrymu enw",
+"cancel" => "diddymu",
+"replaced {new_name} with {old_name}" => "newidiwyd {new_name} yn lle {old_name}",
+"undo" => "dadwneud",
+"perform delete operation" => "cyflawni gweithred dileu",
+"1 file uploading" => "1 ffeil yn llwytho i fyny",
+"files uploading" => "ffeiliau'n llwytho i fyny",
+"'.' is an invalid file name." => "Mae '.' yn enw ffeil annilys.",
+"File name cannot be empty." => "Does dim hawl cael enw ffeil gwag.",
+"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Enw annilys, ni chaniateir, '\\', '/', '<', '>', ':', '\"', '|', '?' na '*'.",
+"Your storage is full, files can not be updated or synced anymore!" => "Mae eich storfa'n llawn, ni ellir diweddaru a chydweddu ffeiliau mwyach!",
+"Your storage is almost full ({usedSpacePercent}%)" => "Mae eich storfa bron a bod yn llawn ({usedSpacePercent}%)",
+"Your download is being prepared. This might take some time if the files are big." => "Wrthi'n paratoi i lwytho i lawr. Gall gymryd peth amser os yw'r ffeiliau'n fawr.",
+"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Enw plygell annilys. Mae'r defnydd o 'Shared' yn cael ei gadw gan Owncloud",
+"Name" => "Enw",
+"Size" => "Maint",
+"Modified" => "Addaswyd",
+"1 folder" => "1 blygell",
+"{count} folders" => "{count} plygell",
+"1 file" => "1 ffeil",
+"{count} files" => "{count} ffeil",
+"Upload" => "Llwytho i fyny",
+"File handling" => "Trafod ffeiliau",
+"Maximum upload size" => "Maint mwyaf llwytho i fyny",
+"max. possible: " => "mwyaf. posib:",
+"Needed for multi-file and folder downloads." => "Angen ar gyfer llwytho mwy nag un ffeil neu blygell i lawr yr un pryd.",
+"Enable ZIP-download" => "Galluogi llwytho i lawr ZIP",
+"0 is unlimited" => "0 yn ddiderfyn",
+"Maximum input size for ZIP files" => "Maint mewnbynnu mwyaf ffeiliau ZIP",
+"Save" => "Cadw",
+"New" => "Newydd",
+"Text file" => "Ffeil destun",
+"Folder" => "Plygell",
+"From link" => "Dolen o",
+"Deleted files" => "Ffeiliau ddilewyd",
+"Cancel upload" => "Diddymu llwytho i fyny",
+"You don’t have write permissions here." => "Nid oes gennych hawliau ysgrifennu fan hyn.",
+"Nothing in here. Upload something!" => "Does dim byd fan hyn. Llwythwch rhywbeth i fyny!",
+"Download" => "Llwytho i lawr",
+"Unshare" => "Dad-rannu",
+"Upload too large" => "Maint llwytho i fyny'n rhy fawr",
+"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Mae'r ffeiliau rydych yn ceisio llwytho i fyny'n fwy na maint mwyaf llwytho ffeiliau i fyny ar y gweinydd hwn.",
+"Files are being scanned, please wait." => "Arhoswch, mae ffeiliau'n cael eu sganio.",
+"Current scanning" => "Sganio cyfredol",
+"Upgrading filesystem cache..." => "Uwchraddio storfa system ffeiliau..."
+);
diff --git a/apps/files/l10n/da.php b/apps/files/l10n/da.php
index c147c939f847bd96768e18ca3850777ab187d883..c2f200e476fe956b2b9247b966b2a982840d4a6a 100644
--- a/apps/files/l10n/da.php
+++ b/apps/files/l10n/da.php
@@ -1,18 +1,25 @@
"Kunne ikke flytte %s - der findes allerede en fil med dette navn",
"Could not move %s" => "Kunne ikke flytte %s",
-"Unable to rename file" => "Kunne ikke omdøbe fil",
"No file was uploaded. Unknown error" => "Ingen fil blev uploadet. Ukendt fejl.",
-"There is no error, the file uploaded with success" => "Der er ingen fejl, filen blev uploadet med success",
+"There is no error, the file uploaded with success" => "Der skete ingen fejl, filen blev succesfuldt uploadet",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Den uploadede fil overstiger upload_max_filesize direktivet i php.ini",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Den uploadede fil overskrider MAX_FILE_SIZE -direktivet som er specificeret i HTML-formularen",
-"The uploaded file was only partially uploaded" => "Den uploadede file blev kun delvist uploadet",
-"No file was uploaded" => "Ingen fil blev uploadet",
-"Missing a temporary folder" => "Mangler en midlertidig mappe",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Den uploadede fil overstiger MAX_FILE_SIZE indstilingen, som specificeret i HTML formularen",
+"The uploaded file was only partially uploaded" => "Filen blev kun delvist uploadet.",
+"No file was uploaded" => "Ingen fil uploadet",
+"Missing a temporary folder" => "Manglende midlertidig mappe.",
"Failed to write to disk" => "Fejl ved skrivning til disk.",
"Not enough storage available" => "Der er ikke nok plads til rådlighed",
"Invalid directory." => "Ugyldig mappe.",
"Files" => "Filer",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Kan ikke uploade din fil - det er enten en mappe eller en fil med et indhold på 0 bytes.",
+"Not enough space available" => "ikke nok tilgængelig ledig plads ",
+"Upload cancelled." => "Upload afbrudt.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Fil upload kører. Hvis du forlader siden nu, vil uploadet blive annuleret.",
+"URL cannot be empty." => "URLen kan ikke være tom.",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Ugyldigt mappenavn. Brug af 'Shared' er forbeholdt af ownCloud",
+"Error" => "Fejl",
+"Share" => "Del",
"Delete permanently" => "Slet permanent",
"Delete" => "Slet",
"Rename" => "Omdøb",
@@ -24,20 +31,14 @@
"replaced {new_name} with {old_name}" => "erstattede {new_name} med {old_name}",
"undo" => "fortryd",
"perform delete operation" => "udfør slet operation",
+"1 file uploading" => "1 fil uploades",
+"files uploading" => "uploader filer",
"'.' is an invalid file name." => "'.' er et ugyldigt filnavn.",
"File name cannot be empty." => "Filnavnet kan ikke stå tomt.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Ugyldigt navn, '\\', '/', '<', '>', ':' | '?', '\"', '', og '*' er ikke tilladt.",
"Your storage is full, files can not be updated or synced anymore!" => "Din opbevaringsplads er fyldt op, filer kan ikke opdateres eller synkroniseres længere!",
"Your storage is almost full ({usedSpacePercent}%)" => "Din opbevaringsplads er næsten fyldt op ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "Dit download forberedes. Dette kan tage lidt tid ved større filer.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Kunne ikke uploade din fil, da det enten er en mappe eller er tom",
-"Upload Error" => "Fejl ved upload",
-"Close" => "Luk",
-"1 file uploading" => "1 fil uploades",
-"{count} files uploading" => "{count} filer uploades",
-"Upload cancelled." => "Upload afbrudt.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Fil upload kører. Hvis du forlader siden nu, vil uploadet blive annuleret.",
-"URL cannot be empty." => "URLen kan ikke være tom.",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Ugyldigt mappenavn. Brug af \"Shared\" er forbeholdt Owncloud",
"Name" => "Navn",
"Size" => "Størrelse",
@@ -65,9 +66,11 @@
"Nothing in here. Upload something!" => "Her er tomt. Upload noget!",
"Download" => "Download",
"Unshare" => "Fjern deling",
-"Upload too large" => "Upload for stor",
+"Upload too large" => "Upload er for stor",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Filerne, du prøver at uploade, er større end den maksimale størrelse for fil-upload på denne server.",
"Files are being scanned, please wait." => "Filerne bliver indlæst, vent venligst.",
"Current scanning" => "Indlæser",
+"file" => "fil",
+"files" => "filer",
"Upgrading filesystem cache..." => "Opgraderer filsystems cachen..."
);
diff --git a/apps/files/l10n/de.php b/apps/files/l10n/de.php
index 53427503f4c0ac790c3a126e1705d99b7f2efded..435c821400df2cf15c0310d9b78f45ecb404be31 100644
--- a/apps/files/l10n/de.php
+++ b/apps/files/l10n/de.php
@@ -1,51 +1,55 @@
"%s konnte nicht verschoben werden - eine Datei mit diesem Namen existiert bereits.",
-"Could not move %s" => "%s konnte nicht verschoben werden",
-"Unable to rename file" => "Die Datei konnte nicht umbenannt werden",
+"Could not move %s - File with this name already exists" => "Konnte %s nicht verschieben. Eine Datei mit diesem Namen existiert bereits",
+"Could not move %s" => "Konnte %s nicht verschieben",
+"Unable to set upload directory." => "Das Upload-Verzeichnis konnte nicht gesetzt werden.",
+"Invalid Token" => "Ungültiges Merkmal",
"No file was uploaded. Unknown error" => "Keine Datei hochgeladen. Unbekannter Fehler",
-"There is no error, the file uploaded with success" => "Datei fehlerfrei hochgeladen.",
+"There is no error, the file uploaded with success" => "Es ist kein Fehler aufgetreten. Die Datei wurde erfolgreich hochgeladen.",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Die hochgeladene Datei überschreitet die upload_max_filesize Vorgabe in php.ini",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Die Größe der hochzuladenden Datei überschreitet die MAX_FILE_SIZE-Richtlinie, die im HTML-Formular angegeben wurde",
-"The uploaded file was only partially uploaded" => "Die Datei wurde nur teilweise hochgeladen.",
-"No file was uploaded" => "Es wurde keine Datei hochgeladen.",
-"Missing a temporary folder" => "Temporärer Ordner fehlt.",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Die Datei ist größer, als die MAX_FILE_SIZE Direktive erlaubt, die im HTML-Formular spezifiziert ist",
+"The uploaded file was only partially uploaded" => "Die Datei konnte nur teilweise übertragen werden",
+"No file was uploaded" => "Keine Datei konnte übertragen werden.",
+"Missing a temporary folder" => "Kein temporärer Ordner vorhanden",
"Failed to write to disk" => "Fehler beim Schreiben auf die Festplatte",
-"Not enough storage available" => "Nicht genug Speicherplatz verfügbar",
+"Not enough storage available" => "Nicht genug Speicher vorhanden.",
"Invalid directory." => "Ungültiges Verzeichnis.",
"Files" => "Dateien",
-"Delete permanently" => "Permanent löschen",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Deine Datei kann nicht hochgeladen werden, weil es sich um einen Ordner handelt oder 0 Bytes groß ist.",
+"Not enough space available" => "Nicht genug Speicherplatz verfügbar",
+"Upload cancelled." => "Upload abgebrochen.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Dateiupload läuft. Wenn Du die Seite jetzt verlässt, wird der Upload abgebrochen.",
+"URL cannot be empty." => "Die URL darf nicht leer sein.",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Der Ordnername ist ungültig. Nur ownCloud kann den Ordner \"Shared\" anlegen",
+"Error" => "Fehler",
+"Share" => "Teilen",
+"Delete permanently" => "Endgültig löschen",
"Delete" => "Löschen",
"Rename" => "Umbenennen",
"Pending" => "Ausstehend",
"{new_name} already exists" => "{new_name} existiert bereits",
"replace" => "ersetzen",
-"suggest name" => "Name vorschlagen",
+"suggest name" => "Namen vorschlagen",
"cancel" => "abbrechen",
"replaced {new_name} with {old_name}" => "{old_name} ersetzt durch {new_name}",
"undo" => "rückgängig machen",
"perform delete operation" => "Löschvorgang ausführen",
+"1 file uploading" => "1 Datei wird hochgeladen",
+"files uploading" => "Dateien werden hoch geladen",
"'.' is an invalid file name." => "'.' ist kein gültiger Dateiname.",
"File name cannot be empty." => "Der Dateiname darf nicht leer sein.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Ungültiger Name, '\\', '/', '<', '>', ':', '\"', '|', '?' und '*' sind nicht zulässig.",
-"Your storage is full, files can not be updated or synced anymore!" => "Ihr Speicherplatz ist voll, Dateien können nicht mehr aktualisiert oder synchronisiert werden!",
-"Your storage is almost full ({usedSpacePercent}%)" => "Ihr Speicherplatz ist fast aufgebraucht ({usedSpacePercent}%)",
+"Your storage is full, files can not be updated or synced anymore!" => "Dein Speicher ist voll, daher können keine Dateien mehr aktualisiert oder synchronisiert werden!",
+"Your storage is almost full ({usedSpacePercent}%)" => "Dein Speicher ist fast voll ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "Dein Download wird vorbereitet. Dies kann bei größeren Dateien etwas dauern.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Deine Datei kann nicht hochgeladen werden, da sie entweder ein Verzeichnis oder 0 Bytes groß ist.",
-"Upload Error" => "Fehler beim Upload",
-"Close" => "Schließen",
-"1 file uploading" => "Eine Datei wird hoch geladen",
-"{count} files uploading" => "{count} Dateien werden hochgeladen",
-"Upload cancelled." => "Upload abgebrochen.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Dateiupload läuft. Wenn Du die Seite jetzt verlässt, wird der Upload abgebrochen.",
-"URL cannot be empty." => "Die URL darf nicht leer sein.",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Ungültiger Verzeichnisname. Die Nutzung von \"Shared\" ist ownCloud vorbehalten.",
"Name" => "Name",
"Size" => "Größe",
-"Modified" => "Bearbeitet",
+"Modified" => "Geändert",
"1 folder" => "1 Ordner",
"{count} folders" => "{count} Ordner",
"1 file" => "1 Datei",
"{count} files" => "{count} Dateien",
+"%s could not be renamed" => "%s konnte nicht umbenannt werden",
"Upload" => "Hochladen",
"File handling" => "Dateibehandlung",
"Maximum upload size" => "Maximale Upload-Größe",
@@ -61,13 +65,18 @@
"From link" => "Von einem Link",
"Deleted files" => "Gelöschte Dateien",
"Cancel upload" => "Upload abbrechen",
-"You don’t have write permissions here." => "Du besitzt hier keine Schreib-Berechtigung.",
+"You don’t have write permissions here." => "Du hast hier keine Schreib-Berechtigung.",
"Nothing in here. Upload something!" => "Alles leer. Lade etwas hoch!",
"Download" => "Herunterladen",
-"Unshare" => "Nicht mehr freigeben",
-"Upload too large" => "Upload zu groß",
+"Size (MB)" => "Größe (MB)",
+"Unshare" => "Freigabe aufheben",
+"Upload too large" => "Der Upload ist zu groß",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Die Datei überschreitet die Maximalgröße für Uploads auf diesem Server.",
"Files are being scanned, please wait." => "Dateien werden gescannt, bitte warten.",
"Current scanning" => "Scanne",
+"directory" => "Verzeichnis",
+"directories" => "Verzeichnisse",
+"file" => "Datei",
+"files" => "Dateien",
"Upgrading filesystem cache..." => "Dateisystem-Cache wird aktualisiert ..."
);
diff --git a/apps/files/l10n/de_DE.php b/apps/files/l10n/de_DE.php
index 538c1b63652f2c0ba16466473d39256215364976..3a323321ba81ac02deeb998c27350e12da96a435 100644
--- a/apps/files/l10n/de_DE.php
+++ b/apps/files/l10n/de_DE.php
@@ -1,51 +1,55 @@
"Konnte %s nicht verschieben - Datei mit diesem Namen existiert bereits",
+"Could not move %s - File with this name already exists" => "Konnte %s nicht verschieben. Eine Datei mit diesem Namen existiert bereits",
"Could not move %s" => "Konnte %s nicht verschieben",
-"Unable to rename file" => "Konnte Datei nicht umbenennen",
+"Unable to set upload directory." => "Das Upload-Verzeichnis konnte nicht gesetzt werden.",
+"Invalid Token" => "Ungültiges Merkmal",
"No file was uploaded. Unknown error" => "Keine Datei hochgeladen. Unbekannter Fehler",
-"There is no error, the file uploaded with success" => "Es sind keine Fehler aufgetreten. Die Datei wurde erfolgreich hochgeladen.",
+"There is no error, the file uploaded with success" => "Es ist kein Fehler aufgetreten. Die Datei wurde erfolgreich hochgeladen.",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Die hochgeladene Datei überschreitet die upload_max_filesize Vorgabe in php.ini",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Die Größe der hochzuladenden Datei überschreitet die MAX_FILE_SIZE-Richtlinie, die im HTML-Formular angegeben wurde",
-"The uploaded file was only partially uploaded" => "Die Datei wurde nur teilweise hochgeladen.",
-"No file was uploaded" => "Es wurde keine Datei hochgeladen.",
-"Missing a temporary folder" => "Der temporäre Ordner fehlt.",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Die Datei ist größer, als die MAX_FILE_SIZE Vorgabe erlaubt, die im HTML-Formular spezifiziert ist",
+"The uploaded file was only partially uploaded" => "Die Datei konnte nur teilweise übertragen werden",
+"No file was uploaded" => "Keine Datei konnte übertragen werden.",
+"Missing a temporary folder" => "Kein temporärer Ordner vorhanden",
"Failed to write to disk" => "Fehler beim Schreiben auf die Festplatte",
"Not enough storage available" => "Nicht genug Speicher vorhanden.",
"Invalid directory." => "Ungültiges Verzeichnis.",
"Files" => "Dateien",
-"Delete permanently" => "Entgültig löschen",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Ihre Datei kann nicht hochgeladen werden, weil es sich um einen Ordner handelt oder 0 Bytes groß ist.",
+"Not enough space available" => "Nicht genügend Speicherplatz verfügbar",
+"Upload cancelled." => "Upload abgebrochen.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Dateiupload läuft. Wenn Sie die Seite jetzt verlassen, wird der Upload abgebrochen.",
+"URL cannot be empty." => "Die URL darf nicht leer sein.",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Ungültiger Ordnername. Die Verwendung von \"Shared\" ist ownCloud vorbehalten.",
+"Error" => "Fehler",
+"Share" => "Teilen",
+"Delete permanently" => "Endgültig löschen",
"Delete" => "Löschen",
"Rename" => "Umbenennen",
"Pending" => "Ausstehend",
"{new_name} already exists" => "{new_name} existiert bereits",
"replace" => "ersetzen",
-"suggest name" => "Name vorschlagen",
+"suggest name" => "Namen vorschlagen",
"cancel" => "abbrechen",
"replaced {new_name} with {old_name}" => "{old_name} wurde ersetzt durch {new_name}",
"undo" => "rückgängig machen",
-"perform delete operation" => "führe das Löschen aus",
+"perform delete operation" => "Löschvorgang ausführen",
+"1 file uploading" => "1 Datei wird hochgeladen",
+"files uploading" => "Dateien werden hoch geladen",
"'.' is an invalid file name." => "'.' ist kein gültiger Dateiname.",
"File name cannot be empty." => "Der Dateiname darf nicht leer sein.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Ungültiger Name, '\\', '/', '<', '>', ':', '\"', '|', '?' und '*' sind nicht zulässig.",
-"Your storage is full, files can not be updated or synced anymore!" => "Ihr Speicher ist voll. Daher können keine Dateien mehr aktualisiert oder synchronisiert werden!",
+"Your storage is full, files can not be updated or synced anymore!" => "Ihr Speicher ist voll, daher können keine Dateien mehr aktualisiert oder synchronisiert werden!",
"Your storage is almost full ({usedSpacePercent}%)" => "Ihr Speicher ist fast voll ({usedSpacePercent}%)",
-"Your download is being prepared. This might take some time if the files are big." => "Ihr Download wird vorbereitet. Dies kann bei größeren Dateien einen Moment dauern.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Ihre Datei kann nicht hochgeladen werden, da sie entweder ein Verzeichnis oder 0 Bytes groß ist.",
-"Upload Error" => "Fehler beim Upload",
-"Close" => "Schließen",
-"1 file uploading" => "1 Datei wird hochgeladen",
-"{count} files uploading" => "{count} Dateien wurden hochgeladen",
-"Upload cancelled." => "Upload abgebrochen.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Der Dateiupload läuft. Wenn Sie die Seite jetzt verlassen, wird der Upload abgebrochen.",
-"URL cannot be empty." => "Die URL darf nicht leer sein.",
+"Your download is being prepared. This might take some time if the files are big." => "Ihr Download wird vorbereitet. Dies kann bei größeren Dateien etwas dauern.",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Ungültiger Verzeichnisname. Die Nutzung von \"Shared\" ist ownCloud vorbehalten",
"Name" => "Name",
"Size" => "Größe",
-"Modified" => "Bearbeitet",
+"Modified" => "Geändert",
"1 folder" => "1 Ordner",
"{count} folders" => "{count} Ordner",
"1 file" => "1 Datei",
"{count} files" => "{count} Dateien",
+"%s could not be renamed" => "%s konnte nicht umbenannt werden",
"Upload" => "Hochladen",
"File handling" => "Dateibehandlung",
"Maximum upload size" => "Maximale Upload-Größe",
@@ -62,12 +66,17 @@
"Deleted files" => "Gelöschte Dateien",
"Cancel upload" => "Upload abbrechen",
"You don’t have write permissions here." => "Sie haben hier keine Schreib-Berechtigungen.",
-"Nothing in here. Upload something!" => "Alles leer. Bitte laden Sie etwas hoch!",
+"Nothing in here. Upload something!" => "Alles leer. Laden Sie etwas hoch!",
"Download" => "Herunterladen",
-"Unshare" => "Nicht mehr freigeben",
+"Size (MB)" => "Größe (MB)",
+"Unshare" => "Freigabe aufheben",
"Upload too large" => "Der Upload ist zu groß",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Die Datei überschreitet die Maximalgröße für Uploads auf diesem Server.",
"Files are being scanned, please wait." => "Dateien werden gescannt, bitte warten.",
"Current scanning" => "Scanne",
-"Upgrading filesystem cache..." => "Aktualisiere den Dateisystem-Cache..."
+"directory" => "Verzeichnis",
+"directories" => "Verzeichnisse",
+"file" => "Datei",
+"files" => "Dateien",
+"Upgrading filesystem cache..." => "Dateisystem-Cache wird aktualisiert ..."
);
diff --git a/apps/files/l10n/el.php b/apps/files/l10n/el.php
index 7682ae24b09670ddd951c9cb89838accd85af8ed..7291dbbf1569a183b7aa3fc410beaa828ec887a4 100644
--- a/apps/files/l10n/el.php
+++ b/apps/files/l10n/el.php
@@ -1,11 +1,10 @@
"Αδυναμία μετακίνησης του %s - υπάρχει ήδη αρχείο με αυτό το όνομα",
"Could not move %s" => "Αδυναμία μετακίνησης του %s",
-"Unable to rename file" => "Αδυναμία μετονομασίας αρχείου",
"No file was uploaded. Unknown error" => "Δεν ανέβηκε κάποιο αρχείο. Άγνωστο σφάλμα",
"There is no error, the file uploaded with success" => "Δεν υπάρχει σφάλμα, το αρχείο εστάλει επιτυχώς",
-"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Το απεσταλμένο αρχείο ξεπερνά την οδηγία upload_max_filesize στο php.ini:",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Το αρχείο υπερβαίνει την οδηγία μέγιστου επιτρεπτού μεγέθους \"MAX_FILE_SIZE\" που έχει οριστεί στην HTML φόρμα",
+"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Το αρχείο που εστάλει υπερβαίνει την οδηγία μέγιστου επιτρεπτού μεγέθους \"upload_max_filesize\" του php.ini",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Το ανεβασμένο αρχείο υπερβαίνει το MAX_FILE_SIZE που ορίζεται στην HTML φόρμα",
"The uploaded file was only partially uploaded" => "Το αρχείο εστάλει μόνο εν μέρει",
"No file was uploaded" => "Κανένα αρχείο δεν στάλθηκε",
"Missing a temporary folder" => "Λείπει ο προσωρινός φάκελος",
@@ -13,6 +12,14 @@
"Not enough storage available" => "Μη επαρκής διαθέσιμος αποθηκευτικός χώρος",
"Invalid directory." => "Μη έγκυρος φάκελος.",
"Files" => "Αρχεία",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Αδυναμία στην αποστολή του αρχείου σας αφού είναι φάκελος ή έχει 0 bytes",
+"Not enough space available" => "Δεν υπάρχει αρκετός διαθέσιμος χώρος",
+"Upload cancelled." => "Η αποστολή ακυρώθηκε.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Η αποστολή του αρχείου βρίσκεται σε εξέλιξη. Το κλείσιμο της σελίδας θα ακυρώσει την αποστολή.",
+"URL cannot be empty." => "Η URL δεν μπορεί να είναι κενή.",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Μη έγκυρο όνομα φακέλου. Η χρήση του 'Κοινόχρηστος' χρησιμοποιείται από το ownCloud",
+"Error" => "Σφάλμα",
+"Share" => "Διαμοιρασμός",
"Delete permanently" => "Μόνιμη διαγραφή",
"Delete" => "Διαγραφή",
"Rename" => "Μετονομασία",
@@ -23,21 +30,15 @@
"cancel" => "ακύρωση",
"replaced {new_name} with {old_name}" => "αντικαταστάθηκε το {new_name} με {old_name}",
"undo" => "αναίρεση",
-"perform delete operation" => "εκτέλεση διαδικασία διαγραφής",
+"perform delete operation" => "εκτέλεση της διαδικασίας διαγραφής",
+"1 file uploading" => "1 αρχείο ανεβαίνει",
+"files uploading" => "αρχεία ανεβαίνουν",
"'.' is an invalid file name." => "'.' είναι μη έγκυρο όνομα αρχείου.",
-"File name cannot be empty." => "Το όνομα αρχείου δεν πρέπει να είναι κενό.",
+"File name cannot be empty." => "Το όνομα αρχείου δεν μπορεί να είναι κενό.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Μη έγκυρο όνομα, '\\', '/', '<', '>', ':', '\"', '|', '?' και '*' δεν επιτρέπονται.",
"Your storage is full, files can not be updated or synced anymore!" => "Ο αποθηκευτικός σας χώρος είναι γεμάτος, τα αρχεία δεν μπορούν να ενημερωθούν ή να συγχρονιστούν πια!",
"Your storage is almost full ({usedSpacePercent}%)" => "Ο αποθηκευτικός χώρος είναι σχεδόν γεμάτος ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "Η λήψη προετοιμάζεται. Αυτό μπορεί να πάρει ώρα εάν τα αρχεία έχουν μεγάλο μέγεθος.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Αδυναμία στην αποστολή του αρχείου σας αφού είναι φάκελος ή έχει 0 bytes",
-"Upload Error" => "Σφάλμα Αποστολής",
-"Close" => "Κλείσιμο",
-"1 file uploading" => "1 αρχείο ανεβαίνει",
-"{count} files uploading" => "{count} αρχεία ανεβαίνουν",
-"Upload cancelled." => "Η αποστολή ακυρώθηκε.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Η αποστολή του αρχείου βρίσκεται σε εξέλιξη. Το κλείσιμο της σελίδας θα ακυρώσει την αποστολή.",
-"URL cannot be empty." => "Η URL δεν πρέπει να είναι κενή.",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Μη έγκυρο όνομα φακέλου. Η χρήση του 'Κοινόχρηστος' χρησιμοποιείται από ο Owncloud",
"Name" => "Όνομα",
"Size" => "Μέγεθος",
@@ -46,7 +47,7 @@
"{count} folders" => "{count} φάκελοι",
"1 file" => "1 αρχείο",
"{count} files" => "{count} αρχεία",
-"Upload" => "Αποστολή",
+"Upload" => "Μεταφόρτωση",
"File handling" => "Διαχείριση αρχείων",
"Maximum upload size" => "Μέγιστο μέγεθος αποστολής",
"max. possible: " => "μέγιστο δυνατό:",
@@ -62,12 +63,16 @@
"Deleted files" => "Διαγραμμένα αρχεία",
"Cancel upload" => "Ακύρωση αποστολής",
"You don’t have write permissions here." => "Δεν έχετε δικαιώματα εγγραφής εδώ.",
-"Nothing in here. Upload something!" => "Δεν υπάρχει τίποτα εδώ. Μεταφορτώστε κάτι!",
+"Nothing in here. Upload something!" => "Δεν υπάρχει τίποτα εδώ. Ανεβάστε κάτι!",
"Download" => "Λήψη",
-"Unshare" => "Διακοπή κοινής χρήσης",
+"Unshare" => "Σταμάτημα διαμοιρασμού",
"Upload too large" => "Πολύ μεγάλο αρχείο προς αποστολή",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Τα αρχεία που προσπαθείτε να ανεβάσετε υπερβαίνουν το μέγιστο μέγεθος αποστολής αρχείων σε αυτόν τον διακομιστή.",
-"Files are being scanned, please wait." => "Τα αρχεία σαρώνονται, παρακαλώ περιμένετε",
-"Current scanning" => "Τρέχουσα αναζήτηση ",
-"Upgrading filesystem cache..." => "Αναβάθμιση μνήμης cache του συστήματος αρχείων..."
+"Files are being scanned, please wait." => "Τα αρχεία σαρώνονται, παρακαλώ περιμένετε.",
+"Current scanning" => "Τρέχουσα ανίχνευση",
+"directory" => "κατάλογος",
+"directories" => "κατάλογοι",
+"file" => "αρχείο",
+"files" => "αρχεία",
+"Upgrading filesystem cache..." => "Ενημέρωση της μνήμης cache του συστήματος αρχείων..."
);
diff --git a/apps/files/l10n/en@pirate.php b/apps/files/l10n/en@pirate.php
new file mode 100644
index 0000000000000000000000000000000000000000..fdd1850da900c44cc2536ae2082becbf96f51e66
--- /dev/null
+++ b/apps/files/l10n/en@pirate.php
@@ -0,0 +1,3 @@
+ "Download"
+);
diff --git a/apps/files/l10n/eo.php b/apps/files/l10n/eo.php
index 225408f9a76e8ef9b664bc1e25e18572016cb8f1..561545ec6aeef5d7a6a1d33922fcf94229eb34bf 100644
--- a/apps/files/l10n/eo.php
+++ b/apps/files/l10n/eo.php
@@ -1,17 +1,26 @@
"Ne eblis movi %s: dosiero kun ĉi tiu nomo jam ekzistas",
"Could not move %s" => "Ne eblis movi %s",
-"Unable to rename file" => "Ne eblis alinomigi dosieron",
"No file was uploaded. Unknown error" => "Neniu dosiero alŝutiĝis. Nekonata eraro.",
-"There is no error, the file uploaded with success" => "Ne estas eraro, la dosiero alŝutiĝis sukcese",
+"There is no error, the file uploaded with success" => "Ne estas eraro, la dosiero alŝutiĝis sukcese.",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "La dosiero alŝutita superas la regulon upload_max_filesize el php.ini: ",
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "La dosiero alŝutita superas la regulon MAX_FILE_SIZE, kiu estas difinita en la HTML-formularo",
-"The uploaded file was only partially uploaded" => "La alŝutita dosiero nur parte alŝutiĝis",
-"No file was uploaded" => "Neniu dosiero estas alŝutita",
-"Missing a temporary folder" => "Mankas tempa dosierujo",
+"The uploaded file was only partially uploaded" => "la alŝutita dosiero nur parte alŝutiĝis",
+"No file was uploaded" => "Neniu dosiero alŝutiĝis.",
+"Missing a temporary folder" => "Mankas provizora dosierujo.",
"Failed to write to disk" => "Malsukcesis skribo al disko",
+"Not enough storage available" => "Ne haveblas sufiĉa memoro",
"Invalid directory." => "Nevalida dosierujo.",
"Files" => "Dosieroj",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Ne eblis alŝuti vian dosieron ĉar ĝi estas dosierujo aŭ havas 0 duumokojn",
+"Not enough space available" => "Ne haveblas sufiĉa spaco",
+"Upload cancelled." => "La alŝuto nuliĝis.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Dosieralŝuto plenumiĝas. Lasi la paĝon nun nuligus la alŝuton.",
+"URL cannot be empty." => "URL ne povas esti malplena.",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Nevalida dosierujnomo. La uzo de “Shared” estas rezervita de ownCloud.",
+"Error" => "Eraro",
+"Share" => "Kunhavigi",
+"Delete permanently" => "Forigi por ĉiam",
"Delete" => "Forigi",
"Rename" => "Alinomigi",
"Pending" => "Traktotaj",
@@ -21,18 +30,15 @@
"cancel" => "nuligi",
"replaced {new_name} with {old_name}" => "anstataŭiĝis {new_name} per {old_name}",
"undo" => "malfari",
+"perform delete operation" => "plenumi forigan operacion",
+"1 file uploading" => "1 dosiero estas alŝutata",
+"files uploading" => "dosieroj estas alŝutataj",
"'.' is an invalid file name." => "'.' ne estas valida dosiernomo.",
"File name cannot be empty." => "Dosiernomo devas ne malpleni.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nevalida nomo: “\\”, “/”, “<”, “>”, “:”, “\"”, “|”, “?” kaj “*” ne permesatas.",
+"Your storage is full, files can not be updated or synced anymore!" => "Via memoro plenas, ne plu eblas ĝisdatigi aŭ sinkronigi dosierojn!",
+"Your storage is almost full ({usedSpacePercent}%)" => "Via memoro preskaŭ plenas ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "Via elŝuto pretiĝatas. Ĉi tio povas daŭri iom da tempo se la dosieroj grandas.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Ne eblis alŝuti vian dosieron ĉar ĝi estas dosierujo aŭ havas 0 duumokojn",
-"Upload Error" => "Alŝuta eraro",
-"Close" => "Fermi",
-"1 file uploading" => "1 dosiero estas alŝutata",
-"{count} files uploading" => "{count} dosieroj alŝutatas",
-"Upload cancelled." => "La alŝuto nuliĝis.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Dosieralŝuto plenumiĝas. Lasi la paĝon nun nuligus la alŝuton.",
-"URL cannot be empty." => "URL ne povas esti malplena.",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Nevalida dosierujnomo. Uzo de “Shared” rezervatas de Owncloud.",
"Name" => "Nomo",
"Size" => "Grando",
@@ -54,12 +60,17 @@
"Text file" => "Tekstodosiero",
"Folder" => "Dosierujo",
"From link" => "El ligilo",
+"Deleted files" => "Forigitaj dosieroj",
"Cancel upload" => "Nuligi alŝuton",
+"You don’t have write permissions here." => "Vi ne havas permeson skribi ĉi tie.",
"Nothing in here. Upload something!" => "Nenio estas ĉi tie. Alŝutu ion!",
"Download" => "Elŝuti",
"Unshare" => "Malkunhavigi",
-"Upload too large" => "Elŝuto tro larĝa",
+"Upload too large" => "Alŝuto tro larĝa",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "La dosieroj, kiujn vi provas alŝuti, transpasas la maksimuman grandon por dosieralŝutoj en ĉi tiu servilo.",
"Files are being scanned, please wait." => "Dosieroj estas skanataj, bonvolu atendi.",
-"Current scanning" => "Nuna skano"
+"Current scanning" => "Nuna skano",
+"file" => "dosiero",
+"files" => "dosieroj",
+"Upgrading filesystem cache..." => "Ĝisdatiĝas dosiersistema kaŝmemoro..."
);
diff --git a/apps/files/l10n/es.php b/apps/files/l10n/es.php
index f702a5b513d4d89ea35f2771074255e14f61627d..2d5ac06ff97a6197fada66c0f8b25e7ceb24cf6e 100644
--- a/apps/files/l10n/es.php
+++ b/apps/files/l10n/es.php
@@ -1,18 +1,27 @@
"No se puede mover %s - Ya existe un archivo con ese nombre",
-"Could not move %s" => "No se puede mover %s",
-"Unable to rename file" => "No se puede renombrar el archivo",
-"No file was uploaded. Unknown error" => "Fallo no se subió el fichero",
-"There is no error, the file uploaded with success" => "No se ha producido ningún error, el archivo se ha subido con éxito",
-"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "El archivo que intentas subir sobrepasa el tamaño definido por la variable upload_max_filesize en php.ini",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "El archivo que intentas subir sobrepasa el tamaño definido por la variable MAX_FILE_SIZE especificada en el formulario HTML",
-"The uploaded file was only partially uploaded" => "El archivo que intentas subir solo se subió parcialmente",
-"No file was uploaded" => "No se ha subido ningún archivo",
-"Missing a temporary folder" => "Falta un directorio temporal",
-"Failed to write to disk" => "La escritura en disco ha fallado",
+"Could not move %s - File with this name already exists" => "No se pudo mover %s - Un archivo con ese nombre ya existe.",
+"Could not move %s" => "No se pudo mover %s",
+"Unable to set upload directory." => "Incapaz de crear directorio de subida.",
+"Invalid Token" => "Token Inválido",
+"No file was uploaded. Unknown error" => "No se subió ningún archivo. Error desconocido",
+"There is no error, the file uploaded with success" => "No hay ningún error, el archivo se ha subido con éxito",
+"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "El archivo subido sobrepasa la directiva upload_max_filesize en php.ini",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "El archivo subido sobrepasa la directiva MAX_FILE_SIZE especificada en el formulario HTML",
+"The uploaded file was only partially uploaded" => "El archivo subido fue sólo subido parcialmente",
+"No file was uploaded" => "No se subió ningún archivo",
+"Missing a temporary folder" => "Falta la carpeta temporal",
+"Failed to write to disk" => "Falló al escribir al disco",
"Not enough storage available" => "No hay suficiente espacio disponible",
-"Invalid directory." => "Directorio invalido.",
+"Invalid directory." => "Directorio inválido.",
"Files" => "Archivos",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Incapaz de subir su archivo, es un directorio o tiene 0 bytes",
+"Not enough space available" => "No hay suficiente espacio disponible",
+"Upload cancelled." => "Subida cancelada.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "La subida del archivo está en proceso. Si sale de la página ahora cancelará la subida.",
+"URL cannot be empty." => "La URL no puede estar vacía.",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Nombre de carpeta invalido. El uso de \"Shared\" está reservado por ownCloud",
+"Error" => "Error",
+"Share" => "Compartir",
"Delete permanently" => "Eliminar permanentemente",
"Delete" => "Eliminar",
"Rename" => "Renombrar",
@@ -23,22 +32,16 @@
"cancel" => "cancelar",
"replaced {new_name} with {old_name}" => "reemplazado {new_name} con {old_name}",
"undo" => "deshacer",
-"perform delete operation" => "Eliminar",
-"'.' is an invalid file name." => "'.' es un nombre de archivo inválido.",
+"perform delete operation" => "Realizar operación de borrado",
+"1 file uploading" => "subiendo 1 archivo",
+"files uploading" => "subiendo archivos",
+"'.' is an invalid file name." => "'.' no es un nombre de archivo válido.",
"File name cannot be empty." => "El nombre de archivo no puede estar vacío.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nombre Invalido, \"\\\", \"/\", \"<\", \">\", \":\", \"\", \"|\" \"?\" y \"*\" no están permitidos ",
-"Your storage is full, files can not be updated or synced anymore!" => "Su almacenamiento esta lleno, los archivos no pueden ser mas actualizados o sincronizados!",
-"Your storage is almost full ({usedSpacePercent}%)" => "Su almacenamiento esta lleno en un ({usedSpacePercent}%)",
-"Your download is being prepared. This might take some time if the files are big." => "Tu descarga esta siendo preparada. Esto puede tardar algun tiempo si los archivos son muy grandes.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "No ha sido posible subir tu archivo porque es un directorio o tiene 0 bytes",
-"Upload Error" => "Error al subir el archivo",
-"Close" => "cerrrar",
-"1 file uploading" => "subiendo 1 archivo",
-"{count} files uploading" => "Subiendo {count} archivos",
-"Upload cancelled." => "Subida cancelada.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "La subida del archivo está en proceso. Salir de la página ahora cancelará la subida.",
-"URL cannot be empty." => "La URL no puede estar vacía.",
-"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Nombre de carpeta invalido. El uso de \"Shared\" esta reservado para Owncloud",
+"Your storage is full, files can not be updated or synced anymore!" => "Su almacenamiento está lleno, ¡no se pueden actualizar o sincronizar más!",
+"Your storage is almost full ({usedSpacePercent}%)" => "Su almacenamiento está casi lleno ({usedSpacePercent}%)",
+"Your download is being prepared. This might take some time if the files are big." => "Su descarga está siendo preparada. Esto puede tardar algún tiempo si los archivos son grandes.",
+"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Nombre de carpeta no es válido. El uso de \"Shared\" está reservado por Owncloud",
"Name" => "Nombre",
"Size" => "Tamaño",
"Modified" => "Modificado",
@@ -46,11 +49,12 @@
"{count} folders" => "{count} carpetas",
"1 file" => "1 archivo",
"{count} files" => "{count} archivos",
+"%s could not be renamed" => "%s no se pudo renombrar",
"Upload" => "Subir",
-"File handling" => "Tratamiento de archivos",
+"File handling" => "Manejo de archivos",
"Maximum upload size" => "Tamaño máximo de subida",
"max. possible: " => "máx. posible:",
-"Needed for multi-file and folder downloads." => "Se necesita para descargas multi-archivo y de carpetas",
+"Needed for multi-file and folder downloads." => "Necesario para multi-archivo y descarga de carpetas",
"Enable ZIP-download" => "Habilitar descarga en ZIP",
"0 is unlimited" => "0 es ilimitado",
"Maximum input size for ZIP files" => "Tamaño máximo para archivos ZIP de entrada",
@@ -58,16 +62,21 @@
"New" => "Nuevo",
"Text file" => "Archivo de texto",
"Folder" => "Carpeta",
-"From link" => "Desde el enlace",
+"From link" => "Desde enlace",
"Deleted files" => "Archivos eliminados",
"Cancel upload" => "Cancelar subida",
-"You don’t have write permissions here." => "No tienes permisos para escribir aquí.",
-"Nothing in here. Upload something!" => "Aquí no hay nada. ¡Sube algo!",
+"You don’t have write permissions here." => "No tiene permisos de escritura aquí.",
+"Nothing in here. Upload something!" => "No hay nada aquí. ¡Suba algo!",
"Download" => "Descargar",
+"Size (MB)" => "Tamaño (MB)",
"Unshare" => "Dejar de compartir",
-"Upload too large" => "El archivo es demasiado grande",
-"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Los archivos que estás intentando subir sobrepasan el tamaño máximo permitido por este servidor.",
-"Files are being scanned, please wait." => "Se están escaneando los archivos, por favor espere.",
-"Current scanning" => "Ahora escaneando",
-"Upgrading filesystem cache..." => "Actualizando cache de archivos de sistema"
+"Upload too large" => "Subida demasido grande",
+"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Los archivos que estás intentando subir sobrepasan el tamaño máximo permitido en este servidor.",
+"Files are being scanned, please wait." => "Los archivos están siendo escaneados, por favor espere.",
+"Current scanning" => "Escaneo actual",
+"directory" => "carpeta",
+"directories" => "carpetas",
+"file" => "archivo",
+"files" => "archivos",
+"Upgrading filesystem cache..." => "Actualizando caché del sistema de archivos"
);
diff --git a/apps/files/l10n/es_AR.php b/apps/files/l10n/es_AR.php
index 6cd7c026922271c7ac57df15ae3ffb23964dfd0b..10bde4c3856d1fb8b0be46e0abae1d5794c3665c 100644
--- a/apps/files/l10n/es_AR.php
+++ b/apps/files/l10n/es_AR.php
@@ -1,22 +1,31 @@
"No se pudo mover %s - Un archivo con este nombre ya existe",
"Could not move %s" => "No se pudo mover %s ",
-"Unable to rename file" => "No fue posible cambiar el nombre al archivo",
+"Unable to set upload directory." => "No fue posible crear el directorio de subida.",
+"Invalid Token" => "Token Inválido",
"No file was uploaded. Unknown error" => "El archivo no fue subido. Error desconocido",
-"There is no error, the file uploaded with success" => "No se han producido errores, el archivo se ha subido con éxito",
+"There is no error, the file uploaded with success" => "No hay errores, el archivo fue subido con éxito",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "El archivo que intentás subir excede el tamaño definido por upload_max_filesize en el php.ini:",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "El archivo que intentás subir sobrepasa el tamaño definido por la variable MAX_FILE_SIZE especificada en el formulario HTML",
-"The uploaded file was only partially uploaded" => "El archivo que intentás subir solo se subió parcialmente",
-"No file was uploaded" => "El archivo no fue subido",
-"Missing a temporary folder" => "Falta un directorio temporal",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "El archivo subido sobrepasa el valor MAX_FILE_SIZE especificada en el formulario HTML",
+"The uploaded file was only partially uploaded" => "El archivo fue subido parcialmente",
+"No file was uploaded" => "No se subió ningún archivo ",
+"Missing a temporary folder" => "Error en la carpera temporal",
"Failed to write to disk" => "Error al escribir en el disco",
"Not enough storage available" => "No hay suficiente capacidad de almacenamiento",
"Invalid directory." => "Directorio invalido.",
"Files" => "Archivos",
+"Unable to upload your file as it is a directory or has 0 bytes" => "No fue posible subir el archivo porque es un directorio o porque su tamaño es 0 bytes",
+"Not enough space available" => "No hay suficiente espacio disponible",
+"Upload cancelled." => "La subida fue cancelada",
+"File upload is in progress. Leaving the page now will cancel the upload." => "La subida del archivo está en proceso. Si salís de la página ahora, la subida se cancelará.",
+"URL cannot be empty." => "La URL no puede estar vacía",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Nombre de carpeta inválido. El uso de \"Shared\" está reservado por ownCloud",
+"Error" => "Error",
+"Share" => "Compartir",
"Delete permanently" => "Borrar de manera permanente",
"Delete" => "Borrar",
"Rename" => "Cambiar nombre",
-"Pending" => "Pendiente",
+"Pending" => "Pendientes",
"{new_name} already exists" => "{new_name} ya existe",
"replace" => "reemplazar",
"suggest name" => "sugerir nombre",
@@ -24,20 +33,14 @@
"replaced {new_name} with {old_name}" => "reemplazado {new_name} con {old_name}",
"undo" => "deshacer",
"perform delete operation" => "Eliminar",
+"1 file uploading" => "Subiendo 1 archivo",
+"files uploading" => "Subiendo archivos",
"'.' is an invalid file name." => "'.' es un nombre de archivo inválido.",
"File name cannot be empty." => "El nombre del archivo no puede quedar vacío.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nombre invalido, '\\', '/', '<', '>', ':', '\"', '|', '?' y '*' no están permitidos.",
"Your storage is full, files can not be updated or synced anymore!" => "El almacenamiento está lleno, los archivos no se pueden seguir actualizando ni sincronizando",
"Your storage is almost full ({usedSpacePercent}%)" => "El almacenamiento está casi lleno ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "Tu descarga esta siendo preparada. Esto puede tardar algun tiempo si los archivos son muy grandes.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "No fue posible subir el archivo porque es un directorio o porque su tamaño es 0 bytes",
-"Upload Error" => "Error al subir el archivo",
-"Close" => "Cerrar",
-"1 file uploading" => "Subiendo 1 archivo",
-"{count} files uploading" => "Subiendo {count} archivos",
-"Upload cancelled." => "La subida fue cancelada",
-"File upload is in progress. Leaving the page now will cancel the upload." => "La subida del archivo está en proceso. Si salís de la página ahora, la subida se cancelará.",
-"URL cannot be empty." => "La URL no puede estar vacía",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Nombre de carpeta inválido. El uso de 'Shared' está reservado por ownCloud",
"Name" => "Nombre",
"Size" => "Tamaño",
@@ -46,6 +49,7 @@
"{count} folders" => "{count} directorios",
"1 file" => "1 archivo",
"{count} files" => "{count} archivos",
+"%s could not be renamed" => "%s no se pudo renombrar",
"Upload" => "Subir",
"File handling" => "Tratamiento de archivos",
"Maximum upload size" => "Tamaño máximo de subida",
@@ -64,10 +68,15 @@
"You don’t have write permissions here." => "No tenés permisos de escritura acá.",
"Nothing in here. Upload something!" => "No hay nada. ¡Subí contenido!",
"Download" => "Descargar",
+"Size (MB)" => "Tamaño (MB)",
"Unshare" => "Dejar de compartir",
-"Upload too large" => "El archivo es demasiado grande",
+"Upload too large" => "El tamaño del archivo que querés subir es demasiado grande",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Los archivos que intentás subir sobrepasan el tamaño máximo ",
"Files are being scanned, please wait." => "Se están escaneando los archivos, por favor esperá.",
"Current scanning" => "Escaneo actual",
+"directory" => "directorio",
+"directories" => "directorios",
+"file" => "archivo",
+"files" => "archivos",
"Upgrading filesystem cache..." => "Actualizando el cache del sistema de archivos"
);
diff --git a/apps/files/l10n/et_EE.php b/apps/files/l10n/et_EE.php
index f1c94e93aab7a02334a4f41f10c0f0f1d38cff6c..c58b066e28719c9fe934f15cd83834971e251fae 100644
--- a/apps/files/l10n/et_EE.php
+++ b/apps/files/l10n/et_EE.php
@@ -1,9 +1,12 @@
"Ei saa liigutada faili %s - samanimeline fail on juba olemas",
"Could not move %s" => "%s liigutamine ebaõnnestus",
-"Unable to rename file" => "Faili ümbernimetamine ebaõnnestus",
+"Unable to set upload directory." => "Üleslaadimiste kausta määramine ebaõnnestus.",
+"Invalid Token" => "Vigane kontrollkood",
"No file was uploaded. Unknown error" => "Ühtegi faili ei laetud üles. Tundmatu viga",
-"There is no error, the file uploaded with success" => "Ühtegi viga pole, fail on üles laetud",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Üles laetud faili suurus ületab HTML vormis määratud upload_max_filesize suuruse",
+"There is no error, the file uploaded with success" => "Ühtegi tõrget polnud, fail on üles laetud",
+"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Üleslaetava faili suurus ületab php.ini poolt määratud upload_max_filesize suuruse:",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Üleslaetud fail ületab MAX_FILE_SIZE suuruse, mis on HTML vormi jaoks määratud",
"The uploaded file was only partially uploaded" => "Fail laeti üles ainult osaliselt",
"No file was uploaded" => "Ühtegi faili ei laetud üles",
"Missing a temporary folder" => "Ajutiste failide kaust puudub",
@@ -11,9 +14,17 @@
"Not enough storage available" => "Saadaval pole piisavalt ruumi",
"Invalid directory." => "Vigane kaust.",
"Files" => "Failid",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Faili ei saa üles laadida, kuna see on kaust või selle suurus on 0 baiti",
+"Not enough space available" => "Pole piisavalt ruumi",
+"Upload cancelled." => "Üleslaadimine tühistati.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Faili üleslaadimine on töös. Lehelt lahkumine katkestab selle üleslaadimise.",
+"URL cannot be empty." => "URL ei saa olla tühi.",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Vigane kausta nimi. 'Shared' kasutamine on reserveeritud ownCloud poolt.",
+"Error" => "Viga",
+"Share" => "Jaga",
"Delete permanently" => "Kustuta jäädavalt",
"Delete" => "Kustuta",
-"Rename" => "ümber",
+"Rename" => "Nimeta ümber",
"Pending" => "Ootel",
"{new_name} already exists" => "{new_name} on juba olemas",
"replace" => "asenda",
@@ -21,17 +32,16 @@
"cancel" => "loobu",
"replaced {new_name} with {old_name}" => "asendas nime {old_name} nimega {new_name}",
"undo" => "tagasi",
+"perform delete operation" => "teosta kustutamine",
+"1 file uploading" => "1 fail üleslaadimisel",
+"files uploading" => "faili üleslaadimisel",
"'.' is an invalid file name." => "'.' on vigane failinimi.",
"File name cannot be empty." => "Faili nimi ei saa olla tühi.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Vigane nimi, '\\', '/', '<', '>', ':', '\"', '|', '?' ja '*' pole lubatud.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Sinu faili üleslaadimine ebaõnnestus, kuna see on kaust või selle suurus on 0 baiti",
-"Upload Error" => "Üleslaadimise viga",
-"Close" => "Sulge",
-"1 file uploading" => "1 faili üleslaadimisel",
-"{count} files uploading" => "{count} faili üleslaadimist",
-"Upload cancelled." => "Üleslaadimine tühistati.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Faili üleslaadimine on töös. Lehelt lahkumine katkestab selle üleslaadimise.",
-"URL cannot be empty." => "URL ei saa olla tühi.",
+"Your storage is full, files can not be updated or synced anymore!" => "Sinu andmemaht on täis! Faile ei uuendata ega sünkroniseerita!",
+"Your storage is almost full ({usedSpacePercent}%)" => "Su andmemaht on peaaegu täis ({usedSpacePercent}%)",
+"Your download is being prepared. This might take some time if the files are big." => "Valmistatakse allalaadimist. See võib võtta veidi aega, kui on tegu suurte failidega. ",
+"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Vigane kataloogi nimi. 'Shared' kasutamine on reserveeritud ownCloud poolt.",
"Name" => "Nimi",
"Size" => "Suurus",
"Modified" => "Muudetud",
@@ -39,6 +49,7 @@
"{count} folders" => "{count} kausta",
"1 file" => "1 fail",
"{count} files" => "{count} faili",
+"%s could not be renamed" => "%s ümbernimetamine ebaõnnestus",
"Upload" => "Lae üles",
"File handling" => "Failide käsitlemine",
"Maximum upload size" => "Maksimaalne üleslaadimise suurus",
@@ -52,12 +63,19 @@
"Text file" => "Tekstifail",
"Folder" => "Kaust",
"From link" => "Allikast",
+"Deleted files" => "Kustutatud failid",
"Cancel upload" => "Tühista üleslaadimine",
+"You don’t have write permissions here." => "Siin puudvad sul kirjutamisõigused.",
"Nothing in here. Upload something!" => "Siin pole midagi. Lae midagi üles!",
"Download" => "Lae alla",
"Unshare" => "Lõpeta jagamine",
"Upload too large" => "Üleslaadimine on liiga suur",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Failid, mida sa proovid üles laadida, ületab serveri poolt üleslaetavatele failidele määratud maksimaalse suuruse.",
-"Files are being scanned, please wait." => "Faile skannitakse, palun oota",
-"Current scanning" => "Praegune skannimine"
+"Files are being scanned, please wait." => "Faile skannitakse, palun oota.",
+"Current scanning" => "Praegune skannimine",
+"directory" => "kaust",
+"directories" => "kaustad",
+"file" => "fail",
+"files" => "faili",
+"Upgrading filesystem cache..." => "Failisüsteemi puhvri uuendamine..."
);
diff --git a/apps/files/l10n/eu.php b/apps/files/l10n/eu.php
index 63c62ce9a55d92e747edcdd88cde30a3ad92d0ff..c87e20b1ff66e4e322f97aeb1ac6e11d633f632e 100644
--- a/apps/files/l10n/eu.php
+++ b/apps/files/l10n/eu.php
@@ -1,18 +1,24 @@
"Ezin da %s mugitu - Izen hau duen fitxategia dagoeneko existitzen da",
"Could not move %s" => "Ezin dira fitxategiak mugitu %s",
-"Unable to rename file" => "Ezin izan da fitxategia berrizendatu",
"No file was uploaded. Unknown error" => "Ez da fitxategirik igo. Errore ezezaguna",
-"There is no error, the file uploaded with success" => "Ez da arazorik izan, fitxategia ongi igo da",
+"There is no error, the file uploaded with success" => "Ez da errorerik egon, fitxategia ongi igo da",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Igotako fitxategiak php.ini fitxategian ezarritako upload_max_filesize muga gainditu du:",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Igotako fitxategiaren tamaina HTML inprimakiko MAX_FILESIZE direktiban adierazitakoa baino handiagoa da",
-"The uploaded file was only partially uploaded" => "Igotako fitxategiaren zati bat baino gehiago ez da igo",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Igotako fitxategia HTML formularioan zehaztutako MAX_FILE_SIZE direktiba baino handidagoa da.",
+"The uploaded file was only partially uploaded" => "Igotako fitxategiaren zati bat bakarrik igo da",
"No file was uploaded" => "Ez da fitxategirik igo",
-"Missing a temporary folder" => "Aldi baterako karpeta falta da",
+"Missing a temporary folder" => "Aldi bateko karpeta falta da",
"Failed to write to disk" => "Errore bat izan da diskoan idazterakoan",
"Not enough storage available" => "Ez dago behar aina leku erabilgarri,",
"Invalid directory." => "Baliogabeko karpeta.",
"Files" => "Fitxategiak",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Ezin izan da zure fitxategia igo karpeta bat delako edo 0 byte dituelako",
+"Not enough space available" => "Ez dago leku nahikorik.",
+"Upload cancelled." => "Igoera ezeztatuta",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Fitxategien igoera martxan da. Orria orain uzteak igoera ezeztatutko du.",
+"URL cannot be empty." => "URLa ezin da hutsik egon.",
+"Error" => "Errorea",
+"Share" => "Elkarbanatu",
"Delete permanently" => "Ezabatu betirako",
"Delete" => "Ezabatu",
"Rename" => "Berrizendatu",
@@ -24,20 +30,14 @@
"replaced {new_name} with {old_name}" => " {new_name}-k {old_name} ordezkatu du",
"undo" => "desegin",
"perform delete operation" => "Ezabatu",
+"1 file uploading" => "fitxategi 1 igotzen",
+"files uploading" => "fitxategiak igotzen",
"'.' is an invalid file name." => "'.' ez da fitxategi izen baliogarria.",
"File name cannot be empty." => "Fitxategi izena ezin da hutsa izan.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "IZen aliogabea, '\\', '/', '<', '>', ':', '\"', '|', '?' eta '*' ez daude baimenduta.",
"Your storage is full, files can not be updated or synced anymore!" => "Zure biltegiratzea beterik dago, ezingo duzu aurrerantzean fitxategirik igo edo sinkronizatu!",
"Your storage is almost full ({usedSpacePercent}%)" => "Zure biltegiratzea nahiko beterik dago (%{usedSpacePercent})",
"Your download is being prepared. This might take some time if the files are big." => "Zure deskarga prestatu egin behar da. Denbora bat har lezake fitxategiak handiak badira. ",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Ezin da zure fitxategia igo, karpeta bat da edo 0 byt ditu",
-"Upload Error" => "Igotzean errore bat suertatu da",
-"Close" => "Itxi",
-"1 file uploading" => "fitxategi 1 igotzen",
-"{count} files uploading" => "{count} fitxategi igotzen",
-"Upload cancelled." => "Igoera ezeztatuta",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Fitxategien igoera martxan da. Orria orain uzteak igoera ezeztatutko du.",
-"URL cannot be empty." => "URLa ezin da hutsik egon.",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Baliogabeako karpeta izena. 'Shared' izena Owncloudek erreserbatzen du",
"Name" => "Izena",
"Size" => "Tamaina",
@@ -65,9 +65,11 @@
"Nothing in here. Upload something!" => "Ez dago ezer. Igo zerbait!",
"Download" => "Deskargatu",
"Unshare" => "Ez elkarbanatu",
-"Upload too large" => "Igotakoa handiegia da",
+"Upload too large" => "Igoera handiegia da",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Igotzen saiatzen ari zaren fitxategiak zerbitzari honek igotzeko onartzen duena baino handiagoak dira.",
"Files are being scanned, please wait." => "Fitxategiak eskaneatzen ari da, itxoin mezedez.",
"Current scanning" => "Orain eskaneatzen ari da",
+"file" => "fitxategia",
+"files" => "fitxategiak",
"Upgrading filesystem cache..." => "Fitxategi sistemaren katxea eguneratzen..."
);
diff --git a/apps/files/l10n/fa.php b/apps/files/l10n/fa.php
index e507ee715c5d2697f2637de79fa868fdd46cd9f8..73f4b493b4d88b3d02edf3fe8819169444a2d6ba 100644
--- a/apps/files/l10n/fa.php
+++ b/apps/files/l10n/fa.php
@@ -1,20 +1,29 @@
"%s نمی تواند حرکت کند - در حال حاضر پرونده با این نام وجود دارد. ",
"Could not move %s" => "%s نمی تواند حرکت کند ",
-"Unable to rename file" => "قادر به تغییر نام پرونده نیست.",
+"Unable to set upload directory." => "قادر به تنظیم پوشه آپلود نمی باشد.",
+"Invalid Token" => "رمز نامعتبر",
"No file was uploaded. Unknown error" => "هیچ فایلی آپلود نشد.خطای ناشناس",
-"There is no error, the file uploaded with success" => "هیچ خطایی وجود ندارد فایل با موفقیت بار گذاری شد",
+"There is no error, the file uploaded with success" => "هیچ خطایی نیست بارگذاری پرونده موفقیت آمیز بود",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "پرونده آپلود شده بیش ازدستور ماکزیمم_حجم فایل_برای آپلود در php.ini استفاده کرده است.",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "حداکثر حجم مجاز برای بارگذاری از طریق HTML \nMAX_FILE_SIZE",
-"The uploaded file was only partially uploaded" => "مقدار کمی از فایل بارگذاری شده",
-"No file was uploaded" => "هیچ فایلی بارگذاری نشده",
-"Missing a temporary folder" => "یک پوشه موقت گم شده است",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "حداکثر حجم قابل بار گذاری از طریق HTML MAX_FILE_SIZE است",
+"The uploaded file was only partially uploaded" => "پرونده بارگذاری شده فقط تاحدودی بارگذاری شده",
+"No file was uploaded" => "هیچ پروندهای بارگذاری نشده",
+"Missing a temporary folder" => "یک پوشه موقت گم شده",
"Failed to write to disk" => "نوشتن بر روی دیسک سخت ناموفق بود",
"Not enough storage available" => "فضای کافی در دسترس نیست",
"Invalid directory." => "فهرست راهنما نامعتبر می باشد.",
-"Files" => "فایل ها",
+"Files" => "پروندهها",
+"Unable to upload your file as it is a directory or has 0 bytes" => "ناتوان در بارگذاری یا فایل یک پوشه است یا 0بایت دارد",
+"Not enough space available" => "فضای کافی در دسترس نیست",
+"Upload cancelled." => "بار گذاری لغو شد",
+"File upload is in progress. Leaving the page now will cancel the upload." => "آپلودکردن پرونده در حال پیشرفت است. در صورت خروج از صفحه آپلود لغو میگردد. ",
+"URL cannot be empty." => "URL نمی تواند خالی باشد.",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "نام پوشه نامعتبر است. استفاده از 'به اشتراک گذاشته شده' متعلق به ownCloud میباشد.",
+"Error" => "خطا",
+"Share" => "اشتراکگذاری",
"Delete permanently" => "حذف قطعی",
-"Delete" => "پاک کردن",
+"Delete" => "حذف",
"Rename" => "تغییرنام",
"Pending" => "در انتظار",
"{new_name} already exists" => "{نام _جدید} در حال حاضر وجود دارد.",
@@ -24,29 +33,24 @@
"replaced {new_name} with {old_name}" => "{نام_جدید} با { نام_قدیمی} جایگزین شد.",
"undo" => "بازگشت",
"perform delete operation" => "انجام عمل حذف",
+"1 file uploading" => "1 پرونده آپلود شد.",
+"files uploading" => "بارگذاری فایل ها",
"'.' is an invalid file name." => "'.' یک نام پرونده نامعتبر است.",
"File name cannot be empty." => "نام پرونده نمی تواند خالی باشد.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "نام نامعتبر ، '\\', '/', '<', '>', ':', '\"', '|', '?' و '*' مجاز نمی باشند.",
"Your storage is full, files can not be updated or synced anymore!" => "فضای ذخیره ی شما کاملا پر است، بیش از این فایلها بهنگام یا همگام سازی نمی توانند بشوند!",
"Your storage is almost full ({usedSpacePercent}%)" => "فضای ذخیره ی شما تقریبا پر است ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "دانلود شما در حال آماده شدن است. در صورتیکه پرونده ها بزرگ باشند ممکن است مدتی طول بکشد.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "ناتوان در بارگذاری یا فایل یک پوشه است یا 0بایت دارد",
-"Upload Error" => "خطا در بار گذاری",
-"Close" => "بستن",
-"1 file uploading" => "1 پرونده آپلود شد.",
-"{count} files uploading" => "{ شمار } فایل های در حال آپلود",
-"Upload cancelled." => "بار گذاری لغو شد",
-"File upload is in progress. Leaving the page now will cancel the upload." => "آپلودکردن پرونده در حال پیشرفت است. در صورت خروج از صفحه آپلود لغو میگردد. ",
-"URL cannot be empty." => "URL نمی تواند خالی باشد.",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "نام پوشه نامعتبر است. استفاده از \" به اشتراک گذاشته شده \" متعلق به سایت Owncloud است.",
"Name" => "نام",
"Size" => "اندازه",
-"Modified" => "تغییر یافته",
+"Modified" => "تاریخ",
"1 folder" => "1 پوشه",
"{count} folders" => "{ شمار} پوشه ها",
"1 file" => "1 پرونده",
"{count} files" => "{ شمار } فایل ها",
-"Upload" => "بارگذاری",
+"%s could not be renamed" => "%s نمیتواند تغییر نام دهد.",
+"Upload" => "بارگزاری",
"File handling" => "اداره پرونده ها",
"Maximum upload size" => "حداکثر اندازه بارگزاری",
"max. possible: " => "حداکثرمقدارممکن:",
@@ -63,11 +67,15 @@
"Cancel upload" => "متوقف کردن بار گذاری",
"You don’t have write permissions here." => "شما اجازه ی نوشتن در اینجا را ندارید",
"Nothing in here. Upload something!" => "اینجا هیچ چیز نیست.",
-"Download" => "بارگیری",
+"Download" => "دانلود",
"Unshare" => "لغو اشتراک",
-"Upload too large" => "حجم بارگذاری بسیار زیاد است",
+"Upload too large" => "سایز فایل برای آپلود زیاد است(م.تنظیمات در php.ini)",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "فایلها بیش از حد تعیین شده در این سرور هستند\nمترجم:با تغییر فایل php,ini میتوان این محدودیت را برطرف کرد",
"Files are being scanned, please wait." => "پرونده ها در حال بازرسی هستند لطفا صبر کنید",
"Current scanning" => "بازرسی کنونی",
+"directory" => "پوشه",
+"directories" => "پوشه ها",
+"file" => "پرونده",
+"files" => "پرونده ها",
"Upgrading filesystem cache..." => "بهبود فایل سیستمی ذخیره گاه..."
);
diff --git a/apps/files/l10n/fi.php b/apps/files/l10n/fi.php
new file mode 100644
index 0000000000000000000000000000000000000000..c5ce878aded2fb3a742cc65acd12f3112d59a4ab
--- /dev/null
+++ b/apps/files/l10n/fi.php
@@ -0,0 +1,3 @@
+ "tallentaa"
+);
diff --git a/apps/files/l10n/fi_FI.php b/apps/files/l10n/fi_FI.php
index 6eb891d29d3b5b902b9090b93c21130f4c0c605b..c57c0ea898ee2804089cd532948c10889e150ce7 100644
--- a/apps/files/l10n/fi_FI.php
+++ b/apps/files/l10n/fi_FI.php
@@ -1,17 +1,24 @@
"Kohteen %s siirto ei onnistunut - Tiedosto samalla nimellä on jo olemassa",
"Could not move %s" => "Kohteen %s siirto ei onnistunut",
-"Unable to rename file" => "Tiedoston nimeäminen uudelleen ei onnistunut",
"No file was uploaded. Unknown error" => "Tiedostoa ei lähetetty. Tuntematon virhe",
"There is no error, the file uploaded with success" => "Ei virheitä, tiedosto lähetettiin onnistuneesti",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Lähetetty tiedosto ylittää HTML-lomakkeessa määritetyn MAX_FILE_SIZE-arvon ylärajan",
+"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Lähetetyn tiedoston koko ylittää php.ini-tiedoston upload_max_filesize-säännön:",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Ladattavan tiedoston maksimikoko ylittää MAX_FILE_SIZE dirketiivin, joka on määritelty HTML-lomakkeessa",
"The uploaded file was only partially uploaded" => "Tiedoston lähetys onnistui vain osittain",
"No file was uploaded" => "Yhtäkään tiedostoa ei lähetetty",
-"Missing a temporary folder" => "Väliaikaiskansiota ei ole olemassa",
+"Missing a temporary folder" => "Tilapäiskansio puuttuu",
"Failed to write to disk" => "Levylle kirjoitus epäonnistui",
"Not enough storage available" => "Tallennustilaa ei ole riittävästi käytettävissä",
"Invalid directory." => "Virheellinen kansio.",
"Files" => "Tiedostot",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Tiedoston lähetys epäonnistui, koska sen koko on 0 tavua tai kyseessä on kansio.",
+"Not enough space available" => "Tilaa ei ole riittävästi",
+"Upload cancelled." => "Lähetys peruttu.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Tiedoston lähetys on meneillään. Sivulta poistuminen nyt peruu tiedoston lähetyksen.",
+"URL cannot be empty." => "Verkko-osoite ei voi olla tyhjä",
+"Error" => "Virhe",
+"Share" => "Jaa",
"Delete permanently" => "Poista pysyvästi",
"Delete" => "Poista",
"Rename" => "Nimeä uudelleen",
@@ -28,15 +35,9 @@
"Your storage is full, files can not be updated or synced anymore!" => "Tallennustila on loppu, tiedostoja ei voi enää päivittää tai synkronoida!",
"Your storage is almost full ({usedSpacePercent}%)" => "Tallennustila on melkein loppu ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "Lataustasi valmistellaan. Tämä saattaa kestää hetken, jos tiedostot ovat suuria kooltaan.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Tiedoston lähetys epäonnistui, koska sen koko on 0 tavua tai kyseessä on kansio",
-"Upload Error" => "Lähetysvirhe.",
-"Close" => "Sulje",
-"Upload cancelled." => "Lähetys peruttu.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Tiedoston lähetys on meneillään. Sivulta poistuminen nyt peruu tiedoston lähetyksen.",
-"URL cannot be empty." => "Verkko-osoite ei voi olla tyhjä",
"Name" => "Nimi",
"Size" => "Koko",
-"Modified" => "Muutettu",
+"Modified" => "Muokattu",
"1 folder" => "1 kansio",
"{count} folders" => "{count} kansiota",
"1 file" => "1 tiedosto",
@@ -59,10 +60,15 @@
"You don’t have write permissions here." => "Tunnuksellasi ei ole kirjoitusoikeuksia tänne.",
"Nothing in here. Upload something!" => "Täällä ei ole mitään. Lähetä tänne jotakin!",
"Download" => "Lataa",
+"Size (MB)" => "Koko (Mt)",
"Unshare" => "Peru jakaminen",
"Upload too large" => "Lähetettävä tiedosto on liian suuri",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Lähetettäväksi valitsemasi tiedostot ylittävät palvelimen salliman tiedostokoon rajan.",
"Files are being scanned, please wait." => "Tiedostoja tarkistetaan, odota hetki.",
"Current scanning" => "Tämänhetkinen tutkinta",
+"directory" => "kansio",
+"directories" => "kansiota",
+"file" => "tiedosto",
+"files" => "tiedostoa",
"Upgrading filesystem cache..." => "Päivitetään tiedostojärjestelmän välimuistia..."
);
diff --git a/apps/files/l10n/fr.php b/apps/files/l10n/fr.php
index 5e53f5ab024df370b33d76e2d8fc18202c9009eb..dc1a33ac65cf61645b73597ff62d1bf816ee9eb4 100644
--- a/apps/files/l10n/fr.php
+++ b/apps/files/l10n/fr.php
@@ -1,22 +1,31 @@
"Impossible de déplacer %s - Un fichier possédant ce nom existe déjà",
"Could not move %s" => "Impossible de déplacer %s",
-"Unable to rename file" => "Impossible de renommer le fichier",
-"No file was uploaded. Unknown error" => "Aucun fichier n'a été chargé. Erreur inconnue",
-"There is no error, the file uploaded with success" => "Aucune erreur, le fichier a été téléversé avec succès",
+"Unable to set upload directory." => "Impossible de définir le dossier pour l'upload, charger.",
+"Invalid Token" => "Jeton non valide",
+"No file was uploaded. Unknown error" => "Aucun fichier n'a été envoyé. Erreur inconnue",
+"There is no error, the file uploaded with success" => "Aucune erreur, le fichier a été envoyé avec succès.",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Le fichier envoyé dépasse la valeur upload_max_filesize située dans le fichier php.ini:",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Le fichier téléversé excède la valeur de MAX_FILE_SIZE spécifiée dans le formulaire HTML",
-"The uploaded file was only partially uploaded" => "Le fichier n'a été que partiellement téléversé",
-"No file was uploaded" => "Aucun fichier n'a été téléversé",
-"Missing a temporary folder" => "Il manque un répertoire temporaire",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Le fichier envoyé dépasse la directive MAX_FILE_SIZE qui est spécifiée dans le formulaire HTML.",
+"The uploaded file was only partially uploaded" => "Le fichier n'a été que partiellement envoyé.",
+"No file was uploaded" => "Pas de fichier envoyé.",
+"Missing a temporary folder" => "Absence de dossier temporaire.",
"Failed to write to disk" => "Erreur d'écriture sur le disque",
"Not enough storage available" => "Plus assez d'espace de stockage disponible",
"Invalid directory." => "Dossier invalide.",
"Files" => "Fichiers",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Impossible d'envoyer votre fichier dans la mesure où il s'agit d'un répertoire ou d'un fichier de taille nulle",
+"Not enough space available" => "Espace disponible insuffisant",
+"Upload cancelled." => "Envoi annulé.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "L'envoi du fichier est en cours. Quitter cette page maintenant annulera l'envoi du fichier.",
+"URL cannot be empty." => "L'URL ne peut-être vide",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Nom de dossier invalide. L'utilisation du mot 'Shared' est réservée à Owncloud",
+"Error" => "Erreur",
+"Share" => "Partager",
"Delete permanently" => "Supprimer de façon définitive",
"Delete" => "Supprimer",
"Rename" => "Renommer",
-"Pending" => "En cours",
+"Pending" => "En attente",
"{new_name} already exists" => "{new_name} existe déjà",
"replace" => "remplacer",
"suggest name" => "Suggérer un nom",
@@ -24,20 +33,14 @@
"replaced {new_name} with {old_name}" => "{new_name} a été remplacé par {old_name}",
"undo" => "annuler",
"perform delete operation" => "effectuer l'opération de suppression",
+"1 file uploading" => "1 fichier en cours d'envoi",
+"files uploading" => "fichiers en cours d'envoi",
"'.' is an invalid file name." => "'.' n'est pas un nom de fichier valide.",
"File name cannot be empty." => "Le nom de fichier ne peut être vide.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nom invalide, les caractères '\\', '/', '<', '>', ':', '\"', '|', '?' et '*' ne sont pas autorisés.",
"Your storage is full, files can not be updated or synced anymore!" => "Votre espage de stockage est plein, les fichiers ne peuvent plus être téléversés ou synchronisés !",
"Your storage is almost full ({usedSpacePercent}%)" => "Votre espace de stockage est presque plein ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "Votre téléchargement est cours de préparation. Ceci peut nécessiter un certain temps si les fichiers sont volumineux.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Impossible de charger vos fichiers car il s'agit d'un dossier ou le fichier fait 0 octet.",
-"Upload Error" => "Erreur de chargement",
-"Close" => "Fermer",
-"1 file uploading" => "1 fichier en cours de téléchargement",
-"{count} files uploading" => "{count} fichiers téléversés",
-"Upload cancelled." => "Chargement annulé.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "L'envoi du fichier est en cours. Quitter cette page maintenant annulera l'envoi du fichier.",
-"URL cannot be empty." => "L'URL ne peut-être vide",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Nom de dossier invalide. L'utilisation du mot 'Shared' est réservée à Owncloud",
"Name" => "Nom",
"Size" => "Taille",
@@ -46,6 +49,7 @@
"{count} folders" => "{count} dossiers",
"1 file" => "1 fichier",
"{count} files" => "{count} fichiers",
+"%s could not be renamed" => "%s ne peut être renommé",
"Upload" => "Envoyer",
"File handling" => "Gestion des fichiers",
"Maximum upload size" => "Taille max. d'envoi",
@@ -64,10 +68,15 @@
"You don’t have write permissions here." => "Vous n'avez pas le droit d'écriture ici.",
"Nothing in here. Upload something!" => "Il n'y a rien ici ! Envoyez donc quelque chose :)",
"Download" => "Télécharger",
+"Size (MB)" => "Taille (Mo)",
"Unshare" => "Ne plus partager",
-"Upload too large" => "Fichier trop volumineux",
+"Upload too large" => "Téléversement trop volumineux",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Les fichiers que vous essayez d'envoyer dépassent la taille maximale permise par ce serveur.",
"Files are being scanned, please wait." => "Les fichiers sont en cours d'analyse, veuillez patienter.",
"Current scanning" => "Analyse en cours",
+"directory" => "dossier",
+"directories" => "dossiers",
+"file" => "fichier",
+"files" => "fichiers",
"Upgrading filesystem cache..." => "Mise à niveau du cache du système de fichier"
);
diff --git a/apps/files/l10n/gl.php b/apps/files/l10n/gl.php
index d48839d0b6022788f0243af3f1054f1469ede71a..4a1c7720caf7637511af2b4c16c382478dc5da5b 100644
--- a/apps/files/l10n/gl.php
+++ b/apps/files/l10n/gl.php
@@ -1,18 +1,27 @@
"Non se moveu %s - Xa existe un ficheiro con ese nome.",
"Could not move %s" => "Non foi posíbel mover %s",
-"Unable to rename file" => "Non é posíbel renomear o ficheiro",
-"No file was uploaded. Unknown error" => "Non foi enviado ningún ficheiro. Produciuse un erro descoñecido.",
-"There is no error, the file uploaded with success" => "Non se produciu ningún erro. O ficheiro enviouse correctamente",
+"Unable to set upload directory." => "Non é posíbel configurar o directorio de envíos.",
+"Invalid Token" => "Marca incorrecta",
+"No file was uploaded. Unknown error" => "Non se enviou ningún ficheiro. Produciuse un erro descoñecido.",
+"There is no error, the file uploaded with success" => "Non houbo erros, o ficheiro enviouse correctamente",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "O ficheiro enviado excede a directiva indicada por upload_max_filesize de php.ini:",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "O ficheiro enviado excede a directiva MAX_FILE_SIZE que foi indicada no formulario HTML",
-"The uploaded file was only partially uploaded" => "O ficheiro enviado foi só parcialmente enviado",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "O ficheiro enviado excede da directiva MAX_FILE_SIZE especificada no formulario HTML",
+"The uploaded file was only partially uploaded" => "O ficheiro so foi parcialmente enviado",
"No file was uploaded" => "Non se enviou ningún ficheiro",
-"Missing a temporary folder" => "Falta un cartafol temporal",
+"Missing a temporary folder" => "Falta o cartafol temporal",
"Failed to write to disk" => "Produciuse un erro ao escribir no disco",
"Not enough storage available" => "Non hai espazo de almacenamento abondo",
"Invalid directory." => "O directorio é incorrecto.",
"Files" => "Ficheiros",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Non foi posíbel enviar o ficheiro pois ou é un directorio ou ten 0 bytes",
+"Not enough space available" => "O espazo dispoñíbel é insuficiente",
+"Upload cancelled." => "Envío cancelado.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "O envío do ficheiro está en proceso. Saír agora da páxina cancelará o envío.",
+"URL cannot be empty." => "O URL non pode quedar baleiro.",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Nome de cartafol incorrecto. O uso de «Compartido» e «Shared» está reservado para o ownClod",
+"Error" => "Erro",
+"Share" => "Compartir",
"Delete permanently" => "Eliminar permanentemente",
"Delete" => "Eliminar",
"Rename" => "Renomear",
@@ -24,20 +33,14 @@
"replaced {new_name} with {old_name}" => "substituír {new_name} por {old_name}",
"undo" => "desfacer",
"perform delete operation" => "realizar a operación de eliminación",
+"1 file uploading" => "Enviándose 1 ficheiro",
+"files uploading" => "ficheiros enviándose",
"'.' is an invalid file name." => "«.» é un nome de ficheiro incorrecto",
"File name cannot be empty." => "O nome de ficheiro non pode estar baleiro",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nome incorrecto, non se permite «\\», «/», «<», «>», «:», «\"», «|», «?» e «*».",
"Your storage is full, files can not be updated or synced anymore!" => "O seu espazo de almacenamento está cheo, non é posíbel actualizar ou sincronizar máis os ficheiros!",
"Your storage is almost full ({usedSpacePercent}%)" => "O seu espazo de almacenamento está case cheo ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "Está a prepararse a súa descarga. Isto pode levar bastante tempo se os ficheiros son grandes.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Non foi posíbel enviar o ficheiro pois ou é un directorio ou ten 0 bytes",
-"Upload Error" => "Produciuse un erro no envío",
-"Close" => "Pechar",
-"1 file uploading" => "Enviándose 1 ficheiro",
-"{count} files uploading" => "Enviandose {count} ficheiros",
-"Upload cancelled." => "Envío cancelado.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "O envío do ficheiro está en proceso. Saír agora da páxina cancelará o envío.",
-"URL cannot be empty." => "O URL non pode quedar baleiro.",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Nome de cartafol incorrecto. O uso de «Shared» está reservado por Owncloud",
"Name" => "Nome",
"Size" => "Tamaño",
@@ -46,12 +49,13 @@
"{count} folders" => "{count} cartafoles",
"1 file" => "1 ficheiro",
"{count} files" => "{count} ficheiros",
+"%s could not be renamed" => "%s non pode cambiar de nome",
"Upload" => "Enviar",
"File handling" => "Manexo de ficheiro",
"Maximum upload size" => "Tamaño máximo do envío",
"max. possible: " => "máx. posíbel: ",
"Needed for multi-file and folder downloads." => "Precísase para a descarga de varios ficheiros e cartafoles.",
-"Enable ZIP-download" => "Habilitar a descarga-ZIP",
+"Enable ZIP-download" => "Activar a descarga ZIP",
"0 is unlimited" => "0 significa ilimitado",
"Maximum input size for ZIP files" => "Tamaño máximo de descarga para os ficheiros ZIP",
"Save" => "Gardar",
@@ -64,10 +68,15 @@
"You don’t have write permissions here." => "Non ten permisos para escribir aquí.",
"Nothing in here. Upload something!" => "Aquí non hai nada. Envíe algo.",
"Download" => "Descargar",
+"Size (MB)" => "Tamaño (MB)",
"Unshare" => "Deixar de compartir",
"Upload too large" => "Envío demasiado grande",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Os ficheiros que tenta enviar exceden do tamaño máximo permitido neste servidor",
"Files are being scanned, please wait." => "Estanse analizando os ficheiros. Agarde.",
"Current scanning" => "Análise actual",
+"directory" => "directorio",
+"directories" => "directorios",
+"file" => "ficheiro",
+"files" => "ficheiros",
"Upgrading filesystem cache..." => "Anovando a caché do sistema de ficheiros..."
);
diff --git a/apps/files/l10n/he.php b/apps/files/l10n/he.php
index 9d6b411c415d826adc98c0f95df0b74cb83a1ab7..52946bc6d0b9cfa39d806c3218964f5b7a94493c 100644
--- a/apps/files/l10n/he.php
+++ b/apps/files/l10n/he.php
@@ -1,13 +1,23 @@
"לא ניתן להעביר את %s - קובץ בשם הזה כבר קיים",
+"Could not move %s" => "לא ניתן להעביר את %s",
"No file was uploaded. Unknown error" => "לא הועלה קובץ. טעות בלתי מזוהה.",
-"There is no error, the file uploaded with success" => "לא אירעה תקלה, הקבצים הועלו בהצלחה",
+"There is no error, the file uploaded with success" => "לא התרחשה שגיאה, הקובץ הועלה בהצלחה",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "הקבצים שנשלחו חורגים מהגודל שצוין בהגדרה upload_max_filesize שבקובץ php.ini:",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "הקובץ שהועלה חרג מההנחיה MAX_FILE_SIZE שצוינה בטופס ה־HTML",
-"The uploaded file was only partially uploaded" => "הקובץ שהועלה הועלה בצורה חלקית",
-"No file was uploaded" => "לא הועלו קבצים",
-"Missing a temporary folder" => "תיקייה זמנית חסרה",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "הקובץ שהועלה גדוך מהערך MAX_FILE_SIZE שהוגדר בתופס HTML",
+"The uploaded file was only partially uploaded" => "הקובץ הועלה באופן חלקי בלבד",
+"No file was uploaded" => "שום קובץ לא הועלה",
+"Missing a temporary folder" => "תקיה זמנית חסרה",
"Failed to write to disk" => "הכתיבה לכונן נכשלה",
+"Not enough storage available" => "אין די שטח פנוי באחסון",
+"Invalid directory." => "תיקייה שגויה.",
"Files" => "קבצים",
+"Unable to upload your file as it is a directory or has 0 bytes" => "לא יכול להעלות את הקובץ מכיוון שזו תקיה או שמשקל הקובץ 0 בתים",
+"Upload cancelled." => "ההעלאה בוטלה.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "מתבצעת כעת העלאת קבצים. עזיבה של העמוד תבטל את ההעלאה.",
+"URL cannot be empty." => "קישור אינו יכול להיות ריק.",
+"Error" => "שגיאה",
+"Share" => "שתף",
"Delete permanently" => "מחק לצמיתות",
"Delete" => "מחיקה",
"Rename" => "שינוי שם",
@@ -18,15 +28,10 @@
"cancel" => "ביטול",
"replaced {new_name} with {old_name}" => "{new_name} הוחלף ב־{old_name}",
"undo" => "ביטול",
-"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "השם שגוי, אסור להשתמש בתווים '\\', '/', '<', '>', ':', '\"', '|', '?' ו־'*'.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "לא יכול להעלות את הקובץ מכיוון שזו תקיה או שמשקל הקובץ 0 בתים",
-"Upload Error" => "שגיאת העלאה",
-"Close" => "סגירה",
+"perform delete operation" => "ביצוע פעולת מחיקה",
"1 file uploading" => "קובץ אחד נשלח",
-"{count} files uploading" => "{count} קבצים נשלחים",
-"Upload cancelled." => "ההעלאה בוטלה.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "מתבצעת כעת העלאת קבצים. עזיבה של העמוד תבטל את ההעלאה.",
-"URL cannot be empty." => "קישור אינו יכול להיות ריק.",
+"files uploading" => "קבצים בהעלאה",
+"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "השם שגוי, אסור להשתמש בתווים '\\', '/', '<', '>', ':', '\"', '|', '?' ו־'*'.",
"Name" => "שם",
"Size" => "גודל",
"Modified" => "זמן שינוי",
@@ -54,5 +59,7 @@
"Upload too large" => "העלאה גדולה מידי",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "הקבצים שניסית להעלות חרגו מהגודל המקסימלי להעלאת קבצים על שרת זה.",
"Files are being scanned, please wait." => "הקבצים נסרקים, נא להמתין.",
-"Current scanning" => "הסריקה הנוכחית"
+"Current scanning" => "הסריקה הנוכחית",
+"file" => "קובץ",
+"files" => "קבצים"
);
diff --git a/apps/files/l10n/hi.php b/apps/files/l10n/hi.php
new file mode 100644
index 0000000000000000000000000000000000000000..151d1f497c7963a9d9d6690e27e08cc6d3dd5dab
--- /dev/null
+++ b/apps/files/l10n/hi.php
@@ -0,0 +1,5 @@
+ "त्रुटि",
+"Share" => "साझा करें",
+"Save" => "सहेजें"
+);
diff --git a/apps/files/l10n/hr.php b/apps/files/l10n/hr.php
index 3516ab8c1e6a76377ca949e19c217fe8013a5ef4..abe8c40bd53fda2abf018eeb061919968385d39f 100644
--- a/apps/files/l10n/hr.php
+++ b/apps/files/l10n/hr.php
@@ -1,28 +1,29 @@
"Datoteka je poslana uspješno i bez pogrešaka",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Poslana datoteka izlazi iz okvira MAX_FILE_SIZE direktive postavljene u HTML obrascu",
-"The uploaded file was only partially uploaded" => "Datoteka je poslana samo djelomično",
-"No file was uploaded" => "Ni jedna datoteka nije poslana",
-"Missing a temporary folder" => "Nedostaje privremena mapa",
+"There is no error, the file uploaded with success" => "Nema pogreške, datoteka je poslana uspješno.",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Poslana datoteka prelazi veličinu prikazanu u MAX_FILE_SIZE direktivi u HTML formi",
+"The uploaded file was only partially uploaded" => "Poslana datoteka je parcijalno poslana",
+"No file was uploaded" => "Datoteka nije poslana",
+"Missing a temporary folder" => "Nedostaje privremeni direktorij",
"Failed to write to disk" => "Neuspjelo pisanje na disk",
"Files" => "Datoteke",
-"Delete" => "Briši",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Nemoguće poslati datoteku jer je prazna ili je direktorij",
+"Upload cancelled." => "Slanje poništeno.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Učitavanje datoteke. Napuštanjem stranice će prekinuti učitavanje.",
+"Error" => "Greška",
+"Share" => "Podijeli",
+"Delete" => "Obriši",
"Rename" => "Promjeni ime",
"Pending" => "U tijeku",
"replace" => "zamjeni",
"suggest name" => "predloži ime",
"cancel" => "odustani",
"undo" => "vrati",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Nemoguće poslati datoteku jer je prazna ili je direktorij",
-"Upload Error" => "Pogreška pri slanju",
-"Close" => "Zatvori",
"1 file uploading" => "1 datoteka se učitava",
-"Upload cancelled." => "Slanje poništeno.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Učitavanje datoteke. Napuštanjem stranice će prekinuti učitavanje.",
-"Name" => "Naziv",
+"files uploading" => "datoteke se učitavaju",
+"Name" => "Ime",
"Size" => "Veličina",
"Modified" => "Zadnja promjena",
-"Upload" => "Pošalji",
+"Upload" => "Učitaj",
"File handling" => "datoteka za rukovanje",
"Maximum upload size" => "Maksimalna veličina prijenosa",
"max. possible: " => "maksimalna moguća: ",
@@ -36,10 +37,12 @@
"Folder" => "mapa",
"Cancel upload" => "Prekini upload",
"Nothing in here. Upload something!" => "Nema ničega u ovoj mapi. Pošalji nešto!",
-"Download" => "Preuzmi",
-"Unshare" => "Prekini djeljenje",
+"Download" => "Preuzimanje",
+"Unshare" => "Makni djeljenje",
"Upload too large" => "Prijenos je preobiman",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Datoteke koje pokušavate prenijeti prelaze maksimalnu veličinu za prijenos datoteka na ovom poslužitelju.",
"Files are being scanned, please wait." => "Datoteke se skeniraju, molimo pričekajte.",
-"Current scanning" => "Trenutno skeniranje"
+"Current scanning" => "Trenutno skeniranje",
+"file" => "datoteka",
+"files" => "datoteke"
);
diff --git a/apps/files/l10n/hu_HU.php b/apps/files/l10n/hu_HU.php
index 54d5033f907d1cdce3825039c6a6877bce46befc..b08335169585ab21b2e9b14a26df6d7f57bd22a3 100644
--- a/apps/files/l10n/hu_HU.php
+++ b/apps/files/l10n/hu_HU.php
@@ -1,18 +1,27 @@
"%s áthelyezése nem sikerült - már létezik másik fájl ezzel a névvel",
"Could not move %s" => "Nem sikerült %s áthelyezése",
-"Unable to rename file" => "Nem lehet átnevezni a fájlt",
+"Unable to set upload directory." => "Nem található a mappa, ahova feltölteni szeretne.",
+"Invalid Token" => "Hibás mappacím",
"No file was uploaded. Unknown error" => "Nem történt feltöltés. Ismeretlen hiba",
"There is no error, the file uploaded with success" => "A fájlt sikerült feltölteni",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "A feltöltött fájl mérete meghaladja a php.ini állományban megadott upload_max_filesize paraméter értékét.",
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "A feltöltött fájl mérete meghaladja a MAX_FILE_SIZE paramétert, ami a HTML formban került megadásra.",
"The uploaded file was only partially uploaded" => "Az eredeti fájlt csak részben sikerült feltölteni.",
-"No file was uploaded" => "Nem töltődött fel semmi",
+"No file was uploaded" => "Nem töltődött fel állomány",
"Missing a temporary folder" => "Hiányzik egy ideiglenes mappa",
"Failed to write to disk" => "Nem sikerült a lemezre történő írás",
"Not enough storage available" => "Nincs elég szabad hely.",
"Invalid directory." => "Érvénytelen mappa.",
"Files" => "Fájlok",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Nem tölthető fel, mert mappa volt, vagy 0 byte méretű",
+"Not enough space available" => "Nincs elég szabad hely",
+"Upload cancelled." => "A feltöltést megszakítottuk.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Fájlfeltöltés van folyamatban. Az oldal elhagyása megszakítja a feltöltést.",
+"URL cannot be empty." => "Az URL nem lehet semmi.",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Érvénytelen mappanév. A 'Shared' az ownCloud számára fenntartott elnevezés",
+"Error" => "Hiba",
+"Share" => "Megosztás",
"Delete permanently" => "Végleges törlés",
"Delete" => "Törlés",
"Rename" => "Átnevezés",
@@ -24,20 +33,14 @@
"replaced {new_name} with {old_name}" => "{new_name} fájlt kicseréltük ezzel: {old_name}",
"undo" => "visszavonás",
"perform delete operation" => "a törlés végrehajtása",
+"1 file uploading" => "1 fájl töltődik föl",
+"files uploading" => "fájl töltődik föl",
"'.' is an invalid file name." => "'.' fájlnév érvénytelen.",
"File name cannot be empty." => "A fájlnév nem lehet semmi.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Érvénytelen elnevezés. Ezek a karakterek nem használhatók: '\\', '/', '<', '>', ':', '\"', '|', '?' és '*'",
"Your storage is full, files can not be updated or synced anymore!" => "A tároló tele van, a fájlok nem frissíthetőek vagy szinkronizálhatóak a jövőben.",
"Your storage is almost full ({usedSpacePercent}%)" => "A tároló majdnem tele van ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "Készül a letöltendő állomány. Ez eltarthat egy ideig, ha nagyok a fájlok.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Nem tölthető fel, mert mappa volt, vagy 0 byte méretű",
-"Upload Error" => "Feltöltési hiba",
-"Close" => "Bezárás",
-"1 file uploading" => "1 fájl töltődik föl",
-"{count} files uploading" => "{count} fájl töltődik föl",
-"Upload cancelled." => "A feltöltést megszakítottuk.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Fájlfeltöltés van folyamatban. Az oldal elhagyása megszakítja a feltöltést.",
-"URL cannot be empty." => "Az URL nem lehet semmi.",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Érvénytelen mappanév. A név használata csak a Owncloud számára lehetséges.",
"Name" => "Név",
"Size" => "Méret",
@@ -46,6 +49,7 @@
"{count} folders" => "{count} mappa",
"1 file" => "1 fájl",
"{count} files" => "{count} fájl",
+"%s could not be renamed" => "%s átnevezése nem sikerült",
"Upload" => "Feltöltés",
"File handling" => "Fájlkezelés",
"Maximum upload size" => "Maximális feltölthető fájlméret",
@@ -64,10 +68,14 @@
"You don’t have write permissions here." => "Itt nincs írásjoga.",
"Nothing in here. Upload something!" => "Itt nincs semmi. Töltsön fel valamit!",
"Download" => "Letöltés",
-"Unshare" => "Megosztás visszavonása",
+"Unshare" => "A megosztás visszavonása",
"Upload too large" => "A feltöltés túl nagy",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "A feltöltendő állományok mérete meghaladja a kiszolgálón megengedett maximális méretet.",
"Files are being scanned, please wait." => "A fájllista ellenőrzése zajlik, kis türelmet!",
"Current scanning" => "Ellenőrzés alatt",
+"directory" => "mappa",
+"directories" => "mappa",
+"file" => "fájl",
+"files" => "fájlok",
"Upgrading filesystem cache..." => "A fájlrendszer gyorsítótárának frissítése zajlik..."
);
diff --git a/apps/files/l10n/hy.php b/apps/files/l10n/hy.php
index 29c0cd8b8d0627dcd2b067b297f902c626f162ef..22edf32c6e68ed17c7a4c3761d4b0006f4f496bc 100644
--- a/apps/files/l10n/hy.php
+++ b/apps/files/l10n/hy.php
@@ -1,6 +1,5 @@
"Ջնջել",
-"Close" => "Փակել",
"Save" => "Պահպանել",
"Download" => "Բեռնել"
);
diff --git a/apps/files/l10n/ia.php b/apps/files/l10n/ia.php
index ae614c1bf5dadfa661d90da8ee0f64f4ae35df75..5970a4cd55a182975b80791a367c1b2b7069f756 100644
--- a/apps/files/l10n/ia.php
+++ b/apps/files/l10n/ia.php
@@ -1,10 +1,11 @@
"Le file incargate solmente esseva incargate partialmente",
-"No file was uploaded" => "Nulle file esseva incargate",
+"No file was uploaded" => "Nulle file esseva incargate.",
"Missing a temporary folder" => "Manca un dossier temporari",
"Files" => "Files",
+"Error" => "Error",
+"Share" => "Compartir",
"Delete" => "Deler",
-"Close" => "Clauder",
"Name" => "Nomine",
"Size" => "Dimension",
"Modified" => "Modificate",
diff --git a/apps/files/l10n/id.php b/apps/files/l10n/id.php
index aff1933e569e9d3b801b5769dcf8d083dbfadf7c..bacdcc8f496e997739d4a927a924b8fb63019f0e 100644
--- a/apps/files/l10n/id.php
+++ b/apps/files/l10n/id.php
@@ -1,46 +1,75 @@
"Tidak dapat memindahkan %s - Berkas dengan nama ini sudah ada",
+"Could not move %s" => "Tidak dapat memindahkan %s",
+"No file was uploaded. Unknown error" => "Tidak ada berkas yang diunggah. Galat tidak dikenal.",
"There is no error, the file uploaded with success" => "Tidak ada galat, berkas sukses diunggah",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "File yang diunggah melampaui directive MAX_FILE_SIZE yang disebutan dalam form HTML.",
+"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Berkas yang diunggah melampaui direktif upload_max_filesize pada php.ini",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Berkas yang diunggah melampaui direktif MAX_FILE_SIZE yang ditentukan dalam formulir HTML.",
"The uploaded file was only partially uploaded" => "Berkas hanya diunggah sebagian",
"No file was uploaded" => "Tidak ada berkas yang diunggah",
-"Missing a temporary folder" => "Kehilangan folder temporer",
+"Missing a temporary folder" => "Folder sementara tidak ada",
"Failed to write to disk" => "Gagal menulis ke disk",
+"Not enough storage available" => "Ruang penyimpanan tidak mencukupi",
+"Invalid directory." => "Direktori tidak valid.",
"Files" => "Berkas",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Gagal mengunggah berkas Anda karena berupa direktori atau mempunyai ukuran 0 byte",
+"Not enough space available" => "Ruang penyimpanan tidak mencukupi",
+"Upload cancelled." => "Pengunggahan dibatalkan.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Berkas sedang diunggah. Meninggalkan halaman ini akan membatalkan proses.",
+"URL cannot be empty." => "URL tidak boleh kosong",
+"Error" => "Galat",
+"Share" => "Bagikan",
+"Delete permanently" => "Hapus secara permanen",
"Delete" => "Hapus",
+"Rename" => "Ubah nama",
"Pending" => "Menunggu",
-"replace" => "mengganti",
+"{new_name} already exists" => "{new_name} sudah ada",
+"replace" => "ganti",
+"suggest name" => "sarankan nama",
"cancel" => "batalkan",
-"undo" => "batal dikerjakan",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Gagal mengunggah berkas anda karena berupa direktori atau mempunyai ukuran 0 byte",
-"Upload Error" => "Terjadi Galat Pengunggahan",
-"Close" => "tutup",
-"Upload cancelled." => "Pengunggahan dibatalkan.",
-"URL cannot be empty." => "tautan tidak boleh kosong",
+"replaced {new_name} with {old_name}" => "mengganti {new_name} dengan {old_name}",
+"undo" => "urungkan",
+"perform delete operation" => "Lakukan operasi penghapusan",
+"1 file uploading" => "1 berkas diunggah",
+"files uploading" => "berkas diunggah",
+"'.' is an invalid file name." => "'.' bukan nama berkas yang valid.",
+"File name cannot be empty." => "Nama berkas tidak boleh kosong.",
+"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nama tidak valid, karakter '\\', '/', '<', '>', ':', '\"', '|', '?' dan '*' tidak diizinkan.",
+"Your storage is full, files can not be updated or synced anymore!" => "Ruang penyimpanan Anda penuh, berkas tidak dapat diperbarui atau disinkronkan lagi!",
+"Your storage is almost full ({usedSpacePercent}%)" => "Ruang penyimpanan hampir penuh ({usedSpacePercent}%)",
+"Your download is being prepared. This might take some time if the files are big." => "Unduhan Anda sedang disiapkan. Prosesnya dapat berlangsung agak lama jika ukuran berkasnya besar.",
+"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Nama folder salah. Nama 'Shared' telah digunakan oleh Owncloud.",
"Name" => "Nama",
"Size" => "Ukuran",
"Modified" => "Dimodifikasi",
-"1 folder" => "1 map",
-"{count} folders" => "{count} map",
+"1 folder" => "1 folder",
+"{count} folders" => "{count} folder",
"1 file" => "1 berkas",
"{count} files" => "{count} berkas",
"Upload" => "Unggah",
"File handling" => "Penanganan berkas",
-"Maximum upload size" => "Ukuran unggah maksimum",
-"max. possible: " => "Kemungkinan maks:",
-"Needed for multi-file and folder downloads." => "Dibutuhkan untuk multi-berkas dan unduhan folder",
+"Maximum upload size" => "Ukuran pengunggahan maksimum",
+"max. possible: " => "Kemungkinan maks.:",
+"Needed for multi-file and folder downloads." => "Dibutuhkan untuk pengunduhan multi-berkas dan multi-folder",
"Enable ZIP-download" => "Aktifkan unduhan ZIP",
-"0 is unlimited" => "0 adalah tidak terbatas",
-"Maximum input size for ZIP files" => "Ukuran masukan maksimal untuk berkas ZIP",
-"Save" => "simpan",
+"0 is unlimited" => "0 berarti tidak terbatas",
+"Maximum input size for ZIP files" => "Ukuran masukan maksimum untuk berkas ZIP",
+"Save" => "Simpan",
"New" => "Baru",
"Text file" => "Berkas teks",
"Folder" => "Folder",
-"Cancel upload" => "Batal mengunggah",
+"From link" => "Dari tautan",
+"Deleted files" => "Berkas yang dihapus",
+"Cancel upload" => "Batal pengunggahan",
+"You don’t have write permissions here." => "Anda tidak memiliki izin menulis di sini.",
"Nothing in here. Upload something!" => "Tidak ada apa-apa di sini. Unggah sesuatu!",
"Download" => "Unduh",
-"Unshare" => "batalkan berbagi",
-"Upload too large" => "Unggahan terlalu besar",
-"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Berkas yang anda coba unggah melebihi ukuran maksimum untuk pengunggahan berkas di server ini.",
-"Files are being scanned, please wait." => "Berkas sedang dipindai, silahkan tunggu.",
-"Current scanning" => "Sedang memindai"
+"Unshare" => "Batalkan berbagi",
+"Upload too large" => "Yang diunggah terlalu besar",
+"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Berkas yang dicoba untuk diunggah melebihi ukuran maksimum pengunggahan berkas di server ini.",
+"Files are being scanned, please wait." => "Berkas sedang dipindai, silakan tunggu.",
+"Current scanning" => "Yang sedang dipindai",
+"file" => "berkas",
+"files" => "berkas-berkas",
+"Upgrading filesystem cache..." => "Meningkatkan tembolok sistem berkas..."
);
diff --git a/apps/files/l10n/is.php b/apps/files/l10n/is.php
index 9d735c3c5411ab29e43c2d0cde6f7c5290b09612..97b19ae93794a4e6c76be0f4cc491b56cd644f27 100644
--- a/apps/files/l10n/is.php
+++ b/apps/files/l10n/is.php
@@ -1,7 +1,6 @@
"Gat ekki fært %s - Skrá með þessu nafni er þegar til",
"Could not move %s" => "Gat ekki fært %s",
-"Unable to rename file" => "Gat ekki endurskýrt skrá",
"No file was uploaded. Unknown error" => "Engin skrá var send inn. Óþekkt villa.",
"There is no error, the file uploaded with success" => "Engin villa, innsending heppnaðist",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Innsend skrá er stærri en upload_max stillingin í php.ini:",
@@ -12,6 +11,13 @@
"Failed to write to disk" => "Tókst ekki að skrifa á disk",
"Invalid directory." => "Ógild mappa.",
"Files" => "Skrár",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Innsending á skrá mistókst, hugsanlega sendir þú möppu eða skráin er 0 bæti.",
+"Not enough space available" => "Ekki nægt pláss tiltækt",
+"Upload cancelled." => "Hætt við innsendingu.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Innsending í gangi. Ef þú ferð af þessari síðu mun innsending misheppnast.",
+"URL cannot be empty." => "Vefslóð má ekki vera tóm.",
+"Error" => "Villa",
+"Share" => "Deila",
"Delete" => "Eyða",
"Rename" => "Endurskýra",
"Pending" => "Bíður",
@@ -21,17 +27,10 @@
"cancel" => "hætta við",
"replaced {new_name} with {old_name}" => "yfirskrifaði {new_name} með {old_name}",
"undo" => "afturkalla",
+"1 file uploading" => "1 skrá innsend",
"'.' is an invalid file name." => "'.' er ekki leyfilegt nafn.",
"File name cannot be empty." => "Nafn skráar má ekki vera tómt",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Ógilt nafn, táknin '\\', '/', '<', '>', ':', '\"', '|', '?' og '*' eru ekki leyfð.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Innsending á skrá mistókst, hugsanlega sendir þú möppu eða skráin er 0 bæti.",
-"Upload Error" => "Villa við innsendingu",
-"Close" => "Loka",
-"1 file uploading" => "1 skrá innsend",
-"{count} files uploading" => "{count} skrár innsendar",
-"Upload cancelled." => "Hætt við innsendingu.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Innsending í gangi. Ef þú ferð af þessari síðu mun innsending misheppnast.",
-"URL cannot be empty." => "Vefslóð má ekki vera tóm.",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Óleyfilegt nafn á möppu. Nafnið 'Shared' er frátekið fyrir Owncloud",
"Name" => "Nafn",
"Size" => "Stærð",
diff --git a/apps/files/l10n/it.php b/apps/files/l10n/it.php
index 2aac4ef20f532176aa0fccbf4433ff377866aead..8ea6bb48aba49d1f75cebac77af1ae1e7f49d6d9 100644
--- a/apps/files/l10n/it.php
+++ b/apps/files/l10n/it.php
@@ -1,18 +1,27 @@
"Impossibile spostare %s - un file con questo nome esiste già",
"Could not move %s" => "Impossibile spostare %s",
-"Unable to rename file" => "Impossibile rinominare il file",
+"Unable to set upload directory." => "Impossibile impostare una cartella di caricamento.",
+"Invalid Token" => "Token non valido",
"No file was uploaded. Unknown error" => "Nessun file è stato inviato. Errore sconosciuto",
-"There is no error, the file uploaded with success" => "Non ci sono errori, file caricato con successo",
+"There is no error, the file uploaded with success" => "Non ci sono errori, il file è stato caricato correttamente",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Il file caricato supera la direttiva upload_max_filesize in php.ini:",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Il file caricato supera il valore MAX_FILE_SIZE definito nel form HTML",
-"The uploaded file was only partially uploaded" => "Il file è stato parzialmente caricato",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Il file inviato supera la direttiva MAX_FILE_SIZE specificata nel modulo HTML",
+"The uploaded file was only partially uploaded" => "Il file è stato caricato solo parzialmente",
"No file was uploaded" => "Nessun file è stato caricato",
-"Missing a temporary folder" => "Cartella temporanea mancante",
+"Missing a temporary folder" => "Manca una cartella temporanea",
"Failed to write to disk" => "Scrittura su disco non riuscita",
"Not enough storage available" => "Spazio di archiviazione insufficiente",
"Invalid directory." => "Cartella non valida.",
"Files" => "File",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Impossibile caricare il file poiché è una cartella o ha una dimensione di 0 byte",
+"Not enough space available" => "Spazio disponibile insufficiente",
+"Upload cancelled." => "Invio annullato",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Caricamento del file in corso. La chiusura della pagina annullerà il caricamento.",
+"URL cannot be empty." => "L'URL non può essere vuoto.",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Nome della cartella non valido. L'uso di 'Shared' è riservato a ownCloud",
+"Error" => "Errore",
+"Share" => "Condividi",
"Delete permanently" => "Elimina definitivamente",
"Delete" => "Elimina",
"Rename" => "Rinomina",
@@ -24,20 +33,14 @@
"replaced {new_name} with {old_name}" => "sostituito {new_name} con {old_name}",
"undo" => "annulla",
"perform delete operation" => "esegui l'operazione di eliminazione",
+"1 file uploading" => "1 file in fase di caricamento",
+"files uploading" => "caricamento file",
"'.' is an invalid file name." => "'.' non è un nome file valido.",
"File name cannot be empty." => "Il nome del file non può essere vuoto.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nome non valido, '\\', '/', '<', '>', ':', '\"', '|', '?' e '*' non sono consentiti.",
"Your storage is full, files can not be updated or synced anymore!" => "Lo spazio di archiviazione è pieno, i file non possono essere più aggiornati o sincronizzati!",
"Your storage is almost full ({usedSpacePercent}%)" => "Lo spazio di archiviazione è quasi pieno ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "Il tuo scaricamento è in fase di preparazione. Ciò potrebbe richiedere del tempo se i file sono grandi.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Impossibile inviare il file poiché è una cartella o ha dimensione 0 byte",
-"Upload Error" => "Errore di invio",
-"Close" => "Chiudi",
-"1 file uploading" => "1 file in fase di caricamento",
-"{count} files uploading" => "{count} file in fase di caricamentoe",
-"Upload cancelled." => "Invio annullato",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Caricamento del file in corso. La chiusura della pagina annullerà il caricamento.",
-"URL cannot be empty." => "L'URL non può essere vuoto.",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Nome della cartella non valido. L'uso di 'Shared' è riservato da ownCloud",
"Name" => "Nome",
"Size" => "Dimensione",
@@ -46,6 +49,7 @@
"{count} folders" => "{count} cartelle",
"1 file" => "1 file",
"{count} files" => "{count} file",
+"%s could not be renamed" => "%s non può essere rinominato",
"Upload" => "Carica",
"File handling" => "Gestione file",
"Maximum upload size" => "Dimensione massima upload",
@@ -64,10 +68,15 @@
"You don’t have write permissions here." => "Qui non hai i permessi di scrittura.",
"Nothing in here. Upload something!" => "Non c'è niente qui. Carica qualcosa!",
"Download" => "Scarica",
+"Size (MB)" => "Dimensione (MB)",
"Unshare" => "Rimuovi condivisione",
-"Upload too large" => "Il file caricato è troppo grande",
+"Upload too large" => "Caricamento troppo grande",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "I file che stai provando a caricare superano la dimensione massima consentita su questo server.",
"Files are being scanned, please wait." => "Scansione dei file in corso, attendi",
"Current scanning" => "Scansione corrente",
+"directory" => "cartella",
+"directories" => "cartelle",
+"file" => "file",
+"files" => "file",
"Upgrading filesystem cache..." => "Aggiornamento della cache del filesystem in corso..."
);
diff --git a/apps/files/l10n/ja_JP.php b/apps/files/l10n/ja_JP.php
index 88349d1ba4022e84598b962386581d5188e5c24a..cb5480199e28535e8a2824df58b96f9e1f245b15 100644
--- a/apps/files/l10n/ja_JP.php
+++ b/apps/files/l10n/ja_JP.php
@@ -1,22 +1,31 @@
"%s を移動できませんでした ― この名前のファイルはすでに存在します",
"Could not move %s" => "%s を移動できませんでした",
-"Unable to rename file" => "ファイル名の変更ができません",
+"Unable to set upload directory." => "アップロードディレクトリを設定出来ません。",
+"Invalid Token" => "無効なトークン",
"No file was uploaded. Unknown error" => "ファイルは何もアップロードされていません。不明なエラー",
"There is no error, the file uploaded with success" => "エラーはありません。ファイルのアップロードは成功しました",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "アップロードされたファイルはphp.ini の upload_max_filesize に設定されたサイズを超えています:",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "アップロードされたファイルはHTMLのフォームに設定されたMAX_FILE_SIZEに設定されたサイズを超えています",
-"The uploaded file was only partially uploaded" => "ファイルは一部分しかアップロードされませんでした",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "アップロードファイルはHTMLフォームで指定された MAX_FILE_SIZE の制限を超えています",
+"The uploaded file was only partially uploaded" => "アップロードファイルは一部分だけアップロードされました",
"No file was uploaded" => "ファイルはアップロードされませんでした",
-"Missing a temporary folder" => "テンポラリフォルダが見つかりません",
+"Missing a temporary folder" => "一時保存フォルダが見つかりません",
"Failed to write to disk" => "ディスクへの書き込みに失敗しました",
"Not enough storage available" => "ストレージに十分な空き容量がありません",
"Invalid directory." => "無効なディレクトリです。",
"Files" => "ファイル",
+"Unable to upload your file as it is a directory or has 0 bytes" => "ディレクトリもしくは0バイトのファイルはアップロードできません",
+"Not enough space available" => "利用可能なスペースが十分にありません",
+"Upload cancelled." => "アップロードはキャンセルされました。",
+"File upload is in progress. Leaving the page now will cancel the upload." => "ファイル転送を実行中です。今このページから移動するとアップロードが中止されます。",
+"URL cannot be empty." => "URLは空にできません。",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "無効なフォルダ名です。'Shared' の利用はownCloudで予約済みです",
+"Error" => "エラー",
+"Share" => "共有",
"Delete permanently" => "完全に削除する",
"Delete" => "削除",
"Rename" => "名前の変更",
-"Pending" => "保留",
+"Pending" => "中断",
"{new_name} already exists" => "{new_name} はすでに存在しています",
"replace" => "置き換え",
"suggest name" => "推奨名称",
@@ -24,28 +33,23 @@
"replaced {new_name} with {old_name}" => "{old_name} を {new_name} に置換",
"undo" => "元に戻す",
"perform delete operation" => "削除を実行",
+"1 file uploading" => "ファイルを1つアップロード中",
+"files uploading" => "ファイルをアップロード中",
"'.' is an invalid file name." => "'.' は無効なファイル名です。",
"File name cannot be empty." => "ファイル名を空にすることはできません。",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "無効な名前、'\\', '/', '<', '>', ':', '\"', '|', '?', '*' は使用できません。",
"Your storage is full, files can not be updated or synced anymore!" => "あなたのストレージは一杯です。ファイルの更新と同期はもうできません!",
"Your storage is almost full ({usedSpacePercent}%)" => "あなたのストレージはほぼ一杯です({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "ダウンロードの準備中です。ファイルサイズが大きい場合は少し時間がかかるかもしれません。",
-"Unable to upload your file as it is a directory or has 0 bytes" => "ディレクトリもしくは0バイトのファイルはアップロードできません",
-"Upload Error" => "アップロードエラー",
-"Close" => "閉じる",
-"1 file uploading" => "ファイルを1つアップロード中",
-"{count} files uploading" => "{count} ファイルをアップロード中",
-"Upload cancelled." => "アップロードはキャンセルされました。",
-"File upload is in progress. Leaving the page now will cancel the upload." => "ファイル転送を実行中です。今このページから移動するとアップロードが中止されます。",
-"URL cannot be empty." => "URLは空にできません。",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "無効なフォルダ名です。'Shared' の利用は ownCloud が予約済みです。",
"Name" => "名前",
"Size" => "サイズ",
-"Modified" => "更新日時",
+"Modified" => "変更",
"1 folder" => "1 フォルダ",
"{count} folders" => "{count} フォルダ",
"1 file" => "1 ファイル",
"{count} files" => "{count} ファイル",
+"%s could not be renamed" => "%sの名前を変更できませんでした",
"Upload" => "アップロード",
"File handling" => "ファイル操作",
"Maximum upload size" => "最大アップロードサイズ",
@@ -55,7 +59,7 @@
"0 is unlimited" => "0を指定した場合は無制限",
"Maximum input size for ZIP files" => "ZIPファイルへの最大入力サイズ",
"Save" => "保存",
-"New" => "新規",
+"New" => "新規作成",
"Text file" => "テキストファイル",
"Folder" => "フォルダ",
"From link" => "リンク",
@@ -64,10 +68,15 @@
"You don’t have write permissions here." => "あなたには書き込み権限がありません。",
"Nothing in here. Upload something!" => "ここには何もありません。何かアップロードしてください。",
"Download" => "ダウンロード",
-"Unshare" => "共有しない",
-"Upload too large" => "ファイルサイズが大きすぎます",
+"Size (MB)" => "サイズ(MB)",
+"Unshare" => "共有解除",
+"Upload too large" => "アップロードには大きすぎます。",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "アップロードしようとしているファイルは、サーバで規定された最大サイズを超えています。",
"Files are being scanned, please wait." => "ファイルをスキャンしています、しばらくお待ちください。",
"Current scanning" => "スキャン中",
+"directory" => "ディレクトリ",
+"directories" => "ディレクトリ",
+"file" => "ファイル",
+"files" => "ファイル",
"Upgrading filesystem cache..." => "ファイルシステムキャッシュを更新中..."
);
diff --git a/apps/files/l10n/ka_GE.php b/apps/files/l10n/ka_GE.php
index 421c720a330024db5d36e0e4ac8eb5322695d234..b04e1b4536d9773a4965cd1073fb6f657391129a 100644
--- a/apps/files/l10n/ka_GE.php
+++ b/apps/files/l10n/ka_GE.php
@@ -1,11 +1,25 @@
"%s –ის გადატანა ვერ მოხერხდა – ფაილი ამ სახელით უკვე არსებობს",
+"Could not move %s" => "%s –ის გადატანა ვერ მოხერხდა",
+"No file was uploaded. Unknown error" => "ფაილი არ აიტვირთა. უცნობი შეცდომა",
"There is no error, the file uploaded with success" => "ჭოცდომა არ დაფიქსირდა, ფაილი წარმატებით აიტვირთა",
+"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "ატვირთული ფაილი აჭარბებს upload_max_filesize დირექტივას php.ini ფაილში",
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "ატვირთული ფაილი აჭარბებს MAX_FILE_SIZE დირექტივას, რომელიც მითითებულია HTML ფორმაში",
"The uploaded file was only partially uploaded" => "ატვირთული ფაილი მხოლოდ ნაწილობრივ აიტვირთა",
"No file was uploaded" => "ფაილი არ აიტვირთა",
"Missing a temporary folder" => "დროებითი საქაღალდე არ არსებობს",
"Failed to write to disk" => "შეცდომა დისკზე ჩაწერისას",
+"Not enough storage available" => "საცავში საკმარისი ადგილი არ არის",
+"Invalid directory." => "დაუშვებელი დირექტორია.",
"Files" => "ფაილები",
+"Unable to upload your file as it is a directory or has 0 bytes" => "თქვენი ფაილის ატვირთვა ვერ მოხერხდა. ის არის საქაღალდე და შეიცავს 0 ბაიტს",
+"Not enough space available" => "საკმარისი ადგილი არ არის",
+"Upload cancelled." => "ატვირთვა შეჩერებულ იქნა.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "მიმდინარეობს ფაილის ატვირთვა. სხვა გვერდზე გადასვლა გამოიწვევს ატვირთვის შეჩერებას",
+"URL cannot be empty." => "URL არ შეიძლება იყოს ცარიელი.",
+"Error" => "შეცდომა",
+"Share" => "გაზიარება",
+"Delete permanently" => "სრულად წაშლა",
"Delete" => "წაშლა",
"Rename" => "გადარქმევა",
"Pending" => "მოცდის რეჟიმში",
@@ -15,13 +29,16 @@
"cancel" => "უარყოფა",
"replaced {new_name} with {old_name}" => "{new_name} შეცვლილია {old_name}–ით",
"undo" => "დაბრუნება",
-"Unable to upload your file as it is a directory or has 0 bytes" => "თქვენი ფაილის ატვირთვა ვერ მოხერხდა. ის არის საქაღალდე და შეიცავს 0 ბაიტს",
-"Upload Error" => "შეცდომა ატვირთვისას",
-"Close" => "დახურვა",
+"perform delete operation" => "მიმდინარეობს წაშლის ოპერაცია",
"1 file uploading" => "1 ფაილის ატვირთვა",
-"{count} files uploading" => "{count} ფაილი იტვირთება",
-"Upload cancelled." => "ატვირთვა შეჩერებულ იქნა.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "მიმდინარეობს ფაილის ატვირთვა. სხვა გვერდზე გადასვლა გამოიწვევს ატვირთვის შეჩერებას",
+"files uploading" => "ფაილები იტვირთება",
+"'.' is an invalid file name." => "'.' არის დაუშვებელი ფაილის სახელი.",
+"File name cannot be empty." => "ფაილის სახელი არ შეიძლება იყოს ცარიელი.",
+"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "არადაშვებადი სახელი, '\\', '/', '<', '>', ':', '\"', '|', '?' და '*' არ არის დაიშვებული.",
+"Your storage is full, files can not be updated or synced anymore!" => "თქვენი საცავი გადაივსო. ფაილების განახლება და სინქრონიზირება ვერ მოხერხდება!",
+"Your storage is almost full ({usedSpacePercent}%)" => "თქვენი საცავი თითქმის გადაივსო ({usedSpacePercent}%)",
+"Your download is being prepared. This might take some time if the files are big." => "გადმოწერის მოთხოვნა მუშავდება. ის მოითხოვს გარკვეულ დროს რაგდან ფაილები არის დიდი ზომის.",
+"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "დაუშვებელი ფოლდერის სახელი. 'Shared'–ის გამოყენება რეზერვირებულია Owncloud–ის მიერ",
"Name" => "სახელი",
"Size" => "ზომა",
"Modified" => "შეცვლილია",
@@ -41,12 +58,16 @@
"New" => "ახალი",
"Text file" => "ტექსტური ფაილი",
"Folder" => "საქაღალდე",
+"From link" => "მისამართიდან",
+"Deleted files" => "წაშლილი ფაილები",
"Cancel upload" => "ატვირთვის გაუქმება",
+"You don’t have write permissions here." => "თქვენ არ გაქვთ ჩაწერის უფლება აქ.",
"Nothing in here. Upload something!" => "აქ არაფერი არ არის. ატვირთე რამე!",
"Download" => "ჩამოტვირთვა",
-"Unshare" => "გაზიარების მოხსნა",
+"Unshare" => "გაუზიარებადი",
"Upload too large" => "ასატვირთი ფაილი ძალიან დიდია",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "ფაილის ზომა რომლის ატვირთვასაც თქვენ აპირებთ, აჭარბებს სერვერზე დაშვებულ მაქსიმუმს.",
"Files are being scanned, please wait." => "მიმდინარეობს ფაილების სკანირება, გთხოვთ დაელოდოთ.",
-"Current scanning" => "მიმდინარე სკანირება"
+"Current scanning" => "მიმდინარე სკანირება",
+"Upgrading filesystem cache..." => "ფაილური სისტემის ქეშის განახლება...."
);
diff --git a/apps/files/l10n/ko.php b/apps/files/l10n/ko.php
index ba45bdaa5d7f2b479f15f10354434d1b489560cf..069c209ee58caf9e23b4b037598068aa9c1492d1 100644
--- a/apps/files/l10n/ko.php
+++ b/apps/files/l10n/ko.php
@@ -1,40 +1,43 @@
"%s 항목을 이동시키지 못하였음 - 파일 이름이 이미 존재함",
"Could not move %s" => "%s 항목을 이딩시키지 못하였음",
-"Unable to rename file" => "파일 이름바꾸기 할 수 없음",
"No file was uploaded. Unknown error" => "파일이 업로드되지 않았습니다. 알 수 없는 오류입니다",
-"There is no error, the file uploaded with success" => "업로드에 성공하였습니다.",
+"There is no error, the file uploaded with success" => "파일 업로드에 성공하였습니다.",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "업로드한 파일이 php.ini의 upload_max_filesize보다 큽니다:",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "업로드한 파일이 HTML 문서에 지정한 MAX_FILE_SIZE보다 더 큼",
-"The uploaded file was only partially uploaded" => "파일이 부분적으로 업로드됨",
-"No file was uploaded" => "업로드된 파일 없음",
-"Missing a temporary folder" => "임시 폴더가 사라짐",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "업로드한 파일 크기가 HTML 폼의 MAX_FILE_SIZE보다 큼",
+"The uploaded file was only partially uploaded" => "파일의 일부분만 업로드됨",
+"No file was uploaded" => "파일이 업로드되지 않았음",
+"Missing a temporary folder" => "임시 폴더가 없음",
"Failed to write to disk" => "디스크에 쓰지 못했습니다",
+"Not enough storage available" => "저장소가 용량이 충분하지 않습니다.",
"Invalid directory." => "올바르지 않은 디렉터리입니다.",
"Files" => "파일",
+"Unable to upload your file as it is a directory or has 0 bytes" => "디렉터리 및 빈 파일은 업로드할 수 없습니다",
+"Not enough space available" => "여유 공간이 부족합니다",
+"Upload cancelled." => "업로드가 취소되었습니다.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "파일 업로드가 진행 중입니다. 이 페이지를 벗어나면 업로드가 취소됩니다.",
+"URL cannot be empty." => "URL을 입력해야 합니다.",
+"Error" => "오류",
+"Share" => "공유",
+"Delete permanently" => "영원히 삭제",
"Delete" => "삭제",
"Rename" => "이름 바꾸기",
-"Pending" => "보류 중",
+"Pending" => "대기 중",
"{new_name} already exists" => "{new_name}이(가) 이미 존재함",
"replace" => "바꾸기",
"suggest name" => "이름 제안",
"cancel" => "취소",
"replaced {new_name} with {old_name}" => "{old_name}이(가) {new_name}(으)로 대체됨",
-"undo" => "실행 취소",
+"undo" => "되돌리기",
+"perform delete operation" => "삭제 작업중",
+"1 file uploading" => "파일 1개 업로드 중",
+"files uploading" => "파일 업로드중",
"'.' is an invalid file name." => "'.' 는 올바르지 않은 파일 이름 입니다.",
"File name cannot be empty." => "파일 이름이 비어 있을 수 없습니다.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "폴더 이름이 올바르지 않습니다. 이름에 문자 '\\', '/', '<', '>', ':', '\"', '|', '? ', '*'는 사용할 수 없습니다.",
"Your storage is full, files can not be updated or synced anymore!" => "저장 공간이 가득 찼습니다. 파일을 업데이트하거나 동기화할 수 없습니다!",
"Your storage is almost full ({usedSpacePercent}%)" => "저장 공간이 거의 가득 찼습니다 ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "다운로드가 준비 중입니다. 파일 크기가 크다면 시간이 오래 걸릴 수도 있습니다.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "이 파일은 디렉터리이거나 비어 있기 때문에 업로드할 수 없습니다",
-"Upload Error" => "업로드 오류",
-"Close" => "닫기",
-"1 file uploading" => "파일 1개 업로드 중",
-"{count} files uploading" => "파일 {count}개 업로드 중",
-"Upload cancelled." => "업로드가 취소되었습니다.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "파일 업로드가 진행 중입니다. 이 페이지를 벗어나면 업로드가 취소됩니다.",
-"URL cannot be empty." => "URL을 입력해야 합니다.",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "폴더 이름이 유효하지 않습니다. ",
"Name" => "이름",
"Size" => "크기",
@@ -56,13 +59,17 @@
"Text file" => "텍스트 파일",
"Folder" => "폴더",
"From link" => "링크에서",
+"Deleted files" => "파일 삭제됨",
"Cancel upload" => "업로드 취소",
+"You don’t have write permissions here." => "당신은 여기에 쓰기를 할 수 있는 권한이 없습니다.",
"Nothing in here. Upload something!" => "내용이 없습니다. 업로드할 수 있습니다!",
"Download" => "다운로드",
"Unshare" => "공유 해제",
-"Upload too large" => "업로드 용량 초과",
+"Upload too large" => "업로드한 파일이 너무 큼",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "이 파일이 서버에서 허용하는 최대 업로드 가능 용량보다 큽니다.",
"Files are being scanned, please wait." => "파일을 검색하고 있습니다. 기다려 주십시오.",
"Current scanning" => "현재 검색",
+"file" => "파일",
+"files" => "파일",
"Upgrading filesystem cache..." => "파일 시스템 캐시 업그레이드 중..."
);
diff --git a/apps/files/l10n/ku_IQ.php b/apps/files/l10n/ku_IQ.php
index 5c5a3d6bd8fae6d14a19fb6084aac33e367ba13d..7b36c3b710b7a426734832e0aea9cb8dd7888603 100644
--- a/apps/files/l10n/ku_IQ.php
+++ b/apps/files/l10n/ku_IQ.php
@@ -1,6 +1,6 @@
"داخستن",
"URL cannot be empty." => "ناونیشانی بهستهر نابێت بهتاڵ بێت.",
+"Error" => "ههڵه",
"Name" => "ناو",
"Upload" => "بارکردن",
"Save" => "پاشکهوتکردن",
diff --git a/apps/files/l10n/lb.php b/apps/files/l10n/lb.php
index b052da3a027c540e4535f6ba41352bfcccaae3f5..9b209a4d5cc010f70f5d4d915f7a127e6c930e01 100644
--- a/apps/files/l10n/lb.php
+++ b/apps/files/l10n/lb.php
@@ -2,19 +2,19 @@
"There is no error, the file uploaded with success" => "Keen Feeler, Datei ass komplett ropgelueden ginn",
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Déi ropgelueden Datei ass méi grouss wei d'MAX_FILE_SIZE Eegenschaft déi an der HTML form uginn ass",
"The uploaded file was only partially uploaded" => "Déi ropgelueden Datei ass nëmmen hallef ropgelueden ginn",
-"No file was uploaded" => "Et ass keng Datei ropgelueden ginn",
+"No file was uploaded" => "Et ass kee Fichier ropgeluede ginn",
"Missing a temporary folder" => "Et feelt en temporären Dossier",
"Failed to write to disk" => "Konnt net op den Disk schreiwen",
"Files" => "Dateien",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Kann deng Datei net eroplueden well et en Dossier ass oder 0 byte grouss ass.",
+"Upload cancelled." => "Upload ofgebrach.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "File Upload am gaang. Wann's de des Säit verléiss gëtt den Upload ofgebrach.",
+"Error" => "Fehler",
+"Share" => "Deelen",
"Delete" => "Läschen",
"replace" => "ersetzen",
"cancel" => "ofbriechen",
"undo" => "réckgängeg man",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Kann deng Datei net eroplueden well et en Dossier ass oder 0 byte grouss ass.",
-"Upload Error" => "Fehler beim eroplueden",
-"Close" => "Zoumaachen",
-"Upload cancelled." => "Upload ofgebrach.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "File Upload am gaang. Wann's de des Säit verléiss gëtt den Upload ofgebrach.",
"Name" => "Numm",
"Size" => "Gréisst",
"Modified" => "Geännert",
@@ -32,10 +32,12 @@
"Folder" => "Dossier",
"Cancel upload" => "Upload ofbriechen",
"Nothing in here. Upload something!" => "Hei ass näischt. Lued eppes rop!",
-"Download" => "Eroflueden",
+"Download" => "Download",
"Unshare" => "Net méi deelen",
"Upload too large" => "Upload ze grouss",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Déi Dateien déi Dir probéiert erop ze lueden sinn méi grouss wei déi Maximal Gréisst déi op dësem Server erlaabt ass.",
"Files are being scanned, please wait." => "Fichieren gi gescannt, war weg.",
-"Current scanning" => "Momentane Scan"
+"Current scanning" => "Momentane Scan",
+"file" => "Datei",
+"files" => "Dateien"
);
diff --git a/apps/files/l10n/lt_LT.php b/apps/files/l10n/lt_LT.php
index 2f16fc224200fe36a54171ea990ab6a02c9220ce..43fb4657dbb0239a9c1e74e7fe8d9a21b569db9b 100644
--- a/apps/files/l10n/lt_LT.php
+++ b/apps/files/l10n/lt_LT.php
@@ -1,11 +1,26 @@
"Klaidų nėra, failas įkeltas sėkmingai",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Įkeliamo failo dydis viršija MAX_FILE_SIZE parametrą, kuris yra nustatytas HTML formoje",
+"Could not move %s - File with this name already exists" => "Nepavyko perkelti %s - failas su tokiu pavadinimu jau egzistuoja",
+"Could not move %s" => "Nepavyko perkelti %s",
+"No file was uploaded. Unknown error" => "Failai nebuvo įkelti dėl nežinomos priežasties",
+"There is no error, the file uploaded with success" => "Failas įkeltas sėkmingai, be klaidų",
+"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Įkeliamas failas yra didesnis nei leidžia upload_max_filesize php.ini faile:",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Įkeliamo failo dydis viršija MAX_FILE_SIZE nustatymą, kuris naudojamas HTML formoje.",
"The uploaded file was only partially uploaded" => "Failas buvo įkeltas tik dalinai",
-"No file was uploaded" => "Nebuvo įkeltas nė vienas failas",
+"No file was uploaded" => "Nebuvo įkeltas joks failas",
"Missing a temporary folder" => "Nėra laikinojo katalogo",
"Failed to write to disk" => "Nepavyko įrašyti į diską",
+"Not enough storage available" => "Nepakanka vietos serveryje",
+"Invalid directory." => "Neteisingas aplankas",
"Files" => "Failai",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Neįmanoma įkelti failo - jo dydis gali būti 0 bitų arba tai katalogas",
+"Not enough space available" => "Nepakanka vietos",
+"Upload cancelled." => "Įkėlimas atšauktas.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Failo įkėlimas pradėtas. Jei paliksite šį puslapį, įkėlimas nutrūks.",
+"URL cannot be empty." => "URL negali būti tuščias.",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Negalimas aplanko pavadinimas. 'Shared' pavadinimas yra rezervuotas ownCloud",
+"Error" => "Klaida",
+"Share" => "Dalintis",
+"Delete permanently" => "Ištrinti negrįžtamai",
"Delete" => "Ištrinti",
"Rename" => "Pervadinti",
"Pending" => "Laukiantis",
@@ -15,13 +30,16 @@
"cancel" => "atšaukti",
"replaced {new_name} with {old_name}" => "pakeiskite {new_name} į {old_name}",
"undo" => "anuliuoti",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Neįmanoma įkelti failo - jo dydis gali būti 0 bitų arba tai katalogas",
-"Upload Error" => "Įkėlimo klaida",
-"Close" => "Užverti",
+"perform delete operation" => "ištrinti",
"1 file uploading" => "įkeliamas 1 failas",
-"{count} files uploading" => "{count} įkeliami failai",
-"Upload cancelled." => "Įkėlimas atšauktas.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Failo įkėlimas pradėtas. Jei paliksite šį puslapį, įkėlimas nutrūks.",
+"files uploading" => "įkeliami failai",
+"'.' is an invalid file name." => "'.' yra neleidžiamas failo pavadinime.",
+"File name cannot be empty." => "Failo pavadinimas negali būti tuščias.",
+"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Neleistinas pavadinimas, '\\', '/', '<', '>', ':', '\"', '|', '?' ir '*' yra neleidžiami.",
+"Your storage is full, files can not be updated or synced anymore!" => "Jūsų visa vieta serveryje užimta",
+"Your storage is almost full ({usedSpacePercent}%)" => "Jūsų vieta serveryje beveik visa užimta ({usedSpacePercent}%)",
+"Your download is being prepared. This might take some time if the files are big." => "Jūsų atsisiuntimas yra paruošiamas. tai gali užtrukti jei atsisiunčiamas didelis failas.",
+"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Negalimas aplanko pavadinimas. 'Shared' pavadinimas yra rezervuotas ownCloud",
"Name" => "Pavadinimas",
"Size" => "Dydis",
"Modified" => "Pakeista",
@@ -41,12 +59,18 @@
"New" => "Naujas",
"Text file" => "Teksto failas",
"Folder" => "Katalogas",
+"From link" => "Iš nuorodos",
+"Deleted files" => "Ištrinti failai",
"Cancel upload" => "Atšaukti siuntimą",
+"You don’t have write permissions here." => "Jūs neturite rašymo leidimo.",
"Nothing in here. Upload something!" => "Čia tuščia. Įkelkite ką nors!",
"Download" => "Atsisiųsti",
"Unshare" => "Nebesidalinti",
"Upload too large" => "Įkėlimui failas per didelis",
-"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Bandomų įkelti failų dydis viršija maksimalų leidžiamą šiame serveryje",
+"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Bandomų įkelti failų dydis viršija maksimalų, kuris leidžiamas šiame serveryje",
"Files are being scanned, please wait." => "Skenuojami failai, prašome palaukti.",
-"Current scanning" => "Šiuo metu skenuojama"
+"Current scanning" => "Šiuo metu skenuojama",
+"file" => "failas",
+"files" => "failai",
+"Upgrading filesystem cache..." => "Atnaujinamas sistemos kešavimas..."
);
diff --git a/apps/files/l10n/lv.php b/apps/files/l10n/lv.php
index a7a9284c6512fa1661554d042198dcfa1d742f11..b0def1e707d7d5164b1d888c267f1e1d46c96f84 100644
--- a/apps/files/l10n/lv.php
+++ b/apps/files/l10n/lv.php
@@ -1,9 +1,8 @@
"Nevarēja pārvietot %s — jau eksistē datne ar tādu nosaukumu",
"Could not move %s" => "Nevarēja pārvietot %s",
-"Unable to rename file" => "Nevarēja pārsaukt datni",
"No file was uploaded. Unknown error" => "Netika augšupielādēta neviena datne. Nezināma kļūda",
-"There is no error, the file uploaded with success" => "Augšupielāde pabeigta bez kļūdām",
+"There is no error, the file uploaded with success" => "Viss kārtībā, datne augšupielādēta veiksmīga",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Augšupielādētā datne pārsniedz upload_max_filesize norādījumu php.ini datnē:",
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Augšupielādētā datne pārsniedz MAX_FILE_SIZE norādi, kas ir norādīta HTML formā",
"The uploaded file was only partially uploaded" => "Augšupielādētā datne ir tikai daļēji augšupielādēta",
@@ -13,6 +12,13 @@
"Not enough storage available" => "Nav pietiekami daudz vietas",
"Invalid directory." => "Nederīga direktorija.",
"Files" => "Datnes",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Nevar augšupielādēt jūsu datni, jo tā ir direktorija vai arī tā ir 0 baitu liela",
+"Not enough space available" => "Nepietiek brīvas vietas",
+"Upload cancelled." => "Augšupielāde ir atcelta.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Notiek augšupielāde. Pametot lapu tagad, tiks atcelta augšupielāde.",
+"URL cannot be empty." => "URL nevar būt tukšs.",
+"Error" => "Kļūda",
+"Share" => "Dalīties",
"Delete permanently" => "Dzēst pavisam",
"Delete" => "Dzēst",
"Rename" => "Pārsaukt",
@@ -24,20 +30,13 @@
"replaced {new_name} with {old_name}" => "aizvietoja {new_name} ar {old_name}",
"undo" => "atsaukt",
"perform delete operation" => "veikt dzēšanas darbību",
+"1 file uploading" => "Augšupielādē 1 datni",
"'.' is an invalid file name." => "'.' ir nederīgs datnes nosaukums.",
"File name cannot be empty." => "Datnes nosaukums nevar būt tukšs.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nederīgs nosaukums, nav atļauti '\\', '/', '<', '>', ':', '\"', '|', '?' un '*'.",
"Your storage is full, files can not be updated or synced anymore!" => "Jūsu krātuve ir pilna, datnes vairs nevar augšupielādēt vai sinhronizēt!",
"Your storage is almost full ({usedSpacePercent}%)" => "Jūsu krātuve ir gandrīz pilna ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "Tiek sagatavota lejupielāde. Tas var aizņemt kādu laiciņu, ja datnes ir lielas.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Nevar augšupielādēt jūsu datni, jo tā ir direktorija vai arī tās izmērs ir 0 baiti",
-"Upload Error" => "Kļūda augšupielādējot",
-"Close" => "Aizvērt",
-"1 file uploading" => "Augšupielādē 1 datni",
-"{count} files uploading" => "augšupielādē {count} datnes",
-"Upload cancelled." => "Augšupielāde ir atcelta.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Notiek augšupielāde. Pametot lapu tagad, tiks atcelta augšupielāde.",
-"URL cannot be empty." => "URL nevar būt tukšs.",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Nederīgs mapes nosaukums. “Koplietots” izmantojums ir rezervēts ownCloud servisam.",
"Name" => "Nosaukums",
"Size" => "Izmērs",
@@ -69,5 +68,7 @@
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Augšupielādējamās datnes pārsniedz servera pieļaujamo datņu augšupielādes apjomu",
"Files are being scanned, please wait." => "Datnes šobrīd tiek caurskatītas, lūdzu, uzgaidiet.",
"Current scanning" => "Šobrīd tiek caurskatīts",
+"file" => "fails",
+"files" => "faili",
"Upgrading filesystem cache..." => "Uzlabo datņu sistēmas kešatmiņu..."
);
diff --git a/apps/files/l10n/mk.php b/apps/files/l10n/mk.php
index cf9ad8abafc75fdcf85a367e91786d0155dd62ca..2dd75f14338a92407d386d3ff6d3f786624817a9 100644
--- a/apps/files/l10n/mk.php
+++ b/apps/files/l10n/mk.php
@@ -1,13 +1,19 @@
"Ниту еден фајл не се вчита. Непозната грешка",
-"There is no error, the file uploaded with success" => "Нема грешка, датотеката беше подигната успешно",
+"There is no error, the file uploaded with success" => "Датотеката беше успешно подигната.",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Подигнатата датотека ја надминува upload_max_filesize директивата во php.ini:",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Подигнатата датотеката ја надминува MAX_FILE_SIZE директивата која беше поставена во HTML формата",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Големината на датотеката ја надминува MAX_FILE_SIZE директивата која беше специфицирана во HTML формата",
"The uploaded file was only partially uploaded" => "Датотеката беше само делумно подигната.",
-"No file was uploaded" => "Не беше подигната датотека",
-"Missing a temporary folder" => "Не постои привремена папка",
+"No file was uploaded" => "Не беше подигната датотека.",
+"Missing a temporary folder" => "Недостасува привремена папка",
"Failed to write to disk" => "Неуспеав да запишам на диск",
"Files" => "Датотеки",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Не може да се преземе вашата датотека бидејќи фолдерот во кој се наоѓа фајлот има големина од 0 бајти",
+"Upload cancelled." => "Преземањето е прекинато.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Подигање на датотека е во тек. Напуштење на страницата ќе го прекине.",
+"URL cannot be empty." => "Адресата неможе да биде празна.",
+"Error" => "Грешка",
+"Share" => "Сподели",
"Delete" => "Избриши",
"Rename" => "Преименувај",
"Pending" => "Чека",
@@ -17,15 +23,8 @@
"cancel" => "откажи",
"replaced {new_name} with {old_name}" => "заменета {new_name} со {old_name}",
"undo" => "врати",
-"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Неправилно име. , '\\', '/', '<', '>', ':', '\"', '|', '?' и '*' не се дозволени.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Не може да се преземе вашата датотека бидејќи фолдерот во кој се наоѓа фајлот има големина од 0 бајти",
-"Upload Error" => "Грешка при преземање",
-"Close" => "Затвои",
"1 file uploading" => "1 датотека се подига",
-"{count} files uploading" => "{count} датотеки се подигаат",
-"Upload cancelled." => "Преземањето е прекинато.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Подигање на датотека е во тек. Напуштење на страницата ќе го прекине.",
-"URL cannot be empty." => "Адресата неможе да биде празна.",
+"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Неправилно име. , '\\', '/', '<', '>', ':', '\"', '|', '?' и '*' не се дозволени.",
"Name" => "Име",
"Size" => "Големина",
"Modified" => "Променето",
@@ -50,8 +49,10 @@
"Nothing in here. Upload something!" => "Тука нема ништо. Снимете нешто!",
"Download" => "Преземи",
"Unshare" => "Не споделувај",
-"Upload too large" => "Датотеката е премногу голема",
+"Upload too large" => "Фајлот кој се вчитува е преголем",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Датотеките кои се обидувате да ги подигнете ја надминуваат максималната големина за подигнување датотеки на овој сервер.",
"Files are being scanned, please wait." => "Се скенираат датотеки, ве молам почекајте.",
-"Current scanning" => "Моментално скенирам"
+"Current scanning" => "Моментално скенирам",
+"file" => "датотека",
+"files" => "датотеки"
);
diff --git a/apps/files/l10n/ms_MY.php b/apps/files/l10n/ms_MY.php
index b15a9111e70475f697e409c700c650d4e55f456a..f96d4d48014eee9d67a5e8979a78d43215c51d52 100644
--- a/apps/files/l10n/ms_MY.php
+++ b/apps/files/l10n/ms_MY.php
@@ -1,21 +1,21 @@
"Tiada fail dimuatnaik. Ralat tidak diketahui.",
-"There is no error, the file uploaded with success" => "Tiada ralat, fail berjaya dimuat naik.",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Fail yang dimuat naik melebihi MAX_FILE_SIZE yang dinyatakan dalam form HTML ",
-"The uploaded file was only partially uploaded" => "Sebahagian daripada fail telah dimuat naik. ",
-"No file was uploaded" => "Tiada fail yang dimuat naik",
-"Missing a temporary folder" => "Folder sementara hilang",
+"There is no error, the file uploaded with success" => "Tiada ralat berlaku, fail berjaya dimuatnaik",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Saiz fail yang dimuatnaik melebihi MAX_FILE_SIZE yang ditetapkan dalam borang HTML",
+"The uploaded file was only partially uploaded" => "Fail yang dimuatnaik tidak lengkap",
+"No file was uploaded" => "Tiada fail dimuatnaik",
+"Missing a temporary folder" => "Direktori sementara hilang",
"Failed to write to disk" => "Gagal untuk disimpan",
-"Files" => "fail",
+"Files" => "Fail-fail",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Tidak boleh memuatnaik fail anda kerana mungkin ianya direktori atau saiz fail 0 bytes",
+"Upload cancelled." => "Muatnaik dibatalkan.",
+"Error" => "Ralat",
+"Share" => "Kongsi",
"Delete" => "Padam",
"Pending" => "Dalam proses",
"replace" => "ganti",
"cancel" => "Batal",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Tidak boleh memuatnaik fail anda kerana mungkin ianya direktori atau saiz fail 0 bytes",
-"Upload Error" => "Muat naik ralat",
-"Close" => "Tutup",
-"Upload cancelled." => "Muatnaik dibatalkan.",
-"Name" => "Nama ",
+"Name" => "Nama",
"Size" => "Saiz",
"Modified" => "Dimodifikasi",
"Upload" => "Muat naik",
@@ -33,8 +33,10 @@
"Cancel upload" => "Batal muat naik",
"Nothing in here. Upload something!" => "Tiada apa-apa di sini. Muat naik sesuatu!",
"Download" => "Muat turun",
-"Upload too large" => "Muat naik terlalu besar",
+"Upload too large" => "Muatnaik terlalu besar",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Fail yang cuba dimuat naik melebihi saiz maksimum fail upload server",
"Files are being scanned, please wait." => "Fail sedang diimbas, harap bersabar.",
-"Current scanning" => "Imbasan semasa"
+"Current scanning" => "Imbasan semasa",
+"file" => "fail",
+"files" => "fail"
);
diff --git a/apps/files/l10n/nb_NO.php b/apps/files/l10n/nb_NO.php
index d9972feb6a585c8bde21be9082311499f3db0126..e6d0ed4104978eff57f8ea664cc0853109f2c448 100644
--- a/apps/files/l10n/nb_NO.php
+++ b/apps/files/l10n/nb_NO.php
@@ -1,12 +1,26 @@
"Kan ikke flytte %s - En fil med samme navn finnes allerede",
+"Could not move %s" => "Kunne ikke flytte %s",
+"Unable to set upload directory." => "Kunne ikke sette opplastingskatalog.",
"No file was uploaded. Unknown error" => "Ingen filer ble lastet opp. Ukjent feil.",
-"There is no error, the file uploaded with success" => "Det er ingen feil. Filen ble lastet opp.",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Filstørrelsen overskrider maksgrensen på MAX_FILE_SIZE som ble oppgitt i HTML-skjemaet",
-"The uploaded file was only partially uploaded" => "Filopplastningen ble bare delvis gjennomført",
-"No file was uploaded" => "Ingen fil ble lastet opp",
-"Missing a temporary folder" => "Mangler en midlertidig mappe",
+"There is no error, the file uploaded with success" => "Pust ut, ingen feil. Filen ble lastet opp problemfritt",
+"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Filstørrelsen overskrider maksgrensedirektivet upload_max_filesize i php.ini-konfigurasjonen.",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Filen du prøvde å laste opp var større enn grensen satt i MAX_FILE_SIZE i HTML-skjemaet.",
+"The uploaded file was only partially uploaded" => "Filen du prøvde å laste opp ble kun delvis lastet opp",
+"No file was uploaded" => "Ingen filer ble lastet opp",
+"Missing a temporary folder" => "Mangler midlertidig mappe",
"Failed to write to disk" => "Klarte ikke å skrive til disk",
+"Not enough storage available" => "Ikke nok lagringsplass",
+"Invalid directory." => "Ugyldig katalog.",
"Files" => "Filer",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Kan ikke laste opp filen din siden det er en mappe eller den har 0 bytes",
+"Not enough space available" => "Ikke nok lagringsplass",
+"Upload cancelled." => "Opplasting avbrutt.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Filopplasting pågår. Forlater du siden nå avbrytes opplastingen.",
+"URL cannot be empty." => "URL-en kan ikke være tom.",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Ugyldig mappenavn. Bruk av \"Shared\" er reservert av ownCloud.",
+"Error" => "Feil",
+"Share" => "Del",
"Delete permanently" => "Slett permanent",
"Delete" => "Slett",
"Rename" => "Omdøp",
@@ -17,15 +31,16 @@
"cancel" => "avbryt",
"replaced {new_name} with {old_name}" => "erstatt {new_name} med {old_name}",
"undo" => "angre",
-"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Ugyldig navn, '\\', '/', '<', '>', ':', '\"', '|', '?' og '*' er ikke tillatt.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Kan ikke laste opp filen din siden det er en mappe eller den har 0 bytes",
-"Upload Error" => "Opplasting feilet",
-"Close" => "Lukk",
+"perform delete operation" => "utfør sletting",
"1 file uploading" => "1 fil lastes opp",
-"{count} files uploading" => "{count} filer laster opp",
-"Upload cancelled." => "Opplasting avbrutt.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Filopplasting pågår. Forlater du siden nå avbrytes opplastingen.",
-"URL cannot be empty." => "URL-en kan ikke være tom.",
+"files uploading" => "filer lastes opp",
+"'.' is an invalid file name." => "'.' er et ugyldig filnavn.",
+"File name cannot be empty." => "Filnavn kan ikke være tomt.",
+"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Ugyldig navn, '\\', '/', '<', '>', ':', '\"', '|', '?' og '*' er ikke tillatt.",
+"Your storage is full, files can not be updated or synced anymore!" => "Lagringsplass er oppbrukt, filer kan ikke lenger oppdateres eller synkroniseres!",
+"Your storage is almost full ({usedSpacePercent}%)" => "Lagringsplass er nesten oppbruker ([usedSpacePercent}%)",
+"Your download is being prepared. This might take some time if the files are big." => "Nedlastingen din klargjøres. Hvis filene er store kan dette ta litt tid.",
+"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Ugyldig mappenavn. Bruk av \"Shared\" er reservert av ownCloud.",
"Name" => "Navn",
"Size" => "Størrelse",
"Modified" => "Endret",
@@ -46,12 +61,20 @@
"Text file" => "Tekstfil",
"Folder" => "Mappe",
"From link" => "Fra link",
+"Deleted files" => "Slettet filer",
"Cancel upload" => "Avbryt opplasting",
+"You don’t have write permissions here." => "Du har ikke skrivetilgang her.",
"Nothing in here. Upload something!" => "Ingenting her. Last opp noe!",
"Download" => "Last ned",
+"Size (MB)" => "Størrelse (MB)",
"Unshare" => "Avslutt deling",
-"Upload too large" => "Opplasting for stor",
+"Upload too large" => "Filen er for stor",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Filene du prøver å laste opp er for store for å laste opp til denne serveren.",
"Files are being scanned, please wait." => "Skanner etter filer, vennligst vent.",
-"Current scanning" => "Pågående skanning"
+"Current scanning" => "Pågående skanning",
+"directory" => "katalog",
+"directories" => "kataloger",
+"file" => "fil",
+"files" => "filer",
+"Upgrading filesystem cache..." => "Oppgraderer filsystemets mellomlager..."
);
diff --git a/apps/files/l10n/nl.php b/apps/files/l10n/nl.php
index 6af7edf2501836bf3ba9dc6d8f7dc497af5464d0..914d5087af10a3253f02487b1b08de453dd6fd87 100644
--- a/apps/files/l10n/nl.php
+++ b/apps/files/l10n/nl.php
@@ -1,22 +1,31 @@
"Kon %s niet verplaatsen - Er bestaat al een bestand met deze naam",
"Could not move %s" => "Kon %s niet verplaatsen",
-"Unable to rename file" => "Kan bestand niet hernoemen",
+"Unable to set upload directory." => "Kan upload map niet instellen.",
+"Invalid Token" => "Ongeldig Token",
"No file was uploaded. Unknown error" => "Er was geen bestand geladen. Onbekende fout",
-"There is no error, the file uploaded with success" => "Geen fout opgetreden, bestand successvol geupload.",
+"There is no error, the file uploaded with success" => "De upload van het bestand is goedgegaan.",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Het geüploade bestand overscheidt de upload_max_filesize optie in php.ini:",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Het geüploade bestand is groter dan de MAX_FILE_SIZE richtlijn die is opgegeven in de HTML-formulier",
-"The uploaded file was only partially uploaded" => "Het bestand is slechts gedeeltelijk geupload",
-"No file was uploaded" => "Geen bestand geüpload",
-"Missing a temporary folder" => "Een tijdelijke map mist",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Het bestand overschrijdt de MAX_FILE_SIZE instelling dat is opgegeven in het HTML formulier",
+"The uploaded file was only partially uploaded" => "Het bestand is gedeeltelijk geüpload",
+"No file was uploaded" => "Er is geen bestand geüpload",
+"Missing a temporary folder" => "Er ontbreekt een tijdelijke map",
"Failed to write to disk" => "Schrijven naar schijf mislukt",
"Not enough storage available" => "Niet genoeg opslagruimte beschikbaar",
"Invalid directory." => "Ongeldige directory.",
"Files" => "Bestanden",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Het lukt niet om uw bestand te uploaded, omdat het een folder of 0 bytes is",
+"Not enough space available" => "Niet genoeg ruimte beschikbaar",
+"Upload cancelled." => "Uploaden geannuleerd.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Bestandsupload is bezig. Wanneer de pagina nu verlaten wordt, stopt de upload.",
+"URL cannot be empty." => "URL kan niet leeg zijn.",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Ongeldige mapnaam. Gebruik van 'Gedeeld' is voorbehouden aan Owncloud zelf",
+"Error" => "Fout",
+"Share" => "Delen",
"Delete permanently" => "Verwijder definitief",
"Delete" => "Verwijder",
"Rename" => "Hernoem",
-"Pending" => "Wachten",
+"Pending" => "In behandeling",
"{new_name} already exists" => "{new_name} bestaat al",
"replace" => "vervang",
"suggest name" => "Stel een naam voor",
@@ -24,29 +33,23 @@
"replaced {new_name} with {old_name}" => "verving {new_name} met {old_name}",
"undo" => "ongedaan maken",
"perform delete operation" => "uitvoeren verwijderactie",
+"1 file uploading" => "1 bestand wordt ge-upload",
+"files uploading" => "bestanden aan het uploaden",
"'.' is an invalid file name." => "'.' is een ongeldige bestandsnaam.",
"File name cannot be empty." => "Bestandsnaam kan niet leeg zijn.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Onjuiste naam; '\\', '/', '<', '>', ':', '\"', '|', '?' en '*' zijn niet toegestaan.",
"Your storage is full, files can not be updated or synced anymore!" => "Uw opslagruimte zit vol, Bestanden kunnen niet meer worden ge-upload of gesynchroniseerd!",
"Your storage is almost full ({usedSpacePercent}%)" => "Uw opslagruimte zit bijna vol ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "Uw download wordt voorbereid. Dit kan enige tijd duren bij grote bestanden.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "uploaden van de file mislukt, het is of een directory of de bestandsgrootte is 0 bytes",
-"Upload Error" => "Upload Fout",
-"Close" => "Sluit",
-"1 file uploading" => "1 bestand wordt ge-upload",
-"{count} files uploading" => "{count} bestanden aan het uploaden",
-"Upload cancelled." => "Uploaden geannuleerd.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Bestandsupload is bezig. Wanneer de pagina nu verlaten wordt, stopt de upload.",
-"URL cannot be empty." => "URL kan niet leeg zijn.",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Ongeldige mapnaam. Gebruik van'Gedeeld' is voorbehouden aan Owncloud",
"Name" => "Naam",
-"Size" => "Bestandsgrootte",
-"Modified" => "Laatst aangepast",
+"Size" => "Grootte",
+"Modified" => "Aangepast",
"1 folder" => "1 map",
"{count} folders" => "{count} mappen",
"1 file" => "1 bestand",
"{count} files" => "{count} bestanden",
-"Upload" => "Upload",
+"Upload" => "Uploaden",
"File handling" => "Bestand",
"Maximum upload size" => "Maximale bestandsgrootte voor uploads",
"max. possible: " => "max. mogelijk: ",
@@ -54,7 +57,7 @@
"Enable ZIP-download" => "Zet ZIP-download aan",
"0 is unlimited" => "0 is ongelimiteerd",
"Maximum input size for ZIP files" => "Maximale grootte voor ZIP bestanden",
-"Save" => "Opslaan",
+"Save" => "Bewaren",
"New" => "Nieuw",
"Text file" => "Tekstbestand",
"Folder" => "Map",
@@ -63,11 +66,13 @@
"Cancel upload" => "Upload afbreken",
"You don’t have write permissions here." => "U hebt hier geen schrijfpermissies.",
"Nothing in here. Upload something!" => "Er bevindt zich hier niets. Upload een bestand!",
-"Download" => "Download",
-"Unshare" => "Stop delen",
-"Upload too large" => "Bestanden te groot",
+"Download" => "Downloaden",
+"Unshare" => "Stop met delen",
+"Upload too large" => "Upload is te groot",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "De bestanden die u probeert te uploaden zijn groter dan de maximaal toegestane bestandsgrootte voor deze server.",
"Files are being scanned, please wait." => "Bestanden worden gescand, even wachten.",
"Current scanning" => "Er wordt gescand",
+"file" => "bestand",
+"files" => "bestanden",
"Upgrading filesystem cache..." => "Upgraden bestandssysteem cache..."
);
diff --git a/apps/files/l10n/nn_NO.php b/apps/files/l10n/nn_NO.php
index 8a4ab91ea7ec74d9cc21fdfad63d5545ba76d78b..dcc3373bea0510bf7d019c2e4135430566f98418 100644
--- a/apps/files/l10n/nn_NO.php
+++ b/apps/files/l10n/nn_NO.php
@@ -1,23 +1,74 @@
"Klarte ikkje flytta %s – det finst allereie ei fil med dette namnet",
+"Could not move %s" => "Klarte ikkje flytta %s",
+"No file was uploaded. Unknown error" => "Ingen filer lasta opp. Ukjend feil",
"There is no error, the file uploaded with success" => "Ingen feil, fila vart lasta opp",
+"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Fila du lasta opp er større enn det «upload_max_filesize» i php.ini tillater: ",
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Den opplasta fila er større enn variabelen MAX_FILE_SIZE i HTML-skjemaet",
"The uploaded file was only partially uploaded" => "Fila vart berre delvis lasta opp",
"No file was uploaded" => "Ingen filer vart lasta opp",
"Missing a temporary folder" => "Manglar ei mellombels mappe",
+"Failed to write to disk" => "Klarte ikkje skriva til disk",
+"Not enough storage available" => "Ikkje nok lagringsplass tilgjengeleg",
+"Invalid directory." => "Ugyldig mappe.",
"Files" => "Filer",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Klarte ikkje lasta opp fila sidan ho er ei mappe eller er på 0 byte",
+"Not enough space available" => "Ikkje nok lagringsplass tilgjengeleg",
+"Upload cancelled." => "Opplasting avbroten.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Fila lastar no opp. Viss du forlèt sida no vil opplastinga verta avbroten.",
+"URL cannot be empty." => "Nettadressa kan ikkje vera tom.",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Ugyldig mappenamn. Mappa «Shared» er reservert av ownCloud",
+"Error" => "Feil",
+"Share" => "Del",
+"Delete permanently" => "Slett for godt",
"Delete" => "Slett",
-"Close" => "Lukk",
+"Rename" => "Endra namn",
+"Pending" => "Under vegs",
+"{new_name} already exists" => "{new_name} finst allereie",
+"replace" => "byt ut",
+"suggest name" => "føreslå namn",
+"cancel" => "avbryt",
+"replaced {new_name} with {old_name}" => "bytte ut {new_name} med {old_name}",
+"undo" => "angre",
+"perform delete operation" => "utfør sletting",
+"1 file uploading" => "1 fil lastar opp",
+"files uploading" => "filer lastar opp",
+"'.' is an invalid file name." => "«.» er eit ugyldig filnamn.",
+"File name cannot be empty." => "Filnamnet kan ikkje vera tomt.",
+"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Ugyldig namn, «\\», «/», «<», «>», «:», «\"», «|», «?» og «*» er ikkje tillate.",
+"Your storage is full, files can not be updated or synced anymore!" => "Lagringa di er full, kan ikkje lenger oppdatera eller synkronisera!",
+"Your storage is almost full ({usedSpacePercent}%)" => "Lagringa di er nesten full ({usedSpacePercent} %)",
+"Your download is being prepared. This might take some time if the files are big." => "Gjer klar nedlastinga di. Dette kan ta ei stund viss filene er store.",
+"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Ugyldig mappenamn. Mappa «Shared» er reservert av ownCloud",
"Name" => "Namn",
"Size" => "Storleik",
"Modified" => "Endra",
+"1 folder" => "1 mappe",
+"{count} folders" => "{count} mapper",
+"1 file" => "1 fil",
+"{count} files" => "{count} filer",
"Upload" => "Last opp",
+"File handling" => "Filhandtering",
"Maximum upload size" => "Maksimal opplastingsstorleik",
+"max. possible: " => "maks. moglege:",
+"Needed for multi-file and folder downloads." => "Nødvendig for fleirfils- og mappenedlastingar.",
+"Enable ZIP-download" => "Slå på ZIP-nedlasting",
+"0 is unlimited" => "0 er ubegrensa",
+"Maximum input size for ZIP files" => "Maksimal storleik for ZIP-filer",
"Save" => "Lagre",
"New" => "Ny",
"Text file" => "Tekst fil",
"Folder" => "Mappe",
+"From link" => "Frå lenkje",
+"Deleted files" => "Sletta filer",
+"Cancel upload" => "Avbryt opplasting",
+"You don’t have write permissions here." => "Du har ikkje skriverettar her.",
"Nothing in here. Upload something!" => "Ingenting her. Last noko opp!",
"Download" => "Last ned",
+"Unshare" => "Udel",
"Upload too large" => "For stor opplasting",
-"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Filene du prøver å laste opp er større enn maksgrensa til denne tenaren."
+"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Filene du prøver å lasta opp er større enn maksgrensa til denne tenaren.",
+"Files are being scanned, please wait." => "Skannar filer, ver venleg og vent.",
+"Current scanning" => "Køyrande skanning",
+"Upgrading filesystem cache..." => "Oppgraderer mellomlageret av filsystemet …"
);
diff --git a/apps/files/l10n/oc.php b/apps/files/l10n/oc.php
index 7a39e9399f5c3d7e49ff2af9d07c645996d74a7c..703aeb3fbad97037fe3ff6ef68494b6638a899d9 100644
--- a/apps/files/l10n/oc.php
+++ b/apps/files/l10n/oc.php
@@ -6,6 +6,11 @@
"Missing a temporary folder" => "Un dorsièr temporari manca",
"Failed to write to disk" => "L'escriptura sul disc a fracassat",
"Files" => "Fichièrs",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Impossible d'amontcargar lo teu fichièr qu'es un repertòri o que ten pas que 0 octet.",
+"Upload cancelled." => "Amontcargar anullat.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Un amontcargar es a se far. Daissar aquesta pagina ara tamparà lo cargament. ",
+"Error" => "Error",
+"Share" => "Parteja",
"Delete" => "Escafa",
"Rename" => "Torna nomenar",
"Pending" => "Al esperar",
@@ -13,11 +18,8 @@
"suggest name" => "nom prepausat",
"cancel" => "anulla",
"undo" => "defar",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Impossible d'amontcargar lo teu fichièr qu'es un repertòri o que ten pas que 0 octet.",
-"Upload Error" => "Error d'amontcargar",
"1 file uploading" => "1 fichièr al amontcargar",
-"Upload cancelled." => "Amontcargar anullat.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Un amontcargar es a se far. Daissar aquesta pagina ara tamparà lo cargament. ",
+"files uploading" => "fichièrs al amontcargar",
"Name" => "Nom",
"Size" => "Talha",
"Modified" => "Modificat",
@@ -36,9 +38,11 @@
"Cancel upload" => " Anulla l'amontcargar",
"Nothing in here. Upload something!" => "Pas res dedins. Amontcarga qualquaren",
"Download" => "Avalcarga",
-"Unshare" => "Non parteja",
+"Unshare" => "Pas partejador",
"Upload too large" => "Amontcargament tròp gròs",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Los fichièrs que sias a amontcargar son tròp pesucs per la talha maxi pel servidor.",
"Files are being scanned, please wait." => "Los fiichièrs son a èsser explorats, ",
-"Current scanning" => "Exploracion en cors"
+"Current scanning" => "Exploracion en cors",
+"file" => "fichièr",
+"files" => "fichièrs"
);
diff --git a/apps/files/l10n/pl.php b/apps/files/l10n/pl.php
index 89eb3421291944cdec37b27f1d8506c94c08d258..a3acfea6618b65e48c6382fa8a86dc59eb506a50 100644
--- a/apps/files/l10n/pl.php
+++ b/apps/files/l10n/pl.php
@@ -1,18 +1,27 @@
"Nie można było przenieść %s - Plik o takiej nazwie już istnieje",
"Could not move %s" => "Nie można było przenieść %s",
-"Unable to rename file" => "Nie można zmienić nazwy pliku",
+"Unable to set upload directory." => "Nie można ustawić katalog wczytywania.",
+"Invalid Token" => "Nieprawidłowy Token",
"No file was uploaded. Unknown error" => "Żaden plik nie został załadowany. Nieznany błąd",
-"There is no error, the file uploaded with success" => "Przesłano plik",
+"There is no error, the file uploaded with success" => "Nie było błędów, plik wysłano poprawnie.",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Wgrany plik przekracza wartość upload_max_filesize zdefiniowaną w php.ini: ",
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Wysłany plik przekracza wielkość dyrektywy MAX_FILE_SIZE określonej w formularzu HTML",
"The uploaded file was only partially uploaded" => "Załadowany plik został wysłany tylko częściowo.",
-"No file was uploaded" => "Nie przesłano żadnego pliku",
-"Missing a temporary folder" => "Brak katalogu tymczasowego",
+"No file was uploaded" => "Nie wysłano żadnego pliku",
+"Missing a temporary folder" => "Brak folderu tymczasowego",
"Failed to write to disk" => "Błąd zapisu na dysk",
"Not enough storage available" => "Za mało dostępnego miejsca",
"Invalid directory." => "Zła ścieżka.",
"Files" => "Pliki",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Nie można wczytać pliku, ponieważ jest on katalogiem lub ma 0 bajtów",
+"Not enough space available" => "Za mało miejsca",
+"Upload cancelled." => "Wczytywanie anulowane.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Wysyłanie pliku jest w toku. Jeśli opuścisz tę stronę, wysyłanie zostanie przerwane.",
+"URL cannot be empty." => "URL nie może być pusty.",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Nieprawidłowa nazwa folderu. Wykorzystanie 'Shared' jest zarezerwowane przez ownCloud",
+"Error" => "Błąd",
+"Share" => "Udostępnij",
"Delete permanently" => "Trwale usuń",
"Delete" => "Usuń",
"Rename" => "Zmień nazwę",
@@ -24,20 +33,14 @@
"replaced {new_name} with {old_name}" => "zastąpiono {new_name} przez {old_name}",
"undo" => "cofnij",
"perform delete operation" => "wykonaj operację usunięcia",
+"1 file uploading" => "1 plik wczytywany",
+"files uploading" => "pliki wczytane",
"'.' is an invalid file name." => "„.” jest nieprawidłową nazwą pliku.",
"File name cannot be empty." => "Nazwa pliku nie może być pusta.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nieprawidłowa nazwa. Znaki '\\', '/', '<', '>', ':', '\"', '|', '?' oraz '*' są niedozwolone.",
"Your storage is full, files can not be updated or synced anymore!" => "Magazyn jest pełny. Pliki nie mogą zostać zaktualizowane lub zsynchronizowane!",
"Your storage is almost full ({usedSpacePercent}%)" => "Twój magazyn jest prawie pełny ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "Pobieranie jest przygotowywane. Może to zająć trochę czasu jeśli pliki są duże.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Nie można wczytać pliku, ponieważ jest on katalogiem lub ma 0 bajtów",
-"Upload Error" => "Błąd wczytywania",
-"Close" => "Zamknij",
-"1 file uploading" => "1 plik wczytywany",
-"{count} files uploading" => "Ilość przesyłanych plików: {count}",
-"Upload cancelled." => "Wczytywanie anulowane.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Wysyłanie pliku jest w toku. Jeśli opuścisz tę stronę, wysyłanie zostanie przerwane.",
-"URL cannot be empty." => "URL nie może być pusty.",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Nieprawidłowa nazwa folderu. Korzystanie z nazwy „Shared” jest zarezerwowane dla ownCloud",
"Name" => "Nazwa",
"Size" => "Rozmiar",
@@ -46,7 +49,8 @@
"{count} folders" => "Ilość folderów: {count}",
"1 file" => "1 plik",
"{count} files" => "Ilość plików: {count}",
-"Upload" => "Prześlij",
+"%s could not be renamed" => "%s nie można zmienić nazwy",
+"Upload" => "Wyślij",
"File handling" => "Zarządzanie plikami",
"Maximum upload size" => "Maksymalny rozmiar wysyłanego pliku",
"max. possible: " => "maks. możliwy:",
@@ -57,17 +61,21 @@
"Save" => "Zapisz",
"New" => "Nowy",
"Text file" => "Plik tekstowy",
-"Folder" => "Katalog",
+"Folder" => "Folder",
"From link" => "Z odnośnika",
"Deleted files" => "Pliki usunięte",
"Cancel upload" => "Anuluj wysyłanie",
"You don’t have write permissions here." => "Nie masz uprawnień do zapisu w tym miejscu.",
"Nothing in here. Upload something!" => "Pusto. Wyślij coś!",
"Download" => "Pobierz",
-"Unshare" => "Nie udostępniaj",
-"Upload too large" => "Wysyłany plik ma za duży rozmiar",
+"Unshare" => "Zatrzymaj współdzielenie",
+"Upload too large" => "Ładowany plik jest za duży",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Pliki, które próbujesz przesłać, przekraczają maksymalną dopuszczalną wielkość.",
"Files are being scanned, please wait." => "Skanowanie plików, proszę czekać.",
"Current scanning" => "Aktualnie skanowane",
+"directory" => "Katalog",
+"directories" => "Katalogi",
+"file" => "plik",
+"files" => "pliki",
"Upgrading filesystem cache..." => "Uaktualnianie plików pamięci podręcznej..."
);
diff --git a/apps/files/l10n/pt_BR.php b/apps/files/l10n/pt_BR.php
index 3bebb68227113e7e01b39f667e072fd70608fdac..a1e06483b688164b9311400afcdc5f834de5f05a 100644
--- a/apps/files/l10n/pt_BR.php
+++ b/apps/files/l10n/pt_BR.php
@@ -1,18 +1,27 @@
"Impossível mover %s - Um arquivo com este nome já existe",
"Could not move %s" => "Impossível mover %s",
-"Unable to rename file" => "Impossível renomear arquivo",
+"Unable to set upload directory." => "Impossível configurar o diretório de upload",
+"Invalid Token" => "Token inválido",
"No file was uploaded. Unknown error" => "Nenhum arquivo foi enviado. Erro desconhecido",
-"There is no error, the file uploaded with success" => "Não houve nenhum erro, o arquivo foi transferido com sucesso",
+"There is no error, the file uploaded with success" => "Sem erros, o arquivo foi enviado com sucesso",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "O arquivo enviado excede a diretiva upload_max_filesize no php.ini: ",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "O arquivo carregado excede o MAX_FILE_SIZE que foi especificado no formulário HTML",
-"The uploaded file was only partially uploaded" => "O arquivo foi transferido parcialmente",
-"No file was uploaded" => "Nenhum arquivo foi transferido",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "O arquivo carregado excede o argumento MAX_FILE_SIZE especificado no formulário HTML",
+"The uploaded file was only partially uploaded" => "O arquivo foi parcialmente enviado",
+"No file was uploaded" => "Nenhum arquivo enviado",
"Missing a temporary folder" => "Pasta temporária não encontrada",
"Failed to write to disk" => "Falha ao escrever no disco",
"Not enough storage available" => "Espaço de armazenamento insuficiente",
"Invalid directory." => "Diretório inválido.",
"Files" => "Arquivos",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Impossível enviar seus arquivo por ele ser um diretório ou ter 0 bytes.",
+"Not enough space available" => "Espaço de armazenamento insuficiente",
+"Upload cancelled." => "Envio cancelado.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Upload em andamento. Sair da página agora resultará no cancelamento do envio.",
+"URL cannot be empty." => "URL não pode ficar em branco",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Nome de pasta inválido. O uso do nome 'Compartilhado' é reservado ao ownCloud",
+"Error" => "Erro",
+"Share" => "Compartilhar",
"Delete permanently" => "Excluir permanentemente",
"Delete" => "Excluir",
"Rename" => "Renomear",
@@ -24,20 +33,14 @@
"replaced {new_name} with {old_name}" => "Substituído {old_name} por {new_name} ",
"undo" => "desfazer",
"perform delete operation" => "realizar operação de exclusão",
+"1 file uploading" => "enviando 1 arquivo",
+"files uploading" => "enviando arquivos",
"'.' is an invalid file name." => "'.' é um nome de arquivo inválido.",
"File name cannot be empty." => "O nome do arquivo não pode estar vazio.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nome inválido, '\\', '/', '<', '>', ':', '\"', '|', '?' e '*' não são permitidos.",
"Your storage is full, files can not be updated or synced anymore!" => "Seu armazenamento está cheio, arquivos não podem mais ser atualizados ou sincronizados!",
"Your storage is almost full ({usedSpacePercent}%)" => "Seu armazenamento está quase cheio ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "Seu download está sendo preparado. Isto pode levar algum tempo se os arquivos forem grandes.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Impossível enviar seus arquivo por ele ser um diretório ou ter 0 bytes.",
-"Upload Error" => "Erro de envio",
-"Close" => "Fechar",
-"1 file uploading" => "enviando 1 arquivo",
-"{count} files uploading" => "Enviando {count} arquivos",
-"Upload cancelled." => "Envio cancelado.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Upload em andamento. Sair da página agora resultará no cancelamento do envio.",
-"URL cannot be empty." => "URL não pode ficar em branco",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Nome de pasta inválido. O uso de 'Shared' é reservado para o Owncloud",
"Name" => "Nome",
"Size" => "Tamanho",
@@ -46,7 +49,8 @@
"{count} folders" => "{count} pastas",
"1 file" => "1 arquivo",
"{count} files" => "{count} arquivos",
-"Upload" => "Carregar",
+"%s could not be renamed" => "%s não pode ser renomeado",
+"Upload" => "Upload",
"File handling" => "Tratamento de Arquivo",
"Maximum upload size" => "Tamanho máximo para carregar",
"max. possible: " => "max. possível:",
@@ -54,7 +58,7 @@
"Enable ZIP-download" => "Habilitar ZIP-download",
"0 is unlimited" => "0 para ilimitado",
"Maximum input size for ZIP files" => "Tamanho máximo para arquivo ZIP",
-"Save" => "Salvar",
+"Save" => "Guardar",
"New" => "Novo",
"Text file" => "Arquivo texto",
"Folder" => "Pasta",
@@ -64,10 +68,15 @@
"You don’t have write permissions here." => "Você não possui permissão de escrita aqui.",
"Nothing in here. Upload something!" => "Nada aqui.Carrege alguma coisa!",
"Download" => "Baixar",
+"Size (MB)" => "Tamanho (MB)",
"Unshare" => "Descompartilhar",
-"Upload too large" => "Arquivo muito grande",
+"Upload too large" => "Upload muito grande",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Os arquivos que você está tentando carregar excedeu o tamanho máximo para arquivos no servidor.",
"Files are being scanned, please wait." => "Arquivos sendo escaneados, por favor aguarde.",
"Current scanning" => "Scanning atual",
+"directory" => "diretório",
+"directories" => "diretórios",
+"file" => "arquivo",
+"files" => "arquivos",
"Upgrading filesystem cache..." => "Atualizando cache do sistema de arquivos..."
);
diff --git a/apps/files/l10n/pt_PT.php b/apps/files/l10n/pt_PT.php
index 7162517e8162dcff122399c849521733ad5a79b1..4273de9c47841f374dc61ee79cbdd48b6f5dcde6 100644
--- a/apps/files/l10n/pt_PT.php
+++ b/apps/files/l10n/pt_PT.php
@@ -1,20 +1,27 @@
"Não foi possível mover o ficheiro %s - Já existe um ficheiro com esse nome",
"Could not move %s" => "Não foi possível move o ficheiro %s",
-"Unable to rename file" => "Não foi possível renomear o ficheiro",
"No file was uploaded. Unknown error" => "Nenhum ficheiro foi carregado. Erro desconhecido",
-"There is no error, the file uploaded with success" => "Sem erro, ficheiro enviado com sucesso",
+"There is no error, the file uploaded with success" => "Não ocorreram erros, o ficheiro foi submetido com sucesso",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "O ficheiro enviado excede o limite permitido na directiva do php.ini upload_max_filesize",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "O ficheiro enviado excede o diretivo MAX_FILE_SIZE especificado no formulário HTML",
-"The uploaded file was only partially uploaded" => "O ficheiro enviado só foi enviado parcialmente",
-"No file was uploaded" => "Não foi enviado nenhum ficheiro",
-"Missing a temporary folder" => "Falta uma pasta temporária",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "O tamanho do ficheiro carregado ultrapassa o valor MAX_FILE_SIZE definido no formulário HTML",
+"The uploaded file was only partially uploaded" => "O ficheiro seleccionado foi apenas carregado parcialmente",
+"No file was uploaded" => "Nenhum ficheiro foi submetido",
+"Missing a temporary folder" => "Está a faltar a pasta temporária",
"Failed to write to disk" => "Falhou a escrita no disco",
"Not enough storage available" => "Não há espaço suficiente em disco",
"Invalid directory." => "Directório Inválido",
"Files" => "Ficheiros",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Não é possível fazer o envio do ficheiro devido a ser uma pasta ou ter 0 bytes",
+"Not enough space available" => "Espaço em disco insuficiente!",
+"Upload cancelled." => "Envio cancelado.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Envio de ficheiro em progresso. Irá cancelar o envio se sair da página agora.",
+"URL cannot be empty." => "O URL não pode estar vazio.",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Nome da pasta inválido. Palavra 'Shared' é reservado pela ownCloud",
+"Error" => "Erro",
+"Share" => "Partilhar",
"Delete permanently" => "Eliminar permanentemente",
-"Delete" => "Apagar",
+"Delete" => "Eliminar",
"Rename" => "Renomear",
"Pending" => "Pendente",
"{new_name} already exists" => "O nome {new_name} já existe",
@@ -24,20 +31,14 @@
"replaced {new_name} with {old_name}" => "substituido {new_name} por {old_name}",
"undo" => "desfazer",
"perform delete operation" => "Executar a tarefa de apagar",
+"1 file uploading" => "A enviar 1 ficheiro",
+"files uploading" => "A enviar os ficheiros",
"'.' is an invalid file name." => "'.' não é um nome de ficheiro válido!",
"File name cannot be empty." => "O nome do ficheiro não pode estar vazio.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nome Inválido, os caracteres '\\', '/', '<', '>', ':', '\"', '|', '?' e '*' não são permitidos.",
"Your storage is full, files can not be updated or synced anymore!" => "O seu armazenamento está cheio, os ficheiros não podem ser sincronizados.",
"Your storage is almost full ({usedSpacePercent}%)" => "O seu espaço de armazenamento está quase cheiro ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "O seu download está a ser preparado. Este processo pode demorar algum tempo se os ficheiros forem grandes.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Não é possível fazer o envio do ficheiro devido a ser uma pasta ou ter 0 bytes",
-"Upload Error" => "Erro no envio",
-"Close" => "Fechar",
-"1 file uploading" => "A enviar 1 ficheiro",
-"{count} files uploading" => "A carregar {count} ficheiros",
-"Upload cancelled." => "Envio cancelado.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Envio de ficheiro em progresso. Irá cancelar o envio se sair da página agora.",
-"URL cannot be empty." => "O URL não pode estar vazio.",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Nome de pasta inválido. O Uso de 'shared' é reservado para o ownCloud",
"Name" => "Nome",
"Size" => "Tamanho",
@@ -46,11 +47,11 @@
"{count} folders" => "{count} pastas",
"1 file" => "1 ficheiro",
"{count} files" => "{count} ficheiros",
-"Upload" => "Enviar",
+"Upload" => "Carregar",
"File handling" => "Manuseamento de ficheiros",
"Maximum upload size" => "Tamanho máximo de envio",
"max. possible: " => "max. possivel: ",
-"Needed for multi-file and folder downloads." => "Necessário para descarregamento múltiplo de ficheiros e pastas",
+"Needed for multi-file and folder downloads." => "Necessário para multi download de ficheiros e pastas",
"Enable ZIP-download" => "Permitir descarregar em ficheiro ZIP",
"0 is unlimited" => "0 é ilimitado",
"Maximum input size for ZIP files" => "Tamanho máximo para ficheiros ZIP",
@@ -65,9 +66,11 @@
"Nothing in here. Upload something!" => "Vazio. Envie alguma coisa!",
"Download" => "Transferir",
"Unshare" => "Deixar de partilhar",
-"Upload too large" => "Envio muito grande",
-"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Os ficheiros que está a tentar enviar excedem o tamanho máximo de envio permitido neste servidor.",
+"Upload too large" => "Upload muito grande",
+"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Os ficheiro que está a tentar enviar excedem o tamanho máximo de envio neste servidor.",
"Files are being scanned, please wait." => "Os ficheiros estão a ser analisados, por favor aguarde.",
"Current scanning" => "Análise actual",
+"file" => "ficheiro",
+"files" => "ficheiros",
"Upgrading filesystem cache..." => "Atualizar cache do sistema de ficheiros..."
);
diff --git a/apps/files/l10n/ro.php b/apps/files/l10n/ro.php
index 153caba2291e8938db91e0e8d0f3316f993df763..b0cca7d7a8289cc10d0dd2368398c5977fc479b0 100644
--- a/apps/files/l10n/ro.php
+++ b/apps/files/l10n/ro.php
@@ -1,17 +1,28 @@
"Nu se poate de mutat %s - Fișier cu acest nume deja există",
+"Could not move %s - File with this name already exists" => "%s nu se poate muta - Fișierul cu acest nume există deja ",
"Could not move %s" => "Nu s-a putut muta %s",
-"Unable to rename file" => "Nu s-a putut redenumi fișierul",
+"Unable to set upload directory." => "Imposibil de a seta directorul pentru incărcare.",
+"Invalid Token" => "Jeton Invalid",
"No file was uploaded. Unknown error" => "Nici un fișier nu a fost încărcat. Eroare necunoscută",
-"There is no error, the file uploaded with success" => "Nicio eroare, fișierul a fost încărcat cu succes",
+"There is no error, the file uploaded with success" => "Nu a apărut nici o eroare, fișierul a fost încărcat cu succes",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Fisierul incarcat depaseste upload_max_filesize permisi in php.ini: ",
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Fișierul are o dimensiune mai mare decât variabile MAX_FILE_SIZE specificată în formularul HTML",
"The uploaded file was only partially uploaded" => "Fișierul a fost încărcat doar parțial",
-"No file was uploaded" => "Niciun fișier încărcat",
-"Missing a temporary folder" => "Lipsește un dosar temporar",
+"No file was uploaded" => "Nu a fost încărcat nici un fișier",
+"Missing a temporary folder" => "Lipsește un director temporar",
"Failed to write to disk" => "Eroare la scriere pe disc",
+"Not enough storage available" => "Nu este suficient spațiu disponibil",
"Invalid directory." => "Director invalid.",
"Files" => "Fișiere",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Nu s-a putut încărca fișierul tău deoarece pare să fie un director sau are 0 bytes.",
+"Not enough space available" => "Nu este suficient spațiu disponibil",
+"Upload cancelled." => "Încărcare anulată.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Fișierul este în curs de încărcare. Părăsirea paginii va întrerupe încărcarea.",
+"URL cannot be empty." => "Adresa URL nu poate fi goală.",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Nume de dosar invalid. Utilizarea 'Shared' e rezervată de ownCloud",
+"Error" => "Eroare",
+"Share" => "Partajează",
+"Delete permanently" => "Stergere permanenta",
"Delete" => "Șterge",
"Rename" => "Redenumire",
"Pending" => "În așteptare",
@@ -21,18 +32,15 @@
"cancel" => "anulare",
"replaced {new_name} with {old_name}" => "{new_name} inlocuit cu {old_name}",
"undo" => "Anulează ultima acțiune",
+"perform delete operation" => "efectueaza operatiunea de stergere",
+"1 file uploading" => "un fișier se încarcă",
+"files uploading" => "fișiere se încarcă",
"'.' is an invalid file name." => "'.' este un nume invalid de fișier.",
"File name cannot be empty." => "Numele fișierului nu poate rămâne gol.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nume invalid, '\\', '/', '<', '>', ':', '\"', '|', '?' si '*' nu sunt permise.",
+"Your storage is full, files can not be updated or synced anymore!" => "Spatiul de stocare este plin, nu mai puteti incarca s-au sincroniza alte fisiere.",
+"Your storage is almost full ({usedSpacePercent}%)" => "Spatiul de stocare este aproape plin ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "Se pregătește descărcarea. Aceasta poate să dureze ceva timp dacă fișierele sunt mari.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Nu s-a putut încărca fișierul tău deoarece pare să fie un director sau are 0 bytes.",
-"Upload Error" => "Eroare la încărcare",
-"Close" => "Închide",
-"1 file uploading" => "un fișier se încarcă",
-"{count} files uploading" => "{count} fisiere incarcate",
-"Upload cancelled." => "Încărcare anulată.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Fișierul este în curs de încărcare. Părăsirea paginii va întrerupe încărcarea.",
-"URL cannot be empty." => "Adresa URL nu poate fi goală.",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Invalid folder name. Usage of 'Shared' is reserved by Ownclou",
"Name" => "Nume",
"Size" => "Dimensiune",
@@ -41,7 +49,8 @@
"{count} folders" => "{count} foldare",
"1 file" => "1 fisier",
"{count} files" => "{count} fisiere",
-"Upload" => "Încarcă",
+"%s could not be renamed" => "%s nu a putut fi redenumit",
+"Upload" => "Încărcare",
"File handling" => "Manipulare fișiere",
"Maximum upload size" => "Dimensiune maximă admisă la încărcare",
"max. possible: " => "max. posibil:",
@@ -49,17 +58,24 @@
"Enable ZIP-download" => "Activează descărcare fișiere compresate",
"0 is unlimited" => "0 e nelimitat",
"Maximum input size for ZIP files" => "Dimensiunea maximă de intrare pentru fișiere compresate",
-"Save" => "Salvare",
+"Save" => "Salvează",
"New" => "Nou",
"Text file" => "Fișier text",
"Folder" => "Dosar",
"From link" => "de la adresa",
+"Deleted files" => "Sterge fisierele",
"Cancel upload" => "Anulează încărcarea",
+"You don’t have write permissions here." => "Nu ai permisiunea de a sterge fisiere aici.",
"Nothing in here. Upload something!" => "Nimic aici. Încarcă ceva!",
"Download" => "Descarcă",
-"Unshare" => "Anulează partajarea",
+"Unshare" => "Anulare partajare",
"Upload too large" => "Fișierul încărcat este prea mare",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Fișierul care l-ai încărcat a depășită limita maximă admisă la încărcare pe acest server.",
"Files are being scanned, please wait." => "Fișierele sunt scanate, te rog așteptă.",
-"Current scanning" => "În curs de scanare"
+"Current scanning" => "În curs de scanare",
+"directory" => "catalog",
+"directories" => "cataloage",
+"file" => "fișier",
+"files" => "fișiere",
+"Upgrading filesystem cache..." => "Modernizare fisiere de sistem cache.."
);
diff --git a/apps/files/l10n/ru.php b/apps/files/l10n/ru.php
index cf8ee7c6c75693c0bda14776b6f5372b6af9533c..225de32d62ea38c56cd404daea5824d1a9af51a4 100644
--- a/apps/files/l10n/ru.php
+++ b/apps/files/l10n/ru.php
@@ -1,18 +1,27 @@
"Невозможно переместить %s - файл с таким именем уже существует",
"Could not move %s" => "Невозможно переместить %s",
-"Unable to rename file" => "Невозможно переименовать файл",
+"Unable to set upload directory." => "Не удалось установить каталог загрузки.",
+"Invalid Token" => "Недопустимый маркер",
"No file was uploaded. Unknown error" => "Файл не был загружен. Неизвестная ошибка",
-"There is no error, the file uploaded with success" => "Файл успешно загружен",
+"There is no error, the file uploaded with success" => "Файл загружен успешно.",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Файл превышает размер установленный upload_max_filesize в php.ini:",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Файл превышает размер MAX_FILE_SIZE, указаный в HTML-форме",
-"The uploaded file was only partially uploaded" => "Файл был загружен не полностью",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Загружаемый файл превосходит значение переменной MAX_FILE_SIZE, указанной в форме HTML",
+"The uploaded file was only partially uploaded" => "Файл загружен частично",
"No file was uploaded" => "Файл не был загружен",
-"Missing a temporary folder" => "Невозможно найти временную папку",
+"Missing a temporary folder" => "Отсутствует временная папка",
"Failed to write to disk" => "Ошибка записи на диск",
"Not enough storage available" => "Недостаточно доступного места в хранилище",
"Invalid directory." => "Неправильный каталог.",
"Files" => "Файлы",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Файл не был загружен: его размер 0 байт либо это не файл, а директория.",
+"Not enough space available" => "Недостаточно свободного места",
+"Upload cancelled." => "Загрузка отменена.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Файл в процессе загрузки. Покинув страницу вы прервёте загрузку.",
+"URL cannot be empty." => "Ссылка не может быть пустой.",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Неправильное имя каталога. Имя 'Shared' зарезервировано.",
+"Error" => "Ошибка",
+"Share" => "Открыть доступ",
"Delete permanently" => "Удалено навсегда",
"Delete" => "Удалить",
"Rename" => "Переименовать",
@@ -23,30 +32,25 @@
"cancel" => "отмена",
"replaced {new_name} with {old_name}" => "заменено {new_name} на {old_name}",
"undo" => "отмена",
-"perform delete operation" => "выполняется операция удаления",
+"perform delete operation" => "выполнить операцию удаления",
+"1 file uploading" => "загружается 1 файл",
+"files uploading" => "файлы загружаются",
"'.' is an invalid file name." => "'.' - неправильное имя файла.",
"File name cannot be empty." => "Имя файла не может быть пустым.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Неправильное имя, '\\', '/', '<', '>', ':', '\"', '|', '?' и '*' недопустимы.",
"Your storage is full, files can not be updated or synced anymore!" => "Ваше дисковое пространство полностью заполнено, произведите очистку перед загрузкой новых файлов.",
"Your storage is almost full ({usedSpacePercent}%)" => "Ваше хранилище почти заполнено ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "Загрузка началась. Это может потребовать много времени, если файл большого размера.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Не удается загрузить файл размером 0 байт в каталог",
-"Upload Error" => "Ошибка загрузки",
-"Close" => "Закрыть",
-"1 file uploading" => "загружается 1 файл",
-"{count} files uploading" => "{count} файлов загружается",
-"Upload cancelled." => "Загрузка отменена.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Файл в процессе загрузки. Покинув страницу вы прервёте загрузку.",
-"URL cannot be empty." => "Ссылка не может быть пустой.",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Неправильное имя каталога. Имя 'Shared' зарезервировано.",
-"Name" => "Название",
+"Name" => "Имя",
"Size" => "Размер",
"Modified" => "Изменён",
"1 folder" => "1 папка",
"{count} folders" => "{count} папок",
"1 file" => "1 файл",
"{count} files" => "{count} файлов",
-"Upload" => "Загрузить",
+"%s could not be renamed" => "%s не может быть переименован",
+"Upload" => "Загрузка",
"File handling" => "Управление файлами",
"Maximum upload size" => "Максимальный размер загружаемого файла",
"max. possible: " => "макс. возможно: ",
@@ -64,10 +68,15 @@
"You don’t have write permissions here." => "У вас нет разрешений на запись здесь.",
"Nothing in here. Upload something!" => "Здесь ничего нет. Загрузите что-нибудь!",
"Download" => "Скачать",
-"Unshare" => "Отменить публикацию",
-"Upload too large" => "Файл слишком большой",
-"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Файлы, которые Вы пытаетесь загрузить, превышают лимит для файлов на этом сервере.",
+"Size (MB)" => "Размер (Мб)",
+"Unshare" => "Закрыть общий доступ",
+"Upload too large" => "Файл слишком велик",
+"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Файлы, которые вы пытаетесь загрузить, превышают лимит для файлов на этом сервере.",
"Files are being scanned, please wait." => "Подождите, файлы сканируются.",
"Current scanning" => "Текущее сканирование",
-"Upgrading filesystem cache..." => "Обновление кеша файловой системы..."
+"directory" => "директория",
+"directories" => "директории",
+"file" => "файл",
+"files" => "файлы",
+"Upgrading filesystem cache..." => "Обновление кэша файловой системы..."
);
diff --git a/apps/files/l10n/ru_RU.php b/apps/files/l10n/ru_RU.php
index 054ed8094db1b6d74d861565689a47aa736dc615..e0bfab33215ff8036017e3b024630f40c148fe63 100644
--- a/apps/files/l10n/ru_RU.php
+++ b/apps/files/l10n/ru_RU.php
@@ -1,71 +1,16 @@
"Неполучается перенести %s - Файл с таким именем уже существует",
-"Could not move %s" => "Неполучается перенести %s ",
-"Unable to rename file" => "Невозможно переименовать файл",
"No file was uploaded. Unknown error" => "Файл не был загружен. Неизвестная ошибка",
-"There is no error, the file uploaded with success" => "Ошибка отсутствует, файл загружен успешно.",
-"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Размер загружаемого файла превышает upload_max_filesize директиву в php.ini:",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Размер загруженного",
-"The uploaded file was only partially uploaded" => "Загружаемый файл был загружен частично",
+"There is no error, the file uploaded with success" => "Ошибки нет, файл успешно загружен",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Размер загружаемого файла превысил максимально допустимый в директиве MAX_FILE_SIZE, специфицированной в HTML-форме",
+"The uploaded file was only partially uploaded" => "Загружаемый файл был загружен лишь частично",
"No file was uploaded" => "Файл не был загружен",
-"Missing a temporary folder" => "Отсутствует временная папка",
+"Missing a temporary folder" => "Отсутствие временной папки",
"Failed to write to disk" => "Не удалось записать на диск",
"Not enough storage available" => "Недостаточно места в хранилище",
-"Invalid directory." => "Неверный каталог.",
-"Files" => "Файлы",
-"Delete permanently" => "Удалить навсегда",
+"Share" => "Сделать общим",
"Delete" => "Удалить",
-"Rename" => "Переименовать",
-"Pending" => "Ожидающий решения",
-"{new_name} already exists" => "{новое_имя} уже существует",
-"replace" => "отмена",
-"suggest name" => "подобрать название",
-"cancel" => "отменить",
-"replaced {new_name} with {old_name}" => "заменено {новое_имя} с {старое_имя}",
-"undo" => "отменить действие",
-"perform delete operation" => "выполняется процесс удаления",
-"'.' is an invalid file name." => "'.' является неверным именем файла.",
-"File name cannot be empty." => "Имя файла не может быть пустым.",
-"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Некорректное имя, '\\', '/', '<', '>', ':', '\"', '|', '?' и '*' не допустимы.",
-"Your storage is full, files can not be updated or synced anymore!" => "Ваше хранилище переполнено, фалы больше не могут быть обновлены или синхронизированы!",
-"Your storage is almost full ({usedSpacePercent}%)" => "Ваше хранилище почти полно ({usedSpacePercent}%)",
-"Your download is being prepared. This might take some time if the files are big." => "Идёт подготовка к скачке Вашего файла. Это может занять некоторое время, если фалы большие.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Невозможно загрузить файл,\n так как он имеет нулевой размер или является директорией",
-"Upload Error" => "Ошибка загрузки",
-"Close" => "Закрыть",
-"1 file uploading" => "загрузка 1 файла",
-"{count} files uploading" => "{количество} загружено файлов",
-"Upload cancelled." => "Загрузка отменена",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Процесс загрузки файла. Если покинуть страницу сейчас, загрузка будет отменена.",
-"URL cannot be empty." => "URL не должен быть пустым.",
-"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Неверное имя папки. Использование наименования 'Опубликовано' зарезервировано Owncloud",
+"Error" => "Ошибка",
"Name" => "Имя",
-"Size" => "Размер",
-"Modified" => "Изменен",
-"1 folder" => "1 папка",
-"{count} folders" => "{количество} папок",
-"1 file" => "1 файл",
-"{count} files" => "{количество} файлов",
-"Upload" => "Загрузить ",
-"File handling" => "Работа с файлами",
-"Maximum upload size" => "Максимальный размер загружаемого файла",
-"max. possible: " => "Максимально возможный",
-"Needed for multi-file and folder downloads." => "Необходимо для множественной загрузки.",
-"Enable ZIP-download" => "Включение ZIP-загрузки",
-"0 is unlimited" => "0 без ограничений",
-"Maximum input size for ZIP files" => "Максимальный размер входящих ZIP-файлов ",
"Save" => "Сохранить",
-"New" => "Новый",
-"Text file" => "Текстовый файл",
-"Folder" => "Папка",
-"From link" => "По ссылке",
-"Cancel upload" => "Отмена загрузки",
-"Nothing in here. Upload something!" => "Здесь ничего нет. Загрузите что-нибудь!",
-"Download" => "Загрузить",
-"Unshare" => "Скрыть",
-"Upload too large" => "Загрузка слишком велика",
-"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Размер файлов, которые Вы пытаетесь загрузить, превышает максимально допустимый размер для загрузки на данный сервер.",
-"Files are being scanned, please wait." => "Файлы сканируются, пожалуйста, подождите.",
-"Current scanning" => "Текущее сканирование",
-"Upgrading filesystem cache..." => "Обновление кэша файловой системы... "
+"Download" => "Загрузка"
);
diff --git a/apps/files/l10n/si_LK.php b/apps/files/l10n/si_LK.php
index de2b89068451e83d9833f7ec8494fea9b853bb54..82fca4bc75d6e720b0749b4869054daca096e79f 100644
--- a/apps/files/l10n/si_LK.php
+++ b/apps/files/l10n/si_LK.php
@@ -1,30 +1,30 @@
"ගොනුවක් උඩුගත නොවුනි. නොහැඳිනු දෝෂයක්",
-"There is no error, the file uploaded with success" => "නිවැරදි ව ගොනුව උඩුගත කෙරිනි",
+"There is no error, the file uploaded with success" => "දෝෂයක් නොමැත. සාර්ථකව ගොනුව උඩුගත කෙරුණි",
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "උඩුගත කළ ගොනුවේ විශාලත්වය HTML පෝරමයේ නියම කළ ඇති MAX_FILE_SIZE විශාලත්වයට වඩා වැඩිය",
"The uploaded file was only partially uploaded" => "උඩුගත කළ ගොනුවේ කොටසක් පමණක් උඩුගත විය",
-"No file was uploaded" => "කිසිදු ගොනවක් උඩුගත නොවිනි",
-"Missing a temporary folder" => "තාවකාලික ෆොල්ඩරයක් සොයාගත නොහැක",
+"No file was uploaded" => "ගොනුවක් උඩුගත නොවුණි",
+"Missing a temporary folder" => "තාවකාලික ෆොල්ඩරයක් අතුරුදහන්",
"Failed to write to disk" => "තැටිගත කිරීම අසාර්ථකයි",
"Files" => "ගොනු",
-"Delete" => "මකන්න",
+"Upload cancelled." => "උඩුගත කිරීම අත් හරින්න ලදී",
+"File upload is in progress. Leaving the page now will cancel the upload." => "උඩුගතකිරීමක් සිදුවේ. පිටුව හැර යාමෙන් එය නැවතෙනු ඇත",
+"URL cannot be empty." => "යොමුව හිස් විය නොහැක",
+"Error" => "දෝෂයක්",
+"Share" => "බෙදා හදා ගන්න",
+"Delete" => "මකා දමන්න",
"Rename" => "නැවත නම් කරන්න",
"replace" => "ප්රතිස්ථාපනය කරන්න",
"suggest name" => "නමක් යෝජනා කරන්න",
"cancel" => "අත් හරින්න",
"undo" => "නිෂ්ප්රභ කරන්න",
-"Upload Error" => "උඩුගත කිරීමේ දෝශයක්",
-"Close" => "වසන්න",
"1 file uploading" => "1 ගොනුවක් උඩගත කෙරේ",
-"Upload cancelled." => "උඩුගත කිරීම අත් හරින්න ලදී",
-"File upload is in progress. Leaving the page now will cancel the upload." => "උඩුගතකිරීමක් සිදුවේ. පිටුව හැර යාමෙන් එය නැවතෙනු ඇත",
-"URL cannot be empty." => "යොමුව හිස් විය නොහැක",
"Name" => "නම",
"Size" => "ප්රමාණය",
"Modified" => "වෙනස් කළ",
"1 folder" => "1 ෆොල්ඩරයක්",
"1 file" => "1 ගොනුවක්",
-"Upload" => "උඩුගත කිරීම",
+"Upload" => "උඩුගත කරන්න",
"File handling" => "ගොනු පරිහරණය",
"Maximum upload size" => "උඩුගත කිරීමක උපරිම ප්රමාණය",
"max. possible: " => "හැකි උපරිමය:",
@@ -39,10 +39,12 @@
"From link" => "යොමුවෙන්",
"Cancel upload" => "උඩුගත කිරීම අත් හරින්න",
"Nothing in here. Upload something!" => "මෙහි කිසිවක් නොමැත. යමක් උඩුගත කරන්න",
-"Download" => "බාගත කිරීම",
+"Download" => "බාන්න",
"Unshare" => "නොබෙදු",
"Upload too large" => "උඩුගත කිරීම විශාල වැඩිය",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "ඔබ උඩුගත කිරීමට තැත් කරන ගොනු මෙම සේවාදායකයා උඩුගත කිරීමට ඉඩදී ඇති උපරිම ගොනු විශාලත්වයට වඩා වැඩිය",
"Files are being scanned, please wait." => "ගොනු පරික්ෂා කෙරේ. මඳක් රැඳී සිටින්න",
-"Current scanning" => "වර්තමාන පරික්ෂාව"
+"Current scanning" => "වර්තමාන පරික්ෂාව",
+"file" => "ගොනුව",
+"files" => "ගොනු"
);
diff --git a/apps/files/l10n/sk_SK.php b/apps/files/l10n/sk_SK.php
index a6cb2909111d3e9183acae000e50453492db5e89..ac71f30e9078d51c55693ac46ab10069b0b2cf6b 100644
--- a/apps/files/l10n/sk_SK.php
+++ b/apps/files/l10n/sk_SK.php
@@ -1,22 +1,31 @@
"Nie je možné presunúť %s - súbor s týmto menom už existuje",
"Could not move %s" => "Nie je možné presunúť %s",
-"Unable to rename file" => "Nemožno premenovať súbor",
+"Unable to set upload directory." => "Nemožno nastaviť priečinok pre nahrané súbory.",
+"Invalid Token" => "Neplatný token",
"No file was uploaded. Unknown error" => "Žiaden súbor nebol odoslaný. Neznáma chyba",
"There is no error, the file uploaded with success" => "Nenastala žiadna chyba, súbor bol úspešne nahraný",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Nahraný súbor predčil konfiguračnú direktívu upload_max_filesize v súbore php.ini:",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Nahrávaný súbor presiahol MAX_FILE_SIZE direktívu, ktorá bola špecifikovaná v HTML formulári",
-"The uploaded file was only partially uploaded" => "Nahrávaný súbor bol iba čiastočne nahraný",
-"No file was uploaded" => "Žiaden súbor nebol nahraný",
-"Missing a temporary folder" => "Chýbajúci dočasný priečinok",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Ukladaný súbor prekračuje nastavenie MAX_FILE_SIZE z volieb HTML formulára.",
+"The uploaded file was only partially uploaded" => "Ukladaný súbor sa nahral len čiastočne",
+"No file was uploaded" => "Žiadny súbor nebol uložený",
+"Missing a temporary folder" => "Chýba dočasný priečinok",
"Failed to write to disk" => "Zápis na disk sa nepodaril",
"Not enough storage available" => "Nedostatok dostupného úložného priestoru",
-"Invalid directory." => "Neplatný priečinok",
+"Invalid directory." => "Neplatný priečinok.",
"Files" => "Súbory",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Nedá sa odoslať Váš súbor, pretože je to priečinok, alebo je jeho veľkosť 0 bajtov",
+"Not enough space available" => "Nie je k dispozícii dostatok miesta",
+"Upload cancelled." => "Odosielanie zrušené.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Opustenie stránky zruší práve prebiehajúce odosielanie súboru.",
+"URL cannot be empty." => "URL nemôže byť prázdne.",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Neplatný názov priečinka. Názov \"Shared\" je rezervovaný pre ownCloud",
+"Error" => "Chyba",
+"Share" => "Zdieľať",
"Delete permanently" => "Zmazať trvalo",
-"Delete" => "Odstrániť",
+"Delete" => "Zmazať",
"Rename" => "Premenovať",
-"Pending" => "Čaká sa",
+"Pending" => "Prebieha",
"{new_name} already exists" => "{new_name} už existuje",
"replace" => "nahradiť",
"suggest name" => "pomôcť s menom",
@@ -24,28 +33,23 @@
"replaced {new_name} with {old_name}" => "prepísaný {new_name} súborom {old_name}",
"undo" => "vrátiť",
"perform delete operation" => "vykonať zmazanie",
+"1 file uploading" => "1 súbor sa posiela ",
+"files uploading" => "nahrávanie súborov",
"'.' is an invalid file name." => "'.' je neplatné meno súboru.",
"File name cannot be empty." => "Meno súboru nemôže byť prázdne",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nesprávne meno, '\\', '/', '<', '>', ':', '\"', '|', '?' a '*' nie sú povolené hodnoty.",
"Your storage is full, files can not be updated or synced anymore!" => "Vaše úložisko je plné. Súbory nemožno aktualizovať ani synchronizovať!",
"Your storage is almost full ({usedSpacePercent}%)" => "Vaše úložisko je takmer plné ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "Vaše sťahovanie sa pripravuje. Ak sú sťahované súbory veľké, môže to chvíľu trvať.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Nemôžem nahrať súbor lebo je to priečinok alebo má 0 bajtov.",
-"Upload Error" => "Chyba odosielania",
-"Close" => "Zavrieť",
-"1 file uploading" => "1 súbor sa posiela ",
-"{count} files uploading" => "{count} súborov odosielaných",
-"Upload cancelled." => "Odosielanie zrušené",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Opustenie stránky zruší práve prebiehajúce odosielanie súboru.",
-"URL cannot be empty." => "URL nemôže byť prázdne",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Neplatné meno priečinka. Používanie mena 'Shared' je vyhradené len pre Owncloud",
-"Name" => "Meno",
+"Name" => "Názov",
"Size" => "Veľkosť",
"Modified" => "Upravené",
"1 folder" => "1 priečinok",
"{count} folders" => "{count} priečinkov",
"1 file" => "1 súbor",
"{count} files" => "{count} súborov",
+"%s could not be renamed" => "%s nemohol byť premenovaný",
"Upload" => "Odoslať",
"File handling" => "Nastavenie správania sa k súborom",
"Maximum upload size" => "Maximálna veľkosť odosielaného súboru",
@@ -55,7 +59,7 @@
"0 is unlimited" => "0 znamená neobmedzené",
"Maximum input size for ZIP files" => "Najväčšia veľkosť ZIP súborov",
"Save" => "Uložiť",
-"New" => "Nový",
+"New" => "Nová",
"Text file" => "Textový súbor",
"Folder" => "Priečinok",
"From link" => "Z odkazu",
@@ -63,11 +67,15 @@
"Cancel upload" => "Zrušiť odosielanie",
"You don’t have write permissions here." => "Nemáte oprávnenie na zápis.",
"Nothing in here. Upload something!" => "Žiadny súbor. Nahrajte niečo!",
-"Download" => "Stiahnuť",
-"Unshare" => "Nezdielať",
-"Upload too large" => "Odosielaný súbor je príliš veľký",
+"Download" => "Sťahovanie",
+"Unshare" => "Zrušiť zdieľanie",
+"Upload too large" => "Nahrávanie je príliš veľké",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Súbory, ktoré sa snažíte nahrať, presahujú maximálnu veľkosť pre nahratie súborov na tento server.",
"Files are being scanned, please wait." => "Čakajte, súbory sú prehľadávané.",
"Current scanning" => "Práve prezerané",
+"directory" => "priečinok",
+"directories" => "priečinky",
+"file" => "súbor",
+"files" => "súbory",
"Upgrading filesystem cache..." => "Aktualizujem medzipamäť súborového systému..."
);
diff --git a/apps/files/l10n/sl.php b/apps/files/l10n/sl.php
index 01405530ffad019de2b6447a9e55ee9cb8843b07..bb01e5475d50541d702939d5de5e961685cb5f55 100644
--- a/apps/files/l10n/sl.php
+++ b/apps/files/l10n/sl.php
@@ -1,19 +1,28 @@
"Ni mogoče premakniti %s - datoteka s tem imenom že obstaja",
+"Could not move %s - File with this name already exists" => "%s ni mogoče premakniti - datoteka s tem imenom že obstaja",
"Could not move %s" => "Ni mogoče premakniti %s",
-"Unable to rename file" => "Ni mogoče preimenovati datoteke",
-"No file was uploaded. Unknown error" => "Ni poslane nobene datoteke. Neznana napaka.",
-"There is no error, the file uploaded with success" => "Datoteka je uspešno poslana.",
+"Unable to set upload directory." => "Mapo, v katero boste prenašali dokumente, ni mogoče določiti",
+"Invalid Token" => "Neveljaven žeton",
+"No file was uploaded. Unknown error" => "Ni poslane datoteke. Neznana napaka.",
+"There is no error, the file uploaded with success" => "Datoteka je uspešno naložena.",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Poslana datoteka presega dovoljeno velikost, ki je določena z možnostjo upload_max_filesize v datoteki php.ini:",
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Poslana datoteka presega velikost, ki jo določa parameter največje dovoljene velikosti v obrazcu HTML.",
-"The uploaded file was only partially uploaded" => "Datoteka je le delno naložena",
-"No file was uploaded" => "Nobena datoteka ni bila naložena",
+"The uploaded file was only partially uploaded" => "Poslan je le del datoteke.",
+"No file was uploaded" => "Ni poslane datoteke",
"Missing a temporary folder" => "Manjka začasna mapa",
"Failed to write to disk" => "Pisanje na disk je spodletelo",
"Not enough storage available" => "Na voljo ni dovolj prostora",
"Invalid directory." => "Neveljavna mapa.",
"Files" => "Datoteke",
-"Delete permanently" => "Izbriši trajno",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Pošiljanja ni mogoče izvesti, saj gre za mapo oziroma datoteko velikosti 0 bajtov.",
+"Not enough space available" => "Na voljo ni dovolj prostora.",
+"Upload cancelled." => "Pošiljanje je preklicano.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "V teku je pošiljanje datoteke. Če zapustite to stran zdaj, bo pošiljanje preklicano.",
+"URL cannot be empty." => "Naslov URL ne sme biti prazna vrednost.",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Ime mape je neveljavno. Uporaba oznake \"Souporaba\" je rezervirana za ownCloud",
+"Error" => "Napaka",
+"Share" => "Souporaba",
+"Delete permanently" => "Izbriši dokončno",
"Delete" => "Izbriši",
"Rename" => "Preimenuj",
"Pending" => "V čakanju ...",
@@ -24,20 +33,14 @@
"replaced {new_name} with {old_name}" => "preimenovano ime {new_name} z imenom {old_name}",
"undo" => "razveljavi",
"perform delete operation" => "izvedi opravilo brisanja",
+"1 file uploading" => "Pošiljanje 1 datoteke",
+"files uploading" => "poteka pošiljanje datotek",
"'.' is an invalid file name." => "'.' je neveljavno ime datoteke.",
"File name cannot be empty." => "Ime datoteke ne sme biti prazno polje.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Neveljavno ime, znaki '\\', '/', '<', '>', ':', '\"', '|', '?' in '*' niso dovoljeni.",
"Your storage is full, files can not be updated or synced anymore!" => "Shramba je povsem napolnjena. Datotek ni več mogoče posodabljati in usklajevati!",
"Your storage is almost full ({usedSpacePercent}%)" => "Mesto za shranjevanje je skoraj polno ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "Postopek priprave datoteke za prejem je lahko dolgotrajen, če je datoteka zelo velika.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Pošiljanje ni mogoče, saj gre za mapo, ali pa je datoteka velikosti 0 bajtov.",
-"Upload Error" => "Napaka med pošiljanjem",
-"Close" => "Zapri",
-"1 file uploading" => "Pošiljanje 1 datoteke",
-"{count} files uploading" => "pošiljanje {count} datotek",
-"Upload cancelled." => "Pošiljanje je preklicano.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "V teku je pošiljanje datoteke. Če zapustite to stran zdaj, bo pošiljanje preklicano.",
-"URL cannot be empty." => "Naslov URL ne sme biti prazna vrednost.",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Neveljavno ime mape. Uporaba oznake \"Souporaba\" je zadržan za sistem ownCloud.",
"Name" => "Ime",
"Size" => "Velikost",
@@ -46,6 +49,7 @@
"{count} folders" => "{count} map",
"1 file" => "1 datoteka",
"{count} files" => "{count} datotek",
+"%s could not be renamed" => "%s ni bilo mogoče preimenovati",
"Upload" => "Pošlji",
"File handling" => "Upravljanje z datotekami",
"Maximum upload size" => "Največja velikost za pošiljanja",
@@ -55,7 +59,7 @@
"0 is unlimited" => "0 predstavlja neomejeno vrednost",
"Maximum input size for ZIP files" => "Največja vhodna velikost za datoteke ZIP",
"Save" => "Shrani",
-"New" => "Nova",
+"New" => "Novo",
"Text file" => "Besedilna datoteka",
"Folder" => "Mapa",
"From link" => "Iz povezave",
@@ -64,10 +68,14 @@
"You don’t have write permissions here." => "Za to mesto ni ustreznih dovoljenj za pisanje.",
"Nothing in here. Upload something!" => "Tukaj še ni ničesar. Najprej je treba kakšno datoteko poslati v oblak!",
"Download" => "Prejmi",
-"Unshare" => "Odstrani iz souporabe",
+"Unshare" => "Prekliči souporabo",
"Upload too large" => "Prekoračenje omejitve velikosti",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Datoteke, ki jih želite poslati, presegajo največjo dovoljeno velikost na strežniku.",
"Files are being scanned, please wait." => "Poteka preučevanje datotek, počakajte ...",
"Current scanning" => "Trenutno poteka preučevanje",
+"directory" => "direktorij",
+"directories" => "direktoriji",
+"file" => "datoteka",
+"files" => "datoteke",
"Upgrading filesystem cache..." => "Nadgrajevanje predpomnilnika datotečnega sistema ..."
);
diff --git a/apps/files/l10n/sq.php b/apps/files/l10n/sq.php
new file mode 100644
index 0000000000000000000000000000000000000000..2daca10a416cf8b426b019e3952d9d8210c47ef0
--- /dev/null
+++ b/apps/files/l10n/sq.php
@@ -0,0 +1,73 @@
+ "%s nuk u spostua - Aty ekziston një skedar me të njëjtin emër",
+"Could not move %s" => "%s nuk u spostua",
+"No file was uploaded. Unknown error" => "Nuk u ngarkua asnjë skedar. Veprim i gabuar i panjohur",
+"There is no error, the file uploaded with success" => "Nuk pati veprime të gabuara, skedari u ngarkua me sukses",
+"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Skedari i ngarkuar tejkalon udhëzimin upload_max_filesize tek php.ini:",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Skedari i ngarkuar tejkalon udhëzimin MAX_FILE_SIZE të specifikuar në formularin HTML",
+"The uploaded file was only partially uploaded" => "Skedari i ngarkuar u ngarkua vetëm pjesërisht",
+"No file was uploaded" => "Nuk u ngarkua asnjë skedar",
+"Missing a temporary folder" => "Një dosje e përkohshme nuk u gjet",
+"Failed to write to disk" => "Ruajtja në disk dështoi",
+"Not enough storage available" => "Nuk ka mbetur hapësirë memorizimi e mjaftueshme",
+"Invalid directory." => "Dosje e pavlefshme.",
+"Files" => "Skedarët",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Nuk është i mundur ngarkimi i skedarit tuaj sepse është dosje ose ka dimension 0 byte",
+"Not enough space available" => "Nuk ka hapësirë memorizimi e mjaftueshme",
+"Upload cancelled." => "Ngarkimi u anulua.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Ngarkimi i skedarit është në vazhdim. Nqse ndërroni faqen tani ngarkimi do të anulohet.",
+"URL cannot be empty." => "URL-i nuk mund të jetë bosh.",
+"Error" => "Veprim i gabuar",
+"Share" => "Nda",
+"Delete permanently" => "Elimino përfundimisht",
+"Delete" => "Elimino",
+"Rename" => "Riemërto",
+"Pending" => "Pezulluar",
+"{new_name} already exists" => "{new_name} ekziston",
+"replace" => "zëvëndëso",
+"suggest name" => "sugjero një emër",
+"cancel" => "anulo",
+"replaced {new_name} with {old_name}" => "U zëvëndësua {new_name} me {old_name}",
+"undo" => "anulo",
+"perform delete operation" => "ekzekuto operacionin e eliminimit",
+"1 file uploading" => "Po ngarkohet 1 skedar",
+"files uploading" => "po ngarkoj skedarët",
+"'.' is an invalid file name." => "'.' është emër i pavlefshëm.",
+"File name cannot be empty." => "Emri i skedarit nuk mund të jetë bosh.",
+"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Emër i pavlefshëm, '\\', '/', '<', '>', ':', '\"', '|', '?' dhe '*' nuk lejohen.",
+"Your storage is full, files can not be updated or synced anymore!" => "Hapësira juaj e memorizimit është plot, nuk mund të ngarkoni apo sinkronizoni më skedarët.",
+"Your storage is almost full ({usedSpacePercent}%)" => "Hapësira juaj e memorizimit është gati plot ({usedSpacePercent}%)",
+"Your download is being prepared. This might take some time if the files are big." => "Shkarkimi juaj po përgatitet. Mund të duhet pak kohë nqse skedarët janë të mëdhenj.",
+"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Emri i dosjes është i pavlefshëm. Përdorimi i \"Shared\" është i rezervuar nga Owncloud-i.",
+"Name" => "Emri",
+"Size" => "Dimensioni",
+"Modified" => "Modifikuar",
+"1 folder" => "1 dosje",
+"{count} folders" => "{count} dosje",
+"1 file" => "1 skedar",
+"{count} files" => "{count} skedarë",
+"Upload" => "Ngarko",
+"File handling" => "Trajtimi i skedarit",
+"Maximum upload size" => "Dimensioni maksimal i ngarkimit",
+"max. possible: " => "maks. i mundur:",
+"Needed for multi-file and folder downloads." => "Duhet për shkarkimin e dosjeve dhe të skedarëve",
+"Enable ZIP-download" => "Aktivizo shkarkimin e ZIP-eve",
+"0 is unlimited" => "0 është i pakufizuar",
+"Maximum input size for ZIP files" => "Dimensioni maksimal i ngarkimit të skedarëve ZIP",
+"Save" => "Ruaj",
+"New" => "I ri",
+"Text file" => "Skedar teksti",
+"Folder" => "Dosje",
+"From link" => "Nga lidhja",
+"Deleted files" => "Skedarë të eliminuar",
+"Cancel upload" => "Anulo ngarkimin",
+"You don’t have write permissions here." => "Nuk keni të drejta për të shkruar këtu.",
+"Nothing in here. Upload something!" => "Këtu nuk ka asgjë. Ngarkoni diçka!",
+"Download" => "Shkarko",
+"Unshare" => "Hiq ndarjen",
+"Upload too large" => "Ngarkimi është shumë i madh",
+"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Skedarët që doni të ngarkoni tejkalojnë dimensionet maksimale për ngarkimet në këtë server.",
+"Files are being scanned, please wait." => "Skedarët po analizohen, ju lutemi pritni.",
+"Current scanning" => "Analizimi aktual",
+"Upgrading filesystem cache..." => "Po përmirësoj memorjen e filesystem-it..."
+);
diff --git a/apps/files/l10n/sr.php b/apps/files/l10n/sr.php
index fe71ee9c90d1b05bcd9712f9b5ca340dd0157d43..68f2f5a93b67df5d097877c1924ce966d2417e94 100644
--- a/apps/files/l10n/sr.php
+++ b/apps/files/l10n/sr.php
@@ -1,4 +1,7 @@
"Не могу да преместим %s – датотека с овим именом већ постоји",
+"Could not move %s" => "Не могу да преместим %s",
+"No file was uploaded. Unknown error" => "Ниједна датотека није отпремљена услед непознате грешке",
"There is no error, the file uploaded with success" => "Није дошло до грешке. Датотека је успешно отпремљена.",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Отпремљена датотека прелази смерницу upload_max_filesize у датотеци php.ini:",
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Отпремљена датотека прелази смерницу MAX_FILE_SIZE која је наведена у HTML обрасцу",
@@ -6,7 +9,17 @@
"No file was uploaded" => "Датотека није отпремљена",
"Missing a temporary folder" => "Недостаје привремена фасцикла",
"Failed to write to disk" => "Не могу да пишем на диск",
+"Not enough storage available" => "Нема довољно простора",
+"Invalid directory." => "неисправна фасцикла.",
"Files" => "Датотеке",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Не могу да отпремим датотеку као фасциклу или она има 0 бајтова",
+"Not enough space available" => "Нема довољно простора",
+"Upload cancelled." => "Отпремање је прекинуто.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Отпремање датотеке је у току. Ако сада напустите страницу, прекинућете отпремање.",
+"URL cannot be empty." => "Адреса не може бити празна.",
+"Error" => "Грешка",
+"Share" => "Дели",
+"Delete permanently" => "Обриши за стално",
"Delete" => "Обриши",
"Rename" => "Преименуј",
"Pending" => "На чекању",
@@ -16,15 +29,17 @@
"cancel" => "откажи",
"replaced {new_name} with {old_name}" => "замењено {new_name} са {old_name}",
"undo" => "опозови",
-"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Неисправан назив. Следећи знакови нису дозвољени: \\, /, <, >, :, \", |, ? и *.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Не могу да отпремим датотеку као фасциклу или она има 0 бајтова",
-"Upload Error" => "Грешка при отпремању",
-"Close" => "Затвори",
+"perform delete operation" => "обриши",
"1 file uploading" => "Отпремам 1 датотеку",
-"{count} files uploading" => "Отпремам {count} датотеке/а",
-"Upload cancelled." => "Отпремање је прекинуто.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Отпремање датотеке је у току. Ако сада напустите страницу, прекинућете отпремање.",
-"Name" => "Назив",
+"files uploading" => "датотеке се отпремају",
+"'.' is an invalid file name." => "Датотека „.“ је неисправног имена.",
+"File name cannot be empty." => "Име датотеке не може бити празно.",
+"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Неисправан назив. Следећи знакови нису дозвољени: \\, /, <, >, :, \", |, ? и *.",
+"Your storage is full, files can not be updated or synced anymore!" => "Ваше складиште је пуно. Датотеке више не могу бити ажуриране ни синхронизоване.",
+"Your storage is almost full ({usedSpacePercent}%)" => "Ваше складиште је скоро па пуно ({usedSpacePercent}%)",
+"Your download is being prepared. This might take some time if the files are big." => "Припремам преузимање. Ово може да потраје ако су датотеке велике.",
+"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Неисправно име фасцикле. Фасцикла „Shared“ је резервисана за ownCloud.",
+"Name" => "Име",
"Size" => "Величина",
"Modified" => "Измењено",
"1 folder" => "1 фасцикла",
@@ -44,12 +59,15 @@
"Text file" => "текстуална датотека",
"Folder" => "фасцикла",
"From link" => "Са везе",
+"Deleted files" => "Обрисане датотеке",
"Cancel upload" => "Прекини отпремање",
+"You don’t have write permissions here." => "Овде немате дозволу за писање.",
"Nothing in here. Upload something!" => "Овде нема ничег. Отпремите нешто!",
"Download" => "Преузми",
"Unshare" => "Укини дељење",
"Upload too large" => "Датотека је превелика",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Датотеке које желите да отпремите прелазе ограничење у величини.",
"Files are being scanned, please wait." => "Скенирам датотеке…",
-"Current scanning" => "Тренутно скенирање"
+"Current scanning" => "Тренутно скенирање",
+"Upgrading filesystem cache..." => "Дограђујем кеш система датотека…"
);
diff --git a/apps/files/l10n/sr@latin.php b/apps/files/l10n/sr@latin.php
index 0fda24532dca3d034d3b4cc57968d59ddd6cb9a0..fb08bca2cae91733e2c1501ed3bace48110858ec 100644
--- a/apps/files/l10n/sr@latin.php
+++ b/apps/files/l10n/sr@latin.php
@@ -6,7 +6,6 @@
"Missing a temporary folder" => "Nedostaje privremena fascikla",
"Files" => "Fajlovi",
"Delete" => "Obriši",
-"Close" => "Zatvori",
"Name" => "Ime",
"Size" => "Veličina",
"Modified" => "Zadnja izmena",
diff --git a/apps/files/l10n/sv.php b/apps/files/l10n/sv.php
index ca9610a33c7766bb746df9c14008180b134b41fd..70f3121a20c78a94e20714d51ab34d16ed44a4ce 100644
--- a/apps/files/l10n/sv.php
+++ b/apps/files/l10n/sv.php
@@ -1,18 +1,27 @@
"Kunde inte flytta %s - Det finns redan en fil med detta namn",
"Could not move %s" => "Kan inte flytta %s",
-"Unable to rename file" => "Kan inte byta namn på filen",
+"Unable to set upload directory." => "Kan inte sätta mapp för uppladdning.",
+"Invalid Token" => "Ogiltig token",
"No file was uploaded. Unknown error" => "Ingen fil uppladdad. Okänt fel",
-"There is no error, the file uploaded with success" => "Inga fel uppstod. Filen laddades upp utan problem",
+"There is no error, the file uploaded with success" => "Inga fel uppstod. Filen laddades upp utan problem.",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Den uppladdade filen överskrider upload_max_filesize direktivet php.ini:",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Den uppladdade filen överstiger MAX_FILE_SIZE direktivet som anges i HTML-formulär",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Den uppladdade filen överskrider MAX_FILE_SIZE direktivet som har angetts i HTML formuläret",
"The uploaded file was only partially uploaded" => "Den uppladdade filen var endast delvis uppladdad",
-"No file was uploaded" => "Ingen fil blev uppladdad",
-"Missing a temporary folder" => "Saknar en tillfällig mapp",
+"No file was uploaded" => "Ingen fil laddades upp",
+"Missing a temporary folder" => "En temporär mapp saknas",
"Failed to write to disk" => "Misslyckades spara till disk",
"Not enough storage available" => "Inte tillräckligt med lagringsutrymme tillgängligt",
"Invalid directory." => "Felaktig mapp.",
"Files" => "Filer",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Kan inte ladda upp din fil eftersom det är en katalog eller har 0 bytes",
+"Not enough space available" => "Inte tillräckligt med utrymme tillgängligt",
+"Upload cancelled." => "Uppladdning avbruten.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Filuppladdning pågår. Lämnar du sidan så avbryts uppladdningen.",
+"URL cannot be empty." => "URL kan inte vara tom.",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Ogiltigt mappnamn. Användning av 'Shared' är reserverad av ownCloud",
+"Error" => "Fel",
+"Share" => "Dela",
"Delete permanently" => "Radera permanent",
"Delete" => "Radera",
"Rename" => "Byt namn",
@@ -24,20 +33,14 @@
"replaced {new_name} with {old_name}" => "ersatt {new_name} med {old_name}",
"undo" => "ångra",
"perform delete operation" => "utför raderingen",
+"1 file uploading" => "1 filuppladdning",
+"files uploading" => "filer laddas upp",
"'.' is an invalid file name." => "'.' är ett ogiltigt filnamn.",
"File name cannot be empty." => "Filnamn kan inte vara tomt.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Ogiltigt namn, '\\', '/', '<', '>', ':', '\"', '|', '?' och '*' är inte tillåtet.",
-"Your storage is full, files can not be updated or synced anymore!" => "Ditt lagringsutrymme är fullt, filer kan ej längre laddas upp eller synkas!",
+"Your storage is full, files can not be updated or synced anymore!" => "Ditt lagringsutrymme är fullt, filer kan inte längre uppdateras eller synkroniseras!",
"Your storage is almost full ({usedSpacePercent}%)" => "Ditt lagringsutrymme är nästan fullt ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "Din nedladdning förbereds. Det kan ta tid om det är stora filer.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Kunde inte ladda upp dina filer eftersom det antingen är en mapp eller har 0 bytes.",
-"Upload Error" => "Uppladdningsfel",
-"Close" => "Stäng",
-"1 file uploading" => "1 filuppladdning",
-"{count} files uploading" => "{count} filer laddas upp",
-"Upload cancelled." => "Uppladdning avbruten.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Filuppladdning pågår. Lämnar du sidan så avbryts uppladdningen.",
-"URL cannot be empty." => "URL kan inte vara tom.",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Ogiltigt mappnamn. Användande av 'Shared' är reserverat av ownCloud",
"Name" => "Namn",
"Size" => "Storlek",
@@ -46,6 +49,7 @@
"{count} folders" => "{count} mappar",
"1 file" => "1 fil",
"{count} files" => "{count} filer",
+"%s could not be renamed" => "%s kunde inte namnändras",
"Upload" => "Ladda upp",
"File handling" => "Filhantering",
"Maximum upload size" => "Maximal storlek att ladda upp",
@@ -69,5 +73,9 @@
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Filerna du försöker ladda upp överstiger den maximala storleken för filöverföringar på servern.",
"Files are being scanned, please wait." => "Filer skannas, var god vänta",
"Current scanning" => "Aktuell skanning",
+"directory" => "mapp",
+"directories" => "mappar",
+"file" => "fil",
+"files" => "filer",
"Upgrading filesystem cache..." => "Uppgraderar filsystemets cache..."
);
diff --git a/apps/files/l10n/ta_LK.php b/apps/files/l10n/ta_LK.php
index 304453f1290b87b5b30e3df562bf0c77488625ef..e03b88569b76d903b393a1ec1f3a7eae54c8ed4f 100644
--- a/apps/files/l10n/ta_LK.php
+++ b/apps/files/l10n/ta_LK.php
@@ -7,7 +7,13 @@
"Missing a temporary folder" => "ஒரு தற்காலிகமான கோப்புறையை காணவில்லை",
"Failed to write to disk" => "வட்டில் எழுத முடியவில்லை",
"Files" => "கோப்புகள்",
-"Delete" => "அழிக்க",
+"Unable to upload your file as it is a directory or has 0 bytes" => "அடைவு அல்லது 0 bytes ஐ கொண்டுள்ளதால் உங்களுடைய கோப்பை பதிவேற்ற முடியவில்லை",
+"Upload cancelled." => "பதிவேற்றல் இரத்து செய்யப்பட்டுள்ளது",
+"File upload is in progress. Leaving the page now will cancel the upload." => "கோப்பு பதிவேற்றம் செயல்பாட்டில் உள்ளது. இந்தப் பக்கத்திலிருந்து வெறியேறுவதானது பதிவேற்றலை இரத்து செய்யும்.",
+"URL cannot be empty." => "URL வெறுமையாக இருக்கமுடியாது.",
+"Error" => "வழு",
+"Share" => "பகிர்வு",
+"Delete" => "நீக்குக",
"Rename" => "பெயர்மாற்றம்",
"Pending" => "நிலுவையிலுள்ள",
"{new_name} already exists" => "{new_name} ஏற்கனவே உள்ளது",
@@ -16,15 +22,8 @@
"cancel" => "இரத்து செய்க",
"replaced {new_name} with {old_name}" => "{new_name} ஆனது {old_name} இனால் மாற்றப்பட்டது",
"undo" => "முன் செயல் நீக்கம் ",
-"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "செல்லுபடியற்ற பெயர்,'\\', '/', '<', '>', ':', '\"', '|', '?' மற்றும் '*' ஆகியன அனுமதிக்கப்படமாட்டாது.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "அடைவு அல்லது 0 bytes ஐ கொண்டுள்ளதால் உங்களுடைய கோப்பை பதிவேற்ற முடியவில்லை",
-"Upload Error" => "பதிவேற்றல் வழு",
-"Close" => "மூடுக",
"1 file uploading" => "1 கோப்பு பதிவேற்றப்படுகிறது",
-"{count} files uploading" => "{எண்ணிக்கை} கோப்புகள் பதிவேற்றப்படுகின்றது",
-"Upload cancelled." => "பதிவேற்றல் இரத்து செய்யப்பட்டுள்ளது",
-"File upload is in progress. Leaving the page now will cancel the upload." => "கோப்பு பதிவேற்றம் செயல்பாட்டில் உள்ளது. இந்தப் பக்கத்திலிருந்து வெறியேறுவதானது பதிவேற்றலை இரத்து செய்யும்.",
-"URL cannot be empty." => "URL வெறுமையாக இருக்கமுடியாது.",
+"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "செல்லுபடியற்ற பெயர்,'\\', '/', '<', '>', ':', '\"', '|', '?' மற்றும் '*' ஆகியன அனுமதிக்கப்படமாட்டாது.",
"Name" => "பெயர்",
"Size" => "அளவு",
"Modified" => "மாற்றப்பட்டது",
@@ -40,7 +39,7 @@
"Enable ZIP-download" => "ZIP பதிவிறக்கலை இயலுமைப்படுத்துக",
"0 is unlimited" => "0 ஆனது எல்லையற்றது",
"Maximum input size for ZIP files" => "ZIP கோப்புகளுக்கான ஆகக்கூடிய உள்ளீட்டு அளவு",
-"Save" => "சேமிக்க",
+"Save" => "சேமிக்க ",
"New" => "புதிய",
"Text file" => "கோப்பு உரை",
"Folder" => "கோப்புறை",
diff --git a/apps/files/l10n/te.php b/apps/files/l10n/te.php
new file mode 100644
index 0000000000000000000000000000000000000000..710034de12e114d5e1cb0a802d2fcb2097239f57
--- /dev/null
+++ b/apps/files/l10n/te.php
@@ -0,0 +1,10 @@
+ "పొరపాటు",
+"Delete permanently" => "శాశ్వతంగా తొలగించు",
+"Delete" => "తొలగించు",
+"cancel" => "రద్దుచేయి",
+"Name" => "పేరు",
+"Size" => "పరిమాణం",
+"Save" => "భద్రపరచు",
+"Folder" => "సంచయం"
+);
diff --git a/apps/files/l10n/th_TH.php b/apps/files/l10n/th_TH.php
index 2353501b4782dfe8ba4649a43ef9dabf282ea3e4..5b2eab6b3a1256cab59425a1bfcf3ead2bd0819f 100644
--- a/apps/files/l10n/th_TH.php
+++ b/apps/files/l10n/th_TH.php
@@ -1,18 +1,24 @@
"ไม่สามารถย้าย %s ได้ - ไฟล์ที่ใช้ชื่อนี้มีอยู่แล้ว",
"Could not move %s" => "ไม่สามารถย้าย %s ได้",
-"Unable to rename file" => "ไม่สามารถเปลี่ยนชื่อไฟล์ได้",
"No file was uploaded. Unknown error" => "ยังไม่มีไฟล์ใดที่ถูกอัพโหลด เกิดข้อผิดพลาดที่ไม่ทราบสาเหตุ",
-"There is no error, the file uploaded with success" => "ไม่มีข้อผิดพลาดใดๆ ไฟล์ถูกอัพโหลดเรียบร้อยแล้ว",
+"There is no error, the file uploaded with success" => "ไม่พบข้อผิดพลาดใดๆ, ไฟล์ถูกอัพโหลดเรียบร้อยแล้ว",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "ขนาดไฟล์ที่อัพโหลดมีขนาดเกิน upload_max_filesize ที่ระบุไว้ใน php.ini",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "ไฟล์ที่อัพโหลดมีขนาดเกินคำสั่ง MAX_FILE_SIZE ที่ระบุเอาไว้ในรูปแบบคำสั่งในภาษา HTML",
-"The uploaded file was only partially uploaded" => "ไฟล์ที่อัพโหลดยังไม่ได้ถูกอัพโหลดอย่างสมบูรณ์",
-"No file was uploaded" => "ยังไม่มีไฟล์ที่ถูกอัพโหลด",
-"Missing a temporary folder" => "แฟ้มเอกสารชั่วคราวเกิดการสูญหาย",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "ไฟล์ที่อัพโหลดมีขนาดไฟล์ใหญ่เกินจำนวนที่กำหนดไว้ในคำสั่ง MAX_FILE_SIZE ที่ถูกระบุไว้ในรูปแบบของ HTML",
+"The uploaded file was only partially uploaded" => "ไฟล์ถูกอัพโหลดได้เพียงบางส่วนเท่านั้น",
+"No file was uploaded" => "ไม่มีไฟล์ที่ถูกอัพโหลด",
+"Missing a temporary folder" => "โฟลเดอร์ชั่วคราวเกิดการสูญหาย",
"Failed to write to disk" => "เขียนข้อมูลลงแผ่นดิสก์ล้มเหลว",
"Not enough storage available" => "เหลือพื้นที่ไม่เพียงสำหรับใช้งาน",
"Invalid directory." => "ไดเร็กทอรี่ไม่ถูกต้อง",
"Files" => "ไฟล์",
+"Unable to upload your file as it is a directory or has 0 bytes" => "ไม่สามารถอัพโหลดไฟล์ของคุณได้ เนื่องจากไฟล์ดังกล่าวเป็นไดเร็กทอรี่ หรือ มีขนาดไฟล์ 0 ไบต์",
+"Not enough space available" => "มีพื้นที่เหลือไม่เพียงพอ",
+"Upload cancelled." => "การอัพโหลดถูกยกเลิก",
+"File upload is in progress. Leaving the page now will cancel the upload." => "การอัพโหลดไฟล์กำลังอยู่ในระหว่างดำเนินการ การออกจากหน้าเว็บนี้จะทำให้การอัพโหลดถูกยกเลิก",
+"URL cannot be empty." => "URL ไม่สามารถเว้นว่างได้",
+"Error" => "ข้อผิดพลาด",
+"Share" => "แชร์",
"Delete" => "ลบ",
"Rename" => "เปลี่ยนชื่อ",
"Pending" => "อยู่ระหว่างดำเนินการ",
@@ -23,24 +29,18 @@
"replaced {new_name} with {old_name}" => "แทนที่ {new_name} ด้วย {old_name} แล้ว",
"undo" => "เลิกทำ",
"perform delete operation" => "ดำเนินการตามคำสั่งลบ",
+"1 file uploading" => "กำลังอัพโหลดไฟล์ 1 ไฟล์",
+"files uploading" => "การอัพโหลดไฟล์",
"'.' is an invalid file name." => "'.' เป็นชื่อไฟล์ที่ไม่ถูกต้อง",
"File name cannot be empty." => "ชื่อไฟล์ไม่สามารถเว้นว่างได้",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "ชื่อที่ใช้ไม่ถูกต้อง, '\\', '/', '<', '>', ':', '\"', '|', '?' และ '*' ไม่ได้รับอนุญาตให้ใช้งานได้",
"Your storage is full, files can not be updated or synced anymore!" => "พื้นที่จัดเก็บข้อมูลของคุณเต็มแล้ว ไม่สามารถอัพเดทหรือผสานไฟล์ต่างๆได้อีกต่อไป",
"Your storage is almost full ({usedSpacePercent}%)" => "พื้นที่จัดเก็บข้อมูลของคุณใกล้เต็มแล้ว ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "กำลังเตรียมดาวน์โหลดข้อมูล หากไฟล์มีขนาดใหญ่ อาจใช้เวลาสักครู่",
-"Unable to upload your file as it is a directory or has 0 bytes" => "ไม่สามารถอัพโหลดไฟล์ของคุณได้ เนื่องจากไฟล์ดังกล่าวเป็นไดเร็กทอรี่หรือมีขนาด 0 ไบต์",
-"Upload Error" => "เกิดข้อผิดพลาดในการอัพโหลด",
-"Close" => "ปิด",
-"1 file uploading" => "กำลังอัพโหลดไฟล์ 1 ไฟล์",
-"{count} files uploading" => "กำลังอัพโหลด {count} ไฟล์",
-"Upload cancelled." => "การอัพโหลดถูกยกเลิก",
-"File upload is in progress. Leaving the page now will cancel the upload." => "การอัพโหลดไฟล์กำลังอยู่ในระหว่างดำเนินการ การออกจากหน้าเว็บนี้จะทำให้การอัพโหลดถูกยกเลิก",
-"URL cannot be empty." => "URL ไม่สามารถเว้นว่างได้",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "ชื่อโฟลเดอร์ไม่ถูกต้อง การใช้งาน 'แชร์' สงวนไว้สำหรับ Owncloud เท่านั้น",
"Name" => "ชื่อ",
"Size" => "ขนาด",
-"Modified" => "ปรับปรุงล่าสุด",
+"Modified" => "แก้ไขแล้ว",
"1 folder" => "1 โฟลเดอร์",
"{count} folders" => "{count} โฟลเดอร์",
"1 file" => "1 ไฟล์",
@@ -61,10 +61,12 @@
"Cancel upload" => "ยกเลิกการอัพโหลด",
"Nothing in here. Upload something!" => "ยังไม่มีไฟล์ใดๆอยู่ที่นี่ กรุณาอัพโหลดไฟล์!",
"Download" => "ดาวน์โหลด",
-"Unshare" => "ยกเลิกการแชร์ข้อมูล",
+"Unshare" => "ยกเลิกการแชร์",
"Upload too large" => "ไฟล์ที่อัพโหลดมีขนาดใหญ่เกินไป",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "ไฟล์ที่คุณพยายามที่จะอัพโหลดมีขนาดเกินกว่าขนาดสูงสุดที่กำหนดไว้ให้อัพโหลดได้สำหรับเซิร์ฟเวอร์นี้",
"Files are being scanned, please wait." => "ไฟล์กำลังอยู่ระหว่างการสแกน, กรุณารอสักครู่.",
"Current scanning" => "ไฟล์ที่กำลังสแกนอยู่ขณะนี้",
+"file" => "ไฟล์",
+"files" => "ไฟล์",
"Upgrading filesystem cache..." => "กำลังอัพเกรดหน่วยความจำแคชของระบบไฟล์..."
);
diff --git a/apps/files/l10n/tr.php b/apps/files/l10n/tr.php
index 547b490330a93a616df4bb208f62f8635eddd5ff..0b2dbb12dd9fc496b422dde6515f50dd7f08b9a7 100644
--- a/apps/files/l10n/tr.php
+++ b/apps/files/l10n/tr.php
@@ -1,18 +1,25 @@
"%s taşınamadı. Bu isimde dosya zaten var.",
"Could not move %s" => "%s taşınamadı",
-"Unable to rename file" => "Dosya adı değiştirilemedi",
"No file was uploaded. Unknown error" => "Dosya yüklenmedi. Bilinmeyen hata",
-"There is no error, the file uploaded with success" => "Bir hata yok, dosya başarıyla yüklendi",
+"There is no error, the file uploaded with success" => "Dosya başarıyla yüklendi, hata oluşmadı",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "php.ini dosyasında upload_max_filesize ile belirtilen dosya yükleme sınırı aşıldı.",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Yüklenen dosya HTML formundaki MAX_FILE_SIZE sınırını aşıyor",
-"The uploaded file was only partially uploaded" => "Yüklenen dosyanın sadece bir kısmı yüklendi",
-"No file was uploaded" => "Hiç dosya yüklenmedi",
-"Missing a temporary folder" => "Geçici bir klasör eksik",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Yüklenecek dosyanın boyutu HTML formunda belirtilen MAX_FILE_SIZE limitini aşıyor",
+"The uploaded file was only partially uploaded" => "Dosya kısmen karşıya yüklenebildi",
+"No file was uploaded" => "Hiç dosya gönderilmedi",
+"Missing a temporary folder" => "Geçici dizin eksik",
"Failed to write to disk" => "Diske yazılamadı",
"Not enough storage available" => "Yeterli disk alanı yok",
"Invalid directory." => "Geçersiz dizin.",
"Files" => "Dosyalar",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Dosyanızın boyutu 0 byte olduğundan veya bir dizin olduğundan yüklenemedi",
+"Not enough space available" => "Yeterli disk alanı yok",
+"Upload cancelled." => "Yükleme iptal edildi.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Dosya yükleme işlemi sürüyor. Şimdi sayfadan ayrılırsanız işleminiz iptal olur.",
+"URL cannot be empty." => "URL boş olamaz.",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Geçersiz dizin adı. 'Shared' dizin ismi kullanımı ownCloud tarafından rezerve edilmiştir.",
+"Error" => "Hata",
+"Share" => "Paylaş",
"Delete permanently" => "Kalıcı olarak sil",
"Delete" => "Sil",
"Rename" => "İsim değiştir.",
@@ -24,22 +31,16 @@
"replaced {new_name} with {old_name}" => "{new_name} ismi {old_name} ile değiştirildi",
"undo" => "geri al",
"perform delete operation" => "Silme işlemini gerçekleştir",
+"1 file uploading" => "1 dosya yüklendi",
+"files uploading" => "Dosyalar yükleniyor",
"'.' is an invalid file name." => "'.' geçersiz dosya adı.",
"File name cannot be empty." => "Dosya adı boş olamaz.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Geçersiz isim, '\\', '/', '<', '>', ':', '\"', '|', '?' ve '*' karakterlerine izin verilmemektedir.",
"Your storage is full, files can not be updated or synced anymore!" => "Depolama alanınız dolu, artık dosyalar güncellenmeyecek yada senkronizasyon edilmeyecek.",
"Your storage is almost full ({usedSpacePercent}%)" => "Depolama alanınız neredeyse dolu ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "İndirmeniz hazırlanıyor. Dosya büyük ise biraz zaman alabilir.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Dosyanızın boyutu 0 byte olduğundan veya bir dizin olduğundan yüklenemedi",
-"Upload Error" => "Yükleme hatası",
-"Close" => "Kapat",
-"1 file uploading" => "1 dosya yüklendi",
-"{count} files uploading" => "{count} dosya yükleniyor",
-"Upload cancelled." => "Yükleme iptal edildi.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Dosya yükleme işlemi sürüyor. Şimdi sayfadan ayrılırsanız işleminiz iptal olur.",
-"URL cannot be empty." => "URL boş olamaz.",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Geçersiz dizin adı. Shared isminin kullanımı Owncloud tarafından rezerver edilmiştir.",
-"Name" => "Ad",
+"Name" => "İsim",
"Size" => "Boyut",
"Modified" => "Değiştirilme",
"1 folder" => "1 dizin",
@@ -65,9 +66,11 @@
"Nothing in here. Upload something!" => "Burada hiçbir şey yok. Birşeyler yükleyin!",
"Download" => "İndir",
"Unshare" => "Paylaşılmayan",
-"Upload too large" => "Yüklemeniz çok büyük",
+"Upload too large" => "Yükleme çok büyük",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Yüklemeye çalıştığınız dosyalar bu sunucudaki maksimum yükleme boyutunu aşıyor.",
"Files are being scanned, please wait." => "Dosyalar taranıyor, lütfen bekleyin.",
"Current scanning" => "Güncel tarama",
+"file" => "dosya",
+"files" => "dosyalar",
"Upgrading filesystem cache..." => "Sistem dosyası önbelleği güncelleniyor"
);
diff --git a/apps/files/l10n/ug.php b/apps/files/l10n/ug.php
new file mode 100644
index 0000000000000000000000000000000000000000..c11ffe7b9bf850471ac1c847ff52f3fbab319d53
--- /dev/null
+++ b/apps/files/l10n/ug.php
@@ -0,0 +1,43 @@
+ "%s يۆتكىيەلمەيدۇ",
+"No file was uploaded. Unknown error" => "ھېچقانداق ھۆججەت يۈكلەنمىدى. يوچۇن خاتالىق",
+"No file was uploaded" => "ھېچقانداق ھۆججەت يۈكلەنمىدى",
+"Missing a temporary folder" => "ۋاقىتلىق قىسقۇچ كەم.",
+"Failed to write to disk" => "دىسكىغا يازالمىدى",
+"Not enough storage available" => "يېتەرلىك ساقلاش بوشلۇقى يوق",
+"Files" => "ھۆججەتلەر",
+"Not enough space available" => "يېتەرلىك بوشلۇق يوق",
+"Upload cancelled." => "يۈكلەشتىن ۋاز كەچتى.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "ھۆججەت يۈكلەش مەشغۇلاتى ئېلىپ بېرىلىۋاتىدۇ. Leaving the page now will cancel the upload.",
+"Error" => "خاتالىق",
+"Share" => "ھەمبەھىر",
+"Delete permanently" => "مەڭگۈلۈك ئۆچۈر",
+"Delete" => "ئۆچۈر",
+"Rename" => "ئات ئۆزگەرت",
+"Pending" => "كۈتۈۋاتىدۇ",
+"{new_name} already exists" => "{new_name} مەۋجۇت",
+"replace" => "ئالماشتۇر",
+"suggest name" => "تەۋسىيە ئات",
+"cancel" => "ۋاز كەچ",
+"undo" => "يېنىۋال",
+"1 file uploading" => "1 ھۆججەت يۈكلىنىۋاتىدۇ",
+"files uploading" => "ھۆججەت يۈكلىنىۋاتىدۇ",
+"Name" => "ئاتى",
+"Size" => "چوڭلۇقى",
+"Modified" => "ئۆزگەرتكەن",
+"1 folder" => "1 قىسقۇچ",
+"1 file" => "1 ھۆججەت",
+"{count} files" => "{count} ھۆججەت",
+"Upload" => "يۈكلە",
+"Save" => "ساقلا",
+"New" => "يېڭى",
+"Text file" => "تېكىست ھۆججەت",
+"Folder" => "قىسقۇچ",
+"Deleted files" => "ئۆچۈرۈلگەن ھۆججەتلەر",
+"Cancel upload" => "يۈكلەشتىن ۋاز كەچ",
+"Nothing in here. Upload something!" => "بۇ جايدا ھېچنېمە يوق. Upload something!",
+"Download" => "چۈشۈر",
+"Unshare" => "ھەمبەھىرلىمە",
+"Upload too large" => "يۈكلەندىغىنى بەك چوڭ",
+"Upgrading filesystem cache..." => "ھۆججەت سىستېما غەملىكىنى يۈكسەلدۈرۈۋاتىدۇ…"
+);
diff --git a/apps/files/l10n/uk.php b/apps/files/l10n/uk.php
index f5e161996c0e2e993ba98a802d348f50e4415a24..261853ef202a15c702f0dfbfb1ea9e6a85d642bd 100644
--- a/apps/files/l10n/uk.php
+++ b/apps/files/l10n/uk.php
@@ -1,7 +1,6 @@
"Не вдалося перемістити %s - Файл з таким ім'ям вже існує",
"Could not move %s" => "Не вдалося перемістити %s",
-"Unable to rename file" => "Не вдалося перейменувати файл",
"No file was uploaded. Unknown error" => "Не завантажено жодного файлу. Невідома помилка",
"There is no error, the file uploaded with success" => "Файл успішно вивантажено без помилок.",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Розмір звантаження перевищує upload_max_filesize параметра в php.ini: ",
@@ -13,6 +12,13 @@
"Not enough storage available" => "Місця більше немає",
"Invalid directory." => "Невірний каталог.",
"Files" => "Файли",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Неможливо завантажити ваш файл тому, що він тека або файл розміром 0 байт",
+"Not enough space available" => "Місця більше немає",
+"Upload cancelled." => "Завантаження перервано.",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Виконується завантаження файлу. Закриття цієї сторінки приведе до відміни завантаження.",
+"URL cannot be empty." => "URL не може бути пустим.",
+"Error" => "Помилка",
+"Share" => "Поділитися",
"Delete permanently" => "Видалити назавжди",
"Delete" => "Видалити",
"Rename" => "Перейменувати",
@@ -24,20 +30,14 @@
"replaced {new_name} with {old_name}" => "замінено {new_name} на {old_name}",
"undo" => "відмінити",
"perform delete operation" => "виконати операцію видалення",
+"1 file uploading" => "1 файл завантажується",
+"files uploading" => "файли завантажуються",
"'.' is an invalid file name." => "'.' це невірне ім'я файлу.",
"File name cannot be empty." => " Ім'я файлу не може бути порожнім.",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Невірне ім'я, '\\', '/', '<', '>', ':', '\"', '|', '?' та '*' не дозволені.",
"Your storage is full, files can not be updated or synced anymore!" => "Ваше сховище переповнене, файли більше не можуть бути оновлені або синхронізовані !",
"Your storage is almost full ({usedSpacePercent}%)" => "Ваше сховище майже повне ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "Ваше завантаження готується. Це може зайняти деякий час, якщо файли завеликі.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Неможливо завантажити ваш файл тому, що він тека або файл розміром 0 байт",
-"Upload Error" => "Помилка завантаження",
-"Close" => "Закрити",
-"1 file uploading" => "1 файл завантажується",
-"{count} files uploading" => "{count} файлів завантажується",
-"Upload cancelled." => "Завантаження перервано.",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Виконується завантаження файлу. Закриття цієї сторінки приведе до відміни завантаження.",
-"URL cannot be empty." => "URL не може бути пустим.",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Невірне ім'я теки. Використання \"Shared\" зарезервовано Owncloud",
"Name" => "Ім'я",
"Size" => "Розмір",
@@ -46,7 +46,7 @@
"{count} folders" => "{count} папок",
"1 file" => "1 файл",
"{count} files" => "{count} файлів",
-"Upload" => "Відвантажити",
+"Upload" => "Вивантажити",
"File handling" => "Робота з файлами",
"Maximum upload size" => "Максимальний розмір відвантажень",
"max. possible: " => "макс.можливе:",
@@ -64,10 +64,12 @@
"You don’t have write permissions here." => "У вас тут немає прав на запис.",
"Nothing in here. Upload something!" => "Тут нічого немає. Відвантажте що-небудь!",
"Download" => "Завантажити",
-"Unshare" => "Заборонити доступ",
+"Unshare" => "Закрити доступ",
"Upload too large" => "Файл занадто великий",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Файли,що ви намагаєтесь відвантажити перевищують максимальний дозволений розмір файлів на цьому сервері.",
"Files are being scanned, please wait." => "Файли скануються, зачекайте, будь-ласка.",
"Current scanning" => "Поточне сканування",
+"file" => "файл",
+"files" => "файли",
"Upgrading filesystem cache..." => "Оновлення кеша файлової системи..."
);
diff --git a/apps/files/l10n/ur_PK.php b/apps/files/l10n/ur_PK.php
new file mode 100644
index 0000000000000000000000000000000000000000..aa87eeda385efc7fd0a155e28808004f47a2b8c8
--- /dev/null
+++ b/apps/files/l10n/ur_PK.php
@@ -0,0 +1,4 @@
+ "ایرر",
+"Unshare" => "شئیرنگ ختم کریں"
+);
diff --git a/apps/files/l10n/vi.php b/apps/files/l10n/vi.php
index affca6c12f86b9109dcd20781ea2aeb209598fec..e3c9fd5488a4c84664ab87bfc7837b5c9c0cf831 100644
--- a/apps/files/l10n/vi.php
+++ b/apps/files/l10n/vi.php
@@ -1,22 +1,28 @@
"Không thể di chuyển %s - Đã có tên file này trên hệ thống",
+"Could not move %s - File with this name already exists" => "Không thể di chuyển %s - Đã có tên tập tin này trên hệ thống",
"Could not move %s" => "Không thể di chuyển %s",
-"Unable to rename file" => "Không thể đổi tên file",
"No file was uploaded. Unknown error" => "Không có tập tin nào được tải lên. Lỗi không xác định",
"There is no error, the file uploaded with success" => "Không có lỗi, các tập tin đã được tải lên thành công",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "The uploaded file exceeds the upload_max_filesize directive in php.ini: ",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Kích thước những tập tin tải lên vượt quá MAX_FILE_SIZE đã được quy định",
-"The uploaded file was only partially uploaded" => "Tập tin tải lên mới chỉ tải lên được một phần",
-"No file was uploaded" => "Không có tập tin nào được tải lên",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Tập tin được tải lên vượt quá MAX_FILE_SIZE được quy định trong mẫu HTML",
+"The uploaded file was only partially uploaded" => "Các tập tin được tải lên chỉ tải lên được một phần",
+"No file was uploaded" => "Chưa có file nào được tải lên",
"Missing a temporary folder" => "Không tìm thấy thư mục tạm",
"Failed to write to disk" => "Không thể ghi ",
"Not enough storage available" => "Không đủ không gian lưu trữ",
"Invalid directory." => "Thư mục không hợp lệ",
"Files" => "Tập tin",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Không thể tải lên tập tin của bạn ,nó như là một thư mục hoặc có 0 byte",
+"Not enough space available" => "Không đủ chỗ trống cần thiết",
+"Upload cancelled." => "Hủy tải lên",
+"File upload is in progress. Leaving the page now will cancel the upload." => "Tập tin tải lên đang được xử lý. Nếu bạn rời khỏi trang bây giờ sẽ hủy quá trình này.",
+"URL cannot be empty." => "URL không được để trống.",
+"Error" => "Lỗi",
+"Share" => "Chia sẻ",
"Delete permanently" => "Xóa vĩnh vễn",
"Delete" => "Xóa",
"Rename" => "Sửa tên",
-"Pending" => "Chờ",
+"Pending" => "Đang chờ",
"{new_name} already exists" => "{new_name} đã tồn tại",
"replace" => "thay thế",
"suggest name" => "tên gợi ý",
@@ -24,20 +30,14 @@
"replaced {new_name} with {old_name}" => "đã thay thế {new_name} bằng {old_name}",
"undo" => "lùi lại",
"perform delete operation" => "thực hiện việc xóa",
+"1 file uploading" => "1 tệp tin đang được tải lên",
+"files uploading" => "tệp tin đang được tải lên",
"'.' is an invalid file name." => "'.' là một tên file không hợp lệ",
"File name cannot be empty." => "Tên file không được rỗng",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Tên không hợp lệ, '\\', '/', '<', '>', ':', '\"', '|', '?' và '*' thì không được phép dùng.",
"Your storage is full, files can not be updated or synced anymore!" => "Your storage is full, files can not be updated or synced anymore!",
"Your storage is almost full ({usedSpacePercent}%)" => "Your storage is almost full ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "Your download is being prepared. This might take some time if the files are big.",
-"Unable to upload your file as it is a directory or has 0 bytes" => "Không thể tải lên tập tin này do nó là một thư mục hoặc kích thước tập tin bằng 0 byte",
-"Upload Error" => "Tải lên lỗi",
-"Close" => "Đóng",
-"1 file uploading" => "1 tệp tin đang được tải lên",
-"{count} files uploading" => "{count} tập tin đang tải lên",
-"Upload cancelled." => "Hủy tải lên",
-"File upload is in progress. Leaving the page now will cancel the upload." => "Tập tin tải lên đang được xử lý. Nếu bạn rời khỏi trang bây giờ sẽ hủy quá trình này.",
-"URL cannot be empty." => "URL không được để trống.",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Invalid folder name. Usage of 'Shared' is reserved by Owncloud",
"Name" => "Tên",
"Size" => "Kích cỡ",
@@ -61,12 +61,15 @@
"From link" => "Từ liên kết",
"Deleted files" => "File đã bị xóa",
"Cancel upload" => "Hủy upload",
+"You don’t have write permissions here." => "Bạn không có quyền ghi vào đây.",
"Nothing in here. Upload something!" => "Không có gì ở đây .Hãy tải lên một cái gì đó !",
-"Download" => "Tải xuống",
-"Unshare" => "Không chia sẽ",
+"Download" => "Tải về",
+"Unshare" => "Bỏ chia sẻ",
"Upload too large" => "Tập tin tải lên quá lớn",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Các tập tin bạn đang tải lên vượt quá kích thước tối đa cho phép trên máy chủ .",
"Files are being scanned, please wait." => "Tập tin đang được quét ,vui lòng chờ.",
"Current scanning" => "Hiện tại đang quét",
-"Upgrading filesystem cache..." => "Upgrading filesystem cache..."
+"file" => "file",
+"files" => "files",
+"Upgrading filesystem cache..." => "Đang nâng cấp bộ nhớ đệm cho tập tin hệ thống..."
);
diff --git a/apps/files/l10n/zh_CN.GB2312.php b/apps/files/l10n/zh_CN.GB2312.php
index fa75627f141da59894425a31de973b64b97cde34..a515b8ac1bf55dd0b5c819789aff3bb51360d04a 100644
--- a/apps/files/l10n/zh_CN.GB2312.php
+++ b/apps/files/l10n/zh_CN.GB2312.php
@@ -1,36 +1,55 @@
"无法移动 %s - 存在同名文件",
+"Could not move %s" => "无法移动 %s",
+"Unable to set upload directory." => "无法设置上传文件夹",
+"Invalid Token" => "非法Token",
"No file was uploaded. Unknown error" => "没有上传文件。未知错误",
-"There is no error, the file uploaded with success" => "没有任何错误,文件上传成功了",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "上传的文件超过了HTML表单指定的MAX_FILE_SIZE",
-"The uploaded file was only partially uploaded" => "文件只有部分被上传",
-"No file was uploaded" => "没有上传完成的文件",
-"Missing a temporary folder" => "丢失了一个临时文件夹",
+"There is no error, the file uploaded with success" => "文件上传成功",
+"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "上传的文件超过了php.ini指定的upload_max_filesize",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "上传的文件超过了 HTML 表格中指定的 MAX_FILE_SIZE 选项",
+"The uploaded file was only partially uploaded" => "文件部分上传",
+"No file was uploaded" => "没有上传文件",
+"Missing a temporary folder" => "缺失临时文件夹",
"Failed to write to disk" => "写磁盘失败",
+"Not enough storage available" => "容量不足",
+"Invalid directory." => "无效文件夹",
"Files" => "文件",
+"Unable to upload your file as it is a directory or has 0 bytes" => "不能上传您的文件,由于它是文件夹或者为空文件",
+"Not enough space available" => "容量不足",
+"Upload cancelled." => "上传取消了",
+"File upload is in progress. Leaving the page now will cancel the upload." => "文件正在上传。关闭页面会取消上传。",
+"URL cannot be empty." => "网址不能为空。",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "无效文件夹名。“Shared”已经被系统保留。",
+"Error" => "出错",
+"Share" => "分享",
+"Delete permanently" => "永久删除",
"Delete" => "删除",
"Rename" => "重命名",
-"Pending" => "Pending",
+"Pending" => "等待中",
"{new_name} already exists" => "{new_name} 已存在",
"replace" => "替换",
"suggest name" => "推荐名称",
"cancel" => "取消",
"replaced {new_name} with {old_name}" => "已用 {old_name} 替换 {new_name}",
"undo" => "撤销",
-"Unable to upload your file as it is a directory or has 0 bytes" => "不能上传你指定的文件,可能因为它是个文件夹或者大小为0",
-"Upload Error" => "上传错误",
-"Close" => "关闭",
+"perform delete operation" => "执行删除",
"1 file uploading" => "1 个文件正在上传",
-"{count} files uploading" => "{count} 个文件正在上传",
-"Upload cancelled." => "上传取消了",
-"File upload is in progress. Leaving the page now will cancel the upload." => "文件正在上传。关闭页面会取消上传。",
-"URL cannot be empty." => "网址不能为空。",
-"Name" => "名字",
+"files uploading" => "个文件正在上传",
+"'.' is an invalid file name." => "'.' 文件名不正确",
+"File name cannot be empty." => "文件名不能为空",
+"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "文件名内不能包含以下符号:\\ / < > : \" | ?和 *",
+"Your storage is full, files can not be updated or synced anymore!" => "容量已满,不能再同步/上传文件了!",
+"Your storage is almost full ({usedSpacePercent}%)" => "你的空间快用满了 ({usedSpacePercent}%)",
+"Your download is being prepared. This might take some time if the files are big." => "正在下载,可能会花点时间,跟文件大小有关",
+"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "不正确文件夹名。Shared是保留名,不能使用。",
+"Name" => "名称",
"Size" => "大小",
"Modified" => "修改日期",
"1 folder" => "1 个文件夹",
"{count} folders" => "{count} 个文件夹",
"1 file" => "1 个文件",
"{count} files" => "{count} 个文件",
+"%s could not be renamed" => "不能重命名 %s",
"Upload" => "上传",
"File handling" => "文件处理中",
"Maximum upload size" => "最大上传大小",
@@ -44,12 +63,20 @@
"Text file" => "文本文档",
"Folder" => "文件夹",
"From link" => "来自链接",
+"Deleted files" => "已删除的文件",
"Cancel upload" => "取消上传",
+"You don’t have write permissions here." => "您没有写入权限。",
"Nothing in here. Upload something!" => "这里没有东西.上传点什么!",
"Download" => "下载",
-"Unshare" => "取消共享",
-"Upload too large" => "上传的文件太大了",
+"Size (MB)" => "大小 (MB)",
+"Unshare" => "取消分享",
+"Upload too large" => "上传过大",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "你正在试图上传的文件超过了此服务器支持的最大的文件大小.",
"Files are being scanned, please wait." => "正在扫描文件,请稍候.",
-"Current scanning" => "正在扫描"
+"Current scanning" => "正在扫描",
+"directory" => "文件夹",
+"directories" => "文件夹",
+"file" => "文件",
+"files" => "文件",
+"Upgrading filesystem cache..." => "升级系统缓存..."
);
diff --git a/apps/files/l10n/zh_CN.php b/apps/files/l10n/zh_CN.php
index 2923126d10fbe08c585ace566a54f0b63b5d97be..68680676a1953356a6017f6921e1d9ad3b2cd54e 100644
--- a/apps/files/l10n/zh_CN.php
+++ b/apps/files/l10n/zh_CN.php
@@ -1,22 +1,31 @@
"无法移动 %s - 同名文件已存在",
"Could not move %s" => "无法移动 %s",
-"Unable to rename file" => "无法重命名文件",
+"Unable to set upload directory." => "无法设置上传文件夹。",
+"Invalid Token" => "无效密匙",
"No file was uploaded. Unknown error" => "没有文件被上传。未知错误",
-"There is no error, the file uploaded with success" => "没有发生错误,文件上传成功。",
+"There is no error, the file uploaded with success" => "文件上传成功,没有错误发生",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "上传文件大小已超过php.ini中upload_max_filesize所规定的值",
-"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "上传的文件超过了在HTML 表单中指定的MAX_FILE_SIZE",
-"The uploaded file was only partially uploaded" => "只上传了文件的一部分",
-"No file was uploaded" => "文件没有上传",
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "上传的文件长度超出了 HTML 表单中 MAX_FILE_SIZE 的限制",
+"The uploaded file was only partially uploaded" => "已上传文件只上传了部分(不完整)",
+"No file was uploaded" => "没有文件被上传",
"Missing a temporary folder" => "缺少临时目录",
"Failed to write to disk" => "写入磁盘失败",
"Not enough storage available" => "没有足够的存储空间",
"Invalid directory." => "无效文件夹。",
"Files" => "文件",
+"Unable to upload your file as it is a directory or has 0 bytes" => "无法上传您的文件,文件夹或者空文件",
+"Not enough space available" => "没有足够可用空间",
+"Upload cancelled." => "上传已取消",
+"File upload is in progress. Leaving the page now will cancel the upload." => "文件正在上传中。现在离开此页会导致上传动作被取消。",
+"URL cannot be empty." => "URL不能为空",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "无效的文件夹名。”Shared“ 是 Owncloud 预留的文件夹",
+"Error" => "错误",
+"Share" => "分享",
"Delete permanently" => "永久删除",
"Delete" => "删除",
"Rename" => "重命名",
-"Pending" => "操作等待中",
+"Pending" => "等待",
"{new_name} already exists" => "{new_name} 已存在",
"replace" => "替换",
"suggest name" => "建议名称",
@@ -24,20 +33,14 @@
"replaced {new_name} with {old_name}" => "已将 {old_name}替换成 {new_name}",
"undo" => "撤销",
"perform delete operation" => "进行删除操作",
+"1 file uploading" => "1个文件上传中",
+"files uploading" => "文件上传中",
"'.' is an invalid file name." => "'.' 是一个无效的文件名。",
"File name cannot be empty." => "文件名不能为空。",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "无效名称,'\\', '/', '<', '>', ':', '\"', '|', '?' 和 '*' 不被允许使用。",
"Your storage is full, files can not be updated or synced anymore!" => "您的存储空间已满,文件将无法更新或同步!",
"Your storage is almost full ({usedSpacePercent}%)" => "您的存储空间即将用完 ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "下载正在准备中。如果文件较大可能会花费一些时间。",
-"Unable to upload your file as it is a directory or has 0 bytes" => "无法上传文件,因为它是一个目录或者大小为 0 字节",
-"Upload Error" => "上传错误",
-"Close" => "关闭",
-"1 file uploading" => "1个文件上传中",
-"{count} files uploading" => "{count} 个文件上传中",
-"Upload cancelled." => "上传已取消",
-"File upload is in progress. Leaving the page now will cancel the upload." => "文件正在上传中。现在离开此页会导致上传动作被取消。",
-"URL cannot be empty." => "URL不能为空",
"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "无效文件夹名。'共享' 是 Owncloud 预留的文件夹名。",
"Name" => "名称",
"Size" => "大小",
@@ -46,6 +49,7 @@
"{count} folders" => "{count} 个文件夹",
"1 file" => "1 个文件",
"{count} files" => "{count} 个文件",
+"%s could not be renamed" => "%s 不能被重命名",
"Upload" => "上传",
"File handling" => "文件处理",
"Maximum upload size" => "最大上传大小",
@@ -59,15 +63,17 @@
"Text file" => "文本文件",
"Folder" => "文件夹",
"From link" => "来自链接",
-"Deleted files" => "删除文件",
+"Deleted files" => "已删除文件",
"Cancel upload" => "取消上传",
"You don’t have write permissions here." => "您没有写权限",
"Nothing in here. Upload something!" => "这里还什么都没有。上传些东西吧!",
"Download" => "下载",
-"Unshare" => "取消分享",
+"Unshare" => "取消共享",
"Upload too large" => "上传文件过大",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "您正尝试上传的文件超过了此服务器可以上传的最大容量限制",
"Files are being scanned, please wait." => "文件正在被扫描,请稍候。",
"Current scanning" => "当前扫描",
+"file" => "文件",
+"files" => "文件",
"Upgrading filesystem cache..." => "正在更新文件系统缓存..."
);
diff --git a/apps/files/l10n/zh_HK.php b/apps/files/l10n/zh_HK.php
index 4eaa908476be860f756907589d60b6905f614524..4402812f2b69ad10b71f4243c17620ea729ef7fd 100644
--- a/apps/files/l10n/zh_HK.php
+++ b/apps/files/l10n/zh_HK.php
@@ -1,7 +1,10 @@
"文件",
+"Error" => "錯誤",
+"Share" => "分享",
"Delete" => "刪除",
"Name" => "名稱",
+"{count} folders" => "{}文件夾",
"Upload" => "上傳",
"Save" => "儲存",
"Download" => "下載",
diff --git a/apps/files/l10n/zh_TW.php b/apps/files/l10n/zh_TW.php
index 793fedac41260ef5630419250e01b2bc6bad9c03..6801b311ae4d9aeba5678eb1a7bfd40e44d9aaa6 100644
--- a/apps/files/l10n/zh_TW.php
+++ b/apps/files/l10n/zh_TW.php
@@ -1,18 +1,27 @@
"無法移動 %s - 同名的檔案已經存在",
"Could not move %s" => "無法移動 %s",
-"Unable to rename file" => "無法重新命名檔案",
+"Unable to set upload directory." => "無法設定上傳目錄。",
+"Invalid Token" => "無效的 token",
"No file was uploaded. Unknown error" => "沒有檔案被上傳。未知的錯誤。",
"There is no error, the file uploaded with success" => "無錯誤,檔案上傳成功",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "上傳的檔案大小超過 php.ini 當中 upload_max_filesize 參數的設定:",
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "上傳的檔案大小超過 HTML 表單中 MAX_FILE_SIZE 的限制",
"The uploaded file was only partially uploaded" => "只有檔案的一部分被上傳",
-"No file was uploaded" => "無已上傳檔案",
-"Missing a temporary folder" => "遺失暫存資料夾",
+"No file was uploaded" => "沒有檔案被上傳",
+"Missing a temporary folder" => "找不到暫存資料夾",
"Failed to write to disk" => "寫入硬碟失敗",
"Not enough storage available" => "儲存空間不足",
"Invalid directory." => "無效的資料夾。",
"Files" => "檔案",
+"Unable to upload your file as it is a directory or has 0 bytes" => "無法上傳您的檔案因為它可能是一個目錄或檔案大小為0",
+"Not enough space available" => "沒有足夠的可用空間",
+"Upload cancelled." => "上傳已取消",
+"File upload is in progress. Leaving the page now will cancel the upload." => "檔案上傳中。離開此頁面將會取消上傳。",
+"URL cannot be empty." => "URL 不能為空白。",
+"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "無效的資料夾名稱,'Shared' 的使用被 ownCloud 保留",
+"Error" => "錯誤",
+"Share" => "分享",
"Delete permanently" => "永久刪除",
"Delete" => "刪除",
"Rename" => "重新命名",
@@ -24,21 +33,15 @@
"replaced {new_name} with {old_name}" => "使用 {new_name} 取代 {old_name}",
"undo" => "復原",
"perform delete operation" => "進行刪除動作",
+"1 file uploading" => "1 個檔案正在上傳",
+"files uploading" => "檔案正在上傳中",
"'.' is an invalid file name." => "'.' 是不合法的檔名。",
"File name cannot be empty." => "檔名不能為空。",
"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "檔名不合法,不允許 '\\', '/', '<', '>', ':', '\"', '|', '?' 和 '*' 。",
"Your storage is full, files can not be updated or synced anymore!" => "您的儲存空間已滿,沒有辦法再更新或是同步檔案!",
"Your storage is almost full ({usedSpacePercent}%)" => "您的儲存空間快要滿了 ({usedSpacePercent}%)",
"Your download is being prepared. This might take some time if the files are big." => "正在準備您的下載,若您的檔案較大,將會需要更多時間。",
-"Unable to upload your file as it is a directory or has 0 bytes" => "無法上傳您的檔案因為它可能是一個目錄或檔案大小為0",
-"Upload Error" => "上傳發生錯誤",
-"Close" => "關閉",
-"1 file uploading" => "1 個檔案正在上傳",
-"{count} files uploading" => "{count} 個檔案正在上傳",
-"Upload cancelled." => "上傳取消",
-"File upload is in progress. Leaving the page now will cancel the upload." => "檔案上傳中。離開此頁面將會取消上傳。",
-"URL cannot be empty." => "URL 不能為空白.",
-"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "無效的資料夾名稱,'Shared' 的使用被 Owncloud 保留",
+"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "無效的資料夾名稱,'Shared' 的使用被 ownCloud 保留",
"Name" => "名稱",
"Size" => "大小",
"Modified" => "修改",
@@ -46,6 +49,7 @@
"{count} folders" => "{count} 個資料夾",
"1 file" => "1 個檔案",
"{count} files" => "{count} 個檔案",
+"%s could not be renamed" => "無法重新命名 %s",
"Upload" => "上傳",
"File handling" => "檔案處理",
"Maximum upload size" => "最大上傳檔案大小",
@@ -59,13 +63,20 @@
"Text file" => "文字檔",
"Folder" => "資料夾",
"From link" => "從連結",
+"Deleted files" => "已刪除的檔案",
"Cancel upload" => "取消上傳",
-"Nothing in here. Upload something!" => "沒有任何東西。請上傳內容!",
+"You don’t have write permissions here." => "您在這裡沒有編輯權。",
+"Nothing in here. Upload something!" => "這裡什麼也沒有,上傳一些東西吧!",
"Download" => "下載",
+"Size (MB)" => "大小 (MB)",
"Unshare" => "取消共享",
"Upload too large" => "上傳過大",
-"The files you are trying to upload exceed the maximum size for file uploads on this server." => "您試圖上傳的檔案已超過伺服器的最大檔案大小限制。 ",
+"The files you are trying to upload exceed the maximum size for file uploads on this server." => "您試圖上傳的檔案已超過伺服器的最大檔案大小限制。",
"Files are being scanned, please wait." => "正在掃描檔案,請稍等。",
"Current scanning" => "目前掃描",
-"Upgrading filesystem cache..." => "正在更新檔案系統快取..."
+"directory" => "目錄",
+"directories" => "目錄",
+"file" => "檔案",
+"files" => "檔案",
+"Upgrading filesystem cache..." => "正在升級檔案系統快取..."
);
diff --git a/apps/files/lib/app.php b/apps/files/lib/app.php
new file mode 100644
index 0000000000000000000000000000000000000000..f7052ef80b0eadccb22c20c5b4c6a1d971cd6ba1
--- /dev/null
+++ b/apps/files/lib/app.php
@@ -0,0 +1,79 @@
+.
+ *
+ */
+
+
+namespace OCA\Files;
+
+class App {
+ private $l10n;
+ private $view;
+
+ public function __construct($view, $l10n) {
+ $this->view = $view;
+ $this->l10n = $l10n;
+ }
+
+ /**
+ * rename a file
+ *
+ * @param string $dir
+ * @param string $oldname
+ * @param string $newname
+ * @return array
+ */
+ public function rename($dir, $oldname, $newname) {
+ $result = array(
+ 'success' => false,
+ 'data' => NULL
+ );
+
+ // rename to "/Shared" is denied
+ if( $dir === '/' and $newname === 'Shared' ) {
+ $result['data'] = array(
+ 'message' => $this->l10n->t("Invalid folder name. Usage of 'Shared' is reserved by ownCloud")
+ );
+ } elseif(
+ // rename to "." is denied
+ $newname !== '.' and
+ // rename of "/Shared" is denied
+ !($dir === '/' and $oldname === 'Shared') and
+ // THEN try to rename
+ $this->view->rename($dir . '/' . $oldname, $dir . '/' . $newname)
+ ) {
+ // successful rename
+ $result['success'] = true;
+ $result['data'] = array(
+ 'dir' => $dir,
+ 'file' => $oldname,
+ 'newname' => $newname
+ );
+ } else {
+ // rename failed
+ $result['data'] = array(
+ 'message' => $this->l10n->t('%s could not be renamed', array($oldname))
+ );
+ }
+ return $result;
+ }
+
+}
\ No newline at end of file
diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php
index a53df4e2d3e808af55e8d55136e56868cf627342..7d679bc4bf65434cc14be3369d9df7c7230d1c9d 100644
--- a/apps/files/templates/index.php
+++ b/apps/files/templates/index.php
@@ -23,8 +23,10 @@
method="post"
enctype="multipart/form-data"
target="file_upload_target_1">
+ = 0):?>
+
@@ -32,7 +34,7 @@
value="(max )">
-
+
@@ -44,13 +46,12 @@
-
-
+ .
+ *
+ */
+
+class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase {
+
+ function setUp() {
+ // mock OC_L10n
+ $l10nMock = $this->getMock('\OC_L10N', array('t'), array(), '', false);
+ $l10nMock->expects($this->any())
+ ->method('t')
+ ->will($this->returnArgument(0));
+ $viewMock = $this->getMock('\OC\Files\View', array('rename', 'normalizePath'), array(), '', false);
+ $viewMock->expects($this->any())
+ ->method('normalizePath')
+ ->will($this->returnArgument(0));
+ $viewMock->expects($this->any())
+ ->method('rename')
+ ->will($this->returnValue(true));
+ $this->files = new \OCA\Files\App($viewMock, $l10nMock);
+ }
+
+ /**
+ * @brief test rename of file/folder named "Shared"
+ */
+ function testRenameSharedFolder() {
+ $dir = '/';
+ $oldname = 'Shared';
+ $newname = 'new_name';
+
+ $result = $this->files->rename($dir, $oldname, $newname);
+ $expected = array(
+ 'success' => false,
+ 'data' => array('message' => '%s could not be renamed')
+ );
+
+ $this->assertEquals($expected, $result);
+ }
+
+ /**
+ * @brief test rename of file/folder named "Shared"
+ */
+ function testRenameSharedFolderInSubdirectory() {
+ $dir = '/test';
+ $oldname = 'Shared';
+ $newname = 'new_name';
+
+ $result = $this->files->rename($dir, $oldname, $newname);
+ $expected = array(
+ 'success' => true,
+ 'data' => array(
+ 'dir' => $dir,
+ 'file' => $oldname,
+ 'newname' => $newname
+ )
+ );
+
+ $this->assertEquals($expected, $result);
+ }
+
+ /**
+ * @brief test rename of file/folder to "Shared"
+ */
+ function testRenameFolderToShared() {
+ $dir = '/';
+ $oldname = 'oldname';
+ $newname = 'Shared';
+
+ $result = $this->files->rename($dir, $oldname, $newname);
+ $expected = array(
+ 'success' => false,
+ 'data' => array('message' => "Invalid folder name. Usage of 'Shared' is reserved by ownCloud")
+ );
+
+ $this->assertEquals($expected, $result);
+ }
+
+ /**
+ * @brief test rename of file/folder
+ */
+ function testRenameFolder() {
+ $dir = '/';
+ $oldname = 'oldname';
+ $newname = 'newname';
+
+ $result = $this->files->rename($dir, $oldname, $newname);
+ $expected = array(
+ 'success' => true,
+ 'data' => array(
+ 'dir' => $dir,
+ 'file' => $oldname,
+ 'newname' => $newname
+ )
+ );
+
+ $this->assertEquals($expected, $result);
+ }
+}
\ No newline at end of file
diff --git a/apps/files/triggerupdate.php b/apps/files/triggerupdate.php
new file mode 100644
index 0000000000000000000000000000000000000000..0e29edbba35ef32f821d9782ba5ebe95e4e21cbd
--- /dev/null
+++ b/apps/files/triggerupdate.php
@@ -0,0 +1,22 @@
+resolvePath($file);
+ $watcher = $storage->getWatcher($internalPath);
+ $watcher->checkUpdate($internalPath);
+ } else {
+ echo "Usage: php triggerupdate.php /path/to/file\n";
+ }
+} else {
+ echo "This script can be run from the command line only\n";
+}
diff --git a/apps/files_encryption/3rdparty/Crypt_Blowfish/Blowfish.php b/apps/files_encryption/3rdparty/Crypt_Blowfish/Blowfish.php
new file mode 100644
index 0000000000000000000000000000000000000000..4ccacb963e3c535182eba8f5f74470c86abdfc6d
--- /dev/null
+++ b/apps/files_encryption/3rdparty/Crypt_Blowfish/Blowfish.php
@@ -0,0 +1,317 @@
+
+ * @copyright 2005 Matthew Fonda
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version CVS: $Id: Blowfish.php,v 1.81 2005/05/30 18:40:36 mfonda Exp $
+ * @link http://pear.php.net/package/Crypt_Blowfish
+ */
+
+
+require_once 'PEAR.php';
+
+
+/**
+ *
+ * Example usage:
+ * $bf = new Crypt_Blowfish('some secret key!');
+ * $encrypted = $bf->encrypt('this is some example plain text');
+ * $plaintext = $bf->decrypt($encrypted);
+ * echo "plain text: $plaintext";
+ *
+ *
+ * @category Encryption
+ * @package Crypt_Blowfish
+ * @author Matthew Fonda
+ * @copyright 2005 Matthew Fonda
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @link http://pear.php.net/package/Crypt_Blowfish
+ * @version @package_version@
+ * @access public
+ */
+class Crypt_Blowfish
+{
+ /**
+ * P-Array contains 18 32-bit subkeys
+ *
+ * @var array
+ * @access private
+ */
+ var $_P = array();
+
+
+ /**
+ * Array of four S-Blocks each containing 256 32-bit entries
+ *
+ * @var array
+ * @access private
+ */
+ var $_S = array();
+
+ /**
+ * Mcrypt td resource
+ *
+ * @var resource
+ * @access private
+ */
+ var $_td = null;
+
+ /**
+ * Initialization vector
+ *
+ * @var string
+ * @access private
+ */
+ var $_iv = null;
+
+
+ /**
+ * Crypt_Blowfish Constructor
+ * Initializes the Crypt_Blowfish object, and gives a sets
+ * the secret key
+ *
+ * @param string $key
+ * @access public
+ */
+ function Crypt_Blowfish($key)
+ {
+ if (extension_loaded('mcrypt')) {
+ $this->_td = mcrypt_module_open(MCRYPT_BLOWFISH, '', 'ecb', '');
+ $this->_iv = mcrypt_create_iv(8, MCRYPT_RAND);
+ }
+ $this->setKey($key);
+ }
+
+ /**
+ * Deprecated isReady method
+ *
+ * @return bool
+ * @access public
+ * @deprecated
+ */
+ function isReady()
+ {
+ return true;
+ }
+
+ /**
+ * Deprecated init method - init is now a private
+ * method and has been replaced with _init
+ *
+ * @return bool
+ * @access public
+ * @deprecated
+ * @see Crypt_Blowfish::_init()
+ */
+ function init()
+ {
+ $this->_init();
+ }
+
+ /**
+ * Initializes the Crypt_Blowfish object
+ *
+ * @access private
+ */
+ function _init()
+ {
+ $defaults = new Crypt_Blowfish_DefaultKey();
+ $this->_P = $defaults->P;
+ $this->_S = $defaults->S;
+ }
+
+ /**
+ * Enciphers a single 64 bit block
+ *
+ * @param int &$Xl
+ * @param int &$Xr
+ * @access private
+ */
+ function _encipher(&$Xl, &$Xr)
+ {
+ for ($i = 0; $i < 16; $i++) {
+ $temp = $Xl ^ $this->_P[$i];
+ $Xl = ((($this->_S[0][($temp>>24) & 255] +
+ $this->_S[1][($temp>>16) & 255]) ^
+ $this->_S[2][($temp>>8) & 255]) +
+ $this->_S[3][$temp & 255]) ^ $Xr;
+ $Xr = $temp;
+ }
+ $Xr = $Xl ^ $this->_P[16];
+ $Xl = $temp ^ $this->_P[17];
+ }
+
+
+ /**
+ * Deciphers a single 64 bit block
+ *
+ * @param int &$Xl
+ * @param int &$Xr
+ * @access private
+ */
+ function _decipher(&$Xl, &$Xr)
+ {
+ for ($i = 17; $i > 1; $i--) {
+ $temp = $Xl ^ $this->_P[$i];
+ $Xl = ((($this->_S[0][($temp>>24) & 255] +
+ $this->_S[1][($temp>>16) & 255]) ^
+ $this->_S[2][($temp>>8) & 255]) +
+ $this->_S[3][$temp & 255]) ^ $Xr;
+ $Xr = $temp;
+ }
+ $Xr = $Xl ^ $this->_P[1];
+ $Xl = $temp ^ $this->_P[0];
+ }
+
+
+ /**
+ * Encrypts a string
+ *
+ * @param string $plainText
+ * @return string Returns cipher text on success, PEAR_Error on failure
+ * @access public
+ */
+ function encrypt($plainText)
+ {
+ if (!is_string($plainText)) {
+ PEAR::raiseError('Plain text must be a string', 0, PEAR_ERROR_DIE);
+ }
+
+ if (extension_loaded('mcrypt')) {
+ return mcrypt_generic($this->_td, $plainText);
+ }
+
+ $cipherText = '';
+ $len = strlen($plainText);
+ $plainText .= str_repeat(chr(0),(8 - ($len%8))%8);
+ for ($i = 0; $i < $len; $i += 8) {
+ list(,$Xl,$Xr) = unpack("N2",substr($plainText,$i,8));
+ $this->_encipher($Xl, $Xr);
+ $cipherText .= pack("N2", $Xl, $Xr);
+ }
+ return $cipherText;
+ }
+
+
+ /**
+ * Decrypts an encrypted string
+ *
+ * @param string $cipherText
+ * @return string Returns plain text on success, PEAR_Error on failure
+ * @access public
+ */
+ function decrypt($cipherText)
+ {
+ if (!is_string($cipherText)) {
+ PEAR::raiseError('Cipher text must be a string', 1, PEAR_ERROR_DIE);
+ }
+
+ if (extension_loaded('mcrypt')) {
+ return mdecrypt_generic($this->_td, $cipherText);
+ }
+
+ $plainText = '';
+ $len = strlen($cipherText);
+ $cipherText .= str_repeat(chr(0),(8 - ($len%8))%8);
+ for ($i = 0; $i < $len; $i += 8) {
+ list(,$Xl,$Xr) = unpack("N2",substr($cipherText,$i,8));
+ $this->_decipher($Xl, $Xr);
+ $plainText .= pack("N2", $Xl, $Xr);
+ }
+ return $plainText;
+ }
+
+
+ /**
+ * Sets the secret key
+ * The key must be non-zero, and less than or equal to
+ * 56 characters in length.
+ *
+ * @param string $key
+ * @return bool Returns true on success, PEAR_Error on failure
+ * @access public
+ */
+ function setKey($key)
+ {
+ if (!is_string($key)) {
+ PEAR::raiseError('Key must be a string', 2, PEAR_ERROR_DIE);
+ }
+
+ $len = strlen($key);
+
+ if ($len > 56 || $len == 0) {
+ PEAR::raiseError('Key must be less than 56 characters and non-zero. Supplied key length: ' . $len, 3, PEAR_ERROR_DIE);
+ }
+
+ if (extension_loaded('mcrypt')) {
+ mcrypt_generic_init($this->_td, $key, $this->_iv);
+ return true;
+ }
+
+ require_once 'Blowfish/DefaultKey.php';
+ $this->_init();
+
+ $k = 0;
+ $data = 0;
+ $datal = 0;
+ $datar = 0;
+
+ for ($i = 0; $i < 18; $i++) {
+ $data = 0;
+ for ($j = 4; $j > 0; $j--) {
+ $data = $data << 8 | ord($key{$k});
+ $k = ($k+1) % $len;
+ }
+ $this->_P[$i] ^= $data;
+ }
+
+ for ($i = 0; $i <= 16; $i += 2) {
+ $this->_encipher($datal, $datar);
+ $this->_P[$i] = $datal;
+ $this->_P[$i+1] = $datar;
+ }
+ for ($i = 0; $i < 256; $i += 2) {
+ $this->_encipher($datal, $datar);
+ $this->_S[0][$i] = $datal;
+ $this->_S[0][$i+1] = $datar;
+ }
+ for ($i = 0; $i < 256; $i += 2) {
+ $this->_encipher($datal, $datar);
+ $this->_S[1][$i] = $datal;
+ $this->_S[1][$i+1] = $datar;
+ }
+ for ($i = 0; $i < 256; $i += 2) {
+ $this->_encipher($datal, $datar);
+ $this->_S[2][$i] = $datal;
+ $this->_S[2][$i+1] = $datar;
+ }
+ for ($i = 0; $i < 256; $i += 2) {
+ $this->_encipher($datal, $datar);
+ $this->_S[3][$i] = $datal;
+ $this->_S[3][$i+1] = $datar;
+ }
+
+ return true;
+ }
+
+}
+
+?>
diff --git a/apps/files_encryption/3rdparty/Crypt_Blowfish/Blowfish/DefaultKey.php b/apps/files_encryption/3rdparty/Crypt_Blowfish/Blowfish/DefaultKey.php
new file mode 100644
index 0000000000000000000000000000000000000000..2ff8ac788a6b62a4abde68d476c673612b8bfe01
--- /dev/null
+++ b/apps/files_encryption/3rdparty/Crypt_Blowfish/Blowfish/DefaultKey.php
@@ -0,0 +1,327 @@
+
+ * @copyright 2005 Matthew Fonda
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version CVS: $Id: DefaultKey.php,v 1.81 2005/05/30 18:40:37 mfonda Exp $
+ * @link http://pear.php.net/package/Crypt_Blowfish
+ */
+
+
+/**
+ * Class containing default key
+ *
+ * @category Encryption
+ * @package Crypt_Blowfish
+ * @author Matthew Fonda
+ * @copyright 2005 Matthew Fonda
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @link http://pear.php.net/package/Crypt_Blowfish
+ * @version @package_version@
+ * @access public
+ */
+class Crypt_Blowfish_DefaultKey
+{
+ var $P = array();
+
+ var $S = array();
+
+ function Crypt_Blowfish_DefaultKey()
+ {
+ $this->P = array(
+ 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344,
+ 0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89,
+ 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
+ 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917,
+ 0x9216D5D9, 0x8979FB1B
+ );
+
+ $this->S = array(
+ array(
+ 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7,
+ 0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99,
+ 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16,
+ 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E,
+ 0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE,
+ 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013,
+ 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF,
+ 0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E,
+ 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60,
+ 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440,
+ 0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE,
+ 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
+ 0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E,
+ 0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677,
+ 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193,
+ 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032,
+ 0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88,
+ 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
+ 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E,
+ 0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0,
+ 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3,
+ 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98,
+ 0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88,
+ 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
+ 0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6,
+ 0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D,
+ 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B,
+ 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7,
+ 0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA,
+ 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463,
+ 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F,
+ 0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09,
+ 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3,
+ 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB,
+ 0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279,
+ 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
+ 0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB,
+ 0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82,
+ 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB,
+ 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573,
+ 0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0,
+ 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B,
+ 0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790,
+ 0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8,
+ 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4,
+ 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0,
+ 0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7,
+ 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
+ 0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD,
+ 0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1,
+ 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299,
+ 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9,
+ 0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477,
+ 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
+ 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49,
+ 0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF,
+ 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA,
+ 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5,
+ 0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41,
+ 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
+ 0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400,
+ 0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915,
+ 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664,
+ 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A
+ ),
+ array(
+ 0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623,
+ 0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266,
+ 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1,
+ 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E,
+ 0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6,
+ 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
+ 0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E,
+ 0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1,
+ 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
+ 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8,
+ 0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF,
+ 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
+ 0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701,
+ 0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7,
+ 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41,
+ 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331,
+ 0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF,
+ 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
+ 0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E,
+ 0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87,
+ 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C,
+ 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2,
+ 0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16,
+ 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
+ 0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B,
+ 0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509,
+ 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
+ 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3,
+ 0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F,
+ 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A,
+ 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4,
+ 0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960,
+ 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66,
+ 0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28,
+ 0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802,
+ 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
+ 0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510,
+ 0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF,
+ 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14,
+ 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E,
+ 0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50,
+ 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7,
+ 0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8,
+ 0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281,
+ 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
+ 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696,
+ 0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128,
+ 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
+ 0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0,
+ 0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0,
+ 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105,
+ 0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250,
+ 0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3,
+ 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
+ 0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00,
+ 0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061,
+ 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB,
+ 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E,
+ 0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735,
+ 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
+ 0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9,
+ 0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340,
+ 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20,
+ 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7
+ ),
+ array(
+ 0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934,
+ 0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068,
+ 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF,
+ 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840,
+ 0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45,
+ 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504,
+ 0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A,
+ 0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB,
+ 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
+ 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6,
+ 0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42,
+ 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
+ 0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2,
+ 0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB,
+ 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527,
+ 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B,
+ 0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33,
+ 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
+ 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3,
+ 0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC,
+ 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17,
+ 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564,
+ 0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B,
+ 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
+ 0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922,
+ 0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728,
+ 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0,
+ 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E,
+ 0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37,
+ 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D,
+ 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804,
+ 0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B,
+ 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3,
+ 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB,
+ 0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D,
+ 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
+ 0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350,
+ 0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9,
+ 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A,
+ 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE,
+ 0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D,
+ 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC,
+ 0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F,
+ 0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61,
+ 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2,
+ 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9,
+ 0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2,
+ 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
+ 0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E,
+ 0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633,
+ 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10,
+ 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169,
+ 0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52,
+ 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
+ 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5,
+ 0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62,
+ 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634,
+ 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76,
+ 0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24,
+ 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
+ 0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4,
+ 0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C,
+ 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837,
+ 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0
+ ),
+ array(
+ 0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B,
+ 0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE,
+ 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B,
+ 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4,
+ 0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8,
+ 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6,
+ 0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304,
+ 0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22,
+ 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4,
+ 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6,
+ 0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9,
+ 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
+ 0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593,
+ 0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51,
+ 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28,
+ 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C,
+ 0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B,
+ 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
+ 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C,
+ 0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD,
+ 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A,
+ 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319,
+ 0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB,
+ 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
+ 0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991,
+ 0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32,
+ 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680,
+ 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166,
+ 0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE,
+ 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB,
+ 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5,
+ 0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47,
+ 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370,
+ 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D,
+ 0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84,
+ 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
+ 0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8,
+ 0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD,
+ 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9,
+ 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7,
+ 0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38,
+ 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F,
+ 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C,
+ 0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525,
+ 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
+ 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442,
+ 0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964,
+ 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
+ 0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8,
+ 0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D,
+ 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F,
+ 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299,
+ 0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02,
+ 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
+ 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614,
+ 0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A,
+ 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6,
+ 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B,
+ 0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0,
+ 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
+ 0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E,
+ 0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9,
+ 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
+ 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6
+ )
+ );
+ }
+
+}
+
+?>
diff --git a/apps/files_encryption/ajax/adminrecovery.php b/apps/files_encryption/ajax/adminrecovery.php
new file mode 100644
index 0000000000000000000000000000000000000000..6a0186d5a9b1b14d343a486eeb3ac22903cccba9
--- /dev/null
+++ b/apps/files_encryption/ajax/adminrecovery.php
@@ -0,0 +1,59 @@
+
+ * This file is licensed under the Affero General Public License version 3 or later.
+ * See the COPYING-README file.
+ *
+ * @brief Script to handle admin settings for encrypted key recovery
+ */
+use OCA\Encryption;
+
+\OCP\JSON::checkAdminUser();
+\OCP\JSON::checkAppEnabled('files_encryption');
+\OCP\JSON::callCheck();
+
+$l = OC_L10N::get('files_encryption');
+
+$return = false;
+// Enable recoveryAdmin
+
+$recoveryKeyId = OC_Appconfig::getValue('files_encryption', 'recoveryKeyId');
+
+if (isset($_POST['adminEnableRecovery']) && $_POST['adminEnableRecovery'] === '1') {
+
+ $return = \OCA\Encryption\Helper::adminEnableRecovery($recoveryKeyId, $_POST['recoveryPassword']);
+
+ // Return success or failure
+ if ($return) {
+ \OCP\JSON::success(array('data' => array('message' => $l->t('Recovery key successfully enabled'))));
+ } else {
+ \OCP\JSON::error(array(
+ 'data' => array(
+ 'message' => $l->t(
+ 'Could not enable recovery key. Please check your recovery key password!')
+ )
+ ));
+ }
+
+// Disable recoveryAdmin
+} elseif (
+ isset($_POST['adminEnableRecovery'])
+ && '0' === $_POST['adminEnableRecovery']
+) {
+ $return = \OCA\Encryption\Helper::adminDisableRecovery($_POST['recoveryPassword']);
+
+ // Return success or failure
+ if ($return) {
+ \OCP\JSON::success(array('data' => array('message' => $l->t('Recovery key successfully disabled'))));
+ } else {
+ \OCP\JSON::error(array(
+ 'data' => array(
+ 'message' => $l->t(
+ 'Could not disable recovery key. Please check your recovery key password!')
+ )
+ ));
+ }
+}
+
+
diff --git a/apps/files_encryption/ajax/changeRecoveryPassword.php b/apps/files_encryption/ajax/changeRecoveryPassword.php
new file mode 100644
index 0000000000000000000000000000000000000000..366f634a51cc0504887abd1c599e320b404b4a5d
--- /dev/null
+++ b/apps/files_encryption/ajax/changeRecoveryPassword.php
@@ -0,0 +1,52 @@
+
+ * This file is licensed under the Affero General Public License version 3 or later.
+ * See the COPYING-README file.
+ *
+ * @brief Script to change recovery key password
+ *
+ */
+
+use OCA\Encryption;
+
+\OCP\JSON::checkAdminUser();
+\OCP\JSON::checkAppEnabled('files_encryption');
+\OCP\JSON::callCheck();
+
+$l = OC_L10N::get('core');
+
+$return = false;
+
+$oldPassword = $_POST['oldPassword'];
+$newPassword = $_POST['newPassword'];
+
+$view = new \OC\Files\View('/');
+$util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), \OCP\User::getUser());
+
+$proxyStatus = \OC_FileProxy::$enabled;
+\OC_FileProxy::$enabled = false;
+
+$keyId = $util->getRecoveryKeyId();
+$keyPath = '/owncloud_private_key/' . $keyId . '.private.key';
+
+$encryptedRecoveryKey = $view->file_get_contents($keyPath);
+$decryptedRecoveryKey = \OCA\Encryption\Crypt::decryptPrivateKey($encryptedRecoveryKey, $oldPassword);
+
+if ($decryptedRecoveryKey) {
+
+ $encryptedRecoveryKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent($decryptedRecoveryKey, $newPassword);
+ $view->file_put_contents($keyPath, $encryptedRecoveryKey);
+
+ $return = true;
+}
+
+\OC_FileProxy::$enabled = $proxyStatus;
+
+// success or failure
+if ($return) {
+ \OCP\JSON::success(array('data' => array('message' => $l->t('Password successfully changed.'))));
+} else {
+ \OCP\JSON::error(array('data' => array('message' => $l->t('Could not change the password. Maybe the old password was not correct.'))));
+}
\ No newline at end of file
diff --git a/apps/files_encryption/ajax/updatePrivateKeyPassword.php b/apps/files_encryption/ajax/updatePrivateKeyPassword.php
new file mode 100644
index 0000000000000000000000000000000000000000..6fd63dae9cdc2f7c5573a031ceedc4c9e091cebb
--- /dev/null
+++ b/apps/files_encryption/ajax/updatePrivateKeyPassword.php
@@ -0,0 +1,54 @@
+
+ * This file is licensed under the Affero General Public License version 3 or later.
+ * See the COPYING-README file.
+ *
+ * @brief Script to change recovery key password
+ *
+ */
+
+use OCA\Encryption;
+
+\OCP\JSON::checkLoggedIn();
+\OCP\JSON::checkAppEnabled('files_encryption');
+\OCP\JSON::callCheck();
+
+$l = OC_L10N::get('core');
+
+$return = false;
+
+$oldPassword = $_POST['oldPassword'];
+$newPassword = $_POST['newPassword'];
+
+$view = new \OC\Files\View('/');
+$session = new \OCA\Encryption\Session($view);
+$user = \OCP\User::getUser();
+
+$proxyStatus = \OC_FileProxy::$enabled;
+\OC_FileProxy::$enabled = false;
+
+$keyPath = '/' . $user . '/files_encryption/' . $user . '.private.key';
+
+$encryptedKey = $view->file_get_contents($keyPath);
+$decryptedKey = \OCA\Encryption\Crypt::decryptPrivateKey($encryptedKey, $oldPassword);
+
+if ($decryptedKey) {
+
+ $encryptedKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent($decryptedKey, $newPassword);
+ $view->file_put_contents($keyPath, $encryptedKey);
+
+ $session->setPrivateKey($decryptedKey);
+
+ $return = true;
+}
+
+\OC_FileProxy::$enabled = $proxyStatus;
+
+// success or failure
+if ($return) {
+ \OCP\JSON::success(array('data' => array('message' => $l->t('Private key password successfully updated.'))));
+} else {
+ \OCP\JSON::error(array('data' => array('message' => $l->t('Could not update the private key password. Maybe the old password was not correct.'))));
+}
\ No newline at end of file
diff --git a/apps/files_encryption/ajax/userrecovery.php b/apps/files_encryption/ajax/userrecovery.php
new file mode 100644
index 0000000000000000000000000000000000000000..1d0f1ac2d17219c044942f33cc84c6df36a296ab
--- /dev/null
+++ b/apps/files_encryption/ajax/userrecovery.php
@@ -0,0 +1,41 @@
+
+ * This file is licensed under the Affero General Public License version 3 or later.
+ * See the COPYING-README file.
+ *
+ * @brief Script to handle admin settings for encrypted key recovery
+ */
+
+use OCA\Encryption;
+
+\OCP\JSON::checkLoggedIn();
+\OCP\JSON::checkAppEnabled('files_encryption');
+\OCP\JSON::callCheck();
+
+if (
+ isset($_POST['userEnableRecovery'])
+ && (0 == $_POST['userEnableRecovery'] || '1' === $_POST['userEnableRecovery'])
+) {
+
+ $userId = \OCP\USER::getUser();
+ $view = new \OC_FilesystemView('/');
+ $util = new \OCA\Encryption\Util($view, $userId);
+
+ // Save recovery preference to DB
+ $return = $util->setRecoveryForUser($_POST['userEnableRecovery']);
+
+ if ($_POST['userEnableRecovery'] === '1') {
+ $util->addRecoveryKeys();
+ } else {
+ $util->removeRecoveryKeys();
+ }
+
+} else {
+
+ $return = false;
+
+}
+
+// Return success or failure
+($return) ? \OCP\JSON::success() : \OCP\JSON::error();
\ No newline at end of file
diff --git a/apps/files_encryption/appinfo/app.php b/apps/files_encryption/appinfo/app.php
index bf16fec3aea0d60678d0a26d8121c9cbd0413868..90a9984e27f17ea1b1922b09279ac8c2124ea41c 100644
--- a/apps/files_encryption/appinfo/app.php
+++ b/apps/files_encryption/appinfo/app.php
@@ -8,42 +8,63 @@ OC::$CLASSPATH['OCA\Encryption\Stream'] = 'files_encryption/lib/stream.php';
OC::$CLASSPATH['OCA\Encryption\Proxy'] = 'files_encryption/lib/proxy.php';
OC::$CLASSPATH['OCA\Encryption\Session'] = 'files_encryption/lib/session.php';
OC::$CLASSPATH['OCA\Encryption\Capabilities'] = 'files_encryption/lib/capabilities.php';
+OC::$CLASSPATH['OCA\Encryption\Helper'] = 'files_encryption/lib/helper.php';
-OC_FileProxy::register( new OCA\Encryption\Proxy() );
+if (!OC_Config::getValue('maintenance', false)) {
+ OC_FileProxy::register(new OCA\Encryption\Proxy());
-// User-related hooks
-OCP\Util::connectHook( 'OC_User', 'post_login', 'OCA\Encryption\Hooks', 'login' );
-OCP\Util::connectHook( 'OC_User', 'pre_setPassword', 'OCA\Encryption\Hooks', 'setPassphrase' );
+ // User related hooks
+ OCA\Encryption\Helper::registerUserHooks();
-// Sharing-related hooks
-OCP\Util::connectHook( 'OCP\Share', 'post_shared', 'OCA\Encryption\Hooks', 'postShared' );
-OCP\Util::connectHook( 'OCP\Share', 'pre_unshare', 'OCA\Encryption\Hooks', 'preUnshare' );
-OCP\Util::connectHook( 'OCP\Share', 'pre_unshareAll', 'OCA\Encryption\Hooks', 'preUnshareAll' );
+ // Sharing related hooks
+ OCA\Encryption\Helper::registerShareHooks();
-// Webdav-related hooks
-OCP\Util::connectHook( 'OC_Webdav_Properties', 'update', 'OCA\Encryption\Hooks', 'updateKeyfile' );
+ // Filesystem related hooks
+ OCA\Encryption\Helper::registerFilesystemHooks();
-stream_wrapper_register( 'crypt', 'OCA\Encryption\Stream' );
+ // App manager related hooks
+ OCA\Encryption\Helper::registerAppHooks();
-$session = new OCA\Encryption\Session();
+ stream_wrapper_register('crypt', 'OCA\Encryption\Stream');
-if (
- ! $session->getPrivateKey( \OCP\USER::getUser() )
- && OCP\User::isLoggedIn()
- && OCA\Encryption\Crypt::mode() == 'server'
-) {
+ // check if we are logged in
+ if (OCP\User::isLoggedIn()) {
- // Force the user to log-in again if the encryption key isn't unlocked
- // (happens when a user is logged in before the encryption app is
- // enabled)
- OCP\User::logout();
-
- header( "Location: " . OC::$WEBROOT.'/' );
-
- exit();
+ // ensure filesystem is loaded
+ if (!\OC\Files\Filesystem::$loaded) {
+ \OC_Util::setupFS();
+ }
+
+ $view = new OC_FilesystemView('/');
+
+ $sessionReady = OCA\Encryption\Helper::checkRequirements();
+ if($sessionReady) {
+ $session = new \OCA\Encryption\Session($view);
+ }
+
+ $user = \OCP\USER::getUser();
+ // check if user has a private key
+ if ($sessionReady === false
+ || (!$view->file_exists('/' . $user . '/files_encryption/' . $user . '.private.key')
+ && OCA\Encryption\Crypt::mode() === 'server')
+ ) {
+ // Force the user to log-in again if the encryption key isn't unlocked
+ // (happens when a user is logged in before the encryption app is
+ // enabled)
+ OCP\User::logout();
+
+ header("Location: " . OC::$WEBROOT . '/');
+
+ exit();
+ }
+ }
+} else {
+ // logout user if we are in maintenance to force re-login
+ OCP\User::logout();
}
// Register settings scripts
-OCP\App::registerAdmin( 'files_encryption', 'settings' );
-OCP\App::registerPersonal( 'files_encryption', 'settings-personal' );
+OCP\App::registerAdmin('files_encryption', 'settings-admin');
+OCP\App::registerPersonal('files_encryption', 'settings-personal');
+
diff --git a/apps/files_encryption/appinfo/database.xml b/apps/files_encryption/appinfo/database.xml
index d294c35d63d0052e14cc188cebb3603822113aac..4587930da0a3c25fb3eecbb4c39afebf9de866ec 100644
--- a/apps/files_encryption/appinfo/database.xml
+++ b/apps/files_encryption/appinfo/database.xml
@@ -18,6 +18,21 @@
texttrue64
+ What client-side / server-side configuration is used
+
+
+ recovery_enabled
+ integer
+ true
+ 0
+ Whether encryption key recovery is enabled
+
+
+ migration_status
+ integer
+ true
+ 0
+ Whether encryption migration has been performed
diff --git a/apps/files_encryption/appinfo/info.xml b/apps/files_encryption/appinfo/info.xml
index 39ea155488f4f1944a152cc4b85b49bd0394b5fb..46f1375c9875a41bc558a29e49db1db619d93b8e 100644
--- a/apps/files_encryption/appinfo/info.xml
+++ b/apps/files_encryption/appinfo/info.xml
@@ -2,9 +2,9 @@
files_encryptionEncryption
- Server side encryption of files. Warning: You will lose your data if you enable this App and forget your password. Encryption is not yet compatible with LDAP.
+ The new ownCloud 5 files encryption system. After the app was enabled you need to re-login to initialize your encryption keys.AGPL
- Sam Tuke
+ Sam Tuke, Bjoern Schiessle, Florin Peter4true
diff --git a/apps/files_encryption/appinfo/spec.txt b/apps/files_encryption/appinfo/spec.txt
index 2d22dffe08da9d3e1a331aff5166aa9dfd05e16c..ddd3983a9eba2f2e33850d0fe57532093e7c7584 100644
--- a/apps/files_encryption/appinfo/spec.txt
+++ b/apps/files_encryption/appinfo/spec.txt
@@ -9,6 +9,57 @@ Encrypted files
[encrypted data string][delimiter][IV][padding]
[anhAAjAmcGXqj1X9g==][00iv00][MSHU5N5gECP7aAg7][xx] (square braces added)
+
+- Directory structure:
+ - Encrypted user data (catfiles) are stored in the usual /data/user/files dir
+ - Keyfiles are stored in /data/user/files_encryption/keyfiles
+ - Sharekey are stored in /data/user/files_encryption/share-files
+
+- File extensions:
+ - Catfiles have to keep the file extension of the original file, pre-encryption
+ - Keyfiles use .keyfile
+ - Sharekeys have .shareKey
+
+Shared files
+------------
+
+Shared files have a centrally stored catfile and keyfile, and one sharekey for
+each user that shares it.
+
+When sharing is used, a different encryption method is used to encrypt the
+keyfile (openssl_seal). Although shared files have a keyfile, its contents
+use a different format therefore.
+
+Each time a shared file is edited or deleted, all sharekeys for users sharing
+that file must have their sharekeys changed also. The keyfile and catfile
+however need only changing in the owners files, as there is only one copy of
+these.
+
+Publicly shared files (public links)
+------------------------------------
+
+Files shared via public links use a separate system user account called 'ownCloud'. All public files are shared to that user's public key, and the private key is used to access the files when the public link is used in browser.
+
+This means that files shared via public links are accessible only to users who know the shared URL, or to admins who know the 'ownCloud' user password.
+
+Lost password recovery
+----------------------
+
+In order to enable users to read their encrypted files in the event of a password loss/reset scenario, administrators can choose to enable a 'recoveryAdmin' account. This is a user that all user files will automatically be shared to of the option is enabled. This allows the recoveryAdmin user to generate new keyfiles for the user. By default the UID of the recoveryAdmin is 'recoveryAdmin'.
+
+OC_FilesystemView
+-----------------
+
+files_encryption deals extensively with paths and the filesystem. In order to minimise bugs, it makes calls to filesystem methods in a consistent way: OC_FilesystemView{} objects always use '/' as their root, and specify paths each time particular methods are called. e.g. do this:
+
+$view->file_exists( 'path/to/file' );
+
+Not:
+
+$view->chroot( 'path/to' );
+$view->file_exists( 'file' );
+
+Using this convention means that $view objects are more predictable and less likely to break. Problems with paths are the #1 cause of bugs in this app, and consistent $view handling is an important way to prevent them.
Notes
-----
@@ -16,4 +67,11 @@ Notes
- The user passphrase is required in order to set up or upgrade the app. New
keypair generation, and the re-encryption of legacy encrypted files requires
it. Therefore an appinfo/update.php script cannot be used, and upgrade logic
- is handled in the login hook listener.
\ No newline at end of file
+ is handled in the login hook listener. Therefore each time the user logs in
+ their files are scanned to detect unencrypted and legacy encrypted files, and
+ they are (re)encrypted as necessary. This may present a performance issue; we
+ need to monitor this.
+- When files are saved to ownCloud via WebDAV, a .part file extension is used so
+ that the file isn't cached before the upload has been completed. .part files
+ are not compatible with files_encrytion's key management system however, so
+ we have to always sanitise such paths manually before using them.
\ No newline at end of file
diff --git a/apps/files_encryption/appinfo/version b/apps/files_encryption/appinfo/version
index 1d71ef97443918d538e8188167c94d7bbafaf753..bd73f47072b1fe4b9914ec14a7f6d47fcc8f816a 100644
--- a/apps/files_encryption/appinfo/version
+++ b/apps/files_encryption/appinfo/version
@@ -1 +1 @@
-0.3
\ No newline at end of file
+0.4
diff --git a/apps/files_encryption/css/settings-personal.css b/apps/files_encryption/css/settings-personal.css
new file mode 100644
index 0000000000000000000000000000000000000000..4ee0acc9768ce52dc9262764086ecc2f66400b1d
--- /dev/null
+++ b/apps/files_encryption/css/settings-personal.css
@@ -0,0 +1,10 @@
+/* Copyright (c) 2013, Sam Tuke,
+ This file is licensed under the Affero General Public License version 3 or later.
+ See the COPYING-README file. */
+
+#encryptAllError
+, #encryptAllSuccess
+, #recoveryEnabledError
+, #recoveryEnabledSuccess {
+ display: none;
+}
\ No newline at end of file
diff --git a/apps/files_encryption/files/error.php b/apps/files_encryption/files/error.php
new file mode 100644
index 0000000000000000000000000000000000000000..f93c67d920a427f486b4e6adc452ee1547454428
--- /dev/null
+++ b/apps/files_encryption/files/error.php
@@ -0,0 +1,23 @@
+t('Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files.');
+
+ if(isset($_GET['p']) && $_GET['p'] === '1') {
+ header('HTTP/1.0 404 ' . $errorMsg);
+ }
+
+ // check if ajax request
+ if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
+ \OCP\JSON::error(array('data' => array('message' => $errorMsg)));
+ } else {
+ header('HTTP/1.0 404 ' . $errorMsg);
+ $tmpl = new OC_Template('files_encryption', 'invalid_private_key', 'guest');
+ $tmpl->printPage();
+ }
+
+ exit;
+}
diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php
index 2731d5a92f74ad4ed435d77a37d35cc9018cb7df..b2a17f6bca5e344646a76a8e42354d765f439ed4 100644
--- a/apps/files_encryption/hooks/hooks.php
+++ b/apps/files_encryption/hooks/hooks.php
@@ -23,10 +23,11 @@
namespace OCA\Encryption;
+use OC\Files\Filesystem;
+
/**
* Class for hook specific logic
*/
-
class Hooks {
// TODO: use passphrase for encrypting private key that is separate to
@@ -36,156 +37,531 @@ class Hooks {
* @brief Startup encryption backend upon user login
* @note This method should never be called for users using client side encryption
*/
- public static function login( $params ) {
-
- // Manually initialise Filesystem{} singleton with correct
- // fake root path, in order to avoid fatal webdav errors
- \OC\Files\Filesystem::init( $params['uid'], $params['uid'] . '/' . 'files' . '/' );
-
- $view = new \OC_FilesystemView( '/' );
-
- $util = new Util( $view, $params['uid'] );
-
- // Check files_encryption infrastructure is ready for action
- if ( ! $util->ready() ) {
-
- \OC_Log::write( 'Encryption library', 'User account "' . $params['uid'] . '" is not ready for encryption; configuration started', \OC_Log::DEBUG );
-
- return $util->setupServerSide( $params['password'] );
-
- }
-
- \OC_FileProxy::$enabled = false;
-
- $encryptedKey = Keymanager::getPrivateKey( $view, $params['uid'] );
-
- \OC_FileProxy::$enabled = true;
-
- $privateKey = Crypt::symmetricDecryptFileContent( $encryptedKey, $params['password'] );
-
- $session = new Session();
-
- $session->setPrivateKey( $privateKey, $params['uid'] );
-
- $view1 = new \OC_FilesystemView( '/' . $params['uid'] );
-
- // Set legacy encryption key if it exists, to support
- // depreciated encryption system
- if (
- $view1->file_exists( 'encryption.key' )
- && $encLegacyKey = $view1->file_get_contents( 'encryption.key' )
- ) {
-
- $plainLegacyKey = Crypt::legacyDecrypt( $encLegacyKey, $params['password'] );
-
- $session->setLegacyKey( $plainLegacyKey );
-
- }
-
- $publicKey = Keymanager::getPublicKey( $view, $params['uid'] );
-
- // Encrypt existing user files:
- // This serves to upgrade old versions of the encryption
- // app (see appinfo/spec.txt)
- if (
- $util->encryptAll( $publicKey, '/' . $params['uid'] . '/' . 'files', $session->getLegacyKey(), $params['password'] )
- ) {
-
- \OC_Log::write(
- 'Encryption library', 'Encryption of existing files belonging to "' . $params['uid'] . '" started at login'
- , \OC_Log::INFO
- );
-
+ public static function login($params) {
+ $l = new \OC_L10N('files_encryption');
+ //check if all requirements are met
+ if(!Helper::checkRequirements() ) {
+ $error_msg = $l->t("Missing requirements.");
+ $hint = $l->t('Please make sure that PHP 5.3.3 or newer is installed and that the OpenSSL PHP extension is enabled and configured properly. For now, the encryption app has been disabled.');
+ \OC_App::disable('files_encryption');
+ \OCP\Util::writeLog('Encryption library', $error_msg . ' ' . $hint, \OCP\Util::ERROR);
+ \OCP\Template::printErrorPage($error_msg, $hint);
+ }
+
+ $view = new \OC_FilesystemView('/');
+
+ // ensure filesystem is loaded
+ if(!\OC\Files\Filesystem::$loaded) {
+ \OC_Util::setupFS($params['uid']);
+ }
+
+ $util = new Util($view, $params['uid']);
+
+ // setup user, if user not ready force relogin
+ if (Helper::setupUser($util, $params['password']) === false) {
+ return false;
+ }
+
+ $encryptedKey = Keymanager::getPrivateKey($view, $params['uid']);
+
+ $privateKey = Crypt::decryptPrivateKey($encryptedKey, $params['password']);
+
+ if ($privateKey === false) {
+ \OCP\Util::writeLog('Encryption library', 'Private key for user "' . $params['uid']
+ . '" is not valid! Maybe the user password was changed from outside if so please change it back to gain access', \OCP\Util::ERROR);
+ }
+
+ $session = new \OCA\Encryption\Session($view);
+
+ $session->setPrivateKey($privateKey);
+
+ // Check if first-run file migration has already been performed
+ $ready = false;
+ if ($util->getMigrationStatus() === Util::MIGRATION_OPEN) {
+ $ready = $util->beginMigration();
+ }
+
+ // If migration not yet done
+ if ($ready) {
+
+ $userView = new \OC_FilesystemView('/' . $params['uid']);
+
+ // Set legacy encryption key if it exists, to support
+ // depreciated encryption system
+ if (
+ $userView->file_exists('encryption.key')
+ && $encLegacyKey = $userView->file_get_contents('encryption.key')
+ ) {
+
+ $plainLegacyKey = Crypt::legacyDecrypt($encLegacyKey, $params['password']);
+
+ $session->setLegacyKey($plainLegacyKey);
+
+ }
+
+ // Encrypt existing user files:
+ // This serves to upgrade old versions of the encryption
+ // app (see appinfo/spec.txt)
+ if (
+ $util->encryptAll('/' . $params['uid'] . '/' . 'files', $session->getLegacyKey(), $params['password'])
+ ) {
+
+ \OC_Log::write(
+ 'Encryption library', 'Encryption of existing files belonging to "' . $params['uid'] . '" completed'
+ , \OC_Log::INFO
+ );
+
+ }
+
+ // Register successful migration in DB
+ $util->finishMigration();
+
}
return true;
}
-
+
+ /**
+ * @brief setup encryption backend upon user created
+ * @note This method should never be called for users using client side encryption
+ */
+ public static function postCreateUser($params) {
+ $view = new \OC_FilesystemView('/');
+
+ $util = new Util($view, $params['uid']);
+
+ Helper::setupUser($util, $params['password']);
+ }
+
+ /**
+ * @brief cleanup encryption backend upon user deleted
+ * @note This method should never be called for users using client side encryption
+ */
+ public static function postDeleteUser($params) {
+ $view = new \OC_FilesystemView('/');
+
+ // cleanup public key
+ $publicKey = '/public-keys/' . $params['uid'] . '.public.key';
+
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ $view->unlink($publicKey);
+
+ \OC_FileProxy::$enabled = $proxyStatus;
+ }
+
+ /**
+ * @brief If the password can't be changed within ownCloud, than update the key password in advance.
+ */
+ public static function preSetPassphrase($params) {
+ if ( ! \OC_User::canUserChangePassword($params['uid']) ) {
+ self::setPassphrase($params);
+ }
+ }
+
/**
* @brief Change a user's encryption passphrase
* @param array $params keys: uid, password
*/
- public static function setPassphrase( $params ) {
-
+ public static function setPassphrase($params) {
+
// Only attempt to change passphrase if server-side encryption
- // is in use (client-side encryption does not have access to
+ // is in use (client-side encryption does not have access to
// the necessary keys)
- if ( Crypt::mode() == 'server' ) {
-
- $session = new Session();
-
- // Get existing decrypted private key
- $privateKey = $session->getPrivateKey();
-
- // Encrypt private key with new user pwd as passphrase
- $encryptedPrivateKey = Crypt::symmetricEncryptFileContent( $privateKey, $params['password'] );
-
- // Save private key
- Keymanager::setPrivateKey( $encryptedPrivateKey );
-
- // NOTE: Session does not need to be updated as the
- // private key has not changed, only the passphrase
- // used to decrypt it has changed
-
- }
-
+ if (Crypt::mode() === 'server') {
+
+ if ($params['uid'] === \OCP\User::getUser()) {
+
+ $view = new \OC_FilesystemView('/');
+
+ $session = new \OCA\Encryption\Session($view);
+
+ // Get existing decrypted private key
+ $privateKey = $session->getPrivateKey();
+
+ // Encrypt private key with new user pwd as passphrase
+ $encryptedPrivateKey = Crypt::symmetricEncryptFileContent($privateKey, $params['password']);
+
+ // Save private key
+ Keymanager::setPrivateKey($encryptedPrivateKey);
+
+ // NOTE: Session does not need to be updated as the
+ // private key has not changed, only the passphrase
+ // used to decrypt it has changed
+
+
+ } else { // admin changed the password for a different user, create new keys and reencrypt file keys
+
+ $user = $params['uid'];
+ $recoveryPassword = $params['recoveryPassword'];
+ $newUserPassword = $params['password'];
+
+ $view = new \OC_FilesystemView('/');
+
+ // make sure that the users home is mounted
+ \OC\Files\Filesystem::initMountPoints($user);
+
+ $keypair = Crypt::createKeypair();
+
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ // Save public key
+ $view->file_put_contents('/public-keys/' . $user . '.public.key', $keypair['publicKey']);
+
+ // Encrypt private key empty passphrase
+ $encryptedPrivateKey = Crypt::symmetricEncryptFileContent($keypair['privateKey'], $newUserPassword);
+
+ // Save private key
+ $view->file_put_contents(
+ '/' . $user . '/files_encryption/' . $user . '.private.key', $encryptedPrivateKey);
+
+ if ($recoveryPassword) { // if recovery key is set we can re-encrypt the key files
+ $util = new Util($view, $user);
+ $util->recoverUsersFiles($recoveryPassword);
+ }
+
+ \OC_FileProxy::$enabled = $proxyStatus;
+ }
+ }
}
-
+
+ /*
+ * @brief check if files can be encrypted to every user.
+ */
/**
- * @brief update the encryption key of the file uploaded by the client
+ * @param $params
*/
- public static function updateKeyfile( $params ) {
-
- if ( Crypt::mode() == 'client' ) {
-
- if ( isset( $params['properties']['key'] ) ) {
-
- $view = new \OC_FilesystemView( '/' );
- $userId = \OCP\User::getUser();
-
- Keymanager::setFileKey( $view, $params['path'], $userId, $params['properties']['key'] );
-
+ public static function preShared($params) {
+
+ $users = array();
+ $view = new \OC\Files\View('/public-keys/');
+
+ switch ($params['shareType']) {
+ case \OCP\Share::SHARE_TYPE_USER:
+ $users[] = $params['shareWith'];
+ break;
+ case \OCP\Share::SHARE_TYPE_GROUP:
+ $users = \OC_Group::usersInGroup($params['shareWith']);
+ break;
+ }
+
+ $error = false;
+ foreach ($users as $user) {
+ if (!$view->file_exists($user . '.public.key')) {
+ $error = true;
+ break;
+ }
+ }
+
+ if ($error) // Set flag var 'run' to notify emitting
+ // script that hook execution failed
+ {
+ $params['run']->run = false;
+ }
+ // TODO: Make sure files_sharing provides user
+ // feedback on failed share
+ }
+
+ /**
+ * @brief
+ */
+ public static function postShared($params) {
+
+ // NOTE: $params has keys:
+ // [itemType] => file
+ // itemSource -> int, filecache file ID
+ // [parent] =>
+ // [itemTarget] => /13
+ // shareWith -> string, uid of user being shared to
+ // fileTarget -> path of file being shared
+ // uidOwner -> owner of the original file being shared
+ // [shareType] => 0
+ // [shareWith] => test1
+ // [uidOwner] => admin
+ // [permissions] => 17
+ // [fileSource] => 13
+ // [fileTarget] => /test8
+ // [id] => 10
+ // [token] =>
+ // [run] => whether emitting script should continue to run
+ // TODO: Should other kinds of item be encrypted too?
+
+ if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') {
+
+ $view = new \OC_FilesystemView('/');
+ $session = new \OCA\Encryption\Session($view);
+ $userId = \OCP\User::getUser();
+ $util = new Util($view, $userId);
+ $path = $util->fileIdToPath($params['itemSource']);
+
+ $share = $util->getParentFromShare($params['id']);
+ //if parent is set, then this is a re-share action
+ if ($share['parent'] !== null) {
+
+ // get the parent from current share
+ $parent = $util->getShareParent($params['parent']);
+
+ // if parent is file the it is an 1:1 share
+ if ($parent['item_type'] === 'file') {
+
+ // prefix path with Shared
+ $path = '/Shared' . $parent['file_target'];
+ } else {
+
+ // NOTE: parent is folder but shared was a file!
+ // we try to rebuild the missing path
+ // some examples we face here
+ // user1 share folder1 with user2 folder1 has
+ // the following structure
+ // /folder1/subfolder1/subsubfolder1/somefile.txt
+ // user2 re-share subfolder2 with user3
+ // user3 re-share somefile.txt user4
+ // so our path should be
+ // /Shared/subfolder1/subsubfolder1/somefile.txt
+ // while user3 is sharing
+
+ if ($params['itemType'] === 'file') {
+ // get target path
+ $targetPath = $util->fileIdToPath($params['fileSource']);
+ $targetPathSplit = array_reverse(explode('/', $targetPath));
+
+ // init values
+ $path = '';
+ $sharedPart = ltrim($parent['file_target'], '/');
+
+ // rebuild path
+ foreach ($targetPathSplit as $pathPart) {
+ if ($pathPart !== $sharedPart) {
+ $path = '/' . $pathPart . $path;
+ } else {
+ break;
+ }
+ }
+ // prefix path with Shared
+ $path = '/Shared' . $parent['file_target'] . $path;
+ } else {
+ // prefix path with Shared
+ $path = '/Shared' . $parent['file_target'] . $params['fileTarget'];
+ }
+ }
+ }
+
+ $sharingEnabled = \OCP\Share::isEnabled();
+
+ // get the path including mount point only if not a shared folder
+ if (strncmp($path, '/Shared', strlen('/Shared') !== 0)) {
+ // get path including the the storage mount point
+ $path = $util->getPathWithMountPoint($params['itemSource']);
+ }
+
+ // if a folder was shared, get a list of all (sub-)folders
+ if ($params['itemType'] === 'folder') {
+ $allFiles = $util->getAllFiles($path);
} else {
-
- \OC_Log::write(
- 'Encryption library', "Client side encryption is enabled but the client doesn't provide a encryption key for the file!"
- , \OC_Log::ERROR
- );
-
- error_log( "Client side encryption is enabled but the client doesn't provide an encryption key for the file!" );
-
+ $allFiles = array($path);
+ }
+
+ foreach ($allFiles as $path) {
+ $usersSharing = $util->getSharingUsersArray($sharingEnabled, $path);
+ $util->setSharedFileKeyfiles($session, $usersSharing, $path);
}
-
}
-
}
-
+
/**
- * @brief
+ * @brief
*/
- public static function postShared( $params ) {
+ public static function postUnshare($params) {
+
+ // NOTE: $params has keys:
+ // [itemType] => file
+ // [itemSource] => 13
+ // [shareType] => 0
+ // [shareWith] => test1
+ // [itemParent] =>
+
+ if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') {
+
+ $view = new \OC_FilesystemView('/');
+ $userId = \OCP\User::getUser();
+ $util = new Util($view, $userId);
+ $path = $util->fileIdToPath($params['itemSource']);
+
+ // check if this is a re-share
+ if ($params['itemParent']) {
+
+ // get the parent from current share
+ $parent = $util->getShareParent($params['itemParent']);
+
+ // get target path
+ $targetPath = $util->fileIdToPath($params['itemSource']);
+ $targetPathSplit = array_reverse(explode('/', $targetPath));
+
+ // init values
+ $path = '';
+ $sharedPart = ltrim($parent['file_target'], '/');
+
+ // rebuild path
+ foreach ($targetPathSplit as $pathPart) {
+ if ($pathPart !== $sharedPart) {
+ $path = '/' . $pathPart . $path;
+ } else {
+ break;
+ }
+ }
+
+ // prefix path with Shared
+ $path = '/Shared' . $parent['file_target'] . $path;
+ }
+
+ // for group shares get a list of the group members
+ if ($params['shareType'] === \OCP\Share::SHARE_TYPE_GROUP) {
+ $userIds = \OC_Group::usersInGroup($params['shareWith']);
+ } else {
+ if ($params['shareType'] === \OCP\Share::SHARE_TYPE_LINK) {
+ $userIds = array($util->getPublicShareKeyId());
+ } else {
+ $userIds = array($params['shareWith']);
+ }
+ }
+
+ // get the path including mount point only if not a shared folder
+ if (strncmp($path, '/Shared', strlen('/Shared') !== 0)) {
+ // get path including the the storage mount point
+ $path = $util->getPathWithMountPoint($params['itemSource']);
+ }
+
+ // if we unshare a folder we need a list of all (sub-)files
+ if ($params['itemType'] === 'folder') {
+ $allFiles = $util->getAllFiles($path);
+ } else {
+ $allFiles = array($path);
+ }
+
+ foreach ($allFiles as $path) {
+
+ // check if the user still has access to the file, otherwise delete share key
+ $sharingUsers = $util->getSharingUsersArray(true, $path);
+
+ // Unshare every user who no longer has access to the file
+ $delUsers = array_diff($userIds, $sharingUsers);
+
+ // delete share key
+ Keymanager::delShareKey($view, $delUsers, $path);
+ }
+
+ }
}
-
+
/**
- * @brief
+ * @brief after a file is renamed, rename its keyfile and share-keys also fix the file size and fix also the sharing
+ * @param array with oldpath and newpath
+ *
+ * This function is connected to the rename signal of OC_Filesystem and adjust the name and location
+ * of the stored versions along the actual file
*/
- public static function preUnshare( $params ) {
-
- // Delete existing catfile
-
- // Generate new catfile and env keys
-
- // Save env keys to user folders
+ public static function postRename($params) {
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ $view = new \OC_FilesystemView('/');
+ $session = new \OCA\Encryption\Session($view);
+ $userId = \OCP\User::getUser();
+ $util = new Util($view, $userId);
+
+ // Format paths to be relative to user files dir
+ if ($util->isSystemWideMountPoint($params['oldpath'])) {
+ $baseDir = 'files_encryption/';
+ $oldKeyfilePath = $baseDir . 'keyfiles/' . $params['oldpath'];
+ } else {
+ $baseDir = $userId . '/' . 'files_encryption/';
+ $oldKeyfilePath = $baseDir . 'keyfiles/' . $params['oldpath'];
+ }
+
+ if ($util->isSystemWideMountPoint($params['newpath'])) {
+ $newKeyfilePath = $baseDir . 'keyfiles/' . $params['newpath'];
+ } else {
+ $newKeyfilePath = $baseDir . 'keyfiles/' . $params['newpath'];
+ }
+
+ // add key ext if this is not an folder
+ if (!$view->is_dir($oldKeyfilePath)) {
+ $oldKeyfilePath .= '.key';
+ $newKeyfilePath .= '.key';
+
+ // handle share-keys
+ $localKeyPath = $view->getLocalFile($baseDir . 'share-keys/' . $params['oldpath']);
+ $escapedPath = Helper::escapeGlobPattern($localKeyPath);
+ $matches = glob($escapedPath . '*.shareKey');
+ foreach ($matches as $src) {
+ $dst = \OC\Files\Filesystem::normalizePath(str_replace($params['oldpath'], $params['newpath'], $src));
+
+ // create destination folder if not exists
+ if (!file_exists(dirname($dst))) {
+ mkdir(dirname($dst), 0750, true);
+ }
+
+ rename($src, $dst);
+ }
+
+ } else {
+ // handle share-keys folders
+ $oldShareKeyfilePath = $baseDir . 'share-keys/' . $params['oldpath'];
+ $newShareKeyfilePath = $baseDir . 'share-keys/' . $params['newpath'];
+
+ // create destination folder if not exists
+ if (!$view->file_exists(dirname($newShareKeyfilePath))) {
+ $view->mkdir(dirname($newShareKeyfilePath), 0750, true);
+ }
+
+ $view->rename($oldShareKeyfilePath, $newShareKeyfilePath);
+ }
+
+ // Rename keyfile so it isn't orphaned
+ if ($view->file_exists($oldKeyfilePath)) {
+
+ // create destination folder if not exists
+ if (!$view->file_exists(dirname($newKeyfilePath))) {
+ $view->mkdir(dirname($newKeyfilePath), 0750, true);
+ }
+
+ $view->rename($oldKeyfilePath, $newKeyfilePath);
+ }
+
+ // build the path to the file
+ $newPath = '/' . $userId . '/files' . $params['newpath'];
+ $newPathRelative = $params['newpath'];
+
+ if ($util->fixFileSize($newPath)) {
+ // get sharing app state
+ $sharingEnabled = \OCP\Share::isEnabled();
+
+ // get users
+ $usersSharing = $util->getSharingUsersArray($sharingEnabled, $newPathRelative);
+
+ // update sharing-keys
+ $util->setSharedFileKeyfiles($session, $usersSharing, $newPathRelative);
+ }
+
+ \OC_FileProxy::$enabled = $proxyStatus;
}
-
+
/**
- * @brief
+ * set migration status back to '0' so that all new files get encrypted
+ * if the app gets enabled again
+ * @param array $params contains the app ID
*/
- public static function preUnshareAll( $params ) {
-
- trigger_error( "preUnshareAll" );
-
+ public static function preDisable($params) {
+ if ($params['app'] === 'files_encryption') {
+ $query = \OC_DB::prepare('UPDATE `*PREFIX*encryption` SET `migration_status`=0');
+ $query->execute();
+ }
}
-
+
}
diff --git a/apps/files_encryption/js/settings-admin.js b/apps/files_encryption/js/settings-admin.js
new file mode 100644
index 0000000000000000000000000000000000000000..7c1866445eee9133cf090a0a0bc0757d6e33aa22
--- /dev/null
+++ b/apps/files_encryption/js/settings-admin.js
@@ -0,0 +1,102 @@
+/**
+ * Copyright (c) 2013, Sam Tuke , Robin Appelman
+ *
+ * This file is licensed under the Affero General Public License version 3 or later.
+ * See the COPYING-README file.
+ */
+
+OC.msg={
+ startSaving:function(selector){
+ $(selector)
+ .html( t('settings', 'Saving...') )
+ .removeClass('success')
+ .removeClass('error')
+ .stop(true, true)
+ .show();
+ },
+ finishedSaving:function(selector, data){
+ if( data.status === "success" ){
+ $(selector).html( data.data.message )
+ .addClass('success')
+ .stop(true, true)
+ .delay(3000)
+ .fadeOut(900);
+ }else{
+ $(selector).html( data.data.message ).addClass('error');
+ }
+ }
+};
+
+$(document).ready(function(){
+ // Trigger ajax on recoveryAdmin status change
+ var enabledStatus = $('#adminEnableRecovery').val();
+
+ $('input:password[name="recoveryPassword"]').keyup(function(event) {
+ var recoveryPassword = $( '#recoveryPassword' ).val();
+ var checkedButton = $('input:radio[name="adminEnableRecovery"]:checked').val();
+ var uncheckedValue = (1+parseInt(checkedButton)) % 2;
+ if (recoveryPassword != '' ) {
+ $('input:radio[name="adminEnableRecovery"][value="'+uncheckedValue.toString()+'"]').removeAttr("disabled");
+ } else {
+ $('input:radio[name="adminEnableRecovery"][value="'+uncheckedValue.toString()+'"]').attr("disabled", "true");
+ }
+ });
+
+ $( 'input:radio[name="adminEnableRecovery"]' ).change(
+ function() {
+ var recoveryStatus = $( this ).val();
+ var oldStatus = (1+parseInt(recoveryStatus)) % 2;
+ var recoveryPassword = $( '#recoveryPassword' ).val();
+ $.post(
+ OC.filePath( 'files_encryption', 'ajax', 'adminrecovery.php' )
+ , { adminEnableRecovery: recoveryStatus, recoveryPassword: recoveryPassword }
+ , function( result ) {
+ if (result.status === "error") {
+ OC.Notification.show(t('admin', result.data.message));
+ $('input:radio[name="adminEnableRecovery"][value="'+oldStatus.toString()+'"]').attr("checked", "true");
+ } else {
+ OC.Notification.hide();
+ if (recoveryStatus === "0") {
+ $('button:button[name="submitChangeRecoveryKey"]').attr("disabled", "true");
+ $('input:password[name="changeRecoveryPassword"]').attr("disabled", "true");
+ $('input:password[name="changeRecoveryPassword"]').val("");
+ } else {
+ $('input:password[name="changeRecoveryPassword"]').removeAttr("disabled");
+ }
+ }
+ }
+ );
+ }
+ );
+
+ // change recovery password
+
+ $('input:password[name="changeRecoveryPassword"]').keyup(function(event) {
+ var oldRecoveryPassword = $('input:password[id="oldRecoveryPassword"]').val();
+ var newRecoveryPassword = $('input:password[id="newRecoveryPassword"]').val();
+ if (newRecoveryPassword != '' && oldRecoveryPassword != '' ) {
+ $('button:button[name="submitChangeRecoveryKey"]').removeAttr("disabled");
+ } else {
+ $('button:button[name="submitChangeRecoveryKey"]').attr("disabled", "true");
+ }
+ });
+
+
+ $('button:button[name="submitChangeRecoveryKey"]').click(function() {
+ var oldRecoveryPassword = $('input:password[id="oldRecoveryPassword"]').val();
+ var newRecoveryPassword = $('input:password[id="newRecoveryPassword"]').val();
+ OC.msg.startSaving('#encryption .msg');
+ $.post(
+ OC.filePath( 'files_encryption', 'ajax', 'changeRecoveryPassword.php' )
+ , { oldPassword: oldRecoveryPassword, newPassword: newRecoveryPassword }
+ , function( data ) {
+ if (data.status == "error") {
+ OC.msg.finishedSaving('#encryption .msg', data);
+ } else {
+ OC.msg.finishedSaving('#encryption .msg', data);
+ }
+ }
+ );
+ });
+
+});
\ No newline at end of file
diff --git a/apps/files_encryption/js/settings-personal.js b/apps/files_encryption/js/settings-personal.js
new file mode 100644
index 0000000000000000000000000000000000000000..d6535a25b704b85efb0f6eed02536dd3396c3f9c
--- /dev/null
+++ b/apps/files_encryption/js/settings-personal.js
@@ -0,0 +1,98 @@
+/**
+ * Copyright (c) 2013, Sam Tuke
+ * This file is licensed under the Affero General Public License version 3 or later.
+ * See the COPYING-README file.
+ */
+
+function updatePrivateKeyPasswd() {
+ var oldPrivateKeyPassword = $('input:password[id="oldPrivateKeyPassword"]').val();
+ var newPrivateKeyPassword = $('input:password[id="newPrivateKeyPassword"]').val();
+ OC.msg.startSaving('#encryption .msg');
+ $.post(
+ OC.filePath( 'files_encryption', 'ajax', 'updatePrivateKeyPassword.php' )
+ , { oldPassword: oldPrivateKeyPassword, newPassword: newPrivateKeyPassword }
+ , function( data ) {
+ if (data.status === "error") {
+ OC.msg.finishedSaving('#encryption .msg', data);
+ } else {
+ OC.msg.finishedSaving('#encryption .msg', data);
+ }
+ }
+ );
+}
+
+$(document).ready(function(){
+
+ // Trigger ajax on recoveryAdmin status change
+ $( 'input:radio[name="userEnableRecovery"]' ).change(
+ function() {
+
+ // Hide feedback messages in case they're already visible
+ $('#recoveryEnabledSuccess').hide();
+ $('#recoveryEnabledError').hide();
+
+ var recoveryStatus = $( this ).val();
+
+ $.post(
+ OC.filePath( 'files_encryption', 'ajax', 'userrecovery.php' )
+ , { userEnableRecovery: recoveryStatus }
+ , function( data ) {
+ if ( data.status == "success" ) {
+ $('#recoveryEnabledSuccess').show();
+ } else {
+ $('#recoveryEnabledError').show();
+ }
+ }
+ );
+ // Ensure page is not reloaded on form submit
+ return false;
+ }
+ );
+
+ $("#encryptAll").click(
+ function(){
+
+ // Hide feedback messages in case they're already visible
+ $('#encryptAllSuccess').hide();
+ $('#encryptAllError').hide();
+
+ var userPassword = $( '#userPassword' ).val();
+ var encryptAll = $( '#encryptAll' ).val();
+
+ $.post(
+ OC.filePath( 'files_encryption', 'ajax', 'encryptall.php' )
+ , { encryptAll: encryptAll, userPassword: userPassword }
+ , function( data ) {
+ if ( data.status == "success" ) {
+ $('#encryptAllSuccess').show();
+ } else {
+ $('#encryptAllError').show();
+ }
+ }
+ );
+ // Ensure page is not reloaded on form submit
+ return false;
+ }
+
+ );
+
+ // update private key password
+
+ $('input:password[name="changePrivateKeyPassword"]').keyup(function(event) {
+ var oldPrivateKeyPassword = $('input:password[id="oldPrivateKeyPassword"]').val();
+ var newPrivateKeyPassword = $('input:password[id="newPrivateKeyPassword"]').val();
+ if (newPrivateKeyPassword !== '' && oldPrivateKeyPassword !== '' ) {
+ $('button:button[name="submitChangePrivateKeyPassword"]').removeAttr("disabled");
+ if(event.which === 13) {
+ updatePrivateKeyPasswd();
+ }
+ } else {
+ $('button:button[name="submitChangePrivateKeyPassword"]').attr("disabled", "true");
+ }
+ });
+
+ $('button:button[name="submitChangePrivateKeyPassword"]').click(function() {
+ updatePrivateKeyPasswd();
+ });
+
+});
\ No newline at end of file
diff --git a/apps/files_encryption/js/settings.js b/apps/files_encryption/js/settings.js
deleted file mode 100644
index 0be857bb73e9dd6d35a7ad30e702d3a5c25a08a6..0000000000000000000000000000000000000000
--- a/apps/files_encryption/js/settings.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2011, Robin Appelman
- * This file is licensed under the Affero General Public License version 3 or later.
- * See the COPYING-README file.
- */
-
-
-$(document).ready(function(){
- $('#encryption_blacklist').multiSelect({
- oncheck:blackListChange,
- onuncheck:blackListChange,
- createText:'...'
- });
-
- function blackListChange(){
- var blackList=$('#encryption_blacklist').val().join(',');
- OC.AppConfig.setValue('files_encryption','type_blacklist',blackList);
- }
-})
\ No newline at end of file
diff --git a/apps/files_encryption/l10n/ar.php b/apps/files_encryption/l10n/ar.php
index 375fbd9a9a640b439cd4c9d12a5c82bf554a6431..1adc158c6b8d0bf36286c999883d76b1736ec7cb 100644
--- a/apps/files_encryption/l10n/ar.php
+++ b/apps/files_encryption/l10n/ar.php
@@ -1,4 +1,4 @@
"التشفير",
-"None" => "لا شيء"
+"Saving..." => "جاري الحفظ...",
+"Encryption" => "التشفير"
);
diff --git a/apps/files_encryption/l10n/bg_BG.php b/apps/files_encryption/l10n/bg_BG.php
index 07a97f5f8a6d6a2b698297b08e5022e163b5f367..f21f7641c1a58ce1a1994dff92f7a399f60ff0e2 100644
--- a/apps/files_encryption/l10n/bg_BG.php
+++ b/apps/files_encryption/l10n/bg_BG.php
@@ -1,4 +1,4 @@
"Криптиране",
-"None" => "Няма"
+"Saving..." => "Записване...",
+"Encryption" => "Криптиране"
);
diff --git a/apps/files_encryption/l10n/bn_BD.php b/apps/files_encryption/l10n/bn_BD.php
index 43767d565180797d311a9b0b2400d8b00f1abfb3..068de46e7a18d45c52e24a5d98fc69e1b703629c 100644
--- a/apps/files_encryption/l10n/bn_BD.php
+++ b/apps/files_encryption/l10n/bn_BD.php
@@ -1,4 +1,4 @@
"সংকেতায়ন",
-"None" => "কোনটিই নয়"
+"Saving..." => "সংরক্ষণ করা হচ্ছে..",
+"Encryption" => "সংকেতায়ন"
);
diff --git a/apps/files_encryption/l10n/ca.php b/apps/files_encryption/l10n/ca.php
index 0c661353a776ce7644bc8ad3e5c954e2becc28ad..d9d3d7b4fa58f9b006dfc8aadea185ca61ec54fb 100644
--- a/apps/files_encryption/l10n/ca.php
+++ b/apps/files_encryption/l10n/ca.php
@@ -1,7 +1,36 @@
"Encriptatge",
-"File encryption is enabled." => "L'encriptació de fitxers està activada.",
-"The following file types will not be encrypted:" => "Els tipus de fitxers següents no s'encriptaran:",
-"Exclude the following file types from encryption:" => "Exclou els tipus de fitxers següents de l'encriptatge:",
-"None" => "Cap"
+"Recovery key successfully enabled" => "La clau de recuperació s'ha activat",
+"Could not enable recovery key. Please check your recovery key password!" => "No s'ha pogut activar la clau de recuperació. Comproveu contrasenya de la clau de recuperació!",
+"Recovery key successfully disabled" => "La clau de recuperació s'ha descativat",
+"Could not disable recovery key. Please check your recovery key password!" => "No s'ha pogut desactivar la calu de recuperació. Comproveu la contrasenya de la clau de recuperació!",
+"Password successfully changed." => "La contrasenya s'ha canviat.",
+"Could not change the password. Maybe the old password was not correct." => "No s'ha pogut canviar la contrasenya. Potser la contrasenya anterior no era correcta.",
+"Private key password successfully updated." => "La contrasenya de la clau privada s'ha actualitzat.",
+"Could not update the private key password. Maybe the old password was not correct." => "No s'ha pogut actualitzar la contrasenya de la clau privada. Potser la contrasenya anterior no era correcta.",
+"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "La clau privada no és vàlida! Probablement la contrasenya va ser canviada des de fora del sistema ownCloud (per exemple, en el directori de l'empresa). Vostè pot actualitzar la contrasenya de clau privada en la seva configuració personal per poder recuperar l'accés en els arxius xifrats.",
+"Missing requirements." => "Manca de requisits.",
+"Please make sure that PHP 5.3.3 or newer is installed and that the OpenSSL PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Assegureu-vos que teniu instal·lada la versió de PHP 5.3.3 o posterior, i que teniu l'extensió OpenSSL PHP activada i configurada correctament. Per ara, l'aplicació de xifrat esta desactivada.",
+"Saving..." => "Desant...",
+"Your private key is not valid! Maybe the your password was changed from outside." => "La vostra clau privada no és vàlida! Potser la vostra contrasenya ha canviat des de fora.",
+"You can unlock your private key in your " => "Podeu desbloquejar la clau privada en el vostre",
+"personal settings" => "arranjament personal",
+"Encryption" => "Xifrat",
+"Enable recovery key (allow to recover users files in case of password loss):" => "Activa la clau de recuperació (permet recuperar fitxers d'usuaris en cas de pèrdua de contrasenya):",
+"Recovery key password" => "Clau de recuperació de la contrasenya",
+"Enabled" => "Activat",
+"Disabled" => "Desactivat",
+"Change recovery key password:" => "Canvia la clau de recuperació de contrasenya:",
+"Old Recovery key password" => "Antiga clau de recuperació de contrasenya",
+"New Recovery key password" => "Nova clau de recuperació de contrasenya",
+"Change Password" => "Canvia la contrasenya",
+"Your private key password no longer match your log-in password:" => "La clau privada ja no es correspon amb la contrasenya d'accés:",
+"Set your old private key password to your current log-in password." => "Establiu la vostra contrasenya clau en funció de la contrasenya actual d'accés.",
+" If you don't remember your old password you can ask your administrator to recover your files." => "Si no recordeu la contrasenya anterior podeu demanar a l'administrador que recuperi els vostres fitxers.",
+"Old log-in password" => "Contrasenya anterior d'accés",
+"Current log-in password" => "Contrasenya d'accés actual",
+"Update Private Key Password" => "Actualitza la contrasenya de clau privada",
+"Enable password recovery:" => "Habilita la recuperació de contrasenya:",
+"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Activar aquesta opció us permetrà obtenir de nou accés als vostres fitxers encriptats en cas de perdre la contrasenya",
+"File recovery settings updated" => "S'han actualitzat els arranjaments de recuperació de fitxers",
+"Could not update file recovery" => "No s'ha pogut actualitzar la recuperació de fitxers"
);
diff --git a/apps/files_encryption/l10n/cs_CZ.php b/apps/files_encryption/l10n/cs_CZ.php
index d225688a079d78356a3ec1ae5eb3ef9cf4041306..981e629ccfee8d1c2d621c661ee3790d88ade8f8 100644
--- a/apps/files_encryption/l10n/cs_CZ.php
+++ b/apps/files_encryption/l10n/cs_CZ.php
@@ -1,7 +1,22 @@
"Záchranný klíč byl úspěšně povolen",
+"Could not enable recovery key. Please check your recovery key password!" => "Nepodařilo se povolit záchranný klíč. Zkontrolujte prosím vaše heslo záchranného klíče!",
+"Recovery key successfully disabled" => "Záchranný klíč byl úspěšně zakázán",
+"Could not disable recovery key. Please check your recovery key password!" => "Nelze zakázat záchranný klíč. Zkontrolujte prosím heslo vašeho záchranného klíče.",
+"Password successfully changed." => "Heslo bylo úspěšně změněno.",
+"Could not change the password. Maybe the old password was not correct." => "Nelze změnit heslo. Pravděpodobně nebylo stávající heslo zadáno správně.",
+"Private key password successfully updated." => "Heslo soukromého klíče úspěšně aktualizováno.",
+"Could not update the private key password. Maybe the old password was not correct." => "Nelze aktualizovat heslo soukromého klíče. Možná nebylo staré heslo správně.",
+"Saving..." => "Ukládám...",
+"personal settings" => "osobní nastavení",
"Encryption" => "Šifrování",
-"File encryption is enabled." => "Šifrování je povoleno.",
-"The following file types will not be encrypted:" => "Následující typy souborů nebudou šifrovány:",
-"Exclude the following file types from encryption:" => "Vyjmout následující typy souborů ze šifrování:",
-"None" => "Žádné"
+"Enabled" => "Povoleno",
+"Disabled" => "Zakázáno",
+"Change Password" => "Změnit heslo",
+"Old log-in password" => "Staré přihlašovací heslo",
+"Current log-in password" => "Aktuální přihlašovací heslo",
+"Enable password recovery:" => "Povolit obnovu hesla:",
+"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Povolení vám umožní znovu získat přístup k vašim zašifrovaným souborům pokud ztratíte heslo",
+"File recovery settings updated" => "Možnosti obnovy souborů aktualizovány",
+"Could not update file recovery" => "Nelze aktualizovat obnovu souborů"
);
diff --git a/apps/files_encryption/l10n/cy_GB.php b/apps/files_encryption/l10n/cy_GB.php
new file mode 100644
index 0000000000000000000000000000000000000000..6e18a7913c84afb6d279d58be1766c1e1d79e8c8
--- /dev/null
+++ b/apps/files_encryption/l10n/cy_GB.php
@@ -0,0 +1,4 @@
+ "Yn cadw...",
+"Encryption" => "Amgryptiad"
+);
diff --git a/apps/files_encryption/l10n/da.php b/apps/files_encryption/l10n/da.php
index b085381ea7b2b72f8fb66a9844c771ec9739733a..1cd43390aa3c289413c65f9e2390be265c0338dc 100644
--- a/apps/files_encryption/l10n/da.php
+++ b/apps/files_encryption/l10n/da.php
@@ -1,7 +1,4 @@
"Kryptering",
-"File encryption is enabled." => "Fil kryptering aktiveret.",
-"The following file types will not be encrypted:" => "De følgende filtyper vil ikke blive krypteret:",
-"Exclude the following file types from encryption:" => "Ekskluder de følgende fil typer fra kryptering:",
-"None" => "Ingen"
+"Saving..." => "Gemmer...",
+"Encryption" => "Kryptering"
);
diff --git a/apps/files_encryption/l10n/de.php b/apps/files_encryption/l10n/de.php
index cdcd8a40b23c87ae5c13660fd17539a8885b399e..d8265906db55c88c63d4e8c117f0878510a8af19 100644
--- a/apps/files_encryption/l10n/de.php
+++ b/apps/files_encryption/l10n/de.php
@@ -1,7 +1,36 @@
"Wiederherstellungsschlüssel wurde erfolgreich aktiviert",
+"Could not enable recovery key. Please check your recovery key password!" => "Der Wiederherstellungsschlüssel konnte nicht aktiviert werden. Überprüfen Sie Ihr Wiederherstellungspasswort!",
+"Recovery key successfully disabled" => "Wiederherstellungsschlüssel deaktiviert.",
+"Could not disable recovery key. Please check your recovery key password!" => "Der Wiederherstellungsschlüssel konnte nicht deaktiviert werden. Überprüfen Sie Ihr Wiederherstellungspasswort!",
+"Password successfully changed." => "Dein Passwort wurde geändert.",
+"Could not change the password. Maybe the old password was not correct." => "Das Passwort konnte nicht geändert werden. Vielleicht war das alte Passwort falsch.",
+"Private key password successfully updated." => "Passwort des privaten Schlüssels erfolgreich aktualisiert",
+"Could not update the private key password. Maybe the old password was not correct." => "Das Passwort des privaten Schlüssels konnte nicht aktualisiert werden. Eventuell war das alte Passwort falsch.",
+"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Dein privater Schlüssel ist ungültig. Möglicher Weise wurde von außerhalb Dein Passwort geändert (z.B. in deinem gemeinsamen Verzeichnis). Du kannst das Passwort deines privaten Schlüssels in den persönlichen Einstellungen aktualisieren, um wieder an deine Dateien zu gelangen.",
+"Missing requirements." => "Fehlende Vorraussetzungen",
+"Please make sure that PHP 5.3.3 or newer is installed and that the OpenSSL PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Bitte stellen Sie sicher, dass PHP 5.3.3 oder neuer installiert ist und die OpenSSL-PHP-Erweiterung aktiviert und richtig konfiguriert ist. Die Verschlüsselungsanwendung wurde vorerst deaktiviert.",
+"Saving..." => "Speichern...",
+"Your private key is not valid! Maybe the your password was changed from outside." => "Ihr privater Schlüssel ist ungültig! Eventuell wurde Ihr Passwort von außerhalb geändert.",
+"You can unlock your private key in your " => "Du kannst den privaten Schlüssel ändern und zwar in deinem",
+"personal settings" => "Private Einstellungen",
"Encryption" => "Verschlüsselung",
-"File encryption is enabled." => "Dateiverschlüsselung ist aktiviert",
-"The following file types will not be encrypted:" => "Die folgenden Dateitypen werden nicht verschlüsselt:",
-"Exclude the following file types from encryption:" => "Schließe die folgenden Dateitypen von der Verschlüsselung aus:",
-"None" => "Keine"
+"Enable recovery key (allow to recover users files in case of password loss):" => "Wiederherstellungsschlüssel aktivieren (ermöglicht das Wiederherstellen von Dateien, falls das Passwort vergessen wurde):",
+"Recovery key password" => "Wiederherstellungsschlüssel-Passwort",
+"Enabled" => "Aktiviert",
+"Disabled" => "Deaktiviert",
+"Change recovery key password:" => "Wiederherstellungsschlüssel-Passwort ändern:",
+"Old Recovery key password" => "Altes Wiederherstellungsschlüssel-Passwort",
+"New Recovery key password" => "Neues Wiederherstellungsschlüssel-Passwort",
+"Change Password" => "Passwort ändern",
+"Your private key password no longer match your log-in password:" => "Ihr Passwort für ihren privaten Schlüssel stimmt nicht mehr mit ihrem Loginpasswort überein.",
+"Set your old private key password to your current log-in password." => "Setzen Sie ihr altes Passwort für ihren privaten Schlüssel auf ihr aktuelles Login-Passwort",
+" If you don't remember your old password you can ask your administrator to recover your files." => "Wenn Sie Ihr altes Passwort vergessen haben, können Sie den Administrator bitten, Ihre Daten wiederherzustellen.",
+"Old log-in password" => "Altes login Passwort",
+"Current log-in password" => "Aktuelles Passwort",
+"Update Private Key Password" => "Passwort für den privaten Schlüssel aktualisieren",
+"Enable password recovery:" => "Passwortwiederherstellung aktivvieren:",
+"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Wenn Sie diese Option aktivieren, können Sie Ihre verschlüsselten Dateien wiederherstellen, falls Sie Ihr Passwort vergessen",
+"File recovery settings updated" => "Einstellungen zur Wiederherstellung von Dateien wurden aktualisiert",
+"Could not update file recovery" => "Dateiwiederherstellung konnte nicht aktualisiert werden"
);
diff --git a/apps/files_encryption/l10n/de_DE.php b/apps/files_encryption/l10n/de_DE.php
index 4f08b98eb29fdb50d0866b4b8ead9a1e9a468e38..2d7512354d582403395d2e0be10b13dd9cda6f73 100644
--- a/apps/files_encryption/l10n/de_DE.php
+++ b/apps/files_encryption/l10n/de_DE.php
@@ -1,7 +1,36 @@
"Der Wiederherstellungsschlüssel wurde erfolgreich aktiviert.",
+"Could not enable recovery key. Please check your recovery key password!" => "Der Wiederherstellungsschlüssel konnte nicht aktiviert werden. Bitte überprüfen Sie das Passwort für den Wiederherstellungsschlüssel!",
+"Recovery key successfully disabled" => "Der Wiederherstellungsschlüssel wurde erfolgreich deaktiviert.",
+"Could not disable recovery key. Please check your recovery key password!" => "Der Wiederherstellungsschlüssel konnte nicht deaktiviert werden. Bitte überprüfen Sie das Passwort für den Wiederherstellungsschlüssel!",
+"Password successfully changed." => "Das Passwort wurde erfolgreich geändert.",
+"Could not change the password. Maybe the old password was not correct." => "Das Passwort konnte nicht geändert werden. Vielleicht war das alte Passwort nicht richtig.",
+"Private key password successfully updated." => "Das Passwort des privaten Schlüssels wurde erfolgreich aktualisiert.",
+"Could not update the private key password. Maybe the old password was not correct." => "Das Passwort des privaten Schlüssels konnte nicht aktualisiert werden. Vielleicht war das alte Passwort nicht richtig.",
+"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Ihr privater Schlüssel ist ungültig. Möglicher Weise wurde von außerhalb Ihr Passwort geändert (z.B. in Ihrem gemeinsamen Verzeichnis). Sie können das Passwort Ihres privaten Schlüssels in den persönlichen Einstellungen aktualisieren, um wieder an Ihre Dateien zu gelangen.",
+"Missing requirements." => "Fehlende Voraussetzungen",
+"Please make sure that PHP 5.3.3 or newer is installed and that the OpenSSL PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Bitte stellen Sie sicher, dass PHP 5.3.3 oder neuer installiert und die PHP-Erweiterung OpenSSL aktiviert und richtig konfiguriert ist. Zur Zeit ist die Verschlüsselungs-App deaktiviert.",
+"Saving..." => "Speichern...",
+"Your private key is not valid! Maybe the your password was changed from outside." => "Ihr privater Schlüssel ist ungültig! Vielleicht wurde Ihr Passwort von außerhalb geändert.",
+"You can unlock your private key in your " => "Sie können den privaten Schlüssel ändern und zwar in Ihrem",
+"personal settings" => "Persönliche Einstellungen",
"Encryption" => "Verschlüsselung",
-"File encryption is enabled." => "Datei-Verschlüsselung ist aktiviert",
-"The following file types will not be encrypted:" => "Die folgenden Dateitypen werden nicht verschlüsselt:",
-"Exclude the following file types from encryption:" => "Die folgenden Dateitypen von der Verschlüsselung ausnehmen:",
-"None" => "Keine"
+"Enable recovery key (allow to recover users files in case of password loss):" => "Aktivieren Sie den Wiederherstellungsschlüssel (erlaubt die Wiederherstellung des Zugangs zu den Benutzerdateien, wenn das Passwort verloren geht).",
+"Recovery key password" => "Wiederherstellungschlüsselpasswort",
+"Enabled" => "Aktiviert",
+"Disabled" => "Deaktiviert",
+"Change recovery key password:" => "Wiederherstellungsschlüsselpasswort ändern",
+"Old Recovery key password" => "Altes Wiederherstellungsschlüsselpasswort",
+"New Recovery key password" => "Neues Wiederherstellungsschlüsselpasswort ",
+"Change Password" => "Passwort ändern",
+"Your private key password no longer match your log-in password:" => "Das Privatschlüsselpasswort darf nicht länger mit den Login-Passwort übereinstimmen.",
+"Set your old private key password to your current log-in password." => "Setzen Sie Ihr altes Privatschlüsselpasswort auf Ihr aktuelles LogIn-Passwort.",
+" If you don't remember your old password you can ask your administrator to recover your files." => "Falls Sie sich nicht an Ihr altes Passwort erinnern können, fragen Sie bitte Ihren Administrator, um Ihre Dateien wiederherzustellen.",
+"Old log-in password" => "Altes Login-Passwort",
+"Current log-in password" => "Momentanes Login-Passwort",
+"Update Private Key Password" => "Das Passwort des privaten Schlüssels aktualisieren",
+"Enable password recovery:" => "Passwort-Wiederherstellung aktivieren:",
+"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Durch die Aktivierung dieser Option haben Sie die Möglichkeit, wieder auf Ihre verschlüsselten Dateien zugreifen zu können, wenn Sie Ihr Passwort verloren haben.",
+"File recovery settings updated" => "Die Einstellungen für die Dateiwiederherstellung wurden aktualisiert.",
+"Could not update file recovery" => "Die Dateiwiederherstellung konnte nicht aktualisiert werden."
);
diff --git a/apps/files_encryption/l10n/el.php b/apps/files_encryption/l10n/el.php
index 0031a7319445a45b376950d0e4f1f38d379a3dc4..990f464bc1a17b4b116e6a72c12a18d13ca7e2bf 100644
--- a/apps/files_encryption/l10n/el.php
+++ b/apps/files_encryption/l10n/el.php
@@ -1,7 +1,11 @@
"Ο κωδικός αλλάχτηκε επιτυχώς.",
+"Could not change the password. Maybe the old password was not correct." => "Αποτυχία αλλαγής κωδικού ίσως ο παλιός κωδικός να μην ήταν σωστός.",
+"Saving..." => "Γίνεται αποθήκευση...",
+"personal settings" => "προσωπικές ρυθμίσεις",
"Encryption" => "Κρυπτογράφηση",
-"File encryption is enabled." => "Η κρυπτογράφηση αρχείων είναι ενεργή.",
-"The following file types will not be encrypted:" => "Οι παρακάτω τύποι αρχείων δεν θα κρυπτογραφηθούν:",
-"Exclude the following file types from encryption:" => "Εξαίρεση των παρακάτω τύπων αρχείων από την κρυπτογράφηση:",
-"None" => "Καμία"
+"Enabled" => "Ενεργοποιημένο",
+"Disabled" => "Απενεργοποιημένο",
+"Change Password" => "Αλλαγή Κωδικού Πρόσβασης",
+"File recovery settings updated" => "Οι ρυθμίσεις επαναφοράς αρχείων ανανεώθηκαν"
);
diff --git a/apps/files_encryption/l10n/eo.php b/apps/files_encryption/l10n/eo.php
index 50847062c3ba08f0923d447883ca5c83ba2515bd..997b60f8ac3c2d126f37dd46398db5606b79f437 100644
--- a/apps/files_encryption/l10n/eo.php
+++ b/apps/files_encryption/l10n/eo.php
@@ -1,4 +1,15 @@
"La pasvorto sukcese ŝanĝiĝis.",
+"Could not change the password. Maybe the old password was not correct." => "Ne eblis ŝanĝi la pasvorton. Eble la malnova pasvorto malĝustis.",
+"Private key password successfully updated." => "La pasvorto de la malpublika klavo sukcese ĝisdatiĝis.",
+"Saving..." => "Konservante...",
+"personal settings" => "persona agordo",
"Encryption" => "Ĉifrado",
-"None" => "Nenio"
+"Enabled" => "Kapabligita",
+"Disabled" => "Malkapabligita",
+"Change Password" => "Ŝarĝi pasvorton",
+"Your private key password no longer match your log-in password:" => "La pasvorto de via malpublika klavo ne plu kongruas kun via ensaluta pasvorto:",
+"Old log-in password" => "Malnova ensaluta pasvorto",
+"Current log-in password" => "Nuna ensaluta pasvorto",
+"Update Private Key Password" => "Ĝisdatigi la pasvorton de la malpublika klavo"
);
diff --git a/apps/files_encryption/l10n/es.php b/apps/files_encryption/l10n/es.php
index 4ea87b92e7c490b58b390070529ca0818bb4a367..0b49edbd2af62ca9cdfce5abd710a6834af4ebcd 100644
--- a/apps/files_encryption/l10n/es.php
+++ b/apps/files_encryption/l10n/es.php
@@ -1,7 +1,36 @@
"Se ha habilitado la recuperación de archivos",
+"Could not enable recovery key. Please check your recovery key password!" => "No se pudo habilitar la clave de recuperación. Por favor compruebe su contraseña.",
+"Recovery key successfully disabled" => "Clave de recuperación deshabilitada",
+"Could not disable recovery key. Please check your recovery key password!" => "No se pudo deshabilitar la clave de recuperación. Por favor compruebe su contraseña!",
+"Password successfully changed." => "Su contraseña ha sido cambiada",
+"Could not change the password. Maybe the old password was not correct." => "No se pudo cambiar la contraseña. Compruebe que la contraseña actual sea correcta.",
+"Private key password successfully updated." => "Contraseña de clave privada actualizada con éxito.",
+"Could not update the private key password. Maybe the old password was not correct." => "No se pudo cambiar la contraseña. Puede que la contraseña antigua no sea correcta.",
+"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "¡Su clave privada no es válida! Tal vez su contraseña ha sido cambiada desde fuera. Puede actualizar su clave privada en sus opciones personales para recuperar el acceso a sus ficheros.",
+"Missing requirements." => "Requisitos incompletos.",
+"Please make sure that PHP 5.3.3 or newer is installed and that the OpenSSL PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Por favor, asegúrese de que PHP 5.3.3 o posterior está instalado y que la extensión OpenSSL de PHP está habilitada y configurada correctamente. Por el momento, la aplicación de cifrado ha sido deshabilitada.",
+"Saving..." => "Guardando...",
+"Your private key is not valid! Maybe the your password was changed from outside." => "¡Su clave privada no es válida! Tal vez su contraseña ha sido cambiada desde fuera.",
+"You can unlock your private key in your " => "Puede desbloquear su clave privada en su",
+"personal settings" => "opciones personales",
"Encryption" => "Cifrado",
-"File encryption is enabled." => "La encriptacion de archivo esta activada.",
-"The following file types will not be encrypted:" => "Los siguientes tipos de archivo no seran encriptados:",
-"Exclude the following file types from encryption:" => "Excluir los siguientes tipos de archivo de la encriptacion:",
-"None" => "Ninguno"
+"Enable recovery key (allow to recover users files in case of password loss):" => "Habilitar la clave de recuperación (permite recuperar los ficheros del usuario en caso de pérdida de la contraseña);",
+"Recovery key password" => "Contraseña de clave de recuperación",
+"Enabled" => "Habilitar",
+"Disabled" => "Deshabilitado",
+"Change recovery key password:" => "Cambiar la contraseña de la clave de recuperación",
+"Old Recovery key password" => "Antigua clave de recuperación",
+"New Recovery key password" => "Nueva clave de recuperación",
+"Change Password" => "Cambiar contraseña",
+"Your private key password no longer match your log-in password:" => "Su contraseña de clave privada ya no coincide con su contraseña de acceso:",
+"Set your old private key password to your current log-in password." => "Establecer la contraseña de su antigua clave privada a su contraseña actual de acceso.",
+" If you don't remember your old password you can ask your administrator to recover your files." => "Si no recuerda su antigua contraseña puede pedir a su administrador que le recupere sus ficheros.",
+"Old log-in password" => "Contraseña de acceso antigua",
+"Current log-in password" => "Contraseña de acceso actual",
+"Update Private Key Password" => "Actualizar Contraseña de Clave Privada",
+"Enable password recovery:" => "Habilitar la recuperación de contraseña:",
+"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Habilitar esta opción le permitirá volver a tener acceso a sus ficheros cifrados en caso de pérdida de contraseña",
+"File recovery settings updated" => "Opciones de recuperación de archivos actualizada",
+"Could not update file recovery" => "No se pudo actualizar la recuperación de archivos"
);
diff --git a/apps/files_encryption/l10n/es_AR.php b/apps/files_encryption/l10n/es_AR.php
index af522879e16f7d4559413c22cef8ac754ffc1b4e..63c7fb7aa4f9d7ebb5a8a13e70455bbe070c9b34 100644
--- a/apps/files_encryption/l10n/es_AR.php
+++ b/apps/files_encryption/l10n/es_AR.php
@@ -1,7 +1,36 @@
"Se habilitó la recuperación de archivos",
+"Could not enable recovery key. Please check your recovery key password!" => "No se pudo habilitar la clave de recuperación. Por favor, comprobá tu contraseña.",
+"Recovery key successfully disabled" => "Clave de recuperación deshabilitada",
+"Could not disable recovery key. Please check your recovery key password!" => "No fue posible deshabilitar la clave de recuperación. Por favor, comprobá tu contraseña.",
+"Password successfully changed." => "Tu contraseña fue cambiada",
+"Could not change the password. Maybe the old password was not correct." => "No se pudo cambiar la contraseña. Comprobá que la contraseña actual sea correcta.",
+"Private key password successfully updated." => "Contraseña de clave privada actualizada con éxito.",
+"Could not update the private key password. Maybe the old password was not correct." => "No fue posible actualizar la contraseña de la clave privada. Tal vez la contraseña antigua no es correcta.",
+"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "¡Tu clave privada no es válida! Tal vez tu contraseña fue cambiada desde fuera del sistema de ownCloud (por ej. desde tu cuenta de sistema). Podés actualizar tu clave privada en tus opciones personales, para recuperar el acceso a sus archivos.",
+"Missing requirements." => "Requisitos incompletos.",
+"Please make sure that PHP 5.3.3 or newer is installed and that the OpenSSL PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Por favor, asegurate que PHP 5.3.3 o posterior esté instalado y que la extensión OpenSSL de PHP esté habilitada y configurada correctamente. Por el momento, la aplicación de encriptación fue deshabilitada.",
+"Saving..." => "Guardando...",
+"Your private key is not valid! Maybe the your password was changed from outside." => "¡Tu clave privada no es válida! Tal vez tu contraseña fue cambiada desde afuera.",
+"You can unlock your private key in your " => "Podés desbloquear tu clave privada en tu",
+"personal settings" => "Configuración personal",
"Encryption" => "Encriptación",
-"File encryption is enabled." => "La encriptación de archivos no está habilitada",
-"The following file types will not be encrypted:" => "Los siguientes tipos de archivos no serán encriptados",
-"Exclude the following file types from encryption:" => "Excluir los siguientes tipos de archivos de encriptación:",
-"None" => "Ninguno"
+"Enable recovery key (allow to recover users files in case of password loss):" => "Habilitar clave de recuperación (te permite recuperar los archivos de usuario en el caso en que pierdas la contraseña):",
+"Recovery key password" => "Contraseña de recuperación de clave",
+"Enabled" => "Habilitado",
+"Disabled" => "Deshabilitado",
+"Change recovery key password:" => "Cambiar contraseña para recuperar la clave:",
+"Old Recovery key password" => "Contraseña antigua de recuperación de clave",
+"New Recovery key password" => "Nueva contraseña de recuperación de clave",
+"Change Password" => "Cambiar contraseña",
+"Your private key password no longer match your log-in password:" => "Tu contraseña de recuperación de clave ya no coincide con la contraseña de ingreso:",
+"Set your old private key password to your current log-in password." => "Usá tu contraseña de recuperación de clave antigua para tu contraseña de ingreso actual.",
+" If you don't remember your old password you can ask your administrator to recover your files." => "Si no te acordás de tu contraseña antigua, pedile al administrador que recupere tus archivos",
+"Old log-in password" => "Contraseña anterior",
+"Current log-in password" => "Contraseña actual",
+"Update Private Key Password" => "Actualizar contraseña de la clave privada",
+"Enable password recovery:" => "Habilitar contraseña de recuperación:",
+"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Habilitando esta opción te va a permitir tener acceso a tus archivos encriptados incluso si perdés la contraseña",
+"File recovery settings updated" => "Las opciones de recuperación de archivos fueron actualizadas",
+"Could not update file recovery" => "No fue posible actualizar la recuperación de archivos"
);
diff --git a/apps/files_encryption/l10n/et_EE.php b/apps/files_encryption/l10n/et_EE.php
index 0d189ac062ea4cbf9b42654edcd88867e38f3846..c1c8164b8104238810937d41b1f2eef5720b034a 100644
--- a/apps/files_encryption/l10n/et_EE.php
+++ b/apps/files_encryption/l10n/et_EE.php
@@ -1,7 +1,36 @@
"Taastevõtme lubamine õnnestus",
+"Could not enable recovery key. Please check your recovery key password!" => "Ei suutnud lubada taastevõtit. Palun kontrolli oma taastevõtme parooli!",
+"Recovery key successfully disabled" => "Taastevõtme keelamine õnnestus",
+"Could not disable recovery key. Please check your recovery key password!" => "Ei suuda keelata taastevõtit. Palun kontrolli oma taastevõtme parooli!",
+"Password successfully changed." => "Parool edukalt vahetatud.",
+"Could not change the password. Maybe the old password was not correct." => "Ei suutnud vahetada parooli. Võib-olla on vana parool valesti sisestatud.",
+"Private key password successfully updated." => "Privaatse võtme parool edukalt uuendatud.",
+"Could not update the private key password. Maybe the old password was not correct." => "Ei suutnud uuendada privaatse võtme parooli. Võib-olla polnud vana parool õige.",
+"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Sinu privaatne võti pole toimiv! Tõenäoliselt on sinu parool muutunud väljaspool ownCloud süsteemi (näiteks ettevõtte keskhaldus). Sa saad uuendada oma privaatse võtme parooli seadete all taastamaks ligipääsu oma krüpteeritud failidele.",
+"Missing requirements." => "Nõutavad on puudu.",
+"Please make sure that PHP 5.3.3 or newer is installed and that the OpenSSL PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Veendu, et kasutusel oleks PHP 5.3.3 või uuem versioon ning kasutusel oleks OpenSSL PHP laiendus ja see on korrektselt seadistatud. Hetkel on krüpteerimise rakenduse kasutamine peatatud.",
+"Saving..." => "Salvestamine...",
+"Your private key is not valid! Maybe the your password was changed from outside." => "Sinu privaatne võti ei ole õige. Võib-olla on parool vahetatud süsteemi väliselt.",
+"You can unlock your private key in your " => "Saad avada oma privaatse võtme oma",
+"personal settings" => "isiklikes seadetes",
"Encryption" => "Krüpteerimine",
-"File encryption is enabled." => "Faili krüpteerimine on sisse lülitatud.",
-"The following file types will not be encrypted:" => "Järgnevaid failitüüpe ei krüpteerita:",
-"Exclude the following file types from encryption:" => "Järgnevaid failitüüpe ei krüpteerita:",
-"None" => "Pole"
+"Enable recovery key (allow to recover users files in case of password loss):" => "Luba taastevõti (võimada kasutaja failide taastamine parooli kaotuse puhul):",
+"Recovery key password" => "Taastevõtme parool",
+"Enabled" => "Sisse lülitatud",
+"Disabled" => "Väljalülitatud",
+"Change recovery key password:" => "Muuda taastevõtme parooli:",
+"Old Recovery key password" => "Vana taastevõtme parool",
+"New Recovery key password" => "Uus taastevõtme parool",
+"Change Password" => "Muuda parooli",
+"Your private key password no longer match your log-in password:" => "Sinu privaatse võtme parool ei ühti enam sinu sisselogimise parooliga:",
+"Set your old private key password to your current log-in password." => "Pane oma vana privaatvõtme parooliks oma praegune sisselogimise parool.",
+" If you don't remember your old password you can ask your administrator to recover your files." => "Kui sa ei mäleta oma vana parooli, siis palu oma süsteemihalduril taastada ligipääs failidele.",
+"Old log-in password" => "Vana sisselogimise parool",
+"Current log-in password" => "Praegune sisselogimise parool",
+"Update Private Key Password" => "Uuenda privaatse võtme parooli",
+"Enable password recovery:" => "Luba parooli taaste:",
+"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Valiku lubamine võimaldab taastada ligipääsu krüpteeritud failidele kui parooli kaotuse puhul",
+"File recovery settings updated" => "Faili taaste seaded uuendatud",
+"Could not update file recovery" => "Ei suuda uuendada taastefaili"
);
diff --git a/apps/files_encryption/l10n/eu.php b/apps/files_encryption/l10n/eu.php
index 5a22b65728ef5d9d669b57dcd72559cda9830c60..22fe7932688894b779294b14687088f4a3c14a75 100644
--- a/apps/files_encryption/l10n/eu.php
+++ b/apps/files_encryption/l10n/eu.php
@@ -1,7 +1,24 @@
"Berreskuratze gakoa behar bezala gaitua",
+"Could not enable recovery key. Please check your recovery key password!" => "Ezin da berreskuratze gako gaitu. Egiaztatu berreskuratze gako pasahitza!",
+"Recovery key successfully disabled" => "Berreskuratze gakoa behar bezala desgaitu da",
+"Could not disable recovery key. Please check your recovery key password!" => "Ezin da berreskuratze gako desgaitu. Egiaztatu berreskuratze gako pasahitza!",
+"Password successfully changed." => "Pasahitza behar bezala aldatu da.",
+"Could not change the password. Maybe the old password was not correct." => "Ezin izan da pasahitza aldatu. Agian pasahitz zaharra okerrekoa da.",
+"Private key password successfully updated." => "Gako pasahitz pribatu behar bezala eguneratu da.",
+"Could not update the private key password. Maybe the old password was not correct." => "Ezin izan da gako pribatu pasahitza eguneratu. Agian pasahitz zaharra okerrekoa da.",
+"Saving..." => "Gordetzen...",
+"personal settings" => "ezarpen pertsonalak",
"Encryption" => "Enkriptazioa",
-"File encryption is enabled." => "Fitxategien enkriptazioa gaituta dago.",
-"The following file types will not be encrypted:" => "Hurrengo fitxategi motak ez dira enkriptatuko:",
-"Exclude the following file types from encryption:" => "Baztertu hurrengo fitxategi motak enkriptatzetik:",
-"None" => "Bat ere ez"
+"Recovery key password" => "Berreskuratze gako pasahitza",
+"Enabled" => "Gaitua",
+"Disabled" => "Ez-gaitua",
+"Change recovery key password:" => "Aldatu berreskuratze gako pasahitza:",
+"Old Recovery key password" => "Berreskuratze gako pasahitz zaharra",
+"New Recovery key password" => "Berreskuratze gako pasahitz berria",
+"Change Password" => "Aldatu Pasahitza",
+"Update Private Key Password" => "Eguneratu gako pribatu pasahitza",
+"Enable password recovery:" => "Gaitu pasahitz berreskuratzea:",
+"File recovery settings updated" => "Fitxategi berreskuratze ezarpenak eguneratuak",
+"Could not update file recovery" => "Ezin da fitxategi berreskuratzea eguneratu"
);
diff --git a/apps/files_encryption/l10n/fa.php b/apps/files_encryption/l10n/fa.php
index 21ad7e565667e07fb2b69f735dcac5b2f176a9eb..8967ca1eed85b08ae554184d16d311feb498c01e 100644
--- a/apps/files_encryption/l10n/fa.php
+++ b/apps/files_encryption/l10n/fa.php
@@ -1,4 +1,36 @@
"کلید بازیابی با موفقیت فعال شده است.",
+"Could not enable recovery key. Please check your recovery key password!" => "کلید بازیابی نمی تواند فعال شود. لطفا رمزعبور کلید بازیابی خود را بررسی نمایید!",
+"Recovery key successfully disabled" => "کلید بازیابی با موفقیت غیر فعال شده است.",
+"Could not disable recovery key. Please check your recovery key password!" => "کلید بازیابی را نمی تواند غیرفعال نماید. لطفا رمزعبور کلید بازیابی خود را بررسی کنید!",
+"Password successfully changed." => "رمزعبور با موفقیت تغییر یافت.",
+"Could not change the password. Maybe the old password was not correct." => "رمزعبور را نمیتواند تغییر دهد. شاید رمزعبورقدیمی صحیح نمی باشد.",
+"Private key password successfully updated." => "رمزعبور کلید خصوصی با موفقیت به روز شد.",
+"Could not update the private key password. Maybe the old password was not correct." => "رمزعبور کلید خصوصی را نمی تواند به روز کند. شاید رمزعبور قدیمی صحیح نمی باشد.",
+"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "کلید خصوصی شما معتبر نمی باشد! ظاهرا رمزعبور شما بیرون از سیستم ownCloud تغییر یافته است( به عنوان مثال پوشه سازمان شما ). شما میتوانید رمزعبور کلید خصوصی خود را در تنظیمات شخصیتان به روز کنید تا بتوانید به فایل های رمزگذاری شده خود را دسترسی داشته باشید.",
+"Missing requirements." => "نیازمندی های گمشده",
+"Please make sure that PHP 5.3.3 or newer is installed and that the OpenSSL PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "لطفا مطمئن شوید که PHP 5.3.3 یا جدیدتر نصب شده و پسوند OpenSSL PHP فعال است و به درستی پیکربندی شده است. در حال حاضر، برنامه رمزگذاری غیر فعال شده است.",
+"Saving..." => "در حال ذخیره سازی...",
+"Your private key is not valid! Maybe the your password was changed from outside." => "کلید خصوصی شما معتبر نیست! شاید رمزعبوراز بیرون تغییر یافته است.",
+"You can unlock your private key in your " => "شما میتوانید کلید خصوصی خود را باز نمایید.",
+"personal settings" => "تنظیمات شخصی",
"Encryption" => "رمزگذاری",
-"None" => "هیچکدام"
+"Enable recovery key (allow to recover users files in case of password loss):" => "فعال کردن کلید بازیابی(اجازه بازیابی فایل های کاربران در صورت از دست دادن رمزعبور):",
+"Recovery key password" => "رمزعبور کلید بازیابی",
+"Enabled" => "فعال شده",
+"Disabled" => "غیرفعال شده",
+"Change recovery key password:" => "تغییر رمزعبور کلید بازیابی:",
+"Old Recovery key password" => "رمزعبور قدیمی کلید بازیابی ",
+"New Recovery key password" => "رمزعبور جدید کلید بازیابی",
+"Change Password" => "تغییر رمزعبور",
+"Your private key password no longer match your log-in password:" => "رمزعبور کلید خصوصی شما با رمزعبور شما یکسان نیست :",
+"Set your old private key password to your current log-in password." => "رمزعبور قدیمی کلید خصوصی خود را با رمزعبور فعلی تنظیم نمایید.",
+" If you don't remember your old password you can ask your administrator to recover your files." => "اگر رمزعبور قدیمی را فراموش کرده اید میتوانید از مدیر خود برای بازیابی فایل هایتان درخواست نمایید.",
+"Old log-in password" => "رمزعبور قدیمی",
+"Current log-in password" => "رمزعبور فعلی",
+"Update Private Key Password" => "به روز رسانی رمزعبور کلید خصوصی",
+"Enable password recovery:" => "فعال سازی بازیابی رمزعبور:",
+"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "فعال کردن این گزینه به شما اجازه خواهد داد در صورت از دست دادن رمزعبور به فایل های رمزگذاری شده خود دسترسی داشته باشید.",
+"File recovery settings updated" => "تنظیمات بازیابی فایل به روز شده است.",
+"Could not update file recovery" => "به روز رسانی بازیابی فایل را نمی تواند انجام دهد."
);
diff --git a/apps/files_encryption/l10n/fi_FI.php b/apps/files_encryption/l10n/fi_FI.php
index 6352d396b3c1ae65fecc57a1ba2a689aace7863b..a00cc8ab96e09e3339f2326dc9a81e55b1501516 100644
--- a/apps/files_encryption/l10n/fi_FI.php
+++ b/apps/files_encryption/l10n/fi_FI.php
@@ -1,7 +1,9 @@
"Salasana vaihdettiin onnistuneesti.",
+"Could not change the password. Maybe the old password was not correct." => "Salasanan vaihto epäonnistui. Kenties vanha salasana oli väärin.",
+"Saving..." => "Tallennetaan...",
"Encryption" => "Salaus",
-"File encryption is enabled." => "Tiedostojen salaus on käytössä.",
-"The following file types will not be encrypted:" => "Seuraavia tiedostotyyppejä ei salata:",
-"Exclude the following file types from encryption:" => "Älä salaa seuravia tiedostotyyppejä:",
-"None" => "Ei mitään"
+"Enabled" => "Käytössä",
+"Disabled" => "Ei käytössä",
+"Change Password" => "Vaihda salasana"
);
diff --git a/apps/files_encryption/l10n/fr.php b/apps/files_encryption/l10n/fr.php
index 88f1e4a393f24ad432ca05cd3e8a17dbd497ef61..174932d6e8aeb12c269b9819fd8a47aace8b4b6b 100644
--- a/apps/files_encryption/l10n/fr.php
+++ b/apps/files_encryption/l10n/fr.php
@@ -1,7 +1,36 @@
"Clé de récupération activée avec succès",
+"Could not enable recovery key. Please check your recovery key password!" => "Impossible d'activer la clé de récupération. Veuillez vérifier votre mot de passe de clé de récupération !",
+"Recovery key successfully disabled" => "Clé de récupération désactivée avec succès",
+"Could not disable recovery key. Please check your recovery key password!" => "Impossible de désactiver la clé de récupération. Veuillez vérifier votre mot de passe de clé de récupération !",
+"Password successfully changed." => "Mot de passe changé avec succès ",
+"Could not change the password. Maybe the old password was not correct." => "Ne peut pas changer le mot de passe. L'ancien mot de passe est peut-être incorrect.",
+"Private key password successfully updated." => "Mot de passe de la clé privé mis à jour avec succès.",
+"Could not update the private key password. Maybe the old password was not correct." => "Impossible de mettre à jour le mot de passe de la clé privé. Peut-être que l'ancien mot de passe n'était pas correcte.",
+"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Votre clé de sécurité privée n'est pas valide! Il est probable que votre mot de passe ait été changé sans passer par le système ownCloud (par éxemple: le serveur de votre entreprise). Ain d'avoir à nouveau accès à vos fichiers cryptés, vous pouvez mettre à jour votre clé de sécurité privée dans les paramètres personnels de votre compte.",
+"Missing requirements." => "Système minimum requis non respecté.",
+"Please make sure that PHP 5.3.3 or newer is installed and that the OpenSSL PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Veuillez vous assurer qu'une version de PHP 5.3.3 ou plus récente est installée et que l'extension OpenSSL de PHP est activée et configurée correctement. En attendant, l'application de cryptage a été désactivée.",
+"Saving..." => "Enregistrement...",
+"Your private key is not valid! Maybe the your password was changed from outside." => "Votre clef privée est invalide ! Votre mot de passe a peut-être été modifié depuis l'extérieur.",
+"You can unlock your private key in your " => "Vous pouvez déverrouiller votre clé privée dans votre",
+"personal settings" => "paramètres personnel",
"Encryption" => "Chiffrement",
-"File encryption is enabled." => "Le chiffrement des fichiers est activé",
-"The following file types will not be encrypted:" => "Les fichiers de types suivants ne seront pas chiffrés :",
-"Exclude the following file types from encryption:" => "Ne pas chiffrer les fichiers dont les types sont les suivants :",
-"None" => "Aucun"
+"Enable recovery key (allow to recover users files in case of password loss):" => "Activer la clef de récupération (permet de récupérer les fichiers des utilisateurs en cas de perte de mot de passe).",
+"Recovery key password" => "Mot de passe de la clef de récupération",
+"Enabled" => "Activer",
+"Disabled" => "Désactiver",
+"Change recovery key password:" => "Modifier le mot de passe de la clef de récupération :",
+"Old Recovery key password" => "Ancien mot de passe de la clef de récupération",
+"New Recovery key password" => "Nouveau mot de passe de la clef de récupération",
+"Change Password" => "Changer de mot de passe",
+"Your private key password no longer match your log-in password:" => "Le mot de passe de votre clef privée ne correspond plus à votre mot de passe de connexion :",
+"Set your old private key password to your current log-in password." => "Configurez le mot de passe de votre ancienne clef privée avec votre mot de passe courant de connexion. ",
+" If you don't remember your old password you can ask your administrator to recover your files." => "Si vous ne vous souvenez plus de votre ancien mot de passe, vous pouvez demander à votre administrateur de récupérer vos fichiers.",
+"Old log-in password" => "Ancien mot de passe de connexion",
+"Current log-in password" => "Actuel mot de passe de connexion",
+"Update Private Key Password" => "Mettre à jour le mot de passe de votre clé privée",
+"Enable password recovery:" => "Activer la récupération du mot de passe :",
+"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Activer cette option vous permettra d'obtenir à nouveau l'accès à vos fichiers chiffrés en cas de perte de mot de passe",
+"File recovery settings updated" => "Paramètres de récupération de fichiers mis à jour",
+"Could not update file recovery" => "Ne peut pas remettre à jour les fichiers de récupération"
);
diff --git a/apps/files_encryption/l10n/gl.php b/apps/files_encryption/l10n/gl.php
index 3210f71545312e5b90b9677f90ecacd861e4d157..db6f57bb36d1650e83bfe86616d8fd2447e86983 100644
--- a/apps/files_encryption/l10n/gl.php
+++ b/apps/files_encryption/l10n/gl.php
@@ -1,7 +1,36 @@
"Activada satisfactoriamente a chave de recuperación",
+"Could not enable recovery key. Please check your recovery key password!" => "Non foi posíbel activar a chave de recuperación. Comprobe o contrasinal da chave de recuperación!",
+"Recovery key successfully disabled" => "Desactivada satisfactoriamente a chave de recuperación",
+"Could not disable recovery key. Please check your recovery key password!" => "Non foi posíbel desactivar a chave de recuperación. Comprobe o contrasinal da chave de recuperación!",
+"Password successfully changed." => "O contrasinal foi cambiado satisfactoriamente",
+"Could not change the password. Maybe the old password was not correct." => "Non foi posíbel cambiar o contrasinal. Probabelmente o contrasinal antigo non é o correcto.",
+"Private key password successfully updated." => "A chave privada foi actualizada correctamente.",
+"Could not update the private key password. Maybe the old password was not correct." => "Non foi posíbel actualizar o contrasinal da chave privada. É probábel que o contrasinal antigo non sexa correcto.",
+"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "A chave privada non é correcta! É probábel que o seu contrasinal teña sido cambiado desde o exterior (p.ex. o seu directorio corporativo). Vostede pode actualizar o contrasinal da súa chave privada nos seus axustes persoais para recuperar o acceso aos seus ficheiros",
+"Missing requirements." => "Non se cumpren os requisitos.",
+"Please make sure that PHP 5.3.3 or newer is installed and that the OpenSSL PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Asegúrese de que está instalado o PHP 5.3.3 ou posterior e de que a extensión OpenSSL PHP estea activada e configurada correctamente. Polo de agora foi desactivado o aplicativo de cifrado.",
+"Saving..." => "Gardando...",
+"Your private key is not valid! Maybe the your password was changed from outside." => "A chave privada non é correcta! É probábel que o seu contrasinal teña sido cambiado desde o exterior. ",
+"You can unlock your private key in your " => "Pode desbloquear a chave privada nos seus",
+"personal settings" => "axustes persoais",
"Encryption" => "Cifrado",
-"File encryption is enabled." => "O cifrado de ficheiros está activado",
-"The following file types will not be encrypted:" => "Os seguintes tipos de ficheiros non van seren cifrados:",
-"Exclude the following file types from encryption:" => "Excluír os seguintes tipos de ficheiros do cifrado:",
-"None" => "Ningún"
+"Enable recovery key (allow to recover users files in case of password loss):" => "Activar a chave de recuperación (permitirá recuperar os ficheiros dos usuarios no caso de perda do contrasinal):",
+"Recovery key password" => "Contrasinal da chave de recuperación",
+"Enabled" => "Activado",
+"Disabled" => "Desactivado",
+"Change recovery key password:" => "Cambiar o contrasinal da chave de la recuperación:",
+"Old Recovery key password" => "Antigo contrasinal da chave de recuperación",
+"New Recovery key password" => "Novo contrasinal da chave de recuperación",
+"Change Password" => "Cambiar o contrasinal",
+"Your private key password no longer match your log-in password:" => "O seu contrasinal da chave privada non coincide co seu contrasinal de acceso.",
+"Set your old private key password to your current log-in password." => "Estabeleza o seu contrasinal antigo da chave de recuperación ao seu contrasinal de acceso actual",
+" If you don't remember your old password you can ask your administrator to recover your files." => " Se non lembra o seu antigo contrasinal pode pedírllelo ao seu administrador para recuperar os seus ficheiros.",
+"Old log-in password" => "Contrasinal de acceso antigo",
+"Current log-in password" => "Contrasinal de acceso actual",
+"Update Private Key Password" => "Actualizar o contrasinal da chave privada",
+"Enable password recovery:" => "Activar o contrasinal de recuperación:",
+"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Ao activar esta opción permitiráselle volver a obter acceso aos ficheiros cifrados no caso de perda do contrasinal",
+"File recovery settings updated" => "Actualizouse o ficheiro de axustes de recuperación",
+"Could not update file recovery" => "Non foi posíbel actualizar o ficheiro de recuperación"
);
diff --git a/apps/files_encryption/l10n/he.php b/apps/files_encryption/l10n/he.php
index cbb74bfee9a5cb5b7895a46bfac1cff99d58758f..7a80cfa2f9f07af3dca60f85539559762b72a093 100644
--- a/apps/files_encryption/l10n/he.php
+++ b/apps/files_encryption/l10n/he.php
@@ -1,4 +1,4 @@
"הצפנה",
-"None" => "כלום"
+"Saving..." => "שמירה…",
+"Encryption" => "הצפנה"
);
diff --git a/apps/files_encryption/l10n/hr.php b/apps/files_encryption/l10n/hr.php
new file mode 100644
index 0000000000000000000000000000000000000000..9b9284ddc5eaec498397034f55e74681f620a241
--- /dev/null
+++ b/apps/files_encryption/l10n/hr.php
@@ -0,0 +1,3 @@
+ "Spremanje..."
+);
diff --git a/apps/files_encryption/l10n/hu_HU.php b/apps/files_encryption/l10n/hu_HU.php
index 4043da108c0e0a991d2d1385f63eedb172779035..bf95c31f2c5fa61a459b58b0b882d23465c068ce 100644
--- a/apps/files_encryption/l10n/hu_HU.php
+++ b/apps/files_encryption/l10n/hu_HU.php
@@ -1,7 +1,4 @@
"Titkosítás",
-"File encryption is enabled." => "Az állományok titkosítása be van kapcsolva.",
-"The following file types will not be encrypted:" => "A következő fájltípusok nem kerülnek titkosításra:",
-"Exclude the following file types from encryption:" => "Zárjuk ki a titkosításból a következő fájltípusokat:",
-"None" => "Egyik sem"
+"Saving..." => "Mentés...",
+"Encryption" => "Titkosítás"
);
diff --git a/apps/files_encryption/l10n/id.php b/apps/files_encryption/l10n/id.php
index 6044348e72e335b5f813e25382185af6bfd9927f..ad827b537910c58755d2825e024f9286604ee946 100644
--- a/apps/files_encryption/l10n/id.php
+++ b/apps/files_encryption/l10n/id.php
@@ -1,7 +1,4 @@
"Enkripsi",
-"File encryption is enabled." => "Enkripsi berkas aktif.",
-"The following file types will not be encrypted:" => "Tipe berkas berikut tidak akan dienkripsi:",
-"Exclude the following file types from encryption:" => "Kecualikan tipe berkas berikut dari enkripsi:",
-"None" => "Tidak ada"
+"Saving..." => "Menyimpan...",
+"Encryption" => "Enkripsi"
);
diff --git a/apps/files_encryption/l10n/is.php b/apps/files_encryption/l10n/is.php
index bd964185c4575bf57662d2a5536bcb0df8a84648..0f98c6bd3bff6c7c602358919e478ab2b6c1487a 100644
--- a/apps/files_encryption/l10n/is.php
+++ b/apps/files_encryption/l10n/is.php
@@ -1,4 +1,4 @@
"Dulkóðun",
-"None" => "Ekkert"
+"Saving..." => "Er að vista ...",
+"Encryption" => "Dulkóðun"
);
diff --git a/apps/files_encryption/l10n/it.php b/apps/files_encryption/l10n/it.php
index 9ab9bc492a0fb599349802711ac6ada4df5a7237..8d15d1ced363fd7fef203d78cd3dd23cb5731f89 100644
--- a/apps/files_encryption/l10n/it.php
+++ b/apps/files_encryption/l10n/it.php
@@ -1,7 +1,36 @@
"Chiave di ripristino abilitata correttamente",
+"Could not enable recovery key. Please check your recovery key password!" => "Impossibile abilitare la chiave di ripristino. Verifica la password della chiave di ripristino.",
+"Recovery key successfully disabled" => "Chiave di ripristinata disabilitata correttamente",
+"Could not disable recovery key. Please check your recovery key password!" => "Impossibile disabilitare la chiave di ripristino. Verifica la password della chiave di ripristino.",
+"Password successfully changed." => "Password modificata correttamente.",
+"Could not change the password. Maybe the old password was not correct." => "Impossibile cambiare la password. Forse la vecchia password non era corretta.",
+"Private key password successfully updated." => "Password della chiave privata aggiornata correttamente.",
+"Could not update the private key password. Maybe the old password was not correct." => "Impossibile aggiornare la password della chiave privata. Forse la vecchia password non era corretta.",
+"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "La chiave privata non è valida! Forse la password è stata cambiata esternamente al sistema di ownCloud (ad es. la directory aziendale). Puoi aggiornare la password della chiave privata nelle impostazioni personali per ottenere nuovamente l'accesso ai file.",
+"Missing requirements." => "Requisiti mancanti.",
+"Please make sure that PHP 5.3.3 or newer is installed and that the OpenSSL PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Assicurati che sia installato PHP 5.3.3 o versioni successive e che l'estensione OpenSSL di PHP sia abilitata e configurata correttamente. Per ora, l'applicazione di cifratura è disabilitata.",
+"Saving..." => "Salvataggio in corso...",
+"Your private key is not valid! Maybe the your password was changed from outside." => "La tua chiave privata non è valida! Forse è stata modifica dall'esterno.",
+"You can unlock your private key in your " => "Puoi sbloccare la chiave privata nelle tue",
+"personal settings" => "impostazioni personali",
"Encryption" => "Cifratura",
-"File encryption is enabled." => "La cifratura dei file è abilitata.",
-"The following file types will not be encrypted:" => "I seguenti tipi di file non saranno cifrati:",
-"Exclude the following file types from encryption:" => "Escludi i seguenti tipi di file dalla cifratura:",
-"None" => "Nessuna"
+"Enable recovery key (allow to recover users files in case of password loss):" => "Abilita la chiave di recupero (permette di recuperare i file utenti in caso di perdita della password):",
+"Recovery key password" => "Password della chiave di recupero",
+"Enabled" => "Abilitata",
+"Disabled" => "Disabilitata",
+"Change recovery key password:" => "Cambia la password della chiave di recupero:",
+"Old Recovery key password" => "Vecchia password della chiave di recupero",
+"New Recovery key password" => "Nuova password della chiave di recupero",
+"Change Password" => "Modifica password",
+"Your private key password no longer match your log-in password:" => "La password della chiave privata non corrisponde più alla password di accesso:",
+"Set your old private key password to your current log-in password." => "Imposta la vecchia password della chiave privata sull'attuale password di accesso.",
+" If you don't remember your old password you can ask your administrator to recover your files." => "Se non ricordi la vecchia password puoi chiedere al tuo amministratore di recuperare i file.",
+"Old log-in password" => "Vecchia password di accesso",
+"Current log-in password" => "Password di accesso attuale",
+"Update Private Key Password" => "Aggiorna la password della chiave privata",
+"Enable password recovery:" => "Abilita il ripristino della password:",
+"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "L'abilitazione di questa opzione ti consentirà di accedere nuovamente ai file cifrati in caso di perdita della password",
+"File recovery settings updated" => "Impostazioni di ripristino dei file aggiornate",
+"Could not update file recovery" => "Impossibile aggiornare il ripristino dei file"
);
diff --git a/apps/files_encryption/l10n/ja_JP.php b/apps/files_encryption/l10n/ja_JP.php
index 35fba615aec29d6c6974cfd4b369655142e7be79..a1fcbd5c5443604f035cbc9216273b32c21c9279 100644
--- a/apps/files_encryption/l10n/ja_JP.php
+++ b/apps/files_encryption/l10n/ja_JP.php
@@ -1,7 +1,36 @@
"リカバリ用のキーは正常に有効化されました",
+"Could not enable recovery key. Please check your recovery key password!" => "リカバリ用のキーを有効にできませんでした。リカバリ用のキーのパスワードを確認して下さい!",
+"Recovery key successfully disabled" => "リカバリ用のキーを正常に無効化しました",
+"Could not disable recovery key. Please check your recovery key password!" => "リカバリ用のキーを無効化できませんでした。リカバリ用のキーのパスワードを確認して下さい!",
+"Password successfully changed." => "パスワードを変更できました。",
+"Could not change the password. Maybe the old password was not correct." => "パスワードを変更できませんでした。古いパスワードが間違っているかもしれません。",
+"Private key password successfully updated." => "秘密鍵のパスワードが正常に更新されました。",
+"Could not update the private key password. Maybe the old password was not correct." => "秘密鍵のパスワードを更新できませんでした。古いパスワードが正確でない場合があります。",
+"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "秘密鍵が有効ではありません。パスワードがownCloudシステムの外部(例えば、企業ディレクトリ)から変更された恐れがあります。個人設定で秘密鍵のパスワードを更新して、暗号化されたファイルを回復出来ます。",
+"Missing requirements." => "必要要件が満たされていません。",
+"Please make sure that PHP 5.3.3 or newer is installed and that the OpenSSL PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "必ず、PHP 5.3.3以上をインストールし、OpenSSLのPHP拡張を有効にして適切に設定してください。現時点では暗号化アプリは無効になっています。",
+"Saving..." => "保存中...",
+"Your private key is not valid! Maybe the your password was changed from outside." => "秘密鍵が有効ではありません。パスワードが外部から変更された恐れがあります。",
+"You can unlock your private key in your " => "個人設定で",
+"personal settings" => "秘密鍵をアンロックできます",
"Encryption" => "暗号化",
-"File encryption is enabled." => "ファイルの暗号化は有効です。",
-"The following file types will not be encrypted:" => "次のファイルタイプは暗号化されません:",
-"Exclude the following file types from encryption:" => "次のファイルタイプを暗号化から除外:",
-"None" => "なし"
+"Enable recovery key (allow to recover users files in case of password loss):" => "復旧キーを有効化 (万一パスワードを亡くした場合もユーザーのファイルを回復できる):",
+"Recovery key password" => "復旧キーのパスワード",
+"Enabled" => "有効",
+"Disabled" => "無効",
+"Change recovery key password:" => "復旧キーのパスワードを変更:",
+"Old Recovery key password" => "古い復旧キーのパスワード",
+"New Recovery key password" => "新しい復旧キーのパスワード",
+"Change Password" => "パスワードを変更",
+"Your private key password no longer match your log-in password:" => "もはや秘密鍵はログインパスワードと一致しません:",
+"Set your old private key password to your current log-in password." => "古い秘密鍵のパスワードを現在のログインパスワードに設定する。",
+" If you don't remember your old password you can ask your administrator to recover your files." => "古いパスワードを覚えていない場合、管理者に尋ねてファイルを回復することができます。",
+"Old log-in password" => "古いログインパスワード",
+"Current log-in password" => "現在のログインパスワード",
+"Update Private Key Password" => "秘密鍵のパスワードを更新",
+"Enable password recovery:" => "パスワード復旧を有効化:",
+"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "このオプションを有効にすると、パスワードを紛失した場合も、暗号化されたファイルに再度アクセスすることができるようになります。",
+"File recovery settings updated" => "ファイル復旧設定が更新されました",
+"Could not update file recovery" => "ファイル復旧を更新できませんでした"
);
diff --git a/apps/files_encryption/l10n/ka_GE.php b/apps/files_encryption/l10n/ka_GE.php
new file mode 100644
index 0000000000000000000000000000000000000000..55a59f44341af0c3a7a1485e2779807de11deb4e
--- /dev/null
+++ b/apps/files_encryption/l10n/ka_GE.php
@@ -0,0 +1,4 @@
+ "შენახვა...",
+"Encryption" => "ენკრიპცია"
+);
diff --git a/apps/files_encryption/l10n/ko.php b/apps/files_encryption/l10n/ko.php
index bd1580578c42146002ac808db852674b847b0c6b..cf8149da3abf724b6c02b9f0b878bd1c1195aabc 100644
--- a/apps/files_encryption/l10n/ko.php
+++ b/apps/files_encryption/l10n/ko.php
@@ -1,4 +1,4 @@
"암호화",
-"None" => "없음"
+"Saving..." => "저장 중...",
+"Encryption" => "암호화"
);
diff --git a/apps/files_encryption/l10n/ku_IQ.php b/apps/files_encryption/l10n/ku_IQ.php
index 02c030014fa014b23ecefbfcb783efc2cdd2a564..61b720372ec0ac322422ae32d1e7745a11404b8d 100644
--- a/apps/files_encryption/l10n/ku_IQ.php
+++ b/apps/files_encryption/l10n/ku_IQ.php
@@ -1,4 +1,4 @@
"نهێنیکردن",
-"None" => "هیچ"
+"Saving..." => "پاشکهوتدهکات...",
+"Encryption" => "نهێنیکردن"
);
diff --git a/apps/files_encryption/l10n/lb.php b/apps/files_encryption/l10n/lb.php
new file mode 100644
index 0000000000000000000000000000000000000000..77bad681732931b2d094e3a5b1bffcea7770604b
--- /dev/null
+++ b/apps/files_encryption/l10n/lb.php
@@ -0,0 +1,3 @@
+ "Speicheren..."
+);
diff --git a/apps/files_encryption/l10n/lt_LT.php b/apps/files_encryption/l10n/lt_LT.php
index 67769c8f36566ab45dbaafce7057b9f7eaee18b4..84fa902dc655369c802cdef1b6aeafd0da6f36af 100644
--- a/apps/files_encryption/l10n/lt_LT.php
+++ b/apps/files_encryption/l10n/lt_LT.php
@@ -1,4 +1,15 @@
"Atkūrimo raktas sėkmingai įjungtas",
+"Could not enable recovery key. Please check your recovery key password!" => "Neišėjo įjungti jūsų atkūrimo rakto. Prašome jį patikrinti!",
+"Recovery key successfully disabled" => "Atkūrimo raktas sėkmingai išjungtas",
+"Could not disable recovery key. Please check your recovery key password!" => "Neišėjo išjungti jūsų atkūrimo rakto. Prašome jį patikrinti!",
+"Password successfully changed." => "Slaptažodis sėkmingai pakeistas",
+"Could not change the password. Maybe the old password was not correct." => "Slaptažodis nebuvo pakeistas. Gali būti, kad buvo neteisingai suvestas senasis.",
+"Saving..." => "Saugoma...",
"Encryption" => "Šifravimas",
-"None" => "Nieko"
+"Enabled" => "Įjungta",
+"Disabled" => "Išjungta",
+"Change Password" => "Pakeisti slaptažodį",
+"File recovery settings updated" => "Failų atstatymo nustatymai pakeisti",
+"Could not update file recovery" => "Neišėjo atnaujinti failų atkūrimo"
);
diff --git a/apps/files_encryption/l10n/lv.php b/apps/files_encryption/l10n/lv.php
index fc31ccdb92d25209689358bc5e00522f3f2b1e36..04922854ceba7938a57ddd7e041f35105b7afff9 100644
--- a/apps/files_encryption/l10n/lv.php
+++ b/apps/files_encryption/l10n/lv.php
@@ -1,7 +1,4 @@
"Šifrēšana",
-"File encryption is enabled." => "Datņu šifrēšana ir aktivēta.",
-"The following file types will not be encrypted:" => "Sekojošās datnes netiks šifrētas:",
-"Exclude the following file types from encryption:" => "Sekojošos datņu tipus izslēgt no šifrēšanas:",
-"None" => "Nav"
+"Saving..." => "Saglabā...",
+"Encryption" => "Šifrēšana"
);
diff --git a/apps/files_encryption/l10n/mk.php b/apps/files_encryption/l10n/mk.php
index 513606fadc3dd68e5cb2f3d603278d47abef4ab1..a7216f205adbee12a97fd0b208deeed3958e956f 100644
--- a/apps/files_encryption/l10n/mk.php
+++ b/apps/files_encryption/l10n/mk.php
@@ -1,4 +1,4 @@
"Енкрипција",
-"None" => "Ништо"
+"Saving..." => "Снимам...",
+"Encryption" => "Енкрипција"
);
diff --git a/apps/files_encryption/l10n/ms_MY.php b/apps/files_encryption/l10n/ms_MY.php
new file mode 100644
index 0000000000000000000000000000000000000000..bb963cb72d26e8c91fd52d77c707b6dfa3c8dc96
--- /dev/null
+++ b/apps/files_encryption/l10n/ms_MY.php
@@ -0,0 +1,3 @@
+ "Simpan..."
+);
diff --git a/apps/files_encryption/l10n/nb_NO.php b/apps/files_encryption/l10n/nb_NO.php
index a5e16a034218f70cfbd03f2b55073b9c46934166..d4e2b1ffb50a8ef55643cfd438e1a6d54a019804 100644
--- a/apps/files_encryption/l10n/nb_NO.php
+++ b/apps/files_encryption/l10n/nb_NO.php
@@ -1,7 +1,4 @@
"Kryptering",
-"File encryption is enabled." => "Fil-kryptering er aktivert.",
-"The following file types will not be encrypted:" => "Følgende filtyper vil ikke bli kryptert:",
-"Exclude the following file types from encryption:" => "Ekskluder følgende filtyper fra kryptering:",
-"None" => "Ingen"
+"Saving..." => "Lagrer...",
+"Encryption" => "Kryptering"
);
diff --git a/apps/files_encryption/l10n/nl.php b/apps/files_encryption/l10n/nl.php
index b1cba96aad775d5d5256796ab530cf674759651f..093ed2c29c8d29ad5ba1dfb778e3587f372bc477 100644
--- a/apps/files_encryption/l10n/nl.php
+++ b/apps/files_encryption/l10n/nl.php
@@ -1,7 +1,33 @@
"Herstelsleutel succesvol geactiveerd",
+"Could not enable recovery key. Please check your recovery key password!" => "Kon herstelsleutel niet activeren. Controleer het wachtwoord van uw herstelsleutel!",
+"Recovery key successfully disabled" => "Herstelsleutel succesvol gedeactiveerd",
+"Could not disable recovery key. Please check your recovery key password!" => "Kon herstelsleutel niet deactiveren. Controleer het wachtwoord van uw herstelsleutel!",
+"Password successfully changed." => "Wachtwoord succesvol gewijzigd.",
+"Could not change the password. Maybe the old password was not correct." => "Kon wachtwoord niet wijzigen. Wellicht oude wachtwoord niet juist ingevoerd.",
+"Private key password successfully updated." => "Privésleutel succesvol bijgewerkt.",
+"Could not update the private key password. Maybe the old password was not correct." => "Kon het wachtwoord van de privésleutel niet wijzigen. Misschien was het oude wachtwoord onjuist.",
+"Saving..." => "Opslaan",
+"Your private key is not valid! Maybe the your password was changed from outside." => "Uw privésleutel is niet geldig. Misschien was uw wachtwoord van buitenaf gewijzigd.",
+"You can unlock your private key in your " => "U kunt uw privésleutel deblokkeren in uw",
+"personal settings" => "persoonlijke instellingen",
"Encryption" => "Versleuteling",
-"File encryption is enabled." => "Bestandsversleuteling geactiveerd.",
-"The following file types will not be encrypted:" => "De volgende bestandstypen zullen niet worden versleuteld:",
-"Exclude the following file types from encryption:" => "Sluit de volgende bestandstypen uit van versleuteling:",
-"None" => "Geen"
+"Enable recovery key (allow to recover users files in case of password loss):" => "Activeren herstelsleutel (maakt het mogelijk om gebruikersbestanden terug te halen in geval van verlies van het wachtwoord):",
+"Recovery key password" => "Wachtwoord herstelsleulel",
+"Enabled" => "Geactiveerd",
+"Disabled" => "Gedeactiveerd",
+"Change recovery key password:" => "Wijzig wachtwoord herstelsleutel:",
+"Old Recovery key password" => "Oude wachtwoord herstelsleutel",
+"New Recovery key password" => "Nieuwe wachtwoord herstelsleutel",
+"Change Password" => "Wijzigen wachtwoord",
+"Your private key password no longer match your log-in password:" => "Het wachtwoord van uw privésleutel komt niet meer overeen met uw inlogwachtwoord:",
+"Set your old private key password to your current log-in password." => "Stel het wachtwoord van uw oude privésleutel in op uw huidige inlogwachtwoord.",
+" If you don't remember your old password you can ask your administrator to recover your files." => "Als u uw oude wachtwoord niet meer weet, kunt u uw beheerder vragen uw bestanden terug te halen.",
+"Old log-in password" => "Oude wachtwoord",
+"Current log-in password" => "Huidige wachtwoord",
+"Update Private Key Password" => "Bijwerken wachtwoord Privésleutel",
+"Enable password recovery:" => "Activeren wachtwoord herstel:",
+"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Het activeren van deze optie maakt het mogelijk om uw versleutelde bestanden te benaderen als uw wachtwoord kwijt is",
+"File recovery settings updated" => "Bestandsherstel instellingen bijgewerkt",
+"Could not update file recovery" => "Kon bestandsherstel niet bijwerken"
);
diff --git a/apps/files_encryption/l10n/nn_NO.php b/apps/files_encryption/l10n/nn_NO.php
new file mode 100644
index 0000000000000000000000000000000000000000..97b3a27a9d0b7c772d640610beae89c6b2a16ea2
--- /dev/null
+++ b/apps/files_encryption/l10n/nn_NO.php
@@ -0,0 +1,3 @@
+ "Lagrar …"
+);
diff --git a/apps/files_encryption/l10n/oc.php b/apps/files_encryption/l10n/oc.php
new file mode 100644
index 0000000000000000000000000000000000000000..0a34c4cda12199ca891d94bb33cc6c2b34169cab
--- /dev/null
+++ b/apps/files_encryption/l10n/oc.php
@@ -0,0 +1,3 @@
+ "Enregistra..."
+);
diff --git a/apps/files_encryption/l10n/pl.php b/apps/files_encryption/l10n/pl.php
index 2fa86f454f9bfbc1bbf6a361e3c44bc9b9f68739..3928afb1d5c65be919b2d6cb91de3b0668ef52bb 100644
--- a/apps/files_encryption/l10n/pl.php
+++ b/apps/files_encryption/l10n/pl.php
@@ -1,7 +1,33 @@
"Klucz odzyskiwania włączony",
+"Could not enable recovery key. Please check your recovery key password!" => "Nie można włączyć klucza odzyskiwania. Proszę sprawdzić swoje hasło odzyskiwania!",
+"Recovery key successfully disabled" => "Klucz odzyskiwania wyłączony",
+"Could not disable recovery key. Please check your recovery key password!" => "Nie można wyłączyć klucza odzyskiwania. Proszę sprawdzić swoje hasło odzyskiwania!",
+"Password successfully changed." => "Zmiana hasła udana.",
+"Could not change the password. Maybe the old password was not correct." => "Nie można zmienić hasła. Może stare hasło nie było poprawne.",
+"Private key password successfully updated." => "Pomyślnie zaktualizowano hasło klucza prywatnego.",
+"Could not update the private key password. Maybe the old password was not correct." => "Nie można zmienić prywatnego hasła. Może stare hasło nie było poprawne.",
+"Saving..." => "Zapisywanie...",
+"Your private key is not valid! Maybe the your password was changed from outside." => "Klucz prywatny nie jest poprawny! Może Twoje hasło zostało zmienione z zewnątrz.",
+"You can unlock your private key in your " => "Możesz odblokować swój klucz prywatny w swojej",
+"personal settings" => "Ustawienia osobiste",
"Encryption" => "Szyfrowanie",
-"File encryption is enabled." => "Szyfrowanie plików jest włączone",
-"The following file types will not be encrypted:" => "Poniższe typy plików nie będą szyfrowane:",
-"Exclude the following file types from encryption:" => "Wyłącz poniższe typy plików z szyfrowania:",
-"None" => "Brak"
+"Enable recovery key (allow to recover users files in case of password loss):" => "Włączhasło klucza odzyskiwania (pozwala odzyskać pliki użytkowników w przypadku utraty hasła):",
+"Recovery key password" => "Hasło klucza odzyskiwania",
+"Enabled" => "Włączone",
+"Disabled" => "Wyłączone",
+"Change recovery key password:" => "Zmień hasło klucza odzyskiwania",
+"Old Recovery key password" => "Stare hasło klucza odzyskiwania",
+"New Recovery key password" => "Nowe hasło klucza odzyskiwania",
+"Change Password" => "Zmień hasło",
+"Your private key password no longer match your log-in password:" => "Hasło klucza prywatnego nie pasuje do hasła logowania:",
+"Set your old private key password to your current log-in password." => "Podaj swoje stare prywatne hasło aby ustawić nowe",
+" If you don't remember your old password you can ask your administrator to recover your files." => "Jeśli nie pamiętasz swojego starego hasła, poproś swojego administratora, aby odzyskać pliki.",
+"Old log-in password" => "Stare hasło logowania",
+"Current log-in password" => "Bieżące hasło logowania",
+"Update Private Key Password" => "Aktualizacja hasła klucza prywatnego",
+"Enable password recovery:" => "Włącz hasło odzyskiwania:",
+"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Włączenie tej opcji umożliwia otrzymać dostęp do zaszyfrowanych plików w przypadku utraty hasła",
+"File recovery settings updated" => "Ustawienia odzyskiwania plików zmienione",
+"Could not update file recovery" => "Nie można zmienić pliku odzyskiwania"
);
diff --git a/apps/files_encryption/l10n/pt_BR.php b/apps/files_encryption/l10n/pt_BR.php
index 28807db72ce820c067840756b9e19ef6a3cf6d2a..1563243c9931185b2a742e2672fc327435ef1300 100644
--- a/apps/files_encryption/l10n/pt_BR.php
+++ b/apps/files_encryption/l10n/pt_BR.php
@@ -1,7 +1,36 @@
"Recuperação de chave habilitada com sucesso",
+"Could not enable recovery key. Please check your recovery key password!" => "Impossível habilitar recuperação de chave. Por favor verifique sua senha para recuperação de chave!",
+"Recovery key successfully disabled" => "Recuperação de chave desabilitada com sucesso",
+"Could not disable recovery key. Please check your recovery key password!" => "Impossível desabilitar recuperação de chave. Por favor verifique sua senha para recuperação de chave!",
+"Password successfully changed." => "Senha alterada com sucesso.",
+"Could not change the password. Maybe the old password was not correct." => "Não foi possível alterar a senha. Talvez a senha antiga não estava correta.",
+"Private key password successfully updated." => "Senha de chave privada atualizada com sucesso.",
+"Could not update the private key password. Maybe the old password was not correct." => "Não foi possível atualizar a senha de chave privada. Talvez a senha antiga esteja incorreta.",
+"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Sua chave privada não é válida! Provavelmente sua senha foi alterada fora do sistema ownCloud (por exemplo, seu diretório corporativo). Você pode atualizar sua senha de chave privada em suas configurações pessoais para recuperar o acesso a seus arquivos criptografados.",
+"Missing requirements." => "Requisitos em falta.",
+"Please make sure that PHP 5.3.3 or newer is installed and that the OpenSSL PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Por favor, certifique-se que o PHP 5.3.3 ou mais recente está instalado e que a extensão PHP OpenSSL está habilitado e configurado corretamente. Por enquanto, o aplicativo de criptografia foi desativado.",
+"Saving..." => "Salvando...",
+"Your private key is not valid! Maybe the your password was changed from outside." => "Sua chave privada não é válida! Talvez sua senha tenha sido mudada.",
+"You can unlock your private key in your " => "Você pode desbloquear sua chave privada nas suas",
+"personal settings" => "configurações pessoais.",
"Encryption" => "Criptografia",
-"File encryption is enabled." => "A criptografia de arquivos está ativada.",
-"The following file types will not be encrypted:" => "Os seguintes tipos de arquivo não serão criptografados:",
-"Exclude the following file types from encryption:" => "Excluir os seguintes tipos de arquivo da criptografia:",
-"None" => "Nenhuma"
+"Enable recovery key (allow to recover users files in case of password loss):" => "Habilitar chave de recuperação (permite recuperar arquivos de usuários em caso de perda de senha):",
+"Recovery key password" => "Senha da chave de recuperação",
+"Enabled" => "Habilidado",
+"Disabled" => "Desabilitado",
+"Change recovery key password:" => "Mudar a senha da chave de recuperação:",
+"Old Recovery key password" => "Senha antiga da chave de recuperação",
+"New Recovery key password" => "Nova senha da chave de recuperação",
+"Change Password" => "Trocar Senha",
+"Your private key password no longer match your log-in password:" => "Sua senha de chave privada não coincide mais com sua senha de login:",
+"Set your old private key password to your current log-in password." => "Configure sua antiga senha de chave privada para sua atual senha de login.",
+" If you don't remember your old password you can ask your administrator to recover your files." => "Se você não se lembra de sua antiga senha você pode pedir ao administrador que recupere seus arquivos.",
+"Old log-in password" => "Senha antiga de login",
+"Current log-in password" => "Atual senha de login",
+"Update Private Key Password" => "Atualizar senha de chave privada",
+"Enable password recovery:" => "Habilitar recuperação de senha:",
+"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Habilitar essa opção vai permitir que você obtenha novamente acesso aos seus arquivos encriptados em caso de perda de senha",
+"File recovery settings updated" => "Configurações de recuperação de arquivo atualizado",
+"Could not update file recovery" => "Não foi possível atualizar a recuperação de arquivos"
);
diff --git a/apps/files_encryption/l10n/pt_PT.php b/apps/files_encryption/l10n/pt_PT.php
index 1c46011fc10b48b628dd03826aa913e6f5e9d9a2..f485f373a5346850da99dd461c5419859549cdb2 100644
--- a/apps/files_encryption/l10n/pt_PT.php
+++ b/apps/files_encryption/l10n/pt_PT.php
@@ -1,7 +1,15 @@
"Chave de recuperação activada com sucesso",
+"Could not enable recovery key. Please check your recovery key password!" => "Não foi possível activar a chave de recuperação. Por favor verifique a password da chave de recuperação!",
+"Recovery key successfully disabled" => "Chave de recuperação descativada com sucesso",
+"Could not disable recovery key. Please check your recovery key password!" => "Não foi possível desactivar a chave de recuperação. Por favor verifique a password da chave de recuperação.",
+"Password successfully changed." => "Password alterada com sucesso.",
+"Could not change the password. Maybe the old password was not correct." => "Não foi possivel alterar a password. Possivelmente a password antiga não está correcta.",
+"Saving..." => "A guardar...",
"Encryption" => "Encriptação",
-"File encryption is enabled." => "A encriptação de ficheiros está ligada",
-"The following file types will not be encrypted:" => "Os seguintes ficheiros não serão encriptados:",
-"Exclude the following file types from encryption:" => "Excluir da encriptação os seguintes tipos de ficheiro:",
-"None" => "Nenhum"
+"Enabled" => "Activado",
+"Disabled" => "Desactivado",
+"Change Password" => "Mudar a Password",
+"File recovery settings updated" => "Actualizadas as definições de recuperação de ficheiros",
+"Could not update file recovery" => "Não foi possível actualizar a recuperação de ficheiros"
);
diff --git a/apps/files_encryption/l10n/ro.php b/apps/files_encryption/l10n/ro.php
index a5a6fb3cb787e2440a8993be13150190e60d8888..9e04b627c42688174e7bd239a30b06d67eae872a 100644
--- a/apps/files_encryption/l10n/ro.php
+++ b/apps/files_encryption/l10n/ro.php
@@ -1,4 +1,4 @@
"Încriptare",
-"None" => "Niciuna"
+"Saving..." => "Se salvează...",
+"Encryption" => "Încriptare"
);
diff --git a/apps/files_encryption/l10n/ru.php b/apps/files_encryption/l10n/ru.php
index 22c1e3da3747c957863a007ce8bc54708eebe2cf..5bb803de2d0a8f14746aca00444dda2f5768cc57 100644
--- a/apps/files_encryption/l10n/ru.php
+++ b/apps/files_encryption/l10n/ru.php
@@ -1,7 +1,36 @@
"Ключ восстановления успешно установлен",
+"Could not enable recovery key. Please check your recovery key password!" => "Невозможно включить ключ восстановления. Проверьте правильность пароля от ключа!",
+"Recovery key successfully disabled" => "Ключ восстановления успешно отключен",
+"Could not disable recovery key. Please check your recovery key password!" => "Невозможно выключить ключ восстановления. Проверьте правильность пароля от ключа!",
+"Password successfully changed." => "Пароль изменен удачно.",
+"Could not change the password. Maybe the old password was not correct." => "Невозможно изменить пароль. Возможно старый пароль не был верен.",
+"Private key password successfully updated." => "Пароль секретного ключа успешно обновлён.",
+"Could not update the private key password. Maybe the old password was not correct." => "Невозможно обновить пароль от секретного ключа. Возможно, старый пароль указан неверно.",
+"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Ваш секретный ключ не действителен! Вероятно, ваш пароль был изменен вне системы OwnCloud (например, корпоративный каталог). Вы можете обновить секретный ключ в личных настройках на странице восстановления доступа к зашифрованным файлам. ",
+"Missing requirements." => "Требования отсутствуют.",
+"Please make sure that PHP 5.3.3 or newer is installed and that the OpenSSL PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Пожалуйста, убедитесь, что PHP 5.3.3 или новее установлен и что расширение OpenSSL PHP включен и настроен. В настоящее время, шифрование для приложения было отключено.",
+"Saving..." => "Сохранение...",
+"Your private key is not valid! Maybe the your password was changed from outside." => "Секретный ключ недействителен! Возможно, Ваш пароль был изменён в другой программе.",
+"You can unlock your private key in your " => "Вы можете разблокировать закрытый ключ в своём ",
+"personal settings" => "персональные настройки",
"Encryption" => "Шифрование",
-"File encryption is enabled." => "Шифрование файла включено.",
-"The following file types will not be encrypted:" => "Следующие типы файлов не будут зашифрованы:",
-"Exclude the following file types from encryption:" => "Исключить следующие типы файлов из шифрованных:",
-"None" => "Ничего"
+"Enable recovery key (allow to recover users files in case of password loss):" => "Включить ключ восстановления (позволяет пользователям восстановить файлы при потере пароля):",
+"Recovery key password" => "Пароль для ключа восстановления",
+"Enabled" => "Включено",
+"Disabled" => "Отключено",
+"Change recovery key password:" => "Сменить пароль для ключа восстановления:",
+"Old Recovery key password" => "Старый пароль для ключа восстановления",
+"New Recovery key password" => "Новый пароль для ключа восстановления",
+"Change Password" => "Изменить пароль",
+"Your private key password no longer match your log-in password:" => "Пароль от секретного ключа больше не соответствует паролю входа:",
+"Set your old private key password to your current log-in password." => "Замените старый пароль от секретного ключа на новый пароль входа.",
+" If you don't remember your old password you can ask your administrator to recover your files." => "Если вы не помните свой старый пароль, вы можете попросить своего администратора восстановить ваши файлы",
+"Old log-in password" => "Старый пароль для входа",
+"Current log-in password" => "Текущйи пароль для входа",
+"Update Private Key Password" => "Обновить пароль от секретного ключа",
+"Enable password recovery:" => "Включить восстановление пароля:",
+"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Включение этой опции позволит вам получить доступ к своим зашифрованным файлам в случае утери пароля",
+"File recovery settings updated" => "Настройки файла восстановления обновлены",
+"Could not update file recovery" => "Невозможно обновить файл восстановления"
);
diff --git a/apps/files_encryption/l10n/ru_RU.php b/apps/files_encryption/l10n/ru_RU.php
index 7222235485c6f50a15b797ec924ef7ab27aa2645..1351f63f89b8e87ba4b736fc449e52cabed6f1f6 100644
--- a/apps/files_encryption/l10n/ru_RU.php
+++ b/apps/files_encryption/l10n/ru_RU.php
@@ -1,4 +1,3 @@
"Шифрование",
-"None" => "Ни один"
+"Saving..." => "Сохранение"
);
diff --git a/apps/files_encryption/l10n/si_LK.php b/apps/files_encryption/l10n/si_LK.php
index d9cec4b7220210880e57ccc4d4cef45f66f9082f..6c678bb3a4f93ba7dafa670e571d742969a2bc76 100644
--- a/apps/files_encryption/l10n/si_LK.php
+++ b/apps/files_encryption/l10n/si_LK.php
@@ -1,4 +1,4 @@
"ගුප්ත කේතනය",
-"None" => "කිසිවක් නැත"
+"Saving..." => "සුරැකෙමින් පවතී...",
+"Encryption" => "ගුප්ත කේතනය"
);
diff --git a/apps/files_encryption/l10n/sk_SK.php b/apps/files_encryption/l10n/sk_SK.php
index bebb6234710dc2146021ca6a95dcc86a77a658cd..d8894e537061533dceeb8a21743df3f2a47d759f 100644
--- a/apps/files_encryption/l10n/sk_SK.php
+++ b/apps/files_encryption/l10n/sk_SK.php
@@ -1,7 +1,27 @@
"Záchranný kľúč bol úspešne povolený",
+"Could not enable recovery key. Please check your recovery key password!" => "Nepodarilo sa povoliť záchranný kľúč. Skontrolujte prosím Vaše heslo záchranného kľúča!",
+"Recovery key successfully disabled" => "Záchranný kľúč bol úspešne zakázaný",
+"Could not disable recovery key. Please check your recovery key password!" => "Nepodarilo sa zakázať záchranný kľúč. Skontrolujte prosím Vaše heslo záchranného kľúča!",
+"Password successfully changed." => "Heslo úspešne zmenené.",
+"Could not change the password. Maybe the old password was not correct." => "Nemožno zmeniť heslo. Pravdepodobne nebolo staré heslo zadané správne.",
+"Private key password successfully updated." => "Heslo súkromného kľúča je úspešne aktualizované.",
+"Could not update the private key password. Maybe the old password was not correct." => "Nemožno aktualizovať heslo súkromného kľúča. Možno nebolo staré heslo správne.",
+"Saving..." => "Ukladám...",
+"Your private key is not valid! Maybe the your password was changed from outside." => "Váš súkromný kľúč je neplatný. Možno bolo Vaše heslo zmenené z vonku.",
+"personal settings" => "osobné nastavenia",
"Encryption" => "Šifrovanie",
-"File encryption is enabled." => "Šifrovanie súborov nastavené.",
-"The following file types will not be encrypted:" => "Uvedené typy súborov nebudú šifrované:",
-"Exclude the following file types from encryption:" => "Nešifrovať uvedené typy súborov",
-"None" => "Žiadne"
+"Enabled" => "Povolené",
+"Disabled" => "Zakázané",
+"Change Password" => "Zmeniť heslo",
+"Your private key password no longer match your log-in password:" => "Vaše heslo súkromného kľúča je rovnaké ako Vaše prihlasovacie heslo:",
+"Set your old private key password to your current log-in password." => "Nastavte si staré heslo súkromného kľúča k Vášmu súčasnému prihlasovaciemu heslu.",
+" If you don't remember your old password you can ask your administrator to recover your files." => "Ak si nepamätáte svoje staré heslo, môžete požiadať správcu o obnovenie svojich súborov.",
+"Old log-in password" => "Staré prihlasovacie heslo",
+"Current log-in password" => "Súčasné prihlasovacie heslo",
+"Update Private Key Password" => "Aktualizovať heslo súkromného kľúča",
+"Enable password recovery:" => "Povoliť obnovu hesla:",
+"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Povolenie Vám umožní znovu získať prístup k Vašim zašifrovaným súborom, ak stratíte heslo",
+"File recovery settings updated" => "Nastavenie obnovy súborov aktualizované",
+"Could not update file recovery" => "Nemožno aktualizovať obnovenie súborov"
);
diff --git a/apps/files_encryption/l10n/sl.php b/apps/files_encryption/l10n/sl.php
index 4754e21214ea5b66c4a757e59fbe23ea04fca946..8b28ba011558afb74eae6f4af23926550322336f 100644
--- a/apps/files_encryption/l10n/sl.php
+++ b/apps/files_encryption/l10n/sl.php
@@ -1,7 +1,34 @@
"Ključ za obnovitev gesla je bil uspešno nastavljen",
+"Could not enable recovery key. Please check your recovery key password!" => "Ključa za obnovitev gesla ni bilo mogoče nastaviti. Preverite ključ!",
+"Recovery key successfully disabled" => "Ključ za obnovitev gesla je bil uspešno onemogočen",
+"Could not disable recovery key. Please check your recovery key password!" => "Ključa za obnovitev gesla ni bilo mogoče onemogočiti. Preverite ključ!",
+"Password successfully changed." => "Geslo je bilo uspešno spremenjeno.",
+"Could not change the password. Maybe the old password was not correct." => "Gesla ni bilo mogoče spremeniti. Morda vnos starega gesla ni bil pravilen.",
+"Private key password successfully updated." => "Zasebni ključ za geslo je bil uspešno posodobljen.",
+"Could not update the private key password. Maybe the old password was not correct." => "Zasebnega ključa za geslo ni bilo mogoče posodobiti. Morda vnos starega gesla ni bil pravilen.",
+"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Vaš zasebni ključ ni veljaven. Morda je bilo vaše geslo spremenjeno zunaj sistema ownCloud (npr. v skupnem imeniku). Svoj zasebni ključ, ki vam bo omogočil dostop do šifriranih dokumentov, lahko posodobite v osebnih nastavitvah.",
+"Saving..." => "Poteka shranjevanje ...",
+"Your private key is not valid! Maybe the your password was changed from outside." => "Vaš zasebni ključ ni veljaven. Morda je bilo vaše geslo spremenjeno.",
+"You can unlock your private key in your " => "Svoj zasebni ključ lahko odklenite v",
+"personal settings" => "osebne nastavitve",
"Encryption" => "Šifriranje",
-"File encryption is enabled." => "Šifriranje datotek je omogočeno.",
-"The following file types will not be encrypted:" => "Navedene vrste datotek ne bodo šifrirane:",
-"Exclude the following file types from encryption:" => "Ne šifriraj navedenih vrst datotek:",
-"None" => "Brez"
+"Enable recovery key (allow to recover users files in case of password loss):" => "Omogoči ključ za obnovitev datotek (v primeru izgube gesla)",
+"Recovery key password" => "Ključ za obnovitev gesla",
+"Enabled" => "Omogočeno",
+"Disabled" => "Onemogočeno",
+"Change recovery key password:" => "Spremeni ključ za obnovitev gesla:",
+"Old Recovery key password" => "Stari ključ za obnovitev gesla",
+"New Recovery key password" => "Nov ključ za obnovitev gesla",
+"Change Password" => "Spremeni geslo",
+"Your private key password no longer match your log-in password:" => "Vaš zasebni ključ za geslo se ne ujema z vnešenim geslom ob prijavi:",
+"Set your old private key password to your current log-in password." => "Nastavite svoj star zasebni ključ v geslo, vnešeno ob prijavi.",
+" If you don't remember your old password you can ask your administrator to recover your files." => "Če ste svoje geslo pozabili, lahko vaše datoteke obnovi skrbnik sistema.",
+"Old log-in password" => "Staro geslo",
+"Current log-in password" => "Trenutno geslo",
+"Update Private Key Password" => "Posodobi zasebni ključ",
+"Enable password recovery:" => "Omogoči obnovitev gesla:",
+"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Nastavitev te možnosti omogoča ponovno pridobitev dostopa do šifriranih datotek, v primeru da boste geslo pozabili.",
+"File recovery settings updated" => "Nastavitve obnavljanja dokumentov so bile posodobljene",
+"Could not update file recovery" => "Nastavitev za obnavljanje dokumentov ni bilo mogoče posodobiti"
);
diff --git a/apps/files_encryption/l10n/sr.php b/apps/files_encryption/l10n/sr.php
index 91f7fc62a90f5f43b3275b6cf17642976ec4fd9c..a36e37c1790f1e7158feb4d1c3fcdaea563058a4 100644
--- a/apps/files_encryption/l10n/sr.php
+++ b/apps/files_encryption/l10n/sr.php
@@ -1,4 +1,4 @@
"Шифровање",
-"None" => "Ништа"
+"Saving..." => "Чување у току...",
+"Encryption" => "Шифровање"
);
diff --git a/apps/files_encryption/l10n/sv.php b/apps/files_encryption/l10n/sv.php
index e214a937a1d4195883b87866080a523ca50acaf1..3659e22bb4ea133940492a327947885338908573 100644
--- a/apps/files_encryption/l10n/sv.php
+++ b/apps/files_encryption/l10n/sv.php
@@ -1,7 +1,34 @@
"Återställningsnyckeln har framgångsrikt aktiverats",
+"Could not enable recovery key. Please check your recovery key password!" => "Kunde inte aktivera återställningsnyckeln. Vänligen kontrollera ditt lösenord för återställningsnyckeln!",
+"Recovery key successfully disabled" => "Återställningsnyckeln har framgångsrikt inaktiverats",
+"Could not disable recovery key. Please check your recovery key password!" => "Kunde inte inaktivera återställningsnyckeln. Vänligen kontrollera ditt lösenord för återställningsnyckeln!",
+"Password successfully changed." => "Ändringen av lösenordet lyckades.",
+"Could not change the password. Maybe the old password was not correct." => "Kunde inte ändra lösenordet. Kanske det gamla lösenordet inte var rätt.",
+"Private key password successfully updated." => "Den privata lösenordsnyckeln uppdaterades utan problem.",
+"Could not update the private key password. Maybe the old password was not correct." => "Kunde inte uppdatera den privata lösenordsnyckeln. Kanske var det gamla lösenordet fel.",
+"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Din privata lösenordsnyckel är inte giltig! Troligen har ditt lösenord ändrats utanför ownCloud (t.ex. i företagets katalogtjänst). Du kan uppdatera den privata lösenordsnyckeln under dina personliga inställningar för att återfå tillgång till dina filer.",
+"Saving..." => "Sparar...",
+"Your private key is not valid! Maybe the your password was changed from outside." => "Din privata lösenordsnyckel är inte giltig! Kanske byttes ditt lösenord från utsidan.",
+"You can unlock your private key in your " => "Du kan låsa upp din privata nyckel i dina",
+"personal settings" => "personliga inställningar",
"Encryption" => "Kryptering",
-"File encryption is enabled." => "Filkryptering är aktiverat.",
-"The following file types will not be encrypted:" => "Följande filtyper kommer inte att krypteras:",
-"Exclude the following file types from encryption:" => "Exkludera följande filtyper från kryptering:",
-"None" => "Ingen"
+"Enable recovery key (allow to recover users files in case of password loss):" => "Aktivera lösenordsnyckel (för att kunna återfå användarens filer vid glömt eller förlorat lösenord):",
+"Recovery key password" => "Lösenordsnyckel",
+"Enabled" => "Aktiverad",
+"Disabled" => "Inaktiverad",
+"Change recovery key password:" => "Ändra lösenordsnyckel:",
+"Old Recovery key password" => "Gammal lösenordsnyckel",
+"New Recovery key password" => "Ny lösenordsnyckel",
+"Change Password" => "Byt lösenord",
+"Your private key password no longer match your log-in password:" => "Din privata lösenordsnyckel stämmer inte längre överrens med ditt inloggningslösenord:",
+"Set your old private key password to your current log-in password." => "Ställ in din gamla privata lösenordsnyckel till ditt aktuella inloggningslösenord.",
+" If you don't remember your old password you can ask your administrator to recover your files." => "Om du inte kommer ihåg ditt gamla lösenord kan du be din administratör att återställa dina filer.",
+"Old log-in password" => "Gammalt inloggningslösenord",
+"Current log-in password" => "Nuvarande inloggningslösenord",
+"Update Private Key Password" => "Uppdatera den privata lösenordsnyckeln",
+"Enable password recovery:" => "Aktivera lösenordsåterställning",
+"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Genom att aktivera detta alternativ kommer du kunna återfå tillgång till dina krypterade filer om du skulle förlora/glömma ditt lösenord",
+"File recovery settings updated" => "Inställningarna för filåterställning har uppdaterats",
+"Could not update file recovery" => "Kunde inte uppdatera filåterställning"
);
diff --git a/apps/files_encryption/l10n/ta_LK.php b/apps/files_encryption/l10n/ta_LK.php
index 152e631d0fc419a43518e6c985802568a0f90b1b..63fe9ecde86944b117bd14a603506940ddd76e6a 100644
--- a/apps/files_encryption/l10n/ta_LK.php
+++ b/apps/files_encryption/l10n/ta_LK.php
@@ -1,4 +1,4 @@
"மறைக்குறியீடு",
-"None" => "ஒன்றுமில்லை"
+"Saving..." => "சேமிக்கப்படுகிறது...",
+"Encryption" => "மறைக்குறியீடு"
);
diff --git a/apps/files_encryption/l10n/th_TH.php b/apps/files_encryption/l10n/th_TH.php
index e46d249118606f7f97352d974cd6054385262726..6cab4370ccf2413b2140c49bbd0fdfb4ea39edc1 100644
--- a/apps/files_encryption/l10n/th_TH.php
+++ b/apps/files_encryption/l10n/th_TH.php
@@ -1,4 +1,4 @@
"การเข้ารหัส",
-"None" => "ไม่ต้อง"
+"Saving..." => "กำลังบันทึกข้อมูล...",
+"Encryption" => "การเข้ารหัส"
);
diff --git a/apps/files_encryption/l10n/tr.php b/apps/files_encryption/l10n/tr.php
index 6b42c757e6577a64371ba5d57f679eb136d17c48..24c6fa472782376a2373f1709b05038253cb9cdc 100644
--- a/apps/files_encryption/l10n/tr.php
+++ b/apps/files_encryption/l10n/tr.php
@@ -1,7 +1,15 @@
"Kurtarma anahtarı başarıyla etkinleştirildi",
+"Could not enable recovery key. Please check your recovery key password!" => "Kurtarma anahtarı etkinleştirilemedi. Lütfen kurtarma anahtarı parolanızı kontrol edin!",
+"Recovery key successfully disabled" => "Kurtarma anahtarı başarıyla devre dışı bırakıldı",
+"Could not disable recovery key. Please check your recovery key password!" => "Kurtarma anahtarı devre dışı bırakılamadı. Lütfen kurtarma anahtarı parolanızı kontrol edin!",
+"Password successfully changed." => "Şifreniz başarıyla değiştirildi.",
+"Could not change the password. Maybe the old password was not correct." => "Parola değiştirilemedi. Eski parolanız doğru olmayabilir",
+"Saving..." => "Kaydediliyor...",
"Encryption" => "Şifreleme",
-"File encryption is enabled." => "Dosya şifreleme aktif.",
-"The following file types will not be encrypted:" => "Belirtilen dosya tipleri şifrelenmeyecek:",
-"Exclude the following file types from encryption:" => "Seçilen dosya tiplerini şifreleme:",
-"None" => "Hiçbiri"
+"Enabled" => "Etkinleştirildi",
+"Disabled" => "Devre dışı",
+"Change Password" => "Parola değiştir",
+"File recovery settings updated" => "Dosya kurtarma ayarları güncellendi",
+"Could not update file recovery" => "Dosya kurtarma güncellenemedi"
);
diff --git a/apps/files_encryption/l10n/ug.php b/apps/files_encryption/l10n/ug.php
new file mode 100644
index 0000000000000000000000000000000000000000..954d95b4132977305ae13648d6c430b91157ac08
--- /dev/null
+++ b/apps/files_encryption/l10n/ug.php
@@ -0,0 +1,4 @@
+ "ساقلاۋاتىدۇ…",
+"Encryption" => "شىفىرلاش"
+);
diff --git a/apps/files_encryption/l10n/uk.php b/apps/files_encryption/l10n/uk.php
index d495714119163fc5709491d5491a6a2795609cbb..1c176a391423e5abf4e8d6332bd7a14b0d62c7d2 100644
--- a/apps/files_encryption/l10n/uk.php
+++ b/apps/files_encryption/l10n/uk.php
@@ -1,7 +1,4 @@
"Шифрування",
-"File encryption is enabled." => "Увімкнуто шифрування файлів.",
-"The following file types will not be encrypted:" => "Такі типи файлів шифруватись не будуть:",
-"Exclude the following file types from encryption:" => "Виключити наступні типи файлів з шифрування:",
-"None" => "Жоден"
+"Saving..." => "Зберігаю...",
+"Encryption" => "Шифрування"
);
diff --git a/apps/files_encryption/l10n/vi.php b/apps/files_encryption/l10n/vi.php
index 0a88d1b2db60b09f23e67d9ed317e9e4aa771cc7..d11569bb94c443a971dc08716f9467a2571cdad8 100644
--- a/apps/files_encryption/l10n/vi.php
+++ b/apps/files_encryption/l10n/vi.php
@@ -1,7 +1,9 @@
"Đã đổi mật khẩu.",
+"Could not change the password. Maybe the old password was not correct." => "Không thể đổi mật khẩu. Có lẽ do mật khẩu cũ không đúng.",
+"Saving..." => "Đang lưu...",
"Encryption" => "Mã hóa",
-"File encryption is enabled." => "Mã hóa file đã mở",
-"The following file types will not be encrypted:" => "Loại file sau sẽ không được mã hóa",
-"Exclude the following file types from encryption:" => "Việc mã hóa không bao gồm loại file sau",
-"None" => "Không có gì hết"
+"Enabled" => "Bật",
+"Disabled" => "Tắt",
+"Change Password" => "Đổi Mật khẩu"
);
diff --git a/apps/files_encryption/l10n/zh_CN.GB2312.php b/apps/files_encryption/l10n/zh_CN.GB2312.php
index 12d903e6567169d0ca5970e91fb0d4631e54f73b..3c405a81ace8ddfb0ee74281b823a911faa19477 100644
--- a/apps/files_encryption/l10n/zh_CN.GB2312.php
+++ b/apps/files_encryption/l10n/zh_CN.GB2312.php
@@ -1,4 +1,4 @@
"加密",
-"None" => "无"
+"Saving..." => "保存中...",
+"Encryption" => "加密"
);
diff --git a/apps/files_encryption/l10n/zh_CN.php b/apps/files_encryption/l10n/zh_CN.php
index 13fa95203e437684194ed12b40637bbb00d50c6c..a3939165c7a74d247a61ddf9f3d16f5caf6a44fa 100644
--- a/apps/files_encryption/l10n/zh_CN.php
+++ b/apps/files_encryption/l10n/zh_CN.php
@@ -1,7 +1,34 @@
"恢复密钥成功启用",
+"Could not enable recovery key. Please check your recovery key password!" => "不能启用恢复密钥。请检查恢复密钥密码!",
+"Recovery key successfully disabled" => "恢复密钥成功禁用",
+"Could not disable recovery key. Please check your recovery key password!" => "不能禁用恢复密钥。请检查恢复密钥密码!",
+"Password successfully changed." => "密码修改成功。",
+"Could not change the password. Maybe the old password was not correct." => "不能修改密码。旧密码可能不正确。",
+"Private key password successfully updated." => "私钥密码成功更新。",
+"Could not update the private key password. Maybe the old password was not correct." => "无法更新私钥密码。可能旧密码不正确。",
+"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "您的私有密钥无效!也许是您在 ownCloud 系统外更改了密码 (比如,在您的公司目录)。您可以在个人设置里更新您的私钥密码来恢复访问你的加密文件。",
+"Saving..." => "保存中",
+"Your private key is not valid! Maybe the your password was changed from outside." => "您的私钥不正确!可能您在别处更改了密码。",
+"You can unlock your private key in your " => "您可以在这里解锁您的私钥:",
+"personal settings" => "个人设置",
"Encryption" => "加密",
-"File encryption is enabled." => "文件加密已启用.",
-"The following file types will not be encrypted:" => "如下的文件类型将不会被加密:",
-"Exclude the following file types from encryption:" => "从加密中排除如下的文件类型:",
-"None" => "无"
+"Enable recovery key (allow to recover users files in case of password loss):" => "启用恢复密钥(允许你在密码丢失后恢复文件):",
+"Recovery key password" => "恢复密钥密码",
+"Enabled" => "开启",
+"Disabled" => "禁用",
+"Change recovery key password:" => "更改恢复密钥密码",
+"Old Recovery key password" => "旧的恢复密钥密码",
+"New Recovery key password" => "新的恢复密钥密码",
+"Change Password" => "修改密码",
+"Your private key password no longer match your log-in password:" => "您的私钥密码不再匹配您的登录密码:",
+"Set your old private key password to your current log-in password." => "讲您旧的私钥密码改为当前登录密码。",
+" If you don't remember your old password you can ask your administrator to recover your files." => "如果您记不住旧的密码,您可以请求管理员恢复您的文件。",
+"Old log-in password" => "旧登录密码",
+"Current log-in password" => "当前登录密码",
+"Update Private Key Password" => "更新私钥密码",
+"Enable password recovery:" => "启用密码恢复:",
+"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "启用该项将允许你在密码丢失后取回您的加密文件",
+"File recovery settings updated" => "文件恢复设置已更新",
+"Could not update file recovery" => "不能更新文件恢复"
);
diff --git a/apps/files_encryption/l10n/zh_HK.php b/apps/files_encryption/l10n/zh_HK.php
index 0c0b709fdc1f47d88eb809638ab9a75391d08884..0a38a2ddf856ddb1e460af9821642559a44d6e5d 100644
--- a/apps/files_encryption/l10n/zh_HK.php
+++ b/apps/files_encryption/l10n/zh_HK.php
@@ -1,6 +1,3 @@
"加密",
-"File encryption is enabled." => "檔案加密已開啟",
-"The following file types will not be encrypted:" => "以下文件類別將不會被加密",
-"None" => "空"
+"Encryption" => "加密"
);
diff --git a/apps/files_encryption/l10n/zh_TW.php b/apps/files_encryption/l10n/zh_TW.php
index 1655e171433828affb536dc94ee161cf710ae901..d34f51c4870bb6ad4f4217c49b8c68e70bbe63fe 100644
--- a/apps/files_encryption/l10n/zh_TW.php
+++ b/apps/files_encryption/l10n/zh_TW.php
@@ -1,4 +1,11 @@
"成功變更密碼。",
+"Could not change the password. Maybe the old password was not correct." => "無法變更密碼,或許是輸入的舊密碼不正確。",
+"Saving..." => "儲存中...",
"Encryption" => "加密",
-"None" => "無"
+"Enabled" => "已啓用",
+"Disabled" => "已停用",
+"Change Password" => "變更密碼",
+"File recovery settings updated" => "檔案還原設定已更新",
+"Could not update file recovery" => "無法更新檔案還原設定"
);
diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php
index 437a18669e5f2e8d67bb46a9b01752b0873f896b..6543a0de5f3b94b8a059e0bf01f1b1a32260041d 100755
--- a/apps/files_encryption/lib/crypt.php
+++ b/apps/files_encryption/lib/crypt.php
@@ -25,13 +25,8 @@
namespace OCA\Encryption;
-require_once 'Crypt_Blowfish/Blowfish.php';
-
-// Todo:
-// - Add a setting "Don´t encrypt files larger than xx because of performance"
-// - Don't use a password directly as encryption key. but a key which is
-// stored on the server and encrypted with the user password. -> change pass
-// faster
+//require_once '../3rdparty/Crypt_Blowfish/Blowfish.php';
+require_once realpath(dirname(__FILE__) . '/../3rdparty/Crypt_Blowfish/Blowfish.php');
/**
* Class for common cryptography functionality
@@ -41,10 +36,10 @@ class Crypt {
/**
* @brief return encryption mode client or server side encryption
- * @param string user name (use system wide setting if name=null)
+ * @param string $user name (use system wide setting if name=null)
* @return string 'client' or 'server'
*/
- public static function mode( $user = null ) {
+ public static function mode($user = null) {
return 'server';
@@ -56,30 +51,40 @@ class Crypt {
*/
public static function createKeypair() {
- $res = openssl_pkey_new();
-
- // Get private key
- openssl_pkey_export( $res, $privateKey );
+ $return = false;
- // Get public key
- $publicKey = openssl_pkey_get_details( $res );
+ $res = openssl_pkey_new(array('private_key_bits' => 4096));
- $publicKey = $publicKey['key'];
+ if ($res === false) {
+ \OCP\Util::writeLog('Encryption library', 'couldn\'t generate users key-pair for ' . \OCP\User::getUser(), \OCP\Util::ERROR);
+ \OCP\Util::writeLog('Encryption library', openssl_error_string(), \OCP\Util::ERROR);
+ } elseif (openssl_pkey_export($res, $privateKey)) {
+ // Get public key
+ $keyDetails = openssl_pkey_get_details($res);
+ $publicKey = $keyDetails['key'];
- return( array( 'publicKey' => $publicKey, 'privateKey' => $privateKey ) );
+ $return = array(
+ 'publicKey' => $publicKey,
+ 'privateKey' => $privateKey
+ );
+ } else {
+ \OCP\Util::writeLog('Encryption library', 'couldn\'t export users private key, please check your servers openSSL configuration.' . \OCP\User::getUser(), \OCP\Util::ERROR);
+ \OCP\Util::writeLog('Encryption library', openssl_error_string(), \OCP\Util::ERROR);
+ }
+ return $return;
}
/**
* @brief Add arbitrary padding to encrypted data
* @param string $data data to be padded
- * @return padded data
+ * @return string padded data
* @note In order to end up with data exactly 8192 bytes long we must
* add two letters. It is impossible to achieve exactly 8192 length
* blocks with encryption alone, hence padding is added to achieve the
* required length.
*/
- public static function addPadding( $data ) {
+ public static function addPadding($data) {
$padded = $data . 'xx';
@@ -90,13 +95,13 @@ class Crypt {
/**
* @brief Remove arbitrary padding to encrypted data
* @param string $padded padded data to remove padding from
- * @return unpadded data on success, false on error
+ * @return string unpadded data on success, false on error
*/
- public static function removePadding( $padded ) {
+ public static function removePadding($padded) {
- if ( substr( $padded, -2 ) == 'xx' ) {
+ if (substr($padded, -2) === 'xx') {
- $data = substr( $padded, 0, -2 );
+ $data = substr($padded, 0, -2);
return $data;
@@ -111,29 +116,30 @@ class Crypt {
/**
* @brief Check if a file's contents contains an IV and is symmetrically encrypted
- * @return true / false
+ * @param $content
+ * @return boolean
* @note see also OCA\Encryption\Util->isEncryptedPath()
*/
- public static function isCatfile( $content ) {
+ public static function isCatfileContent($content) {
- if ( !$content ) {
+ if (!$content) {
return false;
}
- $noPadding = self::removePadding( $content );
+ $noPadding = self::removePadding($content);
// Fetch encryption metadata from end of file
- $meta = substr( $noPadding, -22 );
+ $meta = substr($noPadding, -22);
// Fetch IV from end of file
- $iv = substr( $meta, -16 );
+ $iv = substr($meta, -16);
// Fetch identifier from start of metadata
- $identifier = substr( $meta, 0, 6 );
+ $identifier = substr($meta, 0, 6);
- if ( $identifier == '00iv00') {
+ if ($identifier === '00iv00') {
return true;
@@ -150,36 +156,36 @@ class Crypt {
* @param string $path
* @return bool
*/
- public static function isEncryptedMeta( $path ) {
+ public static function isEncryptedMeta($path) {
// TODO: Use DI to get \OC\Files\Filesystem out of here
// Fetch all file metadata from DB
- $metadata = \OC\Files\Filesystem::getFileInfo( $path, '' );
+ $metadata = \OC\Files\Filesystem::getFileInfo($path);
// Return encryption status
- return isset( $metadata['encrypted'] ) and ( bool )$metadata['encrypted'];
+ return isset($metadata['encrypted']) && ( bool )$metadata['encrypted'];
}
/**
* @brief Check if a file is encrypted via legacy system
+ * @param $data
* @param string $relPath The path of the file, relative to user/data;
* e.g. filename or /Docs/filename, NOT admin/files/filename
- * @return true / false
+ * @return boolean
*/
- public static function isLegacyEncryptedContent( $data, $relPath ) {
+ public static function isLegacyEncryptedContent($isCatFileContent, $relPath) {
// Fetch all file metadata from DB
- $metadata = \OC\Files\Filesystem::getFileInfo( $relPath, '' );
+ $metadata = \OC\Files\Filesystem::getFileInfo($relPath, '');
// If a file is flagged with encryption in DB, but isn't a
// valid content + IV combination, it's probably using the
// legacy encryption system
- if (
- isset( $metadata['encrypted'] )
- and $metadata['encrypted'] === true
- and ! self::isCatfile( $data )
+ if (isset($metadata['encrypted'])
+ && $metadata['encrypted'] === true
+ && $isCatFileContent === false
) {
return true;
@@ -194,18 +200,18 @@ class Crypt {
/**
* @brief Symmetrically encrypt a string
- * @returns encrypted file
+ * @param $plainContent
+ * @param $iv
+ * @param string $passphrase
+ * @return string encrypted file content
*/
- public static function encrypt( $plainContent, $iv, $passphrase = '' ) {
-
- if ( $encryptedContent = openssl_encrypt( $plainContent, 'AES-128-CFB', $passphrase, false, $iv ) ) {
+ public static function encrypt($plainContent, $iv, $passphrase = '') {
+ if ($encryptedContent = openssl_encrypt($plainContent, 'AES-128-CFB', $passphrase, false, $iv)) {
return $encryptedContent;
-
} else {
-
- \OC_Log::write( 'Encryption library', 'Encryption (symmetric) of content failed', \OC_Log::ERROR );
-
+ \OCP\Util::writeLog('Encryption library', 'Encryption (symmetric) of content failed', \OCP\Util::ERROR);
+ \OCP\Util::writeLog('Encryption library', openssl_error_string(), \OCP\Util::ERROR);
return false;
}
@@ -214,18 +220,21 @@ class Crypt {
/**
* @brief Symmetrically decrypt a string
- * @returns decrypted file
+ * @param $encryptedContent
+ * @param $iv
+ * @param $passphrase
+ * @throws \Exception
+ * @return string decrypted file content
*/
- public static function decrypt( $encryptedContent, $iv, $passphrase ) {
+ public static function decrypt($encryptedContent, $iv, $passphrase) {
- if ( $plainContent = openssl_decrypt( $encryptedContent, 'AES-128-CFB', $passphrase, false, $iv ) ) {
+ if ($plainContent = openssl_decrypt($encryptedContent, 'AES-128-CFB', $passphrase, false, $iv)) {
return $plainContent;
-
} else {
- throw new \Exception( 'Encryption library: Decryption (symmetric) of content failed' );
+ throw new \Exception('Encryption library: Decryption (symmetric) of content failed');
}
@@ -237,7 +246,7 @@ class Crypt {
* @param string $iv IV to be concatenated
* @returns string concatenated content
*/
- public static function concatIv ( $content, $iv ) {
+ public static function concatIv($content, $iv) {
$combined = $content . '00iv00' . $iv;
@@ -250,20 +259,20 @@ class Crypt {
* @param string $catFile concatenated data to be split
* @returns array keys: encrypted, iv
*/
- public static function splitIv ( $catFile ) {
+ public static function splitIv($catFile) {
// Fetch encryption metadata from end of file
- $meta = substr( $catFile, -22 );
+ $meta = substr($catFile, -22);
// Fetch IV from end of file
- $iv = substr( $meta, -16 );
+ $iv = substr($meta, -16);
// Remove IV and IV identifier text to expose encrypted content
- $encrypted = substr( $catFile, 0, -22 );
+ $encrypted = substr($catFile, 0, -22);
$split = array(
- 'encrypted' => $encrypted
- , 'iv' => $iv
+ 'encrypted' => $encrypted,
+ 'iv' => $iv
);
return $split;
@@ -272,36 +281,32 @@ class Crypt {
/**
* @brief Symmetrically encrypts a string and returns keyfile content
- * @param $plainContent content to be encrypted in keyfile
- * @returns encrypted content combined with IV
+ * @param string $plainContent content to be encrypted in keyfile
+ * @param string $passphrase
+ * @return bool|string
+ * @return string encrypted content combined with IV
* @note IV need not be specified, as it will be stored in the returned keyfile
* and remain accessible therein.
*/
- public static function symmetricEncryptFileContent( $plainContent, $passphrase = '' ) {
-
- if ( !$plainContent ) {
+ public static function symmetricEncryptFileContent($plainContent, $passphrase = '') {
+ if (!$plainContent) {
+ \OCP\Util::writeLog('Encryption library', 'symmetrically encryption failed, no content given.', \OCP\Util::ERROR);
return false;
-
}
$iv = self::generateIv();
- if ( $encryptedContent = self::encrypt( $plainContent, $iv, $passphrase ) ) {
-
+ if ($encryptedContent = self::encrypt($plainContent, $iv, $passphrase)) {
// Combine content to encrypt with IV identifier and actual IV
- $catfile = self::concatIv( $encryptedContent, $iv );
-
- $padded = self::addPadding( $catfile );
+ $catfile = self::concatIv($encryptedContent, $iv);
+ $padded = self::addPadding($catfile);
return $padded;
} else {
-
- \OC_Log::write( 'Encryption library', 'Encryption (symmetric) of keyfile content failed', \OC_Log::ERROR );
-
+ \OCP\Util::writeLog('Encryption library', 'Encryption (symmetric) of keyfile content failed', \OCP\Util::ERROR);
return false;
-
}
}
@@ -309,35 +314,69 @@ class Crypt {
/**
* @brief Symmetrically decrypts keyfile content
- * @param string $source
- * @param string $target
- * @param string $key the decryption key
- * @returns decrypted content
+ * @param $keyfileContent
+ * @param string $passphrase
+ * @throws \Exception
+ * @return bool|string
+ * @internal param string $source
+ * @internal param string $target
+ * @internal param string $key the decryption key
+ * @returns string decrypted content
*
* This function decrypts a file
*/
- public static function symmetricDecryptFileContent( $keyfileContent, $passphrase = '' ) {
+ public static function symmetricDecryptFileContent($keyfileContent, $passphrase = '') {
- if ( !$keyfileContent ) {
+ if (!$keyfileContent) {
- throw new \Exception( 'Encryption library: no data provided for decryption' );
+ throw new \Exception('Encryption library: no data provided for decryption');
}
// Remove padding
- $noPadding = self::removePadding( $keyfileContent );
+ $noPadding = self::removePadding($keyfileContent);
// Split into enc data and catfile
- $catfile = self::splitIv( $noPadding );
+ $catfile = self::splitIv($noPadding);
- if ( $plainContent = self::decrypt( $catfile['encrypted'], $catfile['iv'], $passphrase ) ) {
+ if ($plainContent = self::decrypt($catfile['encrypted'], $catfile['iv'], $passphrase)) {
return $plainContent;
+ } else {
+ return false;
+ }
+
+ }
+
+ /**
+ * @brief Decrypt private key and check if the result is a valid keyfile
+ * @param string $encryptedKey encrypted keyfile
+ * @param string $passphrase to decrypt keyfile
+ * @returns encrypted private key or false
+ *
+ * This function decrypts a file
+ */
+ public static function decryptPrivateKey($encryptedKey, $passphrase) {
+
+ $plainKey = self::symmetricDecryptFileContent($encryptedKey, $passphrase);
+
+ // check if this a valid private key
+ $res = openssl_pkey_get_private($plainKey);
+ if (is_resource($res)) {
+ $sslInfo = openssl_pkey_get_details($res);
+ if (!isset($sslInfo['key'])) {
+ $plainKey = false;
+ }
+ } else {
+ $plainKey = false;
}
+ return $plainKey;
+
}
+
/**
* @brief Creates symmetric keyfile content using a generated key
* @param string $plainContent content to be encrypted
@@ -346,15 +385,15 @@ class Crypt {
*
* This function decrypts a file
*/
- public static function symmetricEncryptFileContentKeyfile( $plainContent ) {
+ public static function symmetricEncryptFileContentKeyfile($plainContent) {
$key = self::generateKey();
- if( $encryptedContent = self::symmetricEncryptFileContent( $plainContent, $key ) ) {
+ if ($encryptedContent = self::symmetricEncryptFileContent($plainContent, $key)) {
return array(
- 'key' => $key
- , 'encrypted' => $encryptedContent
+ 'key' => $key,
+ 'encrypted' => $encryptedContent
);
} else {
@@ -368,22 +407,41 @@ class Crypt {
/**
* @brief Create asymmetrically encrypted keyfile content using a generated key
* @param string $plainContent content to be encrypted
- * @returns array keys: key, encrypted
- * @note symmetricDecryptFileContent() can be used to decrypt files created using this method
- *
- * This function decrypts a file
+ * @param array $publicKeys array keys must be the userId of corresponding user
+ * @returns array keys: keys (array, key = userId), data
+ * @note symmetricDecryptFileContent() can decrypt files created using this method
*/
- public static function multiKeyEncrypt( $plainContent, array $publicKeys ) {
+ public static function multiKeyEncrypt($plainContent, array $publicKeys) {
+
+ // openssl_seal returns false without errors if $plainContent
+ // is empty, so trigger our own error
+ if (empty($plainContent)) {
+
+ throw new \Exception('Cannot mutliKeyEncrypt empty plain content');
+
+ }
// Set empty vars to be set by openssl by reference
$sealed = '';
- $envKeys = array();
+ $shareKeys = array();
+ $mappedShareKeys = array();
+
+ if (openssl_seal($plainContent, $sealed, $shareKeys, $publicKeys)) {
+
+ $i = 0;
+
+ // Ensure each shareKey is labelled with its
+ // corresponding userId
+ foreach ($publicKeys as $userId => $publicKey) {
- if( openssl_seal( $plainContent, $sealed, $envKeys, $publicKeys ) ) {
+ $mappedShareKeys[$userId] = $shareKeys[$i];
+ $i++;
+
+ }
return array(
- 'keys' => $envKeys
- , 'encrypted' => $sealed
+ 'keys' => $mappedShareKeys,
+ 'data' => $sealed
);
} else {
@@ -396,27 +454,31 @@ class Crypt {
/**
* @brief Asymmetrically encrypt a file using multiple public keys
- * @param string $plainContent content to be encrypted
+ * @param $encryptedContent
+ * @param $shareKey
+ * @param $privateKey
+ * @return bool
+ * @internal param string $plainContent content to be encrypted
* @returns string $plainContent decrypted string
* @note symmetricDecryptFileContent() can be used to decrypt files created using this method
*
* This function decrypts a file
*/
- public static function multiKeyDecrypt( $encryptedContent, $envKey, $privateKey ) {
+ public static function multiKeyDecrypt($encryptedContent, $shareKey, $privateKey) {
- if ( !$encryptedContent ) {
+ if (!$encryptedContent) {
return false;
}
- if ( openssl_open( $encryptedContent, $plainContent, $envKey, $privateKey ) ) {
+ if (openssl_open($encryptedContent, $plainContent, $shareKey, $privateKey)) {
return $plainContent;
} else {
- \OC_Log::write( 'Encryption library', 'Decryption (asymmetric) of sealed content failed', \OC_Log::ERROR );
+ \OCP\Util::writeLog('Encryption library', 'Decryption (asymmetric) of sealed content with share-key "'.$shareKey.'" failed', \OCP\Util::ERROR);
return false;
@@ -425,12 +487,14 @@ class Crypt {
}
/**
- * @brief Asymmetrically encrypt a string using a public key
- * @returns encrypted file
+ * @brief Asymetrically encrypt a string using a public key
+ * @param $plainContent
+ * @param $publicKey
+ * @return string encrypted file
*/
- public static function keyEncrypt( $plainContent, $publicKey ) {
+ public static function keyEncrypt($plainContent, $publicKey) {
- openssl_public_encrypt( $plainContent, $encryptedContent, $publicKey );
+ openssl_public_encrypt($plainContent, $encryptedContent, $publicKey);
return $encryptedContent;
@@ -438,110 +502,19 @@ class Crypt {
/**
* @brief Asymetrically decrypt a file using a private key
- * @returns decrypted file
- */
- public static function keyDecrypt( $encryptedContent, $privatekey ) {
-
- openssl_private_decrypt( $encryptedContent, $plainContent, $privatekey );
-
- return $plainContent;
-
- }
-
- /**
- * @brief Encrypts content symmetrically and generates keyfile asymmetrically
- * @returns array containing catfile and new keyfile.
- * keys: data, key
- * @note this method is a wrapper for combining other crypt class methods
+ * @param $encryptedContent
+ * @param $privatekey
+ * @return string decrypted file
*/
- public static function keyEncryptKeyfile( $plainContent, $publicKey ) {
+ public static function keyDecrypt($encryptedContent, $privatekey) {
- // Encrypt plain data, generate keyfile & encrypted file
- $cryptedData = self::symmetricEncryptFileContentKeyfile( $plainContent );
-
- // Encrypt keyfile
- $cryptedKey = self::keyEncrypt( $cryptedData['key'], $publicKey );
-
- return array( 'data' => $cryptedData['encrypted'], 'key' => $cryptedKey );
-
- }
-
- /**
- * @brief Takes catfile, keyfile, and private key, and
- * performs decryption
- * @returns decrypted content
- * @note this method is a wrapper for combining other crypt class methods
- */
- public static function keyDecryptKeyfile( $catfile, $keyfile, $privateKey ) {
-
- // Decrypt the keyfile with the user's private key
- $decryptedKeyfile = self::keyDecrypt( $keyfile, $privateKey );
-
- // Decrypt the catfile symmetrically using the decrypted keyfile
- $decryptedData = self::symmetricDecryptFileContent( $catfile, $decryptedKeyfile );
-
- return $decryptedData;
-
- }
-
- /**
- * @brief Symmetrically encrypt a file by combining encrypted component data blocks
- */
- public static function symmetricBlockEncryptFileContent( $plainContent, $key ) {
-
- $crypted = '';
-
- $remaining = $plainContent;
-
- $testarray = array();
-
- while( strlen( $remaining ) ) {
-
- //echo "\n\n\$block = ".substr( $remaining, 0, 6126 );
-
- // Encrypt a chunk of unencrypted data and add it to the rest
- $block = self::symmetricEncryptFileContent( substr( $remaining, 0, 6126 ), $key );
-
- $padded = self::addPadding( $block );
-
- $crypted .= $block;
-
- $testarray[] = $block;
-
- // Remove the data already encrypted from remaining unencrypted data
- $remaining = substr( $remaining, 6126 );
-
- }
-
- return $crypted;
-
- }
-
-
- /**
- * @brief Symmetrically decrypt a file by combining encrypted component data blocks
- */
- public static function symmetricBlockDecryptFileContent( $crypted, $key ) {
-
- $decrypted = '';
-
- $remaining = $crypted;
-
- $testarray = array();
-
- while( strlen( $remaining ) ) {
-
- $testarray[] = substr( $remaining, 0, 8192 );
-
- // Decrypt a chunk of unencrypted data and add it to the rest
- $decrypted .= self::symmetricDecryptFileContent( $remaining, $key );
-
- // Remove the data already encrypted from remaining unencrypted data
- $remaining = substr( $remaining, 8192 );
+ $result = @openssl_private_decrypt($encryptedContent, $plainContent, $privatekey);
+ if ($result) {
+ return $plainContent;
}
- return $decrypted;
+ return $result;
}
@@ -551,24 +524,24 @@ class Crypt {
*/
public static function generateIv() {
- if ( $random = openssl_random_pseudo_bytes( 12, $strong ) ) {
+ if ($random = openssl_random_pseudo_bytes(12, $strong)) {
- if ( !$strong ) {
+ if (!$strong) {
// If OpenSSL indicates randomness is insecure, log error
- \OC_Log::write( 'Encryption library', 'Insecure symmetric key was generated using openssl_random_pseudo_bytes()', \OC_Log::WARN );
+ \OCP\Util::writeLog('Encryption library', 'Insecure symmetric key was generated using openssl_random_pseudo_bytes()', \OCP\Util::WARN);
}
// We encode the iv purely for string manipulation
// purposes - it gets decoded before use
- $iv = base64_encode( $random );
+ $iv = base64_encode($random);
return $iv;
} else {
- throw new \Exception( 'Generating IV failed' );
+ throw new \Exception('Generating IV failed');
}
@@ -581,12 +554,12 @@ class Crypt {
public static function generateKey() {
// Generate key
- if ( $key = base64_encode( openssl_random_pseudo_bytes( 183, $strong ) ) ) {
+ if ($key = base64_encode(openssl_random_pseudo_bytes(183, $strong))) {
- if ( !$strong ) {
+ if (!$strong) {
// If OpenSSL indicates randomness is insecure, log error
- throw new \Exception ( 'Encryption library, Insecure symmetric key was generated using openssl_random_pseudo_bytes()' );
+ throw new \Exception('Encryption library, Insecure symmetric key was generated using openssl_random_pseudo_bytes()');
}
@@ -603,15 +576,15 @@ class Crypt {
/**
* @brief Get the blowfish encryption handeler for a key
* @param $key string (optional)
- * @return Crypt_Blowfish blowfish object
+ * @return \Crypt_Blowfish blowfish object
*
* if the key is left out, the default handeler will be used
*/
- public static function getBlowfish( $key = '' ) {
+ public static function getBlowfish($key = '') {
- if ( $key ) {
+ if ($key) {
- return new \Crypt_Blowfish( $key );
+ return new \Crypt_Blowfish($key);
} else {
@@ -621,13 +594,17 @@ class Crypt {
}
- public static function legacyCreateKey( $passphrase ) {
+ /**
+ * @param $passphrase
+ * @return mixed
+ */
+ public static function legacyCreateKey($passphrase) {
// Generate a random integer
- $key = mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 );
+ $key = mt_rand(10000, 99999) . mt_rand(10000, 99999) . mt_rand(10000, 99999) . mt_rand(10000, 99999);
// Encrypt the key with the passphrase
- $legacyEncKey = self::legacyEncrypt( $key, $passphrase );
+ $legacyEncKey = self::legacyEncrypt($key, $passphrase);
return $legacyEncKey;
@@ -635,61 +612,55 @@ class Crypt {
/**
* @brief encrypts content using legacy blowfish system
- * @param $content the cleartext message you want to encrypt
- * @param $key the encryption key (optional)
- * @returns encrypted content
+ * @param string $content the cleartext message you want to encrypt
+ * @param string $passphrase
+ * @returns string encrypted content
*
* This function encrypts an content
*/
- public static function legacyEncrypt( $content, $passphrase = '' ) {
+ public static function legacyEncrypt($content, $passphrase = '') {
- $bf = self::getBlowfish( $passphrase );
+ $bf = self::getBlowfish($passphrase);
- return $bf->encrypt( $content );
+ return $bf->encrypt($content);
}
/**
* @brief decrypts content using legacy blowfish system
- * @param $content the cleartext message you want to decrypt
- * @param $key the encryption key (optional)
- * @returns cleartext content
+ * @param string $content the cleartext message you want to decrypt
+ * @param string $passphrase
+ * @return string cleartext content
*
* This function decrypts an content
*/
- public static function legacyDecrypt( $content, $passphrase = '' ) {
-
- $bf = self::getBlowfish( $passphrase );
+ public static function legacyDecrypt($content, $passphrase = '') {
- $decrypted = $bf->decrypt( $content );
+ $bf = self::getBlowfish($passphrase);
- $trimmed = rtrim( $decrypted, "\0" );
-
- return $trimmed;
-
- }
-
- public static function legacyKeyRecryptKeyfile( $legacyEncryptedContent, $legacyPassphrase, $publicKey, $newPassphrase ) {
-
- $decrypted = self::legacyDecrypt( $legacyEncryptedContent, $legacyPassphrase );
-
- $recrypted = self::keyEncryptKeyfile( $decrypted, $publicKey );
-
- return $recrypted;
+ $decrypted = $bf->decrypt($content);
+ return $decrypted;
}
/**
- * @brief Re-encryptes a legacy blowfish encrypted file using AES with integrated IV
- * @param $legacyContent the legacy encrypted content to re-encrypt
- * @returns cleartext content
- *
- * This function decrypts an content
+ * @param $data
+ * @param string $key
+ * @param int $maxLength
+ * @return string
*/
- public static function legacyRecrypt( $legacyContent, $legacyPassphrase, $newPassphrase ) {
-
- // TODO: write me
+ public static function legacyBlockDecrypt($data, $key = '', $maxLength = 0) {
+ $result = '';
+ while (strlen($data)) {
+ $result .= self::legacyDecrypt(substr($data, 0, 8192), $key);
+ $data = substr($data, 8192);
+ }
+ if ($maxLength > 0) {
+ return substr($result, 0, $maxLength);
+ } else {
+ return rtrim($result, "\0");
+ }
}
-}
+}
\ No newline at end of file
diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php
new file mode 100755
index 0000000000000000000000000000000000000000..6eee8fed6a63932b01071dc0b173ee8041dc6f1a
--- /dev/null
+++ b/apps/files_encryption/lib/helper.php
@@ -0,0 +1,245 @@
+
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library 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 along with this library. If not, see .
+ *
+ */
+
+namespace OCA\Encryption;
+
+/**
+ * @brief Class to manage registration of hooks an various helper methods
+ * @package OCA\Encryption
+ */
+class Helper {
+
+ /**
+ * @brief register share related hooks
+ *
+ */
+ public static function registerShareHooks() {
+
+ \OCP\Util::connectHook('OCP\Share', 'pre_shared', 'OCA\Encryption\Hooks', 'preShared');
+ \OCP\Util::connectHook('OCP\Share', 'post_shared', 'OCA\Encryption\Hooks', 'postShared');
+ \OCP\Util::connectHook('OCP\Share', 'post_unshare', 'OCA\Encryption\Hooks', 'postUnshare');
+ }
+
+ /**
+ * @brief register user related hooks
+ *
+ */
+ public static function registerUserHooks() {
+
+ \OCP\Util::connectHook('OC_User', 'post_login', 'OCA\Encryption\Hooks', 'login');
+ \OCP\Util::connectHook('OC_User', 'post_setPassword', 'OCA\Encryption\Hooks', 'setPassphrase');
+ \OCP\Util::connectHook('OC_User', 'pre_setPassword', 'OCA\Encryption\Hooks', 'preSetPassphrase');
+ \OCP\Util::connectHook('OC_User', 'post_createUser', 'OCA\Encryption\Hooks', 'postCreateUser');
+ \OCP\Util::connectHook('OC_User', 'post_deleteUser', 'OCA\Encryption\Hooks', 'postDeleteUser');
+ }
+
+ /**
+ * @brief register filesystem related hooks
+ *
+ */
+ public static function registerFilesystemHooks() {
+
+ \OCP\Util::connectHook('OC_Filesystem', 'post_rename', 'OCA\Encryption\Hooks', 'postRename');
+ }
+
+ /**
+ * @brief register app management related hooks
+ *
+ */
+ public static function registerAppHooks() {
+
+ \OCP\Util::connectHook('OC_App', 'pre_disable', 'OCA\Encryption\Hooks', 'preDisable');
+ }
+
+ /**
+ * @brief setup user for files_encryption
+ *
+ * @param Util $util
+ * @param string $password
+ * @return bool
+ */
+ public static function setupUser($util, $password) {
+ // Check files_encryption infrastructure is ready for action
+ if (!$util->ready()) {
+
+ \OCP\Util::writeLog('Encryption library', 'User account "' . $util->getUserId()
+ . '" is not ready for encryption; configuration started', \OCP\Util::DEBUG);
+
+ if (!$util->setupServerSide($password)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * @brief enable recovery
+ *
+ * @param $recoveryKeyId
+ * @param $recoveryPassword
+ * @internal param \OCA\Encryption\Util $util
+ * @internal param string $password
+ * @return bool
+ */
+ public static function adminEnableRecovery($recoveryKeyId, $recoveryPassword) {
+
+ $view = new \OC\Files\View('/');
+
+ if ($recoveryKeyId === null) {
+ $recoveryKeyId = 'recovery_' . substr(md5(time()), 0, 8);
+ \OC_Appconfig::setValue('files_encryption', 'recoveryKeyId', $recoveryKeyId);
+ }
+
+ if (!$view->is_dir('/owncloud_private_key')) {
+ $view->mkdir('/owncloud_private_key');
+ }
+
+ if (
+ (!$view->file_exists("/public-keys/" . $recoveryKeyId . ".public.key")
+ || !$view->file_exists("/owncloud_private_key/" . $recoveryKeyId . ".private.key"))
+ ) {
+
+ $keypair = \OCA\Encryption\Crypt::createKeypair();
+
+ \OC_FileProxy::$enabled = false;
+
+ // Save public key
+
+ if (!$view->is_dir('/public-keys')) {
+ $view->mkdir('/public-keys');
+ }
+
+ $view->file_put_contents('/public-keys/' . $recoveryKeyId . '.public.key', $keypair['publicKey']);
+
+ // Encrypt private key empty passphrase
+ $encryptedPrivateKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent($keypair['privateKey'], $recoveryPassword);
+
+ // Save private key
+ $view->file_put_contents('/owncloud_private_key/' . $recoveryKeyId . '.private.key', $encryptedPrivateKey);
+
+ \OC_FileProxy::$enabled = true;
+
+ // Set recoveryAdmin as enabled
+ \OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 1);
+
+ $return = true;
+
+ } else { // get recovery key and check the password
+ $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), \OCP\User::getUser());
+ $return = $util->checkRecoveryPassword($recoveryPassword);
+ if ($return) {
+ \OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 1);
+ }
+ }
+
+ return $return;
+ }
+
+
+ /**
+ * @brief disable recovery
+ *
+ * @param $recoveryPassword
+ * @return bool
+ */
+ public static function adminDisableRecovery($recoveryPassword) {
+ $util = new Util(new \OC_FilesystemView('/'), \OCP\User::getUser());
+ $return = $util->checkRecoveryPassword($recoveryPassword);
+
+ if ($return) {
+ // Set recoveryAdmin as disabled
+ \OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 0);
+ }
+
+ return $return;
+ }
+
+
+ /**
+ * @brief checks if access is public/anonymous user
+ * @return bool
+ */
+ public static function isPublicAccess() {
+ if (\OCP\USER::getUser() === false
+ || (isset($_GET['service']) && $_GET['service'] == 'files'
+ && isset($_GET['t']))
+ ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @brief Format a path to be relative to the /user/files/ directory
+ * @param string $path the absolute path
+ * @return string e.g. turns '/admin/files/test.txt' into 'test.txt'
+ */
+ public static function stripUserFilesPath($path) {
+ $trimmed = ltrim($path, '/');
+ $split = explode('/', $trimmed);
+ $sliced = array_slice($split, 2);
+ $relPath = implode('/', $sliced);
+
+ return $relPath;
+ }
+
+ /**
+ * @brief redirect to a error page
+ */
+ public static function redirectToErrorPage() {
+ $location = \OC_Helper::linkToAbsolute('apps/files_encryption/files', 'error.php');
+ $post = 0;
+ if(count($_POST) > 0) {
+ $post = 1;
+ }
+ header('Location: ' . $location . '?p=' . $post);
+ exit();
+ }
+
+ /**
+ * check requirements for encryption app.
+ * @return bool true if requirements are met
+ */
+ public static function checkRequirements() {
+ $result = true;
+
+ //openssl extension needs to be loaded
+ $result &= extension_loaded("openssl");
+ // we need php >= 5.3.3
+ $result &= version_compare(phpversion(), '5.3.3', '>=');
+
+ return (bool) $result;
+ }
+
+ /**
+ * @brief glob uses different pattern than regular expressions, escape glob pattern only
+ * @param unescaped path
+ * @return escaped path
+ */
+ public static function escapeGlobPattern($path) {
+ return preg_replace('/(\*|\?|\[)/', '[$1]', $path);
+ }
+}
+
diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php
index 955877971540bf86144ec6048ec47742cefff752..b2fd650f18df497064db867f92048bef39bcddbe 100755
--- a/apps/files_encryption/lib/keymanager.php
+++ b/apps/files_encryption/lib/keymanager.php
@@ -28,19 +28,26 @@ namespace OCA\Encryption;
* @note Where a method requires a view object, it's root must be '/'
*/
class Keymanager {
-
+
/**
* @brief retrieve the ENCRYPTED private key from a user
- *
- * @return string private key or false
+ *
+ * @param \OC_FilesystemView $view
+ * @param string $user
+ * @return string private key or false (hopefully)
* @note the key returned by this method must be decrypted before use
*/
- public static function getPrivateKey( \OC_FilesystemView $view, $user ) {
-
- $path = '/' . $user . '/' . 'files_encryption' . '/' . $user.'.private.key';
-
- $key = $view->file_get_contents( $path );
-
+ public static function getPrivateKey(\OC_FilesystemView $view, $user) {
+
+ $path = '/' . $user . '/' . 'files_encryption' . '/' . $user . '.private.key';
+
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ $key = $view->file_get_contents($path);
+
+ \OC_FileProxy::$enabled = $proxyStatus;
+
return $key;
}
@@ -50,102 +57,157 @@ class Keymanager {
* @param $userId
* @return string public key or false
*/
- public static function getPublicKey( \OC_FilesystemView $view, $userId ) {
-
- return $view->file_get_contents( '/public-keys/' . '/' . $userId . '.public.key' );
-
+ public static function getPublicKey(\OC_FilesystemView $view, $userId) {
+
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ $result = $view->file_get_contents('/public-keys/' . $userId . '.public.key');
+
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ return $result;
+
}
-
+
/**
- * @brief retrieve both keys from a user (private and public)
+ * @brief Retrieve a user's public and private key
* @param \OC_FilesystemView $view
* @param $userId
* @return array keys: privateKey, publicKey
*/
- public static function getUserKeys( \OC_FilesystemView $view, $userId ) {
-
+ public static function getUserKeys(\OC_FilesystemView $view, $userId) {
+
return array(
- 'publicKey' => self::getPublicKey( $view, $userId )
- , 'privateKey' => self::getPrivateKey( $view, $userId )
+ 'publicKey' => self::getPublicKey($view, $userId),
+ 'privateKey' => self::getPrivateKey($view, $userId)
);
-
+
}
-
+
/**
- * @brief Retrieve public keys of all users with access to a file
- * @param string $path Path to file
- * @return array of public keys for the given file
- * @note Checks that the sharing app is enabled should be performed
- * by client code, that isn't checked here
+ * @brief Retrieve public keys for given users
+ * @param \OC_FilesystemView $view
+ * @param array $userIds
+ * @return array of public keys for the specified users
*/
- public static function getPublicKeys( \OC_FilesystemView $view, $userId, $filePath ) {
-
- $path = ltrim( $path, '/' );
-
- $filepath = '/' . $userId . '/files/' . $filePath;
-
- // Check if sharing is enabled
- if ( OC_App::isEnabled( 'files_sharing' ) ) {
-
-
-
- } else {
-
- // check if it is a file owned by the user and not shared at all
- $userview = new \OC_FilesystemView( '/'.$userId.'/files/' );
-
- if ( $userview->file_exists( $path ) ) {
-
- $users[] = $userId;
-
- }
-
- }
-
- $view = new \OC_FilesystemView( '/public-keys/' );
-
- $keylist = array();
-
- $count = 0;
-
- foreach ( $users as $user ) {
-
- $keylist['key'.++$count] = $view->file_get_contents( $user.'.public.key' );
-
+ public static function getPublicKeys(\OC_FilesystemView $view, array $userIds) {
+
+ $keys = array();
+
+ foreach ($userIds as $userId) {
+
+ $keys[$userId] = self::getPublicKey($view, $userId);
+
}
-
- return $keylist;
-
+
+ return $keys;
+
}
-
+
/**
* @brief store file encryption key
*
+ * @param \OC_FilesystemView $view
* @param string $path relative path of the file, including filename
- * @param string $key
+ * @param $userId
+ * @param $catfile
+ * @internal param string $key
* @return bool true/false
- * @note The keyfile is not encrypted here. Client code must
+ * @note The keyfile is not encrypted here. Client code must
* asymmetrically encrypt the keyfile before passing it to this method
*/
- public static function setFileKey( \OC_FilesystemView $view, $path, $userId, $catfile ) {
-
- $basePath = '/' . $userId . '/files_encryption/keyfiles';
-
- $targetPath = self::keySetPreparation( $view, $path, $basePath, $userId );
-
- if ( $view->is_dir( $basePath . '/' . $targetPath ) ) {
-
-
-
+ public static function setFileKey(\OC_FilesystemView $view, $path, $userId, $catfile) {
+
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ //here we need the currently logged in user, while userId can be a different user
+ $util = new Util($view, \OCP\User::getUser());
+ list($owner, $filename) = $util->getUidAndFilename($path);
+
+ // in case of system wide mount points the keys are stored directly in the data directory
+ if ($util->isSystemWideMountPoint($filename)) {
+ $basePath = '/files_encryption/keyfiles';
+ } else {
+ $basePath = '/' . $owner . '/files_encryption/keyfiles';
+ }
+
+ $targetPath = self::keySetPreparation($view, $filename, $basePath, $owner);
+
+ if (!$view->is_dir($basePath . '/' . $targetPath)) {
+
+ // create all parent folders
+ $info = pathinfo($basePath . '/' . $targetPath);
+ $keyfileFolderName = $view->getLocalFolder($info['dirname']);
+
+ if (!file_exists($keyfileFolderName)) {
+
+ mkdir($keyfileFolderName, 0750, true);
+
+ }
+ }
+
+ // try reusing key file if part file
+ if (self::isPartialFilePath($targetPath)) {
+
+ $result = $view->file_put_contents(
+ $basePath . '/' . self::fixPartialFilePath($targetPath) . '.key', $catfile);
+
} else {
- // Save the keyfile in parallel directory
- return $view->file_put_contents( $basePath . '/' . $targetPath . '.key', $catfile );
-
+ $result = $view->file_put_contents($basePath . '/' . $targetPath . '.key', $catfile);
+
}
-
+
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ return $result;
+
}
-
+
+ /**
+ * @brief Remove .path extension from a file path
+ * @param string $path Path that may identify a .part file
+ * @return string File path without .part extension
+ * @note this is needed for reusing keys
+ */
+ public static function fixPartialFilePath($path) {
+
+ if (preg_match('/\.part$/', $path) || preg_match('/\.etmp$/', $path)) {
+
+ $newLength = strlen($path) - 5;
+ $fPath = substr($path, 0, $newLength);
+
+ return $fPath;
+
+ } else {
+
+ return $path;
+
+ }
+
+ }
+
+ /**
+ * @brief Check if a path is a .part file
+ * @param string $path Path that may identify a .part file
+ * @return bool
+ */
+ public static function isPartialFilePath($path) {
+
+ if (preg_match('/\.part$/', $path) || preg_match('/\.etmp$/', $path)) {
+
+ return true;
+
+ } else {
+
+ return false;
+
+ }
+
+ }
+
/**
* @brief retrieve keyfile for an encrypted file
* @param \OC_FilesystemView $view
@@ -156,168 +218,379 @@ class Keymanager {
* @note The keyfile returned is asymmetrically encrypted. Decryption
* of the keyfile must be performed by client code
*/
- public static function getFileKey( \OC_FilesystemView $view, $userId, $filePath ) {
-
- $filePath_f = ltrim( $filePath, '/' );
-
- $catfilePath = '/' . $userId . '/files_encryption/keyfiles/' . $filePath_f . '.key';
-
- if ( $view->file_exists( $catfilePath ) ) {
-
- return $view->file_get_contents( $catfilePath );
-
+ public static function getFileKey(\OC_FilesystemView $view, $userId, $filePath) {
+
+ // try reusing key file if part file
+ if (self::isPartialFilePath($filePath)) {
+
+ $result = self::getFileKey($view, $userId, self::fixPartialFilePath($filePath));
+
+ if ($result) {
+
+ return $result;
+
+ }
+
+ }
+
+ $util = new Util($view, \OCP\User::getUser());
+
+ list($owner, $filename) = $util->getUidAndFilename($filePath);
+ $filePath_f = ltrim($filename, '/');
+
+ // in case of system wide mount points the keys are stored directly in the data directory
+ if ($util->isSystemWideMountPoint($filename)) {
+ $keyfilePath = '/files_encryption/keyfiles/' . $filePath_f . '.key';
} else {
-
- return false;
-
+ $keyfilePath = '/' . $owner . '/files_encryption/keyfiles/' . $filePath_f . '.key';
+ }
+
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ if ($view->file_exists($keyfilePath)) {
+
+ $result = $view->file_get_contents($keyfilePath);
+
+ } else {
+
+ $result = false;
+
}
-
+
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ return $result;
+
}
-
+
/**
* @brief Delete a keyfile
*
- * @param OC_FilesystemView $view
+ * @param \OC_FilesystemView $view
* @param string $userId username
* @param string $path path of the file the key belongs to
* @return bool Outcome of unlink operation
* @note $path must be relative to data/user/files. e.g. mydoc.txt NOT
* /data/admin/files/mydoc.txt
*/
- public static function deleteFileKey( \OC_FilesystemView $view, $userId, $path ) {
-
- $trimmed = ltrim( $path, '/' );
- $keyPath = '/' . $userId . '/files_encryption/keyfiles/' . $trimmed . '.key';
-
- // Unlink doesn't tell us if file was deleted (not found returns
- // true), so we perform our own test
- if ( $view->file_exists( $keyPath ) ) {
-
- return $view->unlink( $keyPath );
-
+ public static function deleteFileKey(\OC_FilesystemView $view, $userId, $path) {
+
+ $trimmed = ltrim($path, '/');
+
+ $util = new Util($view, \OCP\User::getUser());
+
+ if($util->isSystemWideMountPoint($path)) {
+ $keyPath = '/files_encryption/keyfiles/' . $trimmed;
} else {
-
- \OC_Log::write( 'Encryption library', 'Could not delete keyfile; does not exist: "' . $keyPath, \OC_Log::ERROR );
-
- return false;
-
+ $keyPath = '/' . $userId . '/files_encryption/keyfiles/' . $trimmed;
}
-
+
+ $result = false;
+
+ if ($view->is_dir($keyPath)) {
+
+ $result = $view->unlink($keyPath);
+
+ } else {
+ if ($view->file_exists($keyPath . '.key')) {
+
+ $result = $view->unlink($keyPath . '.key');
+
+ }
+ }
+
+ if (!$result) {
+
+ \OCP\Util::writeLog('Encryption library',
+ 'Could not delete keyfile; does not exist: "' . $keyPath, \OCP\Util::ERROR);
+
+ }
+
+ return $result;
+
}
-
+
/**
* @brief store private key from the user
- * @param string key
+ * @param string $key
* @return bool
* @note Encryption of the private key must be performed by client code
* as no encryption takes place here
*/
- public static function setPrivateKey( $key ) {
-
+ public static function setPrivateKey($key) {
+
$user = \OCP\User::getUser();
-
- $view = new \OC_FilesystemView( '/' . $user . '/files_encryption' );
-
+
+ $view = new \OC_FilesystemView('/' . $user . '/files_encryption');
+
+ $proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
-
- if ( !$view->file_exists( '' ) )
- $view->mkdir( '' );
-
- return $view->file_put_contents( $user . '.private.key', $key );
+
+ if (!$view->file_exists(''))
+ $view->mkdir('');
+
+ $result = $view->file_put_contents($user . '.private.key', $key);
+
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ return $result;
}
-
+
/**
- * @brief store private keys from the user
+ * @brief store share key
*
- * @param string privatekey
- * @param string publickey
+ * @param \OC_FilesystemView $view
+ * @param string $path where the share key is stored
+ * @param $shareKey
* @return bool true/false
+ * @note The keyfile is not encrypted here. Client code must
+ * asymmetrically encrypt the keyfile before passing it to this method
*/
- public static function setUserKeys($privatekey, $publickey) {
-
- return ( self::setPrivateKey( $privatekey ) && self::setPublicKey( $publickey ) );
-
+ private static function setShareKey(\OC_FilesystemView $view, $path, $shareKey) {
+
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ $result = $view->file_put_contents($path, $shareKey);
+
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ if (is_int($result) && $result > 0) {
+ return true;
+ } else {
+ return false;
+ }
}
-
+
/**
- * @brief store public key of the user
- *
- * @param string key
- * @return bool true/false
+ * @brief store multiple share keys for a single file
+ * @param \OC_FilesystemView $view
+ * @param $path
+ * @param array $shareKeys
+ * @return bool
+ */
+ public static function setShareKeys(\OC_FilesystemView $view, $path, array $shareKeys) {
+
+ // $shareKeys must be an array with the following format:
+ // [userId] => [encrypted key]
+ // Here we need the currently logged in user, while userId can be a different user
+ $util = new Util($view, \OCP\User::getUser());
+
+ list($owner, $filename) = $util->getUidAndFilename($path);
+
+ // in case of system wide mount points the keys are stored directly in the data directory
+ if ($util->isSystemWideMountPoint($filename)) {
+ $basePath = '/files_encryption/share-keys';
+ } else {
+ $basePath = '/' . $owner . '/files_encryption/share-keys';
+ }
+
+ $shareKeyPath = self::keySetPreparation($view, $filename, $basePath, $owner);
+
+ $result = true;
+
+ foreach ($shareKeys as $userId => $shareKey) {
+
+ // try reusing key file if part file
+ if (self::isPartialFilePath($shareKeyPath)) {
+ $writePath = $basePath . '/' . self::fixPartialFilePath($shareKeyPath) . '.' . $userId . '.shareKey';
+ } else {
+ $writePath = $basePath . '/' . $shareKeyPath . '.' . $userId . '.shareKey';
+ }
+
+ if (!self::setShareKey($view, $writePath, $shareKey)) {
+
+ // If any of the keys are not set, flag false
+ $result = false;
+ }
+ }
+
+ // Returns false if any of the keys weren't set
+ return $result;
+ }
+
+ /**
+ * @brief retrieve shareKey for an encrypted file
+ * @param \OC_FilesystemView $view
+ * @param string $userId
+ * @param string $filePath
+ * @internal param \OCA\Encryption\file $string name
+ * @return string file key or false
+ * @note The sharekey returned is encrypted. Decryption
+ * of the keyfile must be performed by client code
+ */
+ public static function getShareKey(\OC_FilesystemView $view, $userId, $filePath) {
+
+ // try reusing key file if part file
+ if (self::isPartialFilePath($filePath)) {
+
+ $result = self::getShareKey($view, $userId, self::fixPartialFilePath($filePath));
+
+ if ($result) {
+
+ return $result;
+
+ }
+
+ }
+
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ //here we need the currently logged in user, while userId can be a different user
+ $util = new Util($view, \OCP\User::getUser());
+
+ list($owner, $filename) = $util->getUidAndFilename($filePath);
+
+ // in case of system wide mount points the keys are stored directly in the data directory
+ if ($util->isSystemWideMountPoint($filename)) {
+ $shareKeyPath = '/files_encryption/share-keys/' . $filename . '.' . $userId . '.shareKey';
+ } else {
+ $shareKeyPath = '/' . $owner . '/files_encryption/share-keys/' . $filename . '.' . $userId . '.shareKey';
+ }
+
+ if ($view->file_exists($shareKeyPath)) {
+
+ $result = $view->file_get_contents($shareKeyPath);
+
+ } else {
+
+ $result = false;
+
+ }
+
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ return $result;
+
+ }
+
+ /**
+ * @brief delete all share keys of a given file
+ * @param \OC_FilesystemView $view
+ * @param string $userId owner of the file
+ * @param string $filePath path to the file, relative to the owners file dir
+ */
+ public static function delAllShareKeys(\OC_FilesystemView $view, $userId, $filePath) {
+
+ $util = new util($view, $userId);
+
+ if ($util->isSystemWideMountPoint($filePath)) {
+ $baseDir = '/files_encryption/share-keys/';
+ } else {
+ $baseDir = $userId . '/files_encryption/share-keys/';
+ }
+
+
+ if ($view->is_dir($userId . '/files/' . $filePath)) {
+ $view->unlink($baseDir . $filePath);
+ } else {
+ $localKeyPath = $view->getLocalFile($baseDir . $filePath);
+ $escapedPath = Helper::escapeGlobPattern($localKeyPath);
+ $matches = glob($escapedPath . '*.shareKey');
+ foreach ($matches as $ma) {
+ $result = unlink($ma);
+ if (!$result) {
+ \OCP\Util::writeLog('Encryption library',
+ 'Keyfile or shareKey could not be deleted for file "' . $filePath . '"', \OCP\Util::ERROR);
+ }
+ }
+ }
+ }
+
+ /**
+ * @brief Delete a single user's shareKey for a single file
*/
- public static function setPublicKey( $key ) {
-
- $view = new \OC_FilesystemView( '/public-keys' );
-
+ public static function delShareKey(\OC_FilesystemView $view, $userIds, $filePath) {
+
+ $proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
-
- if ( !$view->file_exists( '' ) )
- $view->mkdir( '' );
-
- return $view->file_put_contents( \OCP\User::getUser() . '.public.key', $key );
-
+ //here we need the currently logged in user, while userId can be a different user
+ $util = new Util($view, \OCP\User::getUser());
+
+ list($owner, $filename) = $util->getUidAndFilename($filePath);
+
+ if ($util->isSystemWideMountPoint($filename)) {
+ $shareKeyPath = \OC\Files\Filesystem::normalizePath('/files_encryption/share-keys/' . $filename);
+ } else {
+ $shareKeyPath = \OC\Files\Filesystem::normalizePath('/' . $owner . '/files_encryption/share-keys/' . $filename);
+ }
+
+ if ($view->is_dir($shareKeyPath)) {
+
+ $localPath = \OC\Files\Filesystem::normalizePath($view->getLocalFolder($shareKeyPath));
+ self::recursiveDelShareKeys($localPath, $userIds);
+
+ } else {
+
+ foreach ($userIds as $userId) {
+
+ if (!$view->unlink($shareKeyPath . '.' . $userId . '.shareKey')) {
+ \OCP\Util::writeLog('Encryption library',
+ 'Could not delete shareKey; does not exist: "' . $shareKeyPath . '.' . $userId
+ . '.shareKey"', \OCP\Util::ERROR);
+ }
+
+ }
+ }
+
+ \OC_FileProxy::$enabled = $proxyStatus;
}
-
+
/**
- * @brief store file encryption key
+ * @brief recursively delete share keys from given users
*
- * @param string $path relative path of the file, including filename
- * @param string $key
- * @param null $view
- * @param string $dbClassName
- * @return bool true/false
- * @note The keyfile is not encrypted here. Client code must
- * asymmetrically encrypt the keyfile before passing it to this method
+ * @param string $dir directory
+ * @param array $userIds user ids for which the share keys should be deleted
*/
- public static function setShareKey( \OC_FilesystemView $view, $path, $userId, $shareKey ) {
-
- $basePath = '/' . $userId . '/files_encryption/share-keys';
-
- $shareKeyPath = self::keySetPreparation( $view, $path, $basePath, $userId );
-
- return $view->file_put_contents( $basePath . '/' . $shareKeyPath . '.shareKey', $shareKey );
-
+ private static function recursiveDelShareKeys($dir, $userIds) {
+ foreach ($userIds as $userId) {
+ $extension = '.' . $userId . '.shareKey';
+ $escapedDir = Helper::escapeGlobPattern($dir);
+ $escapedExtension = Helper::escapeGlobPattern($extension);
+ $matches = glob($escapedDir . '/*' . $escapedExtension);
+ }
+ /** @var $matches array */
+ foreach ($matches as $ma) {
+ if (!unlink($ma)) {
+ \OCP\Util::writeLog('Encryption library',
+ 'Could not delete shareKey; does not exist: "' . $ma . '"', \OCP\Util::ERROR);
+ }
+ }
+ $subdirs = $directories = glob($escapedDir . '/*', GLOB_ONLYDIR);
+ foreach ($subdirs as $subdir) {
+ self::recursiveDelShareKeys($subdir, $userIds);
+ }
}
-
+
/**
* @brief Make preparations to vars and filesystem for saving a keyfile
*/
- public static function keySetPreparation( \OC_FilesystemView $view, $path, $basePath, $userId ) {
-
- $targetPath = ltrim( $path, '/' );
-
- $path_parts = pathinfo( $targetPath );
-
+ public static function keySetPreparation(\OC_FilesystemView $view, $path, $basePath, $userId) {
+
+ $targetPath = ltrim($path, '/');
+
+ $path_parts = pathinfo($targetPath);
+
// If the file resides within a subdirectory, create it
- if (
- isset( $path_parts['dirname'] )
- && ! $view->file_exists( $basePath . '/' . $path_parts['dirname'] )
+ if (
+ isset($path_parts['dirname'])
+ && !$view->file_exists($basePath . '/' . $path_parts['dirname'])
) {
-
- $view->mkdir( $basePath . '/' . $path_parts['dirname'] );
-
+ $sub_dirs = explode(DIRECTORY_SEPARATOR, $basePath . '/' . $path_parts['dirname']);
+ $dir = '';
+ foreach ($sub_dirs as $sub_dir) {
+ $dir .= '/' . $sub_dir;
+ if (!$view->is_dir($dir)) {
+ $view->mkdir($dir);
+ }
+ }
}
-
+
return $targetPath;
-
- }
- /**
- * @brief Fetch the legacy encryption key from user files
- * @param string $login used to locate the legacy key
- * @param string $passphrase used to decrypt the legacy key
- * @return true / false
- *
- * if the key is left out, the default handler will be used
- */
- public function getLegacyKey() {
-
- $user = \OCP\User::getUser();
- $view = new \OC_FilesystemView( '/' . $user );
- return $view->file_get_contents( 'encryption.key' );
-
}
-
}
\ No newline at end of file
diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php
index 55cddf2bec81761ca0b6ccbcd27d7fbce7237219..735eba911a952b4adeaed4daf10b84e74b9cd17c 100644
--- a/apps/files_encryption/lib/proxy.php
+++ b/apps/files_encryption/lib/proxy.php
@@ -1,41 +1,45 @@
.
-*
-*/
+ * ownCloud
+ *
+ * @author Sam Tuke, Robin Appelman
+ * @copyright 2012 Sam Tuke samtuke@owncloud.com, Robin Appelman
+ * icewind1991@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library 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 along with this library. If not, see .
+ *
+ */
/**
-* @brief Encryption proxy which handles filesystem operations before and after
-* execution and encrypts, and handles keyfiles accordingly. Used for
-* webui.
-*/
+ * @brief Encryption proxy which handles filesystem operations before and after
+ * execution and encrypts, and handles keyfiles accordingly. Used for
+ * webui.
+ */
namespace OCA\Encryption;
+/**
+ * Class Proxy
+ * @package OCA\Encryption
+ */
class Proxy extends \OC_FileProxy {
private static $blackList = null; //mimetypes blacklisted from encryption
-
+
private static $enableEncryption = null;
-
+
/**
* Check if a file requires encryption
* @param string $path
@@ -43,347 +47,385 @@ class Proxy extends \OC_FileProxy {
*
* Tests if server side encryption is enabled, and file is allowed by blacklists
*/
- private static function shouldEncrypt( $path ) {
-
- if ( is_null( self::$enableEncryption ) ) {
-
- if (
- \OCP\Config::getAppValue( 'files_encryption', 'enable_encryption', 'true' ) == 'true'
- && Crypt::mode() == 'server'
+ private static function shouldEncrypt($path) {
+
+ if (is_null(self::$enableEncryption)) {
+
+ if (
+ \OCP\Config::getAppValue('files_encryption', 'enable_encryption', 'true') === 'true'
+ && Crypt::mode() === 'server'
) {
-
+
self::$enableEncryption = true;
-
+
} else {
-
+
self::$enableEncryption = false;
-
+
}
-
+
}
-
- if ( !self::$enableEncryption ) {
-
+
+ if (!self::$enableEncryption) {
+
return false;
-
+
}
-
- if ( is_null(self::$blackList ) ) {
-
- self::$blackList = explode(',', \OCP\Config::getAppValue( 'files_encryption', 'type_blacklist', 'jpg,png,jpeg,avi,mpg,mpeg,mkv,mp3,oga,ogv,ogg' ) );
-
+
+ if (is_null(self::$blackList)) {
+
+ self::$blackList = explode(',', \OCP\Config::getAppValue('files_encryption', 'type_blacklist', ''));
+
}
-
- if ( Crypt::isCatfile( $path ) ) {
-
+
+ if (Crypt::isCatfileContent($path)) {
+
return true;
-
+
}
-
- $extension = substr( $path, strrpos( $path, '.' ) +1 );
-
- if ( array_search( $extension, self::$blackList ) === false ) {
-
+
+ $extension = substr($path, strrpos($path, '.') + 1);
+
+ if (array_search($extension, self::$blackList) === false) {
+
return true;
-
+
}
-
+
return false;
}
-
- public function preFile_put_contents( $path, &$data ) {
-
- if ( self::shouldEncrypt( $path ) ) {
-
- if ( !is_resource( $data ) ) { //stream put contents should have been converted to fopen
-
- $userId = \OCP\USER::getUser();
-
- $rootView = new \OC_FilesystemView( '/' );
-
- // Set the filesize for userland, before encrypting
- $size = strlen( $data );
-
- // Disable encryption proxy to prevent recursive calls
- \OC_FileProxy::$enabled = false;
-
- // TODO: Check if file is shared, if so, use multiKeyEncrypt
-
- // Encrypt plain data and fetch key
- $encrypted = Crypt::keyEncryptKeyfile( $data, Keymanager::getPublicKey( $rootView, $userId ) );
-
- // Replace plain content with encrypted content by reference
- $data = $encrypted['data'];
-
- $filePath = explode( '/', $path );
-
- $filePath = array_slice( $filePath, 3 );
-
- $filePath = '/' . implode( '/', $filePath );
-
- // TODO: make keyfile dir dynamic from app config
-
- $view = new \OC_FilesystemView( '/' );
-
- // Save keyfile for newly encrypted file in parallel directory tree
- Keymanager::setFileKey( $view, $filePath, $userId, $encrypted['key'] );
-
- // Update the file cache with file info
- \OC\Files\Filesystem::putFileInfo( $path, array( 'encrypted'=>true, 'size' => $size ), '' );
-
- // Re-enable proxy - our work is done
- \OC_FileProxy::$enabled = true;
-
+
+ /**
+ * @param $path
+ * @param $data
+ * @return bool
+ */
+ public function preFile_put_contents($path, &$data) {
+
+ if (self::shouldEncrypt($path)) {
+
+ if (!is_resource($data)) {
+
+ // get root view
+ $view = new \OC_FilesystemView('/');
+
+ // get relative path
+ $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
+
+ if (!isset($relativePath)) {
+ return true;
+ }
+
+ $handle = fopen('crypt://' . $relativePath . '.etmp', 'w');
+ if (is_resource($handle)) {
+
+ // write data to stream
+ fwrite($handle, $data);
+
+ // close stream
+ fclose($handle);
+
+ // disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ // get encrypted content
+ $data = $view->file_get_contents($path . '.etmp');
+
+ // remove our temp file
+ $view->unlink($path . '.etmp');
+
+ // re-enable proxy - our work is done
+ \OC_FileProxy::$enabled = $proxyStatus;
+ }
}
}
-
+
+ return true;
+
}
-
+
/**
* @param string $path Path of file from which has been read
* @param string $data Data that has been read from file
*/
- public function postFile_get_contents( $path, $data ) {
-
- // TODO: Use dependency injection to add required args for view and user etc. to this method
+ public function postFile_get_contents($path, $data) {
+
+ $plainData = null;
+ $view = new \OC_FilesystemView('/');
+
+ // get relative path
+ $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
+
+ // init session
+ $session = new \OCA\Encryption\Session($view);
- // Disable encryption proxy to prevent recursive calls
- \OC_FileProxy::$enabled = false;
-
// If data is a catfile
- if (
- Crypt::mode() == 'server'
- && Crypt::isCatfile( $data )
+ if (
+ Crypt::mode() === 'server'
+ && Crypt::isCatfileContent($data)
) {
-
- $split = explode( '/', $path );
-
- $filePath = array_slice( $split, 3 );
-
- $filePath = '/' . implode( '/', $filePath );
-
- //$cached = \OC\Files\Filesystem::getFileInfo( $path, '' );
-
- $view = new \OC_FilesystemView( '' );
-
- $userId = \OCP\USER::getUser();
-
- // TODO: Check if file is shared, if so, use multiKeyDecrypt
-
- $encryptedKeyfile = Keymanager::getFileKey( $view, $userId, $filePath );
-
- $session = new Session();
-
- $decrypted = Crypt::keyDecryptKeyfile( $data, $encryptedKeyfile, $session->getPrivateKey( $split[1] ) );
-
+
+ $handle = fopen('crypt://' . $relativePath, 'r');
+
+ if (is_resource($handle)) {
+ while (($plainDataChunk = fgets($handle, 8192)) !== false) {
+ $plainData .= $plainDataChunk;
+ }
+ }
+
} elseif (
- Crypt::mode() == 'server'
- && isset( $_SESSION['legacyenckey'] )
- && Crypt::isEncryptedMeta( $path )
+ Crypt::mode() == 'server'
+ && \OC::$session->exists('legacyenckey')
+ && Crypt::isEncryptedMeta($path)
) {
-
- $decrypted = Crypt::legacyDecrypt( $data, $_SESSION['legacyenckey'] );
-
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ $plainData = Crypt::legacyBlockDecrypt($data, $session->getLegacyKey());
+
+ \OC_FileProxy::$enabled = $proxyStatus;
}
-
- \OC_FileProxy::$enabled = true;
-
- if ( ! isset( $decrypted ) ) {
-
- $decrypted = $data;
-
+
+ if (!isset($plainData)) {
+
+ $plainData = $data;
+
}
-
- return $decrypted;
-
+
+ return $plainData;
+
}
-
+
/**
* @brief When a file is deleted, remove its keyfile also
*/
- public function preUnlink( $path ) {
-
+ public function preUnlink($path) {
+
+ // let the trashbin handle this
+ if (\OCP\App::isEnabled('files_trashbin')) {
+ return true;
+ }
+
// Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
-
- $view = new \OC_FilesystemView( '/' );
-
+
+ $view = new \OC_FilesystemView('/');
+
$userId = \OCP\USER::getUser();
-
- // Format path to be relative to user files dir
- $trimmed = ltrim( $path, '/' );
- $split = explode( '/', $trimmed );
- $sliced = array_slice( $split, 2 );
- $relPath = implode( '/', $sliced );
-
- if ( $view->is_dir( $path ) ) {
-
- // Dirs must be handled separately as deleteFileKey
- // doesn't handle them
- $view->unlink( $userId . '/' . 'files_encryption' . '/' . 'keyfiles' . '/'. $relPath );
-
- } else {
-
- // Delete keyfile so it isn't orphaned
- $result = Keymanager::deleteFileKey( $view, $userId, $relPath );
-
- \OC_FileProxy::$enabled = true;
-
- return $result;
-
+
+ $util = new Util($view, $userId);
+
+ // get relative path
+ $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
+
+ list($owner, $ownerPath) = $util->getUidAndFilename($relativePath);
+
+ // Delete keyfile & shareKey so it isn't orphaned
+ if (!Keymanager::deleteFileKey($view, $owner, $ownerPath)) {
+ \OCP\Util::writeLog('Encryption library',
+ 'Keyfile or shareKey could not be deleted for file "' . $ownerPath . '"', \OCP\Util::ERROR);
}
-
+
+ Keymanager::delAllShareKeys($view, $owner, $ownerPath);
+
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ // If we don't return true then file delete will fail; better
+ // to leave orphaned keyfiles than to disallow file deletion
+ return true;
+
}
/**
- * @brief When a file is renamed, rename its keyfile also
- * @return bool Result of rename()
- * @note This is pre rather than post because using post didn't work
+ * @param $path
+ * @return bool
*/
- public function preRename( $oldPath, $newPath ) {
-
- // Disable encryption proxy to prevent recursive calls
- \OC_FileProxy::$enabled = false;
-
- $view = new \OC_FilesystemView( '/' );
-
- $userId = \OCP\USER::getUser();
-
- // Format paths to be relative to user files dir
- $oldTrimmed = ltrim( $oldPath, '/' );
- $oldSplit = explode( '/', $oldTrimmed );
- $oldSliced = array_slice( $oldSplit, 2 );
- $oldRelPath = implode( '/', $oldSliced );
- $oldKeyfilePath = $userId . '/' . 'files_encryption' . '/' . 'keyfiles' . '/' . $oldRelPath . '.key';
-
- $newTrimmed = ltrim( $newPath, '/' );
- $newSplit = explode( '/', $newTrimmed );
- $newSliced = array_slice( $newSplit, 2 );
- $newRelPath = implode( '/', $newSliced );
- $newKeyfilePath = $userId . '/' . 'files_encryption' . '/' . 'keyfiles' . '/' . $newRelPath . '.key';
-
- // Rename keyfile so it isn't orphaned
- $result = $view->rename( $oldKeyfilePath, $newKeyfilePath );
-
- \OC_FileProxy::$enabled = true;
-
- return $result;
-
+ public function postTouch($path) {
+ $this->handleFile($path);
+
+ return true;
}
-
- public function postFopen( $path, &$result ){
-
- if ( !$result ) {
-
+
+ /**
+ * @param $path
+ * @param $result
+ * @return resource
+ */
+ public function postFopen($path, &$result) {
+
+ $path = \OC\Files\Filesystem::normalizePath($path);
+
+ if (!$result) {
+
return $result;
-
+
}
-
- // Reformat path for use with OC_FSV
- $path_split = explode( '/', $path );
- $path_f = implode( array_slice( $path_split, 3 ) );
-
+
+ // split the path parts
+ $pathParts = explode('/', $path);
+
+ // get relative path
+ $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
+
+ // FIXME: handling for /userId/cache used by webdav for chunking. The cache chunks are NOT encrypted
+ if (isset($pathParts[2]) && $pathParts[2] === 'cache') {
+ return $result;
+ }
+
// Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
-
- $meta = stream_get_meta_data( $result );
-
- $view = new \OC_FilesystemView( '' );
-
- $util = new Util( $view, \OCP\USER::getUser());
-
+
+ $meta = stream_get_meta_data($result);
+
+ $view = new \OC_FilesystemView('');
+
+ $util = new Util($view, \OCP\USER::getUser());
+
// If file is already encrypted, decrypt using crypto protocol
- if (
- Crypt::mode() == 'server'
- && $util->isEncryptedPath( $path )
+ if (
+ Crypt::mode() === 'server'
+ && $util->isEncryptedPath($path)
) {
-
+
// Close the original encrypted file
- fclose( $result );
-
+ fclose($result);
+
// Open the file using the crypto stream wrapper
// protocol and let it do the decryption work instead
- $result = fopen( 'crypt://' . $path_f, $meta['mode'] );
-
-
- } elseif (
- self::shouldEncrypt( $path )
- and $meta ['mode'] != 'r'
- and $meta['mode'] != 'rb'
+ $result = fopen('crypt://' . $relativePath, $meta['mode']);
+
+ } elseif (
+ self::shouldEncrypt($path)
+ and $meta ['mode'] !== 'r'
+ and $meta['mode'] !== 'rb'
) {
- // If the file is not yet encrypted, but should be
- // encrypted when it's saved (it's not read only)
-
- // NOTE: this is the case for new files saved via WebDAV
-
- if (
- $view->file_exists( $path )
- and $view->filesize( $path ) > 0
- ) {
- $x = $view->file_get_contents( $path );
-
- $tmp = tmpfile();
-
-// // Make a temporary copy of the original file
-// \OCP\Files::streamCopy( $result, $tmp );
-//
-// // Close the original stream, we'll return another one
-// fclose( $result );
-//
-// $view->file_put_contents( $path_f, $tmp );
-//
-// fclose( $tmp );
-
- }
-
- $result = fopen( 'crypt://'.$path_f, $meta['mode'] );
-
+ $result = fopen('crypt://' . $relativePath, $meta['mode']);
}
-
+
// Re-enable the proxy
- \OC_FileProxy::$enabled = true;
-
+ \OC_FileProxy::$enabled = $proxyStatus;
+
return $result;
-
- }
- public function postGetMimeType( $path, $mime ) {
-
- if ( Crypt::isCatfile( $path ) ) {
-
- $mime = \OCP\Files::getMimeType( 'crypt://' . $path, 'w' );
-
- }
-
- return $mime;
-
}
- public function postStat( $path, $data ) {
-
- if ( Crypt::isCatfile( $path ) ) {
-
- $cached = \OC\Files\Filesystem::getFileInfo( $path, '' );
-
- $data['size'] = $cached['size'];
-
+ /**
+ * @param $path
+ * @param $data
+ * @return array
+ */
+ public function postGetFileInfo($path, $data) {
+
+ // if path is a folder do nothing
+ if (is_array($data) && array_key_exists('size', $data)) {
+
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ // get file size
+ $data['size'] = self::postFileSize($path, $data['size']);
+
+ // Re-enable the proxy
+ \OC_FileProxy::$enabled = $proxyStatus;
}
-
+
return $data;
}
- public function postFileSize( $path, $size ) {
-
- if ( Crypt::isCatfile( $path ) ) {
-
- $cached = \OC\Files\Filesystem::getFileInfo( $path, '' );
-
- return $cached['size'];
-
- } else {
-
+ /**
+ * @param $path
+ * @param $size
+ * @return bool
+ */
+ public function postFileSize($path, $size) {
+
+ $view = new \OC_FilesystemView('/');
+
+ // if path is a folder do nothing
+ if ($view->is_dir($path)) {
return $size;
-
}
+
+ // get relative path
+ $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
+
+ // if path is empty we cannot resolve anything
+ if (empty($relativePath)) {
+ return $size;
+ }
+
+ $fileInfo = false;
+ // get file info from database/cache if not .part file
+ if (!Keymanager::isPartialFilePath($path)) {
+ $fileInfo = $view->getFileInfo($path);
+ }
+
+ // if file is encrypted return real file size
+ if (is_array($fileInfo) && $fileInfo['encrypted'] === true) {
+ $size = $fileInfo['unencrypted_size'];
+ } else {
+ // self healing if file was removed from file cache
+ if (!is_array($fileInfo)) {
+ $fileInfo = array();
+ }
+
+ $userId = \OCP\User::getUser();
+ $util = new Util($view, $userId);
+ $fixSize = $util->getFileSize($path);
+ if ($fixSize > 0) {
+ $size = $fixSize;
+
+ $fileInfo['encrypted'] = true;
+ $fileInfo['unencrypted_size'] = $size;
+
+ // put file info if not .part file
+ if (!Keymanager::isPartialFilePath($relativePath)) {
+ $view->putFileInfo($path, $fileInfo);
+ }
+ }
+
+ }
+ return $size;
+ }
+
+ /**
+ * @param $path
+ */
+ public function handleFile($path) {
+
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ $view = new \OC_FilesystemView('/');
+ $session = new \OCA\Encryption\Session($view);
+ $userId = \OCP\User::getUser();
+ $util = new Util($view, $userId);
+
+ // split the path parts
+ $pathParts = explode('/', $path);
+
+ // get relative path
+ $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
+
+ // only if file is on 'files' folder fix file size and sharing
+ if (isset($pathParts[2]) && $pathParts[2] === 'files' && $util->fixFileSize($path)) {
+
+ // get sharing app state
+ $sharingEnabled = \OCP\Share::isEnabled();
+
+ // get users
+ $usersSharing = $util->getSharingUsersArray($sharingEnabled, $relativePath);
+
+ // update sharing-keys
+ $util->setSharedFileKeyfiles($session, $usersSharing, $relativePath);
+ }
+
+ \OC_FileProxy::$enabled = $proxyStatus;
}
}
diff --git a/apps/files_encryption/lib/session.php b/apps/files_encryption/lib/session.php
index 769a40b359f4f7249c9fcc44353de603f66cdd63..1911386cd12f06832d2406071a4092942191c7d7 100644
--- a/apps/files_encryption/lib/session.php
+++ b/apps/files_encryption/lib/session.php
@@ -28,76 +28,165 @@ namespace OCA\Encryption;
class Session {
+ private $view;
+
+ /**
+ * @brief if session is started, check if ownCloud key pair is set up, if not create it
+ * @param \OC_FilesystemView $view
+ *
+ * @note The ownCloud key pair is used to allow public link sharing even if encryption is enabled
+ */
+ public function __construct($view) {
+
+ $this->view = $view;
+
+ if (!$this->view->is_dir('owncloud_private_key')) {
+
+ $this->view->mkdir('owncloud_private_key');
+
+ }
+
+ $publicShareKeyId = \OC_Appconfig::getValue('files_encryption', 'publicShareKeyId');
+
+ if ($publicShareKeyId === null) {
+ $publicShareKeyId = 'pubShare_' . substr(md5(time()), 0, 8);
+ \OC_Appconfig::setValue('files_encryption', 'publicShareKeyId', $publicShareKeyId);
+ }
+
+ if (
+ !$this->view->file_exists("/public-keys/" . $publicShareKeyId . ".public.key")
+ || !$this->view->file_exists("/owncloud_private_key/" . $publicShareKeyId . ".private.key")
+ ) {
+
+ $keypair = Crypt::createKeypair();
+
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ // Save public key
+
+ if (!$view->is_dir('/public-keys')) {
+ $view->mkdir('/public-keys');
+ }
+
+ $this->view->file_put_contents('/public-keys/' . $publicShareKeyId . '.public.key', $keypair['publicKey']);
+
+ // Encrypt private key empty passphrase
+ $encryptedPrivateKey = Crypt::symmetricEncryptFileContent($keypair['privateKey'], '');
+
+ // Save private key
+ $this->view->file_put_contents(
+ '/owncloud_private_key/' . $publicShareKeyId . '.private.key', $encryptedPrivateKey);
+
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ }
+
+ if (\OCA\Encryption\Helper::isPublicAccess()) {
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ $encryptedKey = $this->view->file_get_contents(
+ '/owncloud_private_key/' . $publicShareKeyId . '.private.key');
+ $privateKey = Crypt::decryptPrivateKey($encryptedKey, '');
+ $this->setPublicSharePrivateKey($privateKey);
+
+ \OC_FileProxy::$enabled = $proxyStatus;
+ }
+ }
+
/**
* @brief Sets user private key to session
+ * @param string $privateKey
* @return bool
*
+ * @note this should only be set on login
*/
- public function setPrivateKey( $privateKey ) {
-
- $_SESSION['privateKey'] = $privateKey;
-
+ public function setPrivateKey($privateKey) {
+
+ \OC::$session->set('privateKey', $privateKey);
+
return true;
-
+
}
-
+
/**
- * @brief Gets user private key from session
+ * @brief Gets user or public share private key from session
* @returns string $privateKey The user's plaintext private key
*
*/
public function getPrivateKey() {
-
- if (
- isset( $_SESSION['privateKey'] )
- && !empty( $_SESSION['privateKey'] )
- ) {
-
- return $_SESSION['privateKey'];
-
+ // return the public share private key if this is a public access
+ if (\OCA\Encryption\Helper::isPublicAccess()) {
+ return $this->getPublicSharePrivateKey();
} else {
-
- return false;
-
+ if (!is_null(\OC::$session->get('privateKey'))) {
+ return \OC::$session->get('privateKey');
+ } else {
+ return false;
+ }
}
-
}
-
+
/**
- * @brief Sets user legacy key to session
+ * @brief Sets public user private key to session
+ * @param string $privateKey
* @return bool
+ */
+ public function setPublicSharePrivateKey($privateKey) {
+
+ \OC::$session->set('publicSharePrivateKey', $privateKey);
+
+ return true;
+
+ }
+
+ /**
+ * @brief Gets public share private key from session
+ * @returns string $privateKey
*
*/
- public function setLegacyKey( $legacyKey ) {
-
- if ( $_SESSION['legacyKey'] = $legacyKey ) {
-
- return true;
-
+ public function getPublicSharePrivateKey() {
+
+ if (!is_null(\OC::$session->get('publicSharePrivateKey'))) {
+ return \OC::$session->get('publicSharePrivateKey');
+ } else {
+ return false;
}
-
}
-
+
+
+ /**
+ * @brief Sets user legacy key to session
+ * @param $legacyKey
+ * @return bool
+ */
+ public function setLegacyKey($legacyKey) {
+
+ \OC::$session->set('legacyKey', $legacyKey);
+
+ return true;
+ }
+
/**
* @brief Gets user legacy key from session
* @returns string $legacyKey The user's plaintext legacy key
*
*/
public function getLegacyKey() {
-
- if (
- isset( $_SESSION['legacyKey'] )
- && !empty( $_SESSION['legacyKey'] )
- ) {
-
- return $_SESSION['legacyKey'];
-
+
+ if (!is_null(\OC::$session->get('legacyKey'))) {
+
+ return \OC::$session->get('legacyKey');
+
} else {
-
+
return false;
-
+
}
-
+
}
-}
\ No newline at end of file
+}
diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php
index 65d7d57a05a740bd164e7476b1c3910afcd7f49f..3c1eb2c5f5e5dcb4273c40040107d07a590fb18b 100644
--- a/apps/files_encryption/lib/stream.php
+++ b/apps/files_encryption/lib/stream.php
@@ -3,7 +3,7 @@
* ownCloud
*
* @author Robin Appelman
- * @copyright 2012 Sam Tuke , 2011 Robin Appelman
+ * @copyright 2012 Sam Tuke , 2011 Robin Appelman
*
*
* This library is free software; you can redistribute it and/or
@@ -32,254 +32,238 @@ namespace OCA\Encryption;
/**
* @brief Provides 'crypt://' stream wrapper protocol.
- * @note We use a stream wrapper because it is the most secure way to handle
+ * @note We use a stream wrapper because it is the most secure way to handle
* decrypted content transfers. There is no safe way to decrypt the entire file
* somewhere on the server, so we have to encrypt and decrypt blocks on the fly.
* @note Paths used with this protocol MUST BE RELATIVE. Use URLs like:
- * crypt://filename, or crypt://subdirectory/filename, NOT
- * crypt:///home/user/owncloud/data. Otherwise keyfiles will be put in
- * [owncloud]/data/user/files_encryption/keyfiles/home/user/owncloud/data and
+ * crypt://filename, or crypt://subdirectory/filename, NOT
+ * crypt:///home/user/owncloud/data. Otherwise keyfiles will be put in
+ * [owncloud]/data/user/files_encryption/keyfiles/home/user/owncloud/data and
* will not be accessible to other methods.
- * @note Data read and written must always be 8192 bytes long, as this is the
- * buffer size used internally by PHP. The encryption process makes the input
- * data longer, and input is chunked into smaller pieces in order to result in
+ * @note Data read and written must always be 8192 bytes long, as this is the
+ * buffer size used internally by PHP. The encryption process makes the input
+ * data longer, and input is chunked into smaller pieces in order to result in
* a 8192 encrypted block size.
+ * @note When files are deleted via webdav, or when they are updated and the
+ * previous version deleted, this is handled by OC\Files\View, and thus the
+ * encryption proxies are used and keyfiles deleted.
*/
class Stream {
+ private $plainKey;
+ private $encKeyfiles;
- public static $sourceStreams = array();
-
- // TODO: make all below properties private again once unit testing is
- // configured correctly
- public $rawPath; // The raw path received by stream_open
- public $path_f; // The raw path formatted to include username and data dir
+ private $rawPath; // The raw path relative to the data dir
+ private $relPath; // rel path to users file dir
private $userId;
private $handle; // Resource returned by fopen
- private $path;
- private $readBuffer; // For streams that dont support seeking
private $meta = array(); // Header / meta for source stream
- private $count;
private $writeCache;
- public $size;
+ private $size;
+ private $unencryptedSize;
private $publicKey;
- private $keyfile;
private $encKeyfile;
- private static $view; // a fsview object set to user dir
+ /**
+ * @var \OC\Files\View
+ */
private $rootView; // a fsview object set to '/'
+ /**
+ * @var \OCA\Encryption\Session
+ */
+ private $session;
+ private $privateKey;
- public function stream_open( $path, $mode, $options, &$opened_path ) {
-
- // Get access to filesystem via filesystemview object
- if ( !self::$view ) {
-
- self::$view = new \OC_FilesystemView( $this->userId . '/' );
+ /**
+ * @param $path
+ * @param $mode
+ * @param $options
+ * @param $opened_path
+ * @return bool
+ */
+ public function stream_open($path, $mode, $options, &$opened_path) {
+ if (!isset($this->rootView)) {
+ $this->rootView = new \OC_FilesystemView('/');
}
-
- // Set rootview object if necessary
- if ( ! $this->rootView ) {
- $this->rootView = new \OC_FilesystemView( $this->userId . '/' );
+ $this->session = new \OCA\Encryption\Session($this->rootView);
- }
-
- $this->userId = \OCP\User::getUser();
-
- // Get the bare file path
- $path = str_replace( 'crypt://', '', $path );
-
- $this->rawPath = $path;
-
- $this->path_f = $this->userId . '/files/' . $path;
-
- if (
- dirname( $path ) == 'streams'
- and isset( self::$sourceStreams[basename( $path )] )
- ) {
-
- // Is this just for unit testing purposes?
+ $this->privateKey = $this->session->getPrivateKey($this->userId);
- $this->handle = self::$sourceStreams[basename( $path )]['stream'];
+ $util = new Util($this->rootView, \OCP\USER::getUser());
- $this->path = self::$sourceStreams[basename( $path )]['path'];
+ $this->userId = $util->getUserId();
- $this->size = self::$sourceStreams[basename( $path )]['size'];
+ // Strip identifier text from path, this gives us the path relative to data//files
+ $this->relPath = \OC\Files\Filesystem::normalizePath(str_replace('crypt://', '', $path));
- } else {
+ // rawPath is relative to the data directory
+ $this->rawPath = $util->getUserFilesDir() . $this->relPath;
- if (
- $mode == 'w'
- or $mode == 'w+'
- or $mode == 'wb'
- or $mode == 'wb+'
- ) {
+ // Disable fileproxies so we can get the file size and open the source file without recursive encryption
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
- $this->size = 0;
+ if (
+ $mode === 'w'
+ or $mode === 'w+'
+ or $mode === 'wb'
+ or $mode === 'wb+'
+ ) {
- } else {
-
-
-
- $this->size = self::$view->filesize( $this->path_f, $mode );
-
- //$this->size = filesize( $path );
-
- }
+ // We're writing a new file so start write counter with 0 bytes
+ $this->size = 0;
+ $this->unencryptedSize = 0;
- // Disable fileproxies so we can open the source file without recursive encryption
- \OC_FileProxy::$enabled = false;
+ } else {
+
+ if($this->privateKey === false) {
+ // if private key is not valid redirect user to a error page
+ \OCA\Encryption\Helper::redirectToErrorPage();
+ }
- //$this->handle = fopen( $path, $mode );
-
- $this->handle = self::$view->fopen( $this->path_f, $mode );
-
- \OC_FileProxy::$enabled = true;
+ $this->size = $this->rootView->filesize($this->rawPath, $mode);
+ }
- if ( !is_resource( $this->handle ) ) {
+ $this->handle = $this->rootView->fopen($this->rawPath, $mode);
- \OCP\Util::writeLog( 'files_encryption', 'failed to open '.$path, \OCP\Util::ERROR );
+ \OC_FileProxy::$enabled = $proxyStatus;
- }
+ if (!is_resource($this->handle)) {
- }
+ \OCP\Util::writeLog('Encryption library', 'failed to open file "' . $this->rawPath . '"', \OCP\Util::ERROR);
- if ( is_resource( $this->handle ) ) {
+ } else {
- $this->meta = stream_get_meta_data( $this->handle );
+ $this->meta = stream_get_meta_data($this->handle);
}
- return is_resource( $this->handle );
+
+ return is_resource($this->handle);
}
-
- public function stream_seek( $offset, $whence = SEEK_SET ) {
-
+
+ /**
+ * @param $offset
+ * @param int $whence
+ */
+ public function stream_seek($offset, $whence = SEEK_SET) {
+
$this->flush();
-
- fseek( $this->handle, $offset, $whence );
-
- }
-
- public function stream_tell() {
- return ftell($this->handle);
+
+ fseek($this->handle, $offset, $whence);
+
}
-
- public function stream_read( $count ) {
-
+
+ /**
+ * @param $count
+ * @return bool|string
+ * @throws \Exception
+ */
+ public function stream_read($count) {
+
$this->writeCache = '';
- if ( $count != 8192 ) {
-
+ if ($count !== 8192) {
+
// $count will always be 8192 https://bugs.php.net/bug.php?id=21641
// This makes this function a lot simpler, but will break this class if the above 'bug' gets 'fixed'
- \OCP\Util::writeLog( 'files_encryption', 'PHP "bug" 21641 no longer holds, decryption system requires refactoring', \OCP\Util::FATAL );
+ \OCP\Util::writeLog('Encryption library', 'PHP "bug" 21641 no longer holds, decryption system requires refactoring', \OCP\Util::FATAL);
die();
}
-// $pos = ftell( $this->handle );
-//
// Get the data from the file handle
- $data = fread( $this->handle, 8192 );
-
- if ( strlen( $data ) ) {
-
- $this->getKey();
-
- $result = Crypt::symmetricDecryptFileContent( $data, $this->keyfile );
-
- } else {
+ $data = fread($this->handle, 8192);
- $result = '';
+ $result = null;
- }
+ if (strlen($data)) {
+
+ if (!$this->getKey()) {
+
+ // Error! We don't have a key to decrypt the file with
+ throw new \Exception(
+ 'Encryption key not found for "' . $this->rawPath . '" during attempted read via stream');
+
+ } else {
+
+ // Decrypt data
+ $result = Crypt::symmetricDecryptFileContent($data, $this->plainKey);
+ }
-// $length = $this->size - $pos;
-//
-// if ( $length < 8192 ) {
-//
-// $result = substr( $result, 0, $length );
-//
-// }
+ }
return $result;
}
-
+
/**
* @brief Encrypt and pad data ready for writing to disk
* @param string $plainData data to be encrypted
* @param string $key key to use for encryption
- * @return encrypted data on success, false on failure
+ * @return string encrypted data on success, false on failure
*/
- public function preWriteEncrypt( $plainData, $key ) {
-
+ public function preWriteEncrypt($plainData, $key) {
+
// Encrypt data to 'catfile', which includes IV
- if ( $encrypted = Crypt::symmetricEncryptFileContent( $plainData, $key ) ) {
-
- return $encrypted;
-
+ if ($encrypted = Crypt::symmetricEncryptFileContent($plainData, $key)) {
+
+ return $encrypted;
+
} else {
-
+
return false;
-
+
}
-
+
}
-
+
/**
- * @brief Get the keyfile for the current file, generate one if necessary
- * @param bool $generate if true, a new key will be generated if none can be found
+ * @brief Fetch the plain encryption key for the file and set it as plainKey property
+ * @internal param bool $generate if true, a new key will be generated if none can be found
* @return bool true on key found and set, false on key not found and new key generated and set
*/
public function getKey() {
-
- // If a keyfile already exists for a file named identically to
- // file to be written
- if ( self::$view->file_exists( $this->userId . '/'. 'files_encryption' . '/' . 'keyfiles' . '/' . $this->rawPath . '.key' ) ) {
-
- // TODO: add error handling for when file exists but no
- // keyfile
-
- // Fetch existing keyfile
- $this->encKeyfile = Keymanager::getFileKey( $this->rootView, $this->userId, $this->rawPath );
-
- $this->getUser();
-
- $session = new Session();
-
- $privateKey = $session->getPrivateKey( $this->userId );
-
- $this->keyfile = Crypt::keyDecrypt( $this->encKeyfile, $privateKey );
-
+
+ // Check if key is already set
+ if (isset($this->plainKey) && isset($this->encKeyfile)) {
+
return true;
-
+
+ }
+
+ // Fetch and decrypt keyfile
+ // Fetch existing keyfile
+ $this->encKeyfile = Keymanager::getFileKey($this->rootView, $this->userId, $this->relPath);
+
+ // If a keyfile already exists
+ if ($this->encKeyfile) {
+
+ // if there is no valid private key return false
+ if ($this->privateKey === false) {
+
+ // if private key is not valid redirect user to a error page
+ \OCA\Encryption\Helper::redirectToErrorPage();
+
+ return false;
+ }
+
+ $shareKey = Keymanager::getShareKey($this->rootView, $this->userId, $this->relPath);
+
+ $this->plainKey = Crypt::multiKeyDecrypt($this->encKeyfile, $shareKey, $this->privateKey);
+
+ return true;
+
} else {
-
+
return false;
-
- }
-
- }
-
- public function getuser() {
-
- // Only get the user again if it isn't already set
- if ( empty( $this->userId ) ) {
-
- // TODO: Move this user call out of here - it belongs
- // elsewhere
- $this->userId = \OCP\User::getUser();
-
+
}
-
- // TODO: Add a method for getting the user in case OCP\User::
- // getUser() doesn't work (can that scenario ever occur?)
-
+
}
-
+
/**
* @brief Handle plain data from the stream, and write it in 8192 byte blocks
* @param string $data data to be written to disk
@@ -289,99 +273,61 @@ class Stream {
* @note Padding is added to each encrypted block to ensure that the resulting block is exactly 8192 bytes. This is removed during stream_read
* @note PHP automatically updates the file pointer after writing data to reflect it's length. There is generally no need to update the poitner manually using fseek
*/
- public function stream_write( $data ) {
-
+ public function stream_write($data) {
+
+ // if there is no valid private key return false
+ if ($this->privateKey === false) {
+ $this->size = 0;
+ return strlen($data);
+ }
+
// Disable the file proxies so that encryption is not
// automatically attempted when the file is written to disk -
// we are handling that separately here and we don't want to
// get into an infinite loop
+ $proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
-
+
// Get the length of the unencrypted data that we are handling
- $length = strlen( $data );
-
- // So far this round, no data has been written
- $written = 0;
-
- // Find out where we are up to in the writing of data to the
+ $length = strlen($data);
+
+ // Find out where we are up to in the writing of data to the
// file
- $pointer = ftell( $this->handle );
-
- // Make sure the userId is set
- $this->getuser();
-
- // TODO: Check if file is shared, if so, use multiKeyEncrypt and
- // save shareKeys in necessary user directories
-
+ $pointer = ftell($this->handle);
+
// Get / generate the keyfile for the file we're handling
// If we're writing a new file (not overwriting an existing
// one), save the newly generated keyfile
- if ( ! $this->getKey() ) {
-
- $this->keyfile = Crypt::generateKey();
-
- $this->publicKey = Keymanager::getPublicKey( $this->rootView, $this->userId );
-
- $this->encKeyfile = Crypt::keyEncrypt( $this->keyfile, $this->publicKey );
-
- $view = new \OC_FilesystemView( '/' );
- $userId = \OCP\User::getUser();
-
- // Save the new encrypted file key
- Keymanager::setFileKey( $view, $this->rawPath, $userId, $this->encKeyfile );
-
+ if (!$this->getKey()) {
+
+ $this->plainKey = Crypt::generateKey();
+
}
// If extra data is left over from the last round, make sure it
// is integrated into the next 6126 / 8192 block
- if ( $this->writeCache ) {
-
+ if ($this->writeCache) {
+
// Concat writeCache to start of $data
$data = $this->writeCache . $data;
-
- // Clear the write cache, ready for resuse - it has been
+
+ // Clear the write cache, ready for reuse - it has been
// flushed and its old contents processed
$this->writeCache = '';
}
-//
-// // Make sure we always start on a block start
- if ( 0 != ( $pointer % 8192 ) ) {
- // if the current position of
- // file indicator is not aligned to a 8192 byte block, fix it
- // so that it is
-
-// fseek( $this->handle, - ( $pointer % 8192 ), SEEK_CUR );
-//
-// $pointer = ftell( $this->handle );
-//
-// $unencryptedNewBlock = fread( $this->handle, 8192 );
-//
-// fseek( $this->handle, - ( $currentPos % 8192 ), SEEK_CUR );
-//
-// $block = Crypt::symmetricDecryptFileContent( $unencryptedNewBlock, $this->keyfile );
-//
-// $x = substr( $block, 0, $currentPos % 8192 );
-//
-// $data = $x . $data;
-//
-// fseek( $this->handle, - ( $currentPos % 8192 ), SEEK_CUR );
-//
- }
-// $currentPos = ftell( $this->handle );
-
-// // While there still remains somed data to be processed & written
- while( strlen( $data ) > 0 ) {
-//
-// // Remaining length for this iteration, not of the
-// // entire file (may be greater than 8192 bytes)
-// $remainingLength = strlen( $data );
-//
-// // If data remaining to be written is less than the
-// // size of 1 6126 byte block
- if ( strlen( $data ) < 6126 ) {
-
+ // While there still remains some data to be processed & written
+ while (strlen($data) > 0) {
+
+ // Remaining length for this iteration, not of the
+ // entire file (may be greater than 8192 bytes)
+ $remainingLength = strlen($data);
+
+ // If data remaining to be written is less than the
+ // size of 1 6126 byte block
+ if ($remainingLength < 6126) {
+
// Set writeCache to contents of $data
// The writeCache will be carried over to the
// next write round, and added to the start of
@@ -394,101 +340,187 @@ class Stream {
// Clear $data ready for next round
$data = '';
-//
+
} else {
-
+
// Read the chunk from the start of $data
- $chunk = substr( $data, 0, 6126 );
-
- $encrypted = $this->preWriteEncrypt( $chunk, $this->keyfile );
-
+ $chunk = substr($data, 0, 6126);
+
+ $encrypted = $this->preWriteEncrypt($chunk, $this->plainKey);
+
// Write the data chunk to disk. This will be
// attended to the last data chunk if the file
// being handled totals more than 6126 bytes
- fwrite( $this->handle, $encrypted );
-
- $writtenLen = strlen( $encrypted );
- //fseek( $this->handle, $writtenLen, SEEK_CUR );
+ fwrite($this->handle, $encrypted);
- // Remove the chunk we just processed from
+ // Remove the chunk we just processed from
// $data, leaving only unprocessed data in $data
// var, for handling on the next round
- $data = substr( $data, 6126 );
+ $data = substr($data, 6126);
}
-
+
}
- $this->size = max( $this->size, $pointer + $length );
-
+ $this->size = max($this->size, $pointer + $length);
+ $this->unencryptedSize += $length;
+
+ \OC_FileProxy::$enabled = $proxyStatus;
+
return $length;
}
- public function stream_set_option( $option, $arg1, $arg2 ) {
- switch($option) {
+ /**
+ * @param $option
+ * @param $arg1
+ * @param $arg2
+ */
+ public function stream_set_option($option, $arg1, $arg2) {
+ $return = false;
+ switch ($option) {
case STREAM_OPTION_BLOCKING:
- stream_set_blocking( $this->handle, $arg1 );
+ $return = stream_set_blocking($this->handle, $arg1);
break;
case STREAM_OPTION_READ_TIMEOUT:
- stream_set_timeout( $this->handle, $arg1, $arg2 );
+ $return = stream_set_timeout($this->handle, $arg1, $arg2);
break;
case STREAM_OPTION_WRITE_BUFFER:
- stream_set_write_buffer( $this->handle, $arg1, $arg2 );
+ $return = stream_set_write_buffer($this->handle, $arg1);
}
+
+ return $return;
}
+ /**
+ * @return array
+ */
public function stream_stat() {
return fstat($this->handle);
}
-
- public function stream_lock( $mode ) {
- flock( $this->handle, $mode );
+
+ /**
+ * @param $mode
+ */
+ public function stream_lock($mode) {
+ return flock($this->handle, $mode);
}
-
+
+ /**
+ * @return bool
+ */
public function stream_flush() {
-
- return fflush( $this->handle );
+
+ return fflush($this->handle);
// Not a typo: http://php.net/manual/en/function.fflush.php
-
+
}
+ /**
+ * @return bool
+ */
public function stream_eof() {
return feof($this->handle);
}
private function flush() {
-
- if ( $this->writeCache ) {
-
+
+ if ($this->writeCache) {
+
// Set keyfile property for file in question
$this->getKey();
-
- $encrypted = $this->preWriteEncrypt( $this->writeCache, $this->keyfile );
-
- fwrite( $this->handle, $encrypted );
-
+
+ $encrypted = $this->preWriteEncrypt($this->writeCache, $this->plainKey);
+
+ fwrite($this->handle, $encrypted);
+
$this->writeCache = '';
-
+
}
-
+
}
+ /**
+ * @return bool
+ */
public function stream_close() {
-
+
$this->flush();
- if (
- $this->meta['mode']!='r'
- and $this->meta['mode']!='rb'
+ // if there is no valid private key return false
+ if ($this->privateKey === false) {
+
+ // cleanup
+ if ($this->meta['mode'] !== 'r' && $this->meta['mode'] !== 'rb') {
+
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ if ($this->rootView->file_exists($this->rawPath) && $this->size === 0) {
+ $this->rootView->unlink($this->rawPath);
+ }
+
+ // Re-enable proxy - our work is done
+ \OC_FileProxy::$enabled = $proxyStatus;
+ }
+
+ // if private key is not valid redirect user to a error page
+ \OCA\Encryption\Helper::redirectToErrorPage();
+ }
+
+ if (
+ $this->meta['mode'] !== 'r'
+ and $this->meta['mode'] !== 'rb'
+ and $this->size > 0
) {
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ // Fetch user's public key
+ $this->publicKey = Keymanager::getPublicKey($this->rootView, $this->userId);
+
+ // Check if OC sharing api is enabled
+ $sharingEnabled = \OCP\Share::isEnabled();
+
+ $util = new Util($this->rootView, $this->userId);
+
+ // Get all users sharing the file includes current user
+ $uniqueUserIds = $util->getSharingUsersArray($sharingEnabled, $this->relPath, $this->userId);
+
+ // Fetch public keys for all sharing users
+ $publicKeys = Keymanager::getPublicKeys($this->rootView, $uniqueUserIds);
+
+ // Encrypt enc key for all sharing users
+ $this->encKeyfiles = Crypt::multiKeyEncrypt($this->plainKey, $publicKeys);
+
+ // Save the new encrypted file key
+ Keymanager::setFileKey($this->rootView, $this->relPath, $this->userId, $this->encKeyfiles['data']);
+
+ // Save the sharekeys
+ Keymanager::setShareKeys($this->rootView, $this->relPath, $this->encKeyfiles['keys']);
+
+ // get file info
+ $fileInfo = $this->rootView->getFileInfo($this->rawPath);
+ if (!is_array($fileInfo)) {
+ $fileInfo = array();
+ }
+
+ // Re-enable proxy - our work is done
+ \OC_FileProxy::$enabled = $proxyStatus;
- \OC\Files\Filesystem::putFileInfo( $this->path, array( 'encrypted' => true, 'size' => $this->size ), '' );
+ // set encryption data
+ $fileInfo['encrypted'] = true;
+ $fileInfo['size'] = $this->size;
+ $fileInfo['unencrypted_size'] = $this->unencryptedSize;
+ // set fileinfo
+ $this->rootView->putFileInfo($this->rawPath, $fileInfo);
}
- return fclose( $this->handle );
+ return fclose($this->handle);
}
diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php
index 52bc74db27a61ee0c26af4e2b2cffdca8b2df419..50e823585d76aa5d7ba3d42cc207ddea9912dd01 100644
--- a/apps/files_encryption/lib/util.php
+++ b/apps/files_encryption/lib/util.php
@@ -3,8 +3,8 @@
* ownCloud
*
* @author Sam Tuke, Frank Karlitschek
- * @copyright 2012 Sam Tuke samtuke@owncloud.com,
- * Frank Karlitschek frank@owncloud.org
+ * @copyright 2012 Sam Tuke ,
+ * Frank Karlitschek
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -21,81 +21,88 @@
*
*/
-// Todo:
+# Bugs
+# ----
+# Sharing a file to a user without encryption set up will not provide them with access but won't notify the sharer
+# Sharing all files to admin for recovery purposes still in progress
+# Possibly public links are broken (not tested since last merge of master)
+
+
+# Missing features
+# ----------------
+# Make sure user knows if large files weren't encrypted
+
+
+# Test
+# ----
+# Test that writing files works when recovery is enabled, and sharing API is disabled
+# Test trashbin support
+
+
+// Old Todo:
// - Crypt/decrypt button in the userinterface
// - Setting if crypto should be on by default
// - Add a setting "Don´t encrypt files larger than xx because of performance
// reasons"
-// - Transparent decrypt/encrypt in filesystem.php. Autodetect if a file is
-// encrypted (.encrypted extension)
-// - Don't use a password directly as encryption key. but a key which is
-// stored on the server and encrypted with the user password. -> password
-// change faster
-// - IMPORTANT! Check if the block lenght of the encrypted data stays the same
namespace OCA\Encryption;
/**
* @brief Class for utilities relating to encrypted file storage system
- * @param OC_FilesystemView $view expected to have OC '/' as root path
+ * @param \OC_FilesystemView $view expected to have OC '/' as root path
* @param string $userId ID of the logged in user
* @param int $client indicating status of client side encryption. Currently
* unused, likely to become obsolete shortly
*/
class Util {
-
-
+
// Web UI:
-
+
//// DONE: files created via web ui are encrypted
//// DONE: file created & encrypted via web ui are readable in web ui
//// DONE: file created & encrypted via web ui are readable via webdav
-
-
+
+
// WebDAV:
-
+
//// DONE: new data filled files added via webdav get encrypted
//// DONE: new data filled files added via webdav are readable via webdav
//// DONE: reading unencrypted files when encryption is enabled works via
//// webdav
//// DONE: files created & encrypted via web ui are readable via webdav
-
-
+
+
// Legacy support:
-
+
//// DONE: add method to check if file is encrypted using new system
//// DONE: add method to check if file is encrypted using old system
//// DONE: add method to fetch legacy key
//// DONE: add method to decrypt legacy encrypted data
-
-
+
+
// Admin UI:
-
+
//// DONE: changing user password also changes encryption passphrase
-
+
//// TODO: add support for optional recovery in case of lost passphrase / keys
//// TODO: add admin optional required long passphrase for users
- //// TODO: add UI buttons for encrypt / decrypt everything
//// TODO: implement flag system to allow user to specify encryption by folder, subfolder, etc.
-
-
- // Sharing:
-
- //// TODO: add support for encrypting to multiple public keys
- //// TODO: add support for decrypting to multiple private keys
-
-
+
+
// Integration testing:
-
+
//// TODO: test new encryption with versioning
- //// TODO: test new encryption with sharing
+ //// DONE: test new encryption with sharing
//// TODO: test new encryption with proxies
-
-
+
+ const MIGRATION_COMPLETED = 1; // migration to new encryption completed
+ const MIGRATION_IN_PROGRESS = -1; // migration is running
+ const MIGRATION_OPEN = 0; // user still needs to be migrated
+
+
private $view; // OC_FilesystemView object for filesystem operations
private $userId; // ID of the currently logged-in user
- private $pwd; // User Password
private $client; // Client side encryption mode flag
private $publicKeyDir; // Dir containing all public user keys
private $encryptionDir; // Dir containing user's files_encryption
@@ -103,166 +110,314 @@ class Util {
private $shareKeysPath; // Dir containing env keys for shared files
private $publicKeyPath; // Path to user's public key
private $privateKeyPath; // Path to user's private key
+ private $publicShareKeyId;
+ private $recoveryKeyId;
+ private $isPublic;
+
+ /**
+ * @param \OC_FilesystemView $view
+ * @param $userId
+ * @param bool $client
+ */
+ public function __construct(\OC_FilesystemView $view, $userId, $client = false) {
- public function __construct( \OC_FilesystemView $view, $userId, $client = false ) {
-
$this->view = $view;
$this->userId = $userId;
$this->client = $client;
- $this->userDir = '/' . $this->userId;
- $this->userFilesDir = '/' . $this->userId . '/' . 'files';
- $this->publicKeyDir = '/' . 'public-keys';
- $this->encryptionDir = '/' . $this->userId . '/' . 'files_encryption';
- $this->keyfilesPath = $this->encryptionDir . '/' . 'keyfiles';
- $this->shareKeysPath = $this->encryptionDir . '/' . 'share-keys';
- $this->publicKeyPath = $this->publicKeyDir . '/' . $this->userId . '.public.key'; // e.g. data/public-keys/admin.public.key
- $this->privateKeyPath = $this->encryptionDir . '/' . $this->userId . '.private.key'; // e.g. data/admin/admin.private.key
-
- }
-
+ $this->isPublic = false;
+
+ $this->publicShareKeyId = \OC_Appconfig::getValue('files_encryption', 'publicShareKeyId');
+ $this->recoveryKeyId = \OC_Appconfig::getValue('files_encryption', 'recoveryKeyId');
+
+ // if we are anonymous/public
+ if (\OCA\Encryption\Helper::isPublicAccess()) {
+ $this->userId = $this->publicShareKeyId;
+
+ // only handle for files_sharing app
+ if (isset($GLOBALS['app']) && $GLOBALS['app'] === 'files_sharing') {
+ $this->userDir = '/' . $GLOBALS['fileOwner'];
+ $this->fileFolderName = 'files';
+ $this->userFilesDir = '/' . $GLOBALS['fileOwner'] . '/'
+ . $this->fileFolderName; // TODO: Does this need to be user configurable?
+ $this->publicKeyDir = '/' . 'public-keys';
+ $this->encryptionDir = '/' . $GLOBALS['fileOwner'] . '/' . 'files_encryption';
+ $this->keyfilesPath = $this->encryptionDir . '/' . 'keyfiles';
+ $this->shareKeysPath = $this->encryptionDir . '/' . 'share-keys';
+ $this->publicKeyPath =
+ $this->publicKeyDir . '/' . $this->userId . '.public.key'; // e.g. data/public-keys/admin.public.key
+ $this->privateKeyPath =
+ '/owncloud_private_key/' . $this->userId . '.private.key'; // e.g. data/admin/admin.private.key
+ $this->isPublic = true;
+ }
+
+ } else {
+ $this->userDir = '/' . $this->userId;
+ $this->fileFolderName = 'files';
+ $this->userFilesDir =
+ '/' . $this->userId . '/' . $this->fileFolderName; // TODO: Does this need to be user configurable?
+ $this->publicKeyDir = '/' . 'public-keys';
+ $this->encryptionDir = '/' . $this->userId . '/' . 'files_encryption';
+ $this->keyfilesPath = $this->encryptionDir . '/' . 'keyfiles';
+ $this->shareKeysPath = $this->encryptionDir . '/' . 'share-keys';
+ $this->publicKeyPath =
+ $this->publicKeyDir . '/' . $this->userId . '.public.key'; // e.g. data/public-keys/admin.public.key
+ $this->privateKeyPath =
+ $this->encryptionDir . '/' . $this->userId . '.private.key'; // e.g. data/admin/admin.private.key
+ }
+ }
+
+ /**
+ * @return bool
+ */
public function ready() {
-
- if(
- !$this->view->file_exists( $this->encryptionDir )
- or !$this->view->file_exists( $this->keyfilesPath )
- or !$this->view->file_exists( $this->shareKeysPath )
- or !$this->view->file_exists( $this->publicKeyPath )
- or !$this->view->file_exists( $this->privateKeyPath )
+
+ if (
+ !$this->view->file_exists($this->encryptionDir)
+ or !$this->view->file_exists($this->keyfilesPath)
+ or !$this->view->file_exists($this->shareKeysPath)
+ or !$this->view->file_exists($this->publicKeyPath)
+ or !$this->view->file_exists($this->privateKeyPath)
) {
-
+
return false;
-
+
} else {
-
+
return true;
-
- }
-
- }
-
- /**
- * @brief Sets up user folders and keys for serverside encryption
- * @param $passphrase passphrase to encrypt server-stored private key with
- */
- public function setupServerSide( $passphrase = null ) {
-
- // Create user dir
- if( !$this->view->file_exists( $this->userDir ) ) {
-
- $this->view->mkdir( $this->userDir );
-
- }
-
- // Create user files dir
- if( !$this->view->file_exists( $this->userFilesDir ) ) {
-
- $this->view->mkdir( $this->userFilesDir );
-
- }
-
- // Create shared public key directory
- if( !$this->view->file_exists( $this->publicKeyDir ) ) {
-
- $this->view->mkdir( $this->publicKeyDir );
-
- }
-
- // Create encryption app directory
- if( !$this->view->file_exists( $this->encryptionDir ) ) {
-
- $this->view->mkdir( $this->encryptionDir );
-
- }
-
- // Create mirrored keyfile directory
- if( !$this->view->file_exists( $this->keyfilesPath ) ) {
-
- $this->view->mkdir( $this->keyfilesPath );
-
- }
-
- // Create mirrored share env keys directory
- if( !$this->view->file_exists( $this->shareKeysPath ) ) {
-
- $this->view->mkdir( $this->shareKeysPath );
-
- }
-
+
+ }
+
+ }
+
+ /**
+ * @brief Sets up user folders and keys for serverside encryption
+ *
+ * @param string $passphrase to encrypt server-stored private key with
+ * @return bool
+ */
+ public function setupServerSide($passphrase = null) {
+
+ // Set directories to check / create
+ $setUpDirs = array(
+ $this->userDir,
+ $this->userFilesDir,
+ $this->publicKeyDir,
+ $this->encryptionDir,
+ $this->keyfilesPath,
+ $this->shareKeysPath
+ );
+
+ // Check / create all necessary dirs
+ foreach ($setUpDirs as $dirPath) {
+
+ if (!$this->view->file_exists($dirPath)) {
+
+ $this->view->mkdir($dirPath);
+
+ }
+
+ }
+
// Create user keypair
- if (
- ! $this->view->file_exists( $this->publicKeyPath )
- or ! $this->view->file_exists( $this->privateKeyPath )
+ // we should never override a keyfile
+ if (
+ !$this->view->file_exists($this->publicKeyPath)
+ && !$this->view->file_exists($this->privateKeyPath)
) {
-
+
// Generate keypair
$keypair = Crypt::createKeypair();
-
- \OC_FileProxy::$enabled = false;
-
- // Save public key
- $this->view->file_put_contents( $this->publicKeyPath, $keypair['publicKey'] );
-
- // Encrypt private key with user pwd as passphrase
- $encryptedPrivateKey = Crypt::symmetricEncryptFileContent( $keypair['privateKey'], $passphrase );
-
- // Save private key
- $this->view->file_put_contents( $this->privateKeyPath, $encryptedPrivateKey );
-
- \OC_FileProxy::$enabled = true;
-
+
+ if ($keypair) {
+
+ \OC_FileProxy::$enabled = false;
+
+ // Encrypt private key with user pwd as passphrase
+ $encryptedPrivateKey = Crypt::symmetricEncryptFileContent($keypair['privateKey'], $passphrase);
+
+ // Save key-pair
+ if ($encryptedPrivateKey) {
+ $this->view->file_put_contents($this->privateKeyPath, $encryptedPrivateKey);
+ $this->view->file_put_contents($this->publicKeyPath, $keypair['publicKey']);
+ }
+
+ \OC_FileProxy::$enabled = true;
+ }
+
+ } else {
+ // check if public-key exists but private-key is missing
+ if ($this->view->file_exists($this->publicKeyPath) && !$this->view->file_exists($this->privateKeyPath)) {
+ \OCP\Util::writeLog('Encryption library',
+ 'public key exists but private key is missing for "' . $this->userId . '"', \OCP\Util::FATAL);
+ return false;
+ } else {
+ if (!$this->view->file_exists($this->publicKeyPath) && $this->view->file_exists($this->privateKeyPath)
+ ) {
+ \OCP\Util::writeLog('Encryption library',
+ 'private key exists but public key is missing for "' . $this->userId . '"', \OCP\Util::FATAL);
+ return false;
+ }
+ }
+ }
+
+ // If there's no record for this user's encryption preferences
+ if (false === $this->recoveryEnabledForUser()) {
+
+ // create database configuration
+ $sql = 'INSERT INTO `*PREFIX*encryption` (`uid`,`mode`,`recovery_enabled`) VALUES (?,?,?)';
+ $args = array(
+ $this->userId,
+ 'server-side',
+ 0
+ );
+ $query = \OCP\DB::prepare($sql);
+ $query->execute($args);
+
}
-
+
return true;
-
+
+ }
+
+ /**
+ * @return string
+ */
+ public function getPublicShareKeyId() {
+ return $this->publicShareKeyId;
+ }
+
+ /**
+ * @brief Check whether pwd recovery is enabled for a given user
+ * @return bool 1 = yes, 0 = no, false = no record
+ *
+ * @note If records are not being returned, check for a hidden space
+ * at the start of the uid in db
+ */
+ public function recoveryEnabledForUser() {
+
+ $sql = 'SELECT `recovery_enabled` FROM `*PREFIX*encryption` WHERE `uid` = ?';
+
+ $args = array($this->userId);
+
+ $query = \OCP\DB::prepare($sql);
+
+ $result = $query->execute($args);
+
+ $recoveryEnabled = array();
+
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
+ } else {
+ if ($result->numRows() > 0) {
+ $row = $result->fetchRow();
+ if (isset($row['recovery_enabled'])) {
+ $recoveryEnabled[] = $row['recovery_enabled'];
+ }
+ }
+ }
+
+ // If no record is found
+ if (empty($recoveryEnabled)) {
+
+ return false;
+
+ // If a record is found
+ } else {
+
+ return $recoveryEnabled[0];
+
+ }
+
+ }
+
+ /**
+ * @brief Enable / disable pwd recovery for a given user
+ * @param bool $enabled Whether to enable or disable recovery
+ * @return bool
+ */
+ public function setRecoveryForUser($enabled) {
+
+ $recoveryStatus = $this->recoveryEnabledForUser();
+
+ // If a record for this user already exists, update it
+ if (false === $recoveryStatus) {
+
+ $sql = 'INSERT INTO `*PREFIX*encryption` (`uid`,`mode`,`recovery_enabled`) VALUES (?,?,?)';
+
+ $args = array(
+ $this->userId,
+ 'server-side',
+ $enabled
+ );
+
+ // Create a new record instead
+ } else {
+
+ $sql = 'UPDATE `*PREFIX*encryption` SET `recovery_enabled` = ? WHERE `uid` = ?';
+
+ $args = array(
+ $enabled,
+ $this->userId
+ );
+
+ }
+
+ return is_numeric(\OC_DB::executeAudited($sql, $args));
+
}
-
+
/**
* @brief Find all files and their encryption status within a directory
* @param string $directory The path of the parent directory to search
+ * @param bool $found the founded files if called again
* @return mixed false if 0 found, array on success. Keys: name, path
-
* @note $directory needs to be a path relative to OC data dir. e.g.
* /admin/files NOT /backup OR /home/www/oc/data/admin/files
*/
- public function findFiles( $directory ) {
-
+ public function findEncFiles($directory, &$found = false) {
+
// Disable proxy - we don't want files to be decrypted before
// we handle them
\OC_FileProxy::$enabled = false;
-
- $found = array( 'plain' => array(), 'encrypted' => array(), 'legacy' => array() );
-
- if (
- $this->view->is_dir( $directory )
- && $handle = $this->view->opendir( $directory )
+
+ if ($found === false) {
+ $found = array(
+ 'plain' => array(),
+ 'encrypted' => array(),
+ 'legacy' => array()
+ );
+ }
+
+ if (
+ $this->view->is_dir($directory)
+ && $handle = $this->view->opendir($directory)
) {
-
- while ( false !== ( $file = readdir( $handle ) ) ) {
-
+
+ while (false !== ($file = readdir($handle))) {
+
if (
- $file != "."
- && $file != ".."
+ $file !== "."
+ && $file !== ".."
) {
-
- $filePath = $directory . '/' . $this->view->getRelativePath( '/' . $file );
- $relPath = $this->stripUserFilesPath( $filePath );
-
+
+ $filePath = $directory . '/' . $this->view->getRelativePath('/' . $file);
+ $relPath = \OCA\Encryption\Helper::stripUserFilesPath($filePath);
+
// If the path is a directory, search
// its contents
- if ( $this->view->is_dir( $filePath ) ) {
-
- $this->findFiles( $filePath );
-
- // If the path is a file, determine
- // its encryption status
- } elseif ( $this->view->is_file( $filePath ) ) {
-
+ if ($this->view->is_dir($filePath)) {
+
+ $this->findEncFiles($filePath, $found);
+
+ // If the path is a file, determine
+ // its encryption status
+ } elseif ($this->view->is_file($filePath)) {
+
// Disable proxies again, some-
// where they got re-enabled :/
\OC_FileProxy::$enabled = false;
-
- $data = $this->view->file_get_contents( $filePath );
-
+
+ $isEncryptedPath = $this->isEncryptedPath($filePath);
// If the file is encrypted
// NOTE: If the userId is
// empty or not set, file will
@@ -270,207 +425,1158 @@ class Util {
// NOTE: This is inefficient;
// scanning every file like this
// will eat server resources :(
- if (
- Keymanager::getFileKey( $this->view, $this->userId, $file )
- && Crypt::isCatfile( $data )
+ if (
+ Keymanager::getFileKey($this->view, $this->userId, $relPath)
+ && $isEncryptedPath
) {
-
- $found['encrypted'][] = array( 'name' => $file, 'path' => $filePath );
-
- // If the file uses old
- // encryption system
- } elseif ( Crypt::isLegacyEncryptedContent( $this->view->file_get_contents( $filePath ), $relPath ) ) {
-
- $found['legacy'][] = array( 'name' => $file, 'path' => $filePath );
-
- // If the file is not encrypted
+
+ $found['encrypted'][] = array(
+ 'name' => $file,
+ 'path' => $filePath
+ );
+
+ // If the file uses old
+ // encryption system
+ } elseif (Crypt::isLegacyEncryptedContent($isEncryptedPath, $relPath)) {
+
+ $found['legacy'][] = array(
+ 'name' => $file,
+ 'path' => $filePath
+ );
+
+ // If the file is not encrypted
} else {
-
- $found['plain'][] = array( 'name' => $file, 'path' => $filePath );
-
+
+ $found['plain'][] = array(
+ 'name' => $file,
+ 'path' => $relPath
+ );
+
}
-
+
}
-
+
}
-
+
}
-
+
\OC_FileProxy::$enabled = true;
-
- if ( empty( $found ) ) {
-
+
+ if (empty($found)) {
+
return false;
-
+
} else {
-
+
return $found;
-
+
}
-
+
}
-
+
\OC_FileProxy::$enabled = true;
-
+
return false;
}
-
- /**
- * @brief Check if a given path identifies an encrypted file
- * @return true / false
- */
- public function isEncryptedPath( $path ) {
-
- // Disable encryption proxy so data retreived is in its
- // original form
+
+ /**
+ * @brief Fetch the last lines of a file efficiently
+ * @note Safe to use on large files; does not read entire file to memory
+ * @note Derivative of http://tekkie.flashbit.net/php/tail-functionality-in-php
+ */
+ public function tail($filename, $numLines) {
+
\OC_FileProxy::$enabled = false;
-
- $data = $this->view->file_get_contents( $path );
-
+
+ $text = '';
+ $pos = -1;
+ $handle = $this->view->fopen($filename, 'r');
+
+ while ($numLines > 0) {
+
+ --$pos;
+
+ if (fseek($handle, $pos, SEEK_END) !== 0) {
+
+ rewind($handle);
+ $numLines = 0;
+
+ } elseif (fgetc($handle) === "\n") {
+
+ --$numLines;
+
+ }
+
+ $block_size = (-$pos) % 8192;
+ if ($block_size === 0 || $numLines === 0) {
+
+ $text = fread($handle, ($block_size === 0 ? 8192 : $block_size)) . $text;
+
+ }
+ }
+
+ fclose($handle);
+
\OC_FileProxy::$enabled = true;
-
- return Crypt::isCatfile( $data );
-
+
+ return $text;
}
-
+
/**
- * @brief Format a path to be relative to the /user/files/ directory
+ * @brief Check if a given path identifies an encrypted file
+ * @param string $path
+ * @return boolean
*/
- public function stripUserFilesPath( $path ) {
-
- $trimmed = ltrim( $path, '/' );
- $split = explode( '/', $trimmed );
- $sliced = array_slice( $split, 2 );
- $relPath = implode( '/', $sliced );
-
- return $relPath;
-
+ public function isEncryptedPath($path) {
+
+ // Disable encryption proxy so data retrieved is in its
+ // original form
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ // we only need 24 byte from the last chunk
+ $data = '';
+ $handle = $this->view->fopen($path, 'r');
+ if (is_resource($handle) && !fseek($handle, -24, SEEK_END)) {
+ $data = fgets($handle);
+ }
+
+ // re-enable proxy
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ return Crypt::isCatfileContent($data);
+
}
-
+
/**
- * @brief Encrypt all files in a directory
- * @param string $publicKey the public key to encrypt files with
- * @param string $dirPath the directory whose files will be encrypted
- * @note Encryption is recursive
+ * @brief get the file size of the unencrypted file
+ * @param string $path absolute path
+ * @return bool
*/
- public function encryptAll( $publicKey, $dirPath, $legacyPassphrase = null, $newPassphrase = null ) {
-
- if ( $found = $this->findFiles( $dirPath ) ) {
-
- // Disable proxy to prevent file being encrypted twice
- \OC_FileProxy::$enabled = false;
-
- // Encrypt unencrypted files
- foreach ( $found['plain'] as $plainFile ) {
-
- // Fetch data from file
- $plainData = $this->view->file_get_contents( $plainFile['path'] );
-
- // Encrypt data, generate catfile
- $encrypted = Crypt::keyEncryptKeyfile( $plainData, $publicKey );
-
- $relPath = $this->stripUserFilesPath( $plainFile['path'] );
-
- // Save keyfile
- Keymanager::setFileKey( $this->view, $relPath, $this->userId, $encrypted['key'] );
-
- // Overwrite the existing file with the encrypted one
- $this->view->file_put_contents( $plainFile['path'], $encrypted['data'] );
-
- $size = strlen( $encrypted['data'] );
-
- // Add the file to the cache
- \OC\Files\Filesystem::putFileInfo( $plainFile['path'], array( 'encrypted'=>true, 'size' => $size ), '' );
-
- }
-
- // Encrypt legacy encrypted files
- if (
- ! empty( $legacyPassphrase )
- && ! empty( $newPassphrase )
- ) {
-
- foreach ( $found['legacy'] as $legacyFile ) {
-
- // Fetch data from file
- $legacyData = $this->view->file_get_contents( $legacyFile['path'] );
-
- // Recrypt data, generate catfile
- $recrypted = Crypt::legacyKeyRecryptKeyfile( $legacyData, $legacyPassphrase, $publicKey, $newPassphrase );
-
- $relPath = $this->stripUserFilesPath( $legacyFile['path'] );
-
- // Save keyfile
- Keymanager::setFileKey( $this->view, $relPath, $this->userId, $recrypted['key'] );
-
- // Overwrite the existing file with the encrypted one
- $this->view->file_put_contents( $legacyFile['path'], $recrypted['data'] );
-
- $size = strlen( $recrypted['data'] );
-
- // Add the file to the cache
- \OC\Files\Filesystem::putFileInfo( $legacyFile['path'], array( 'encrypted'=>true, 'size' => $size ), '' );
-
- }
-
+ public function getFileSize($path) {
+
+ $result = 0;
+
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ // split the path parts
+ $pathParts = explode('/', $path);
+
+ // get relative path
+ $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
+
+ if (isset($pathParts[2]) && $pathParts[2] === 'files' && $this->view->file_exists($path)
+ && $this->isEncryptedPath($path)
+ ) {
+
+ // get the size from filesystem
+ $fullPath = $this->view->getLocalFile($path);
+ $size = filesize($fullPath);
+
+ // calculate last chunk nr
+ $lastChunkNr = floor($size / 8192);
+
+ // open stream
+ $stream = fopen('crypt://' . $relativePath, "r");
+
+ if (is_resource($stream)) {
+ // calculate last chunk position
+ $lastChunckPos = ($lastChunkNr * 8192);
+
+ // seek to end
+ fseek($stream, $lastChunckPos);
+
+ // get the content of the last chunk
+ $lastChunkContent = fread($stream, 8192);
+
+ // calc the real file size with the size of the last chunk
+ $realSize = (($lastChunkNr * 6126) + strlen($lastChunkContent));
+
+ // store file size
+ $result = $realSize;
}
-
- \OC_FileProxy::$enabled = true;
-
- // If files were found, return true
+ }
+
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ return $result;
+ }
+
+ /**
+ * @brief fix the file size of the encrypted file
+ * @param string $path absolute path
+ * @return boolean true / false if file is encrypted
+ */
+ public function fixFileSize($path) {
+
+ $result = false;
+
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ $realSize = $this->getFileSize($path);
+
+ if ($realSize > 0) {
+
+ $cached = $this->view->getFileInfo($path);
+ $cached['encrypted'] = true;
+
+ // set the size
+ $cached['unencrypted_size'] = $realSize;
+
+ // put file info
+ $this->view->putFileInfo($path, $cached);
+
+ $result = true;
+
+ }
+
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ return $result;
+ }
+
+
+ /**
+ * @param $path
+ * @return bool
+ */
+ public function isSharedPath($path) {
+
+ $trimmed = ltrim($path, '/');
+ $split = explode('/', $trimmed);
+
+ if (isset($split[2]) && $split[2] === 'Shared') {
+
return true;
-
+
} else {
-
- // If no files were found, return false
+
return false;
-
+
}
-
+
}
-
+
/**
- * @brief Return important encryption related paths
- * @param string $pathName Name of the directory to return the path of
- * @return string path
+ * @brief Encrypt all files in a directory
+ * @param string $dirPath the directory whose files will be encrypted
+ * @param null $legacyPassphrase
+ * @param null $newPassphrase
+ * @return bool
+ * @note Encryption is recursive
*/
- public function getPath( $pathName ) {
-
- switch ( $pathName ) {
-
+ public function encryptAll($dirPath, $legacyPassphrase = null, $newPassphrase = null) {
+
+ if ($found = $this->findEncFiles($dirPath)) {
+
+ // Disable proxy to prevent file being encrypted twice
+ \OC_FileProxy::$enabled = false;
+
+ // Encrypt unencrypted files
+ foreach ($found['plain'] as $plainFile) {
+
+ //relative to data//file
+ $relPath = $plainFile['path'];
+
+ //relative to /data
+ $rawPath = '/' . $this->userId . '/files/' . $plainFile['path'];
+
+ // Open plain file handle for binary reading
+ $plainHandle = $this->view->fopen($rawPath, 'rb');
+
+ // Open enc file handle for binary writing, with same filename as original plain file
+ $encHandle = fopen('crypt://' . $relPath . '.part', 'wb');
+
+ // Move plain file to a temporary location
+ $size = stream_copy_to_stream($plainHandle, $encHandle);
+
+ fclose($encHandle);
+
+ $fakeRoot = $this->view->getRoot();
+ $this->view->chroot('/' . $this->userId . '/files');
+
+ $this->view->rename($relPath . '.part', $relPath);
+
+ $this->view->chroot($fakeRoot);
+
+ // Add the file to the cache
+ \OC\Files\Filesystem::putFileInfo($relPath, array(
+ 'encrypted' => true,
+ 'size' => $size,
+ 'unencrypted_size' => $size
+ ));
+ }
+
+ // Encrypt legacy encrypted files
+ if (
+ !empty($legacyPassphrase)
+ && !empty($newPassphrase)
+ ) {
+
+ foreach ($found['legacy'] as $legacyFile) {
+
+ // Fetch data from file
+ $legacyData = $this->view->file_get_contents($legacyFile['path']);
+
+ // decrypt data, generate catfile
+ $decrypted = Crypt::legacyBlockDecrypt($legacyData, $legacyPassphrase);
+
+ $rawPath = $legacyFile['path'];
+
+ // enable proxy the ensure encryption is handled
+ \OC_FileProxy::$enabled = true;
+
+ // Open enc file handle for binary writing, with same filename as original plain file
+ $encHandle = $this->view->fopen( $rawPath, 'wb' );
+
+ if (is_resource($encHandle)) {
+
+ // write data to stream
+ fwrite($encHandle, $decrypted);
+
+ // close stream
+ fclose($encHandle);
+ }
+
+ // disable proxy to prevent file being encrypted twice
+ \OC_FileProxy::$enabled = false;
+ }
+ }
+
+ \OC_FileProxy::$enabled = true;
+
+ // If files were found, return true
+ return true;
+ } else {
+
+ // If no files were found, return false
+ return false;
+ }
+ }
+
+ /**
+ * @brief Return important encryption related paths
+ * @param string $pathName Name of the directory to return the path of
+ * @return string path
+ */
+ public function getPath($pathName) {
+
+ switch ($pathName) {
+
case 'publicKeyDir':
-
+
return $this->publicKeyDir;
-
+
break;
-
+
case 'encryptionDir':
-
+
return $this->encryptionDir;
-
+
break;
-
+
case 'keyfilesPath':
-
+
return $this->keyfilesPath;
-
+
break;
-
+
case 'publicKeyPath':
-
+
return $this->publicKeyPath;
-
+
break;
-
+
case 'privateKeyPath':
-
+
return $this->privateKeyPath;
-
+
break;
-
}
-
+
+ return false;
+
+ }
+
+ /**
+ * @brief get path of a file.
+ * @param int $fileId id of the file
+ * @return string path of the file
+ */
+ public static function fileIdToPath($fileId) {
+
+ $sql = 'SELECT `path` FROM `*PREFIX*filecache` WHERE `fileid` = ?';
+
+ $query = \OCP\DB::prepare($sql);
+
+ $result = $query->execute(array($fileId));
+
+ $path = false;
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
+ } else {
+ if ($result->numRows() > 0) {
+ $row = $result->fetchRow();
+ $path = substr($row['path'], strlen('files'));
+ }
+ }
+
+ return $path;
+
+ }
+
+ /**
+ * @brief Filter an array of UIDs to return only ones ready for sharing
+ * @param array $unfilteredUsers users to be checked for sharing readiness
+ * @return array as multi-dimensional array. keys: ready, unready
+ */
+ public function filterShareReadyUsers($unfilteredUsers) {
+
+ // This array will collect the filtered IDs
+ $readyIds = $unreadyIds = array();
+
+ // Loop through users and create array of UIDs that need new keyfiles
+ foreach ($unfilteredUsers as $user) {
+
+ $util = new Util($this->view, $user);
+
+ // Check that the user is encryption capable, or is the
+ // public system user 'ownCloud' (for public shares)
+ if (
+ $user === $this->publicShareKeyId
+ or $user === $this->recoveryKeyId
+ or $util->ready()
+ ) {
+
+ // Construct array of ready UIDs for Keymanager{}
+ $readyIds[] = $user;
+
+ } else {
+
+ // Construct array of unready UIDs for Keymanager{}
+ $unreadyIds[] = $user;
+
+ // Log warning; we can't do necessary setup here
+ // because we don't have the user passphrase
+ \OCP\Util::writeLog('Encryption library',
+ '"' . $user . '" is not setup for encryption', \OCP\Util::WARN);
+
+ }
+
+ }
+
+ return array(
+ 'ready' => $readyIds,
+ 'unready' => $unreadyIds
+ );
+
+ }
+
+ /**
+ * @brief Decrypt a keyfile without knowing how it was encrypted
+ * @param string $filePath
+ * @param string $fileOwner
+ * @param string $privateKey
+ * @return bool|string
+ * @note Checks whether file was encrypted with openssl_seal or
+ * openssl_encrypt, and decrypts accrdingly
+ * @note This was used when 2 types of encryption for keyfiles was used,
+ * but now we've switched to exclusively using openssl_seal()
+ */
+ public function decryptUnknownKeyfile($filePath, $fileOwner, $privateKey) {
+
+ // Get the encrypted keyfile
+ // NOTE: the keyfile format depends on how it was encrypted! At
+ // this stage we don't know how it was encrypted
+ $encKeyfile = Keymanager::getFileKey($this->view, $this->userId, $filePath);
+
+ // We need to decrypt the keyfile
+ // Has the file been shared yet?
+ if (
+ $this->userId === $fileOwner
+ && !Keymanager::getShareKey($this->view, $this->userId, $filePath) // NOTE: we can't use isShared() here because it's a post share hook so it always returns true
+ ) {
+
+ // The file has no shareKey, and its keyfile must be
+ // decrypted conventionally
+ $plainKeyfile = Crypt::keyDecrypt($encKeyfile, $privateKey);
+
+
+ } else {
+
+ // The file has a shareKey and must use it for decryption
+ $shareKey = Keymanager::getShareKey($this->view, $this->userId, $filePath);
+
+ $plainKeyfile = Crypt::multiKeyDecrypt($encKeyfile, $shareKey, $privateKey);
+
+ }
+
+ return $plainKeyfile;
+
+ }
+
+ /**
+ * @brief Encrypt keyfile to multiple users
+ * @param Session $session
+ * @param array $users list of users which should be able to access the file
+ * @param string $filePath path of the file to be shared
+ * @return bool
+ */
+ public function setSharedFileKeyfiles(Session $session, array $users, $filePath) {
+
+ // Make sure users are capable of sharing
+ $filteredUids = $this->filterShareReadyUsers($users);
+
+ // If we're attempting to share to unready users
+ if (!empty($filteredUids['unready'])) {
+
+ \OCP\Util::writeLog('Encryption library',
+ 'Sharing to these user(s) failed as they are unready for encryption:"'
+ . print_r($filteredUids['unready'], 1), \OCP\Util::WARN);
+
+ return false;
+
+ }
+
+ // Get public keys for each user, ready for generating sharekeys
+ $userPubKeys = Keymanager::getPublicKeys($this->view, $filteredUids['ready']);
+
+ // Note proxy status then disable it
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ // Get the current users's private key for decrypting existing keyfile
+ $privateKey = $session->getPrivateKey();
+
+ $fileOwner = \OC\Files\Filesystem::getOwner($filePath);
+
+ // Decrypt keyfile
+ $plainKeyfile = $this->decryptUnknownKeyfile($filePath, $fileOwner, $privateKey);
+
+ // Re-enc keyfile to (additional) sharekeys
+ $multiEncKey = Crypt::multiKeyEncrypt($plainKeyfile, $userPubKeys);
+
+ // Save the recrypted key to it's owner's keyfiles directory
+ // Save new sharekeys to all necessary user directory
+ if (
+ !Keymanager::setFileKey($this->view, $filePath, $fileOwner, $multiEncKey['data'])
+ || !Keymanager::setShareKeys($this->view, $filePath, $multiEncKey['keys'])
+ ) {
+
+ \OCP\Util::writeLog('Encryption library',
+ 'Keyfiles could not be saved for users sharing ' . $filePath, \OCP\Util::ERROR);
+
+ return false;
+
+ }
+
+ // Return proxy to original status
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ return true;
+ }
+
+ /**
+ * @brief Find, sanitise and format users sharing a file
+ * @note This wraps other methods into a portable bundle
+ */
+ public function getSharingUsersArray($sharingEnabled, $filePath, $currentUserId = false) {
+
+ // Check if key recovery is enabled
+ if (
+ \OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled')
+ && $this->recoveryEnabledForUser()
+ ) {
+ $recoveryEnabled = true;
+ } else {
+ $recoveryEnabled = false;
+ }
+
+ // Make sure that a share key is generated for the owner too
+ list($owner, $ownerPath) = $this->getUidAndFilename($filePath);
+
+ $userIds = array();
+ if ($sharingEnabled) {
+
+ // Find out who, if anyone, is sharing the file
+ $result = \OCP\Share::getUsersSharingFile($ownerPath, $owner, true);
+ $userIds = $result['users'];
+ if ($result['public']) {
+ $userIds[] = $this->publicShareKeyId;
+ }
+
+ }
+
+ // If recovery is enabled, add the
+ // Admin UID to list of users to share to
+ if ($recoveryEnabled) {
+ // Find recoveryAdmin user ID
+ $recoveryKeyId = \OC_Appconfig::getValue('files_encryption', 'recoveryKeyId');
+ // Add recoveryAdmin to list of users sharing
+ $userIds[] = $recoveryKeyId;
+ }
+
+ // add current user if given
+ if ($currentUserId !== false) {
+ $userIds[] = $currentUserId;
+ }
+
+ // check if it is a group mount
+ if (\OCP\App::isEnabled("files_external")) {
+ $mount = \OC_Mount_Config::getSystemMountPoints();
+ foreach ($mount as $mountPoint => $data) {
+ if ($mountPoint == substr($ownerPath, 1, strlen($mountPoint))) {
+ $userIds = array_merge($userIds, $this->getUserWithAccessToMountPoint($data['applicable']['users'], $data['applicable']['groups']));
+ }
+ }
+ }
+
+ // Remove duplicate UIDs
+ $uniqueUserIds = array_unique($userIds);
+
+ return $uniqueUserIds;
+
+ }
+
+ private function getUserWithAccessToMountPoint($users, $groups) {
+ $result = array();
+ if (in_array('all', $users)) {
+ $result = \OCP\User::getUsers();
+ } else {
+ $result = array_merge($result, $users);
+ foreach ($groups as $group) {
+ $result = array_merge($result, \OC_Group::usersInGroup($group));
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * @brief start migration mode to initially encrypt users data
+ * @return boolean
+ */
+ public function beginMigration() {
+
+ $return = false;
+
+ $sql = 'UPDATE `*PREFIX*encryption` SET `migration_status` = ? WHERE `uid` = ? and `migration_status` = ?';
+ $args = array(self::MIGRATION_IN_PROGRESS, $this->userId, self::MIGRATION_OPEN);
+ $query = \OCP\DB::prepare($sql);
+ $manipulatedRows = $query->execute($args);
+
+ if ($manipulatedRows === 1) {
+ $return = true;
+ \OCP\Util::writeLog('Encryption library', "Start migration to encryption mode for " . $this->userId, \OCP\Util::INFO);
+ } else {
+ \OCP\Util::writeLog('Encryption library', "Could not activate migration mode for " . $this->userId . ". Probably another process already started the initial encryption", \OCP\Util::WARN);
+ }
+
+ return $return;
+ }
+
+ /**
+ * @brief close migration mode after users data has been encrypted successfully
+ * @return boolean
+ */
+ public function finishMigration() {
+
+ $return = false;
+
+ $sql = 'UPDATE `*PREFIX*encryption` SET `migration_status` = ? WHERE `uid` = ? and `migration_status` = ?';
+ $args = array(self::MIGRATION_COMPLETED, $this->userId, self::MIGRATION_IN_PROGRESS);
+ $query = \OCP\DB::prepare($sql);
+ $manipulatedRows = $query->execute($args);
+
+ if ($manipulatedRows === 1) {
+ $return = true;
+ \OCP\Util::writeLog('Encryption library', "Finish migration successfully for " . $this->userId, \OCP\Util::INFO);
+ } else {
+ \OCP\Util::writeLog('Encryption library', "Could not deactivate migration mode for " . $this->userId, \OCP\Util::WARN);
+ }
+
+ return $return;
+ }
+
+ /**
+ * @brief check if files are already migrated to the encryption system
+ * @return migration status, false = in case of no record
+ * @note If records are not being returned, check for a hidden space
+ * at the start of the uid in db
+ */
+ public function getMigrationStatus() {
+
+ $sql = 'SELECT `migration_status` FROM `*PREFIX*encryption` WHERE `uid` = ?';
+
+ $args = array($this->userId);
+
+ $query = \OCP\DB::prepare($sql);
+
+ $result = $query->execute($args);
+
+ $migrationStatus = array();
+
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
+ } else {
+ if ($result->numRows() > 0) {
+ $row = $result->fetchRow();
+ if (isset($row['migration_status'])) {
+ $migrationStatus[] = $row['migration_status'];
+ }
+ }
+ }
+
+ // If no record is found
+ if (empty($migrationStatus)) {
+ \OCP\Util::writeLog('Encryption library', "Could not get migration status for " . $this->userId . ", no record found", \OCP\Util::ERROR);
+ return false;
+ // If a record is found
+ } else {
+ return (int)$migrationStatus[0];
+ }
+
+ }
+
+ /**
+ * @brief get uid of the owners of the file and the path to the file
+ * @param string $path Path of the file to check
+ * @throws \Exception
+ * @note $shareFilePath must be relative to data/UID/files. Files
+ * relative to /Shared are also acceptable
+ * @return array
+ */
+ public function getUidAndFilename($path) {
+
+ $view = new \OC\Files\View($this->userFilesDir);
+ $fileOwnerUid = $view->getOwner($path);
+
+ // handle public access
+ if ($this->isPublic) {
+ $filename = $path;
+ $fileOwnerUid = $GLOBALS['fileOwner'];
+
+ return array(
+ $fileOwnerUid,
+ $filename
+ );
+ } else {
+
+ // Check that UID is valid
+ if (!\OCP\User::userExists($fileOwnerUid)) {
+ throw new \Exception(
+ 'Could not find owner (UID = "' . var_export($fileOwnerUid, 1) . '") of file "' . $path . '"');
+ }
+
+ // NOTE: Bah, this dependency should be elsewhere
+ \OC\Files\Filesystem::initMountPoints($fileOwnerUid);
+
+ // If the file owner is the currently logged in user
+ if ($fileOwnerUid === $this->userId) {
+
+ // Assume the path supplied is correct
+ $filename = $path;
+
+ } else {
+
+ $info = $view->getFileInfo($path);
+ $ownerView = new \OC\Files\View('/' . $fileOwnerUid . '/files');
+
+ // Fetch real file path from DB
+ $filename = $ownerView->getPath($info['fileid']); // TODO: Check that this returns a path without including the user data dir
+
+ }
+
+ return array(
+ $fileOwnerUid,
+ \OC_Filesystem::normalizePath($filename)
+ );
+ }
+
+
+ }
+
+ /**
+ * @brief go recursively through a dir and collect all files and sub files.
+ * @param string $dir relative to the users files folder
+ * @return array with list of files relative to the users files folder
+ */
+ public function getAllFiles($dir) {
+
+ $result = array();
+
+ $content = $this->view->getDirectoryContent(\OC\Files\Filesystem::normalizePath(
+ $this->userFilesDir . '/' . $dir));
+
+ // handling for re shared folders
+ $pathSplit = explode('/', $dir);
+
+ foreach ($content as $c) {
+
+ $sharedPart = $pathSplit[sizeof($pathSplit) - 1];
+ $targetPathSplit = array_reverse(explode('/', $c['path']));
+
+ $path = '';
+
+ // rebuild path
+ foreach ($targetPathSplit as $pathPart) {
+
+ if ($pathPart !== $sharedPart) {
+
+ $path = '/' . $pathPart . $path;
+
+ } else {
+
+ break;
+
+ }
+
+ }
+
+ $path = $dir . $path;
+
+ if ($c['type'] === 'dir') {
+
+ $result = array_merge($result, $this->getAllFiles($path));
+
+ } else {
+
+ $result[] = $path;
+
+ }
+ }
+
+ return $result;
+
+ }
+
+ /**
+ * @brief get shares parent.
+ * @param int $id of the current share
+ * @return array of the parent
+ */
+ public static function getShareParent($id) {
+
+ $sql = 'SELECT `file_target`, `item_type` FROM `*PREFIX*share` WHERE `id` = ?';
+
+ $query = \OCP\DB::prepare($sql);
+
+ $result = $query->execute(array($id));
+
+ $row = array();
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
+ } else {
+ if ($result->numRows() > 0) {
+ $row = $result->fetchRow();
+ }
+ }
+
+ return $row;
+
+ }
+
+ /**
+ * @brief get shares parent.
+ * @param int $id of the current share
+ * @return array of the parent
+ */
+ public static function getParentFromShare($id) {
+
+ $sql = 'SELECT `parent` FROM `*PREFIX*share` WHERE `id` = ?';
+
+ $query = \OCP\DB::prepare($sql);
+
+ $result = $query->execute(array($id));
+
+ $row = array();
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
+ } else {
+ if ($result->numRows() > 0) {
+ $row = $result->fetchRow();
+ }
+ }
+
+ return $row;
+
+ }
+
+ /**
+ * @brief get owner of the shared files.
+ * @param $id
+ * @internal param int $Id of a share
+ * @return string owner
+ */
+ public function getOwnerFromSharedFile($id) {
+
+ $query = \OCP\DB::prepare('SELECT `parent`, `uid_owner` FROM `*PREFIX*share` WHERE `id` = ?', 1);
+
+ $result = $query->execute(array($id));
+
+ $source = array();
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
+ } else {
+ if ($result->numRows() > 0) {
+ $source = $result->fetchRow();
+ }
+ }
+
+ $fileOwner = false;
+
+ if (isset($source['parent'])) {
+
+ $parent = $source['parent'];
+
+ while (isset($parent)) {
+
+ $query = \OCP\DB::prepare('SELECT `parent`, `uid_owner` FROM `*PREFIX*share` WHERE `id` = ?', 1);
+
+ $result = $query->execute(array($parent));
+
+ $item = array();
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
+ } else {
+ if ($result->numRows() > 0) {
+ $item = $result->fetchRow();
+ }
+ }
+
+ if (isset($item['parent'])) {
+
+ $parent = $item['parent'];
+
+ } else {
+
+ $fileOwner = $item['uid_owner'];
+
+ break;
+
+ }
+ }
+
+ } else {
+
+ $fileOwner = $source['uid_owner'];
+
+ }
+
+ return $fileOwner;
+
+ }
+
+ /**
+ * @return string
+ */
+ public function getUserId() {
+ return $this->userId;
+ }
+
+ /**
+ * @return string
+ */
+ public function getUserFilesDir() {
+ return $this->userFilesDir;
+ }
+
+ /**
+ * @param $password
+ * @return bool
+ */
+ public function checkRecoveryPassword($password) {
+
+ $result = false;
+ $pathKey = '/owncloud_private_key/' . $this->recoveryKeyId . ".private.key";
+
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ $recoveryKey = $this->view->file_get_contents($pathKey);
+
+ $decryptedRecoveryKey = Crypt::decryptPrivateKey($recoveryKey, $password);
+
+ if ($decryptedRecoveryKey) {
+ $result = true;
+ }
+
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+
+ return $result;
+ }
+
+ /**
+ * @return string
+ */
+ public function getRecoveryKeyId() {
+ return $this->recoveryKeyId;
+ }
+
+ /**
+ * @brief add recovery key to all encrypted files
+ */
+ public function addRecoveryKeys($path = '/') {
+ $dirContent = $this->view->getDirectoryContent($this->keyfilesPath . $path);
+ foreach ($dirContent as $item) {
+ // get relative path from files_encryption/keyfiles/
+ $filePath = substr($item['path'], strlen('files_encryption/keyfiles'));
+ if ($item['type'] === 'dir') {
+ $this->addRecoveryKeys($filePath . '/');
+ } else {
+ $session = new \OCA\Encryption\Session(new \OC_FilesystemView('/'));
+ $sharingEnabled = \OCP\Share::isEnabled();
+ // remove '.key' extension from path e.g. 'file.txt.key' to 'file.txt'
+ $file = substr($filePath, 0, -4);
+ $usersSharing = $this->getSharingUsersArray($sharingEnabled, $file);
+ $this->setSharedFileKeyfiles($session, $usersSharing, $file);
+ }
+ }
+ }
+
+ /**
+ * @brief remove recovery key to all encrypted files
+ */
+ public function removeRecoveryKeys($path = '/') {
+ $dirContent = $this->view->getDirectoryContent($this->keyfilesPath . $path);
+ foreach ($dirContent as $item) {
+ // get relative path from files_encryption/keyfiles
+ $filePath = substr($item['path'], strlen('files_encryption/keyfiles'));
+ if ($item['type'] === 'dir') {
+ $this->removeRecoveryKeys($filePath . '/');
+ } else {
+ // remove '.key' extension from path e.g. 'file.txt.key' to 'file.txt'
+ $file = substr($filePath, 0, -4);
+ $this->view->unlink($this->shareKeysPath . '/' . $file . '.' . $this->recoveryKeyId . '.shareKey');
+ }
+ }
+ }
+
+ /**
+ * @brief decrypt given file with recovery key and encrypt it again to the owner and his new key
+ * @param string $file
+ * @param string $privateKey recovery key to decrypt the file
+ */
+ private function recoverFile($file, $privateKey) {
+
+ $sharingEnabled = \OCP\Share::isEnabled();
+
+ // Find out who, if anyone, is sharing the file
+ if ($sharingEnabled) {
+ $result = \OCP\Share::getUsersSharingFile($file, $this->userId, true);
+ $userIds = $result['users'];
+ $userIds[] = $this->recoveryKeyId;
+ if ($result['public']) {
+ $userIds[] = $this->publicShareKeyId;
+ }
+ } else {
+ $userIds = array(
+ $this->userId,
+ $this->recoveryKeyId
+ );
+ }
+ $filteredUids = $this->filterShareReadyUsers($userIds);
+
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ //decrypt file key
+ $encKeyfile = $this->view->file_get_contents($this->keyfilesPath . $file . ".key");
+ $shareKey = $this->view->file_get_contents(
+ $this->shareKeysPath . $file . "." . $this->recoveryKeyId . ".shareKey");
+ $plainKeyfile = Crypt::multiKeyDecrypt($encKeyfile, $shareKey, $privateKey);
+ // encrypt file key again to all users, this time with the new public key for the recovered use
+ $userPubKeys = Keymanager::getPublicKeys($this->view, $filteredUids['ready']);
+ $multiEncKey = Crypt::multiKeyEncrypt($plainKeyfile, $userPubKeys);
+
+ // write new keys to filesystem TDOO!
+ $this->view->file_put_contents($this->keyfilesPath . $file . '.key', $multiEncKey['data']);
+ foreach ($multiEncKey['keys'] as $userId => $shareKey) {
+ $shareKeyPath = $this->shareKeysPath . $file . '.' . $userId . '.shareKey';
+ $this->view->file_put_contents($shareKeyPath, $shareKey);
+ }
+
+ // Return proxy to original status
+ \OC_FileProxy::$enabled = $proxyStatus;
+ }
+
+ /**
+ * @brief collect all files and recover them one by one
+ * @param string $path to look for files keys
+ * @param string $privateKey private recovery key which is used to decrypt the files
+ */
+ private function recoverAllFiles($path, $privateKey) {
+ $dirContent = $this->view->getDirectoryContent($this->keyfilesPath . $path);
+ foreach ($dirContent as $item) {
+ // get relative path from files_encryption/keyfiles
+ $filePath = substr($item['path'], strlen('files_encryption/keyfiles'));
+ if ($item['type'] === 'dir') {
+ $this->recoverAllFiles($filePath . '/', $privateKey);
+ } else {
+ // remove '.key' extension from path e.g. 'file.txt.key' to 'file.txt'
+ $file = substr($filePath, 0, -4);
+ $this->recoverFile($file, $privateKey);
+ }
+ }
+ }
+
+ /**
+ * @brief recover users files in case of password lost
+ * @param string $recoveryPassword
+ */
+ public function recoverUsersFiles($recoveryPassword) {
+
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ $encryptedKey = $this->view->file_get_contents(
+ '/owncloud_private_key/' . $this->recoveryKeyId . '.private.key');
+ $privateKey = Crypt::decryptPrivateKey($encryptedKey, $recoveryPassword);
+
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ $this->recoverAllFiles('/', $privateKey);
+ }
+
+ /**
+ * Get the path including the storage mount point
+ * @param int $id
+ * @return string the path including the mount point like AmazonS3/folder/file.txt
+ */
+ public function getPathWithMountPoint($id) {
+ list($storage, $internalPath) = \OC\Files\Cache\Cache::getById($id);
+ $mount = \OC\Files\Filesystem::getMountByStorageId($storage);
+ $mountPoint = $mount[0]->getMountPoint();
+ $path = \OC\Files\Filesystem::normalizePath($mountPoint . '/' . $internalPath);
+
+ // reformat the path to be relative e.g. /user/files/folder becomes /folder/
+ $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
+
+ return $relativePath;
+ }
+
+ /**
+ * @brief check if the file is stored on a system wide mount point
+ * @param $path relative to /data/user with leading '/'
+ * @return boolean
+ */
+ public function isSystemWideMountPoint($path) {
+ if (\OCP\App::isEnabled("files_external")) {
+ $mount = \OC_Mount_Config::getSystemMountPoints();
+ foreach ($mount as $mountPoint => $data) {
+ if ($mountPoint == substr($path, 1, strlen($mountPoint))) {
+ return true;
+ }
+ }
+ }
+ return false;
}
}
diff --git a/apps/files_encryption/settings-admin.php b/apps/files_encryption/settings-admin.php
new file mode 100644
index 0000000000000000000000000000000000000000..5367605898262f3d66b0e83a5aa9c06859fa8182
--- /dev/null
+++ b/apps/files_encryption/settings-admin.php
@@ -0,0 +1,23 @@
+
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+\OC_Util::checkAdminUser();
+
+$tmpl = new OCP\Template('files_encryption', 'settings-admin');
+
+// Check if an adminRecovery account is enabled for recovering files after lost pwd
+$view = new OC_FilesystemView('');
+
+$recoveryAdminEnabled = OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled');
+
+$tmpl->assign('recoveryEnabled', $recoveryAdminEnabled);
+
+\OCP\Util::addscript('files_encryption', 'settings-admin');
+\OCP\Util::addscript('core', 'multiselect');
+
+return $tmpl->fetchPage();
diff --git a/apps/files_encryption/settings-personal.php b/apps/files_encryption/settings-personal.php
index af0273cfdc4dc4cf1a5c31f6155ff158c8b04d5b..fddc3ea5eee836494eeec89e41114a2a6de86278 100644
--- a/apps/files_encryption/settings-personal.php
+++ b/apps/files_encryption/settings-personal.php
@@ -6,12 +6,34 @@
* See the COPYING-README file.
*/
-$tmpl = new OCP\Template( 'files_encryption', 'settings-personal');
+// Add CSS stylesheet
+\OC_Util::addStyle('files_encryption', 'settings-personal');
-$blackList = explode( ',', \OCP\Config::getAppValue( 'files_encryption', 'type_blacklist', 'jpg,png,jpeg,avi,mpg,mpeg,mkv,mp3,oga,ogv,ogg' ) );
+$tmpl = new OCP\Template('files_encryption', 'settings-personal');
-$tmpl->assign( 'blacklist', $blackList );
+$user = \OCP\USER::getUser();
+$view = new \OC_FilesystemView('/');
+$util = new \OCA\Encryption\Util($view, $user);
+$session = new \OCA\Encryption\Session($view);
-return $tmpl->fetchPage();
+$privateKeySet = ($session->getPrivateKey() !== false) ? true : false;
+
+$recoveryAdminEnabled = OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled');
+$recoveryEnabledForUser = $util->recoveryEnabledForUser();
+
+$result = false;
+
+if ($recoveryAdminEnabled || !$privateKeySet) {
+
+ \OCP\Util::addscript('files_encryption', 'settings-personal');
+ \OCP\Util::addScript('settings', 'personal');
+
+ $tmpl->assign('recoveryEnabled', $recoveryAdminEnabled);
+ $tmpl->assign('recoveryEnabledForUser', $recoveryEnabledForUser);
+ $tmpl->assign('privateKeySet', $privateKeySet);
+
+ $result = $tmpl->fetchPage();
+}
+
+return $result;
-return null;
diff --git a/apps/files_encryption/settings.php b/apps/files_encryption/settings.php
deleted file mode 100644
index d1260f44e9f6ef98a6702f13a9fc3fd3a2a38073..0000000000000000000000000000000000000000
--- a/apps/files_encryption/settings.php
+++ /dev/null
@@ -1,21 +0,0 @@
-
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-
-\OC_Util::checkAdminUser();
-
-$tmpl = new OCP\Template( 'files_encryption', 'settings' );
-
-$blackList = explode( ',', \OCP\Config::getAppValue( 'files_encryption', 'type_blacklist', 'jpg,png,jpeg,avi,mpg,mpeg,mkv,mp3,oga,ogv,ogg' ) );
-
-$tmpl->assign( 'blacklist', $blackList );
-$tmpl->assign( 'encryption_mode', \OC_Appconfig::getValue( 'files_encryption', 'mode', 'none' ) );
-
-\OCP\Util::addscript( 'files_encryption', 'settings' );
-\OCP\Util::addscript( 'core', 'multiselect' );
-
-return $tmpl->fetchPage();
diff --git a/apps/files_encryption/templates/invalid_private_key.php b/apps/files_encryption/templates/invalid_private_key.php
new file mode 100644
index 0000000000000000000000000000000000000000..5c086d6514c1297fb80d5aaea13b9cf90ff3a5ba
--- /dev/null
+++ b/apps/files_encryption/templates/invalid_private_key.php
@@ -0,0 +1,10 @@
+
+
+
+
+ t('Your private key is not valid! Maybe the your password was changed from outside.')); ?>
+
+ t('You can unlock your private key in your ')); ?> t('personal settings')); ?>.
+
+
+
diff --git a/apps/files_encryption/templates/settings-admin.php b/apps/files_encryption/templates/settings-admin.php
new file mode 100644
index 0000000000000000000000000000000000000000..f5f7582c2a69d141e49232f76e49e9fc14c708ac
--- /dev/null
+++ b/apps/files_encryption/templates/settings-admin.php
@@ -0,0 +1,58 @@
+
diff --git a/apps/files_encryption/templates/settings-personal.php b/apps/files_encryption/templates/settings-personal.php
index 5f0accaed5fd960c3c6a2a08b3493f483148b841..38512453207a0af2ab836589d427f1abc394ef16 100644
--- a/apps/files_encryption/templates/settings-personal.php
+++ b/apps/files_encryption/templates/settings-personal.php
@@ -1,22 +1,70 @@
diff --git a/apps/files_encryption/templates/settings.php b/apps/files_encryption/templates/settings.php
deleted file mode 100644
index b873d7f5aafd8e081088de28b8ad009aabcc5a56..0000000000000000000000000000000000000000
--- a/apps/files_encryption/templates/settings.php
+++ /dev/null
@@ -1,20 +0,0 @@
-
diff --git a/apps/files_encryption/test/crypt.php b/apps/files_encryption/test/crypt.php
deleted file mode 100755
index aa87ec328211bd936b922ae7ed3b0daa45594f68..0000000000000000000000000000000000000000
--- a/apps/files_encryption/test/crypt.php
+++ /dev/null
@@ -1,667 +0,0 @@
-, and
- * Robin Appelman
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-
-//require_once "PHPUnit/Framework/TestCase.php";
-require_once realpath( dirname(__FILE__).'/../../../3rdparty/Crypt_Blowfish/Blowfish.php' );
-require_once realpath( dirname(__FILE__).'/../../../lib/base.php' );
-require_once realpath( dirname(__FILE__).'/../lib/crypt.php' );
-require_once realpath( dirname(__FILE__).'/../lib/keymanager.php' );
-require_once realpath( dirname(__FILE__).'/../lib/proxy.php' );
-require_once realpath( dirname(__FILE__).'/../lib/stream.php' );
-require_once realpath( dirname(__FILE__).'/../lib/util.php' );
-require_once realpath( dirname(__FILE__).'/../appinfo/app.php' );
-
-use OCA\Encryption;
-
-// This has to go here because otherwise session errors arise, and the private
-// encryption key needs to be saved in the session
-\OC_User::login( 'admin', 'admin' );
-
-/**
- * @note It would be better to use Mockery here for mocking out the session
- * handling process, and isolate calls to session class and data from the unit
- * tests relating to them (stream etc.). However getting mockery to work and
- * overload classes whilst also using the OC autoloader is difficult due to
- * load order Pear errors.
- */
-
-class Test_Crypt extends \PHPUnit_Framework_TestCase {
-
- function setUp() {
-
- // set content for encrypting / decrypting in tests
- $this->dataLong = file_get_contents( realpath( dirname(__FILE__).'/../lib/crypt.php' ) );
- $this->dataShort = 'hats';
- $this->dataUrl = realpath( dirname(__FILE__).'/../lib/crypt.php' );
- $this->legacyData = realpath( dirname(__FILE__).'/legacy-text.txt' );
- $this->legacyEncryptedData = realpath( dirname(__FILE__).'/legacy-encrypted-text.txt' );
- $this->randomKey = Encryption\Crypt::generateKey();
-
- $keypair = Encryption\Crypt::createKeypair();
- $this->genPublicKey = $keypair['publicKey'];
- $this->genPrivateKey = $keypair['privateKey'];
-
- $this->view = new \OC_FilesystemView( '/' );
-
- \OC_User::setUserId( 'admin' );
- $this->userId = 'admin';
- $this->pass = 'admin';
-
- \OC_Filesystem::init( '/' );
- \OC_Filesystem::mount( 'OC_Filestorage_Local', array('datadir' => \OC_User::getHome($this->userId)), '/' );
-
- }
-
- function tearDown() {
-
- }
-
- function testGenerateKey() {
-
- # TODO: use more accurate (larger) string length for test confirmation
-
- $key = Encryption\Crypt::generateKey();
-
- $this->assertTrue( strlen( $key ) > 16 );
-
- }
-
- function testGenerateIv() {
-
- $iv = Encryption\Crypt::generateIv();
-
- $this->assertEquals( 16, strlen( $iv ) );
-
- return $iv;
-
- }
-
- /**
- * @depends testGenerateIv
- */
- function testConcatIv( $iv ) {
-
- $catFile = Encryption\Crypt::concatIv( $this->dataLong, $iv );
-
- // Fetch encryption metadata from end of file
- $meta = substr( $catFile, -22 );
-
- $identifier = substr( $meta, 0, 6);
-
- // Fetch IV from end of file
- $foundIv = substr( $meta, 6 );
-
- $this->assertEquals( '00iv00', $identifier );
-
- $this->assertEquals( $iv, $foundIv );
-
- // Remove IV and IV identifier text to expose encrypted content
- $data = substr( $catFile, 0, -22 );
-
- $this->assertEquals( $this->dataLong, $data );
-
- return array(
- 'iv' => $iv
- , 'catfile' => $catFile
- );
-
- }
-
- /**
- * @depends testConcatIv
- */
- function testSplitIv( $testConcatIv ) {
-
- // Split catfile into components
- $splitCatfile = Encryption\Crypt::splitIv( $testConcatIv['catfile'] );
-
- // Check that original IV and split IV match
- $this->assertEquals( $testConcatIv['iv'], $splitCatfile['iv'] );
-
- // Check that original data and split data match
- $this->assertEquals( $this->dataLong, $splitCatfile['encrypted'] );
-
- }
-
- function testAddPadding() {
-
- $padded = Encryption\Crypt::addPadding( $this->dataLong );
-
- $padding = substr( $padded, -2 );
-
- $this->assertEquals( 'xx' , $padding );
-
- return $padded;
-
- }
-
- /**
- * @depends testAddPadding
- */
- function testRemovePadding( $padded ) {
-
- $noPadding = Encryption\Crypt::RemovePadding( $padded );
-
- $this->assertEquals( $this->dataLong, $noPadding );
-
- }
-
- function testEncrypt() {
-
- $random = openssl_random_pseudo_bytes( 13 );
-
- $iv = substr( base64_encode( $random ), 0, -4 ); // i.e. E5IG033j+mRNKrht
-
- $crypted = Encryption\Crypt::encrypt( $this->dataUrl, $iv, 'hat' );
-
- $this->assertNotEquals( $this->dataUrl, $crypted );
-
- }
-
- function testDecrypt() {
-
- $random = openssl_random_pseudo_bytes( 13 );
-
- $iv = substr( base64_encode( $random ), 0, -4 ); // i.e. E5IG033j+mRNKrht
-
- $crypted = Encryption\Crypt::encrypt( $this->dataUrl, $iv, 'hat' );
-
- $decrypt = Encryption\Crypt::decrypt( $crypted, $iv, 'hat' );
-
- $this->assertEquals( $this->dataUrl, $decrypt );
-
- }
-
- function testSymmetricEncryptFileContent() {
-
- # TODO: search in keyfile for actual content as IV will ensure this test always passes
-
- $crypted = Encryption\Crypt::symmetricEncryptFileContent( $this->dataShort, 'hat' );
-
- $this->assertNotEquals( $this->dataShort, $crypted );
-
-
- $decrypt = Encryption\Crypt::symmetricDecryptFileContent( $crypted, 'hat' );
-
- $this->assertEquals( $this->dataShort, $decrypt );
-
- }
-
- // These aren't used for now
-// function testSymmetricBlockEncryptShortFileContent() {
-//
-// $crypted = Encryption\Crypt::symmetricBlockEncryptFileContent( $this->dataShort, $this->randomKey );
-//
-// $this->assertNotEquals( $this->dataShort, $crypted );
-//
-//
-// $decrypt = Encryption\Crypt::symmetricBlockDecryptFileContent( $crypted, $this->randomKey );
-//
-// $this->assertEquals( $this->dataShort, $decrypt );
-//
-// }
-//
-// function testSymmetricBlockEncryptLongFileContent() {
-//
-// $crypted = Encryption\Crypt::symmetricBlockEncryptFileContent( $this->dataLong, $this->randomKey );
-//
-// $this->assertNotEquals( $this->dataLong, $crypted );
-//
-//
-// $decrypt = Encryption\Crypt::symmetricBlockDecryptFileContent( $crypted, $this->randomKey );
-//
-// $this->assertEquals( $this->dataLong, $decrypt );
-//
-// }
-
- function testSymmetricStreamEncryptShortFileContent() {
-
- $filename = 'tmp-'.time();
-
- $cryptedFile = file_put_contents( 'crypt://' . $filename, $this->dataShort );
-
- // Test that data was successfully written
- $this->assertTrue( is_int( $cryptedFile ) );
-
-
- // Get file contents without using any wrapper to get it's actual contents on disk
- $retreivedCryptedFile = $this->view->file_get_contents( $this->userId . '/files/' . $filename );
-
- // Check that the file was encrypted before being written to disk
- $this->assertNotEquals( $this->dataShort, $retreivedCryptedFile );
-
- // Get private key
- $encryptedPrivateKey = Encryption\Keymanager::getPrivateKey( $this->view, $this->userId );
-
- $decryptedPrivateKey = Encryption\Crypt::symmetricDecryptFileContent( $encryptedPrivateKey, $this->pass );
-
-
- // Get keyfile
- $encryptedKeyfile = Encryption\Keymanager::getFileKey( $this->view, $this->userId, $filename );
-
- $decryptedKeyfile = Encryption\Crypt::keyDecrypt( $encryptedKeyfile, $decryptedPrivateKey );
-
-
- // Manually decrypt
- $manualDecrypt = Encryption\Crypt::symmetricBlockDecryptFileContent( $retreivedCryptedFile, $decryptedKeyfile );
-
- // Check that decrypted data matches
- $this->assertEquals( $this->dataShort, $manualDecrypt );
-
- }
-
- /**
- * @brief Test that data that is written by the crypto stream wrapper
- * @note Encrypted data is manually prepared and decrypted here to avoid dependency on success of stream_read
- * @note If this test fails with truncate content, check that enough array slices are being rejoined to form $e, as the crypt.php file may have gotten longer and broken the manual
- * reassembly of its data
- */
- function testSymmetricStreamEncryptLongFileContent() {
-
- // Generate a a random filename
- $filename = 'tmp-'.time();
-
- // Save long data as encrypted file using stream wrapper
- $cryptedFile = file_put_contents( 'crypt://' . $filename, $this->dataLong.$this->dataLong );
-
- // Test that data was successfully written
- $this->assertTrue( is_int( $cryptedFile ) );
-
- // Get file contents without using any wrapper to get it's actual contents on disk
- $retreivedCryptedFile = $this->view->file_get_contents( $this->userId . '/files/' . $filename );
-
-// echo "\n\n\$retreivedCryptedFile = $retreivedCryptedFile\n\n";
-
- // Check that the file was encrypted before being written to disk
- $this->assertNotEquals( $this->dataLong.$this->dataLong, $retreivedCryptedFile );
-
- // Manuallly split saved file into separate IVs and encrypted chunks
- $r = preg_split('/(00iv00.{16,18})/', $retreivedCryptedFile, NULL, PREG_SPLIT_DELIM_CAPTURE);
-
- //print_r($r);
-
- // Join IVs and their respective data chunks
- $e = array( $r[0].$r[1], $r[2].$r[3], $r[4].$r[5], $r[6].$r[7], $r[8].$r[9], $r[10].$r[11], $r[12].$r[13] );//.$r[11], $r[12].$r[13], $r[14] );
-
- //print_r($e);
-
-
- // Get private key
- $encryptedPrivateKey = Encryption\Keymanager::getPrivateKey( $this->view, $this->userId );
-
- $decryptedPrivateKey = Encryption\Crypt::symmetricDecryptFileContent( $encryptedPrivateKey, $this->pass );
-
-
- // Get keyfile
- $encryptedKeyfile = Encryption\Keymanager::getFileKey( $this->view, $this->userId, $filename );
-
- $decryptedKeyfile = Encryption\Crypt::keyDecrypt( $encryptedKeyfile, $decryptedPrivateKey );
-
-
- // Set var for reassembling decrypted content
- $decrypt = '';
-
- // Manually decrypt chunk
- foreach ($e as $e) {
-
-// echo "\n\$e = $e";
-
- $chunkDecrypt = Encryption\Crypt::symmetricDecryptFileContent( $e, $decryptedKeyfile );
-
- // Assemble decrypted chunks
- $decrypt .= $chunkDecrypt;
-
-// echo "\n\$chunkDecrypt = $chunkDecrypt";
-
- }
-
-// echo "\n\$decrypt = $decrypt";
-
- $this->assertEquals( $this->dataLong.$this->dataLong, $decrypt );
-
- // Teardown
-
- $this->view->unlink( $filename );
-
- Encryption\Keymanager::deleteFileKey( $filename );
-
- }
-
- /**
- * @brief Test that data that is read by the crypto stream wrapper
- */
- function testSymmetricStreamDecryptShortFileContent() {
-
- $filename = 'tmp-'.time();
-
- // Save long data as encrypted file using stream wrapper
- $cryptedFile = file_put_contents( 'crypt://' . $filename, $this->dataShort );
-
- // Test that data was successfully written
- $this->assertTrue( is_int( $cryptedFile ) );
-
-
- // Get file contents without using any wrapper to get it's actual contents on disk
- $retreivedCryptedFile = $this->view->file_get_contents( $this->userId . '/files/' . $filename );
-
- $decrypt = file_get_contents( 'crypt://' . $filename );
-
- $this->assertEquals( $this->dataShort, $decrypt );
-
- }
-
- function testSymmetricStreamDecryptLongFileContent() {
-
- $filename = 'tmp-'.time();
-
- // Save long data as encrypted file using stream wrapper
- $cryptedFile = file_put_contents( 'crypt://' . $filename, $this->dataLong );
-
- // Test that data was successfully written
- $this->assertTrue( is_int( $cryptedFile ) );
-
-
- // Get file contents without using any wrapper to get it's actual contents on disk
- $retreivedCryptedFile = $this->view->file_get_contents( $this->userId . '/files/' . $filename );
-
- $decrypt = file_get_contents( 'crypt://' . $filename );
-
- $this->assertEquals( $this->dataLong, $decrypt );
-
- }
-
- // Is this test still necessary?
-// function testSymmetricBlockStreamDecryptFileContent() {
-//
-// \OC_User::setUserId( 'admin' );
-//
-// // Disable encryption proxy to prevent unwanted en/decryption
-// \OC_FileProxy::$enabled = false;
-//
-// $cryptedFile = file_put_contents( 'crypt://' . '/blockEncrypt', $this->dataUrl );
-//
-// // Disable encryption proxy to prevent unwanted en/decryption
-// \OC_FileProxy::$enabled = false;
-//
-// echo "\n\n\$cryptedFile = " . $this->view->file_get_contents( '/blockEncrypt' );
-//
-// $retreivedCryptedFile = file_get_contents( 'crypt://' . '/blockEncrypt' );
-//
-// $this->assertEquals( $this->dataUrl, $retreivedCryptedFile );
-//
-// \OC_FileProxy::$enabled = false;
-//
-// }
-
- function testSymmetricEncryptFileContentKeyfile() {
-
- # TODO: search in keyfile for actual content as IV will ensure this test always passes
-
- $crypted = Encryption\Crypt::symmetricEncryptFileContentKeyfile( $this->dataUrl );
-
- $this->assertNotEquals( $this->dataUrl, $crypted['encrypted'] );
-
-
- $decrypt = Encryption\Crypt::symmetricDecryptFileContent( $crypted['encrypted'], $crypted['key'] );
-
- $this->assertEquals( $this->dataUrl, $decrypt );
-
- }
-
- function testIsEncryptedContent() {
-
- $this->assertFalse( Encryption\Crypt::isCatfile( $this->dataUrl ) );
-
- $this->assertFalse( Encryption\Crypt::isCatfile( $this->legacyEncryptedData ) );
-
- $keyfileContent = Encryption\Crypt::symmetricEncryptFileContent( $this->dataUrl, 'hat' );
-
- $this->assertTrue( Encryption\Crypt::isCatfile( $keyfileContent ) );
-
- }
-
- function testMultiKeyEncrypt() {
-
- # TODO: search in keyfile for actual content as IV will ensure this test always passes
-
- $pair1 = Encryption\Crypt::createKeypair();
-
- $this->assertEquals( 2, count( $pair1 ) );
-
- $this->assertTrue( strlen( $pair1['publicKey'] ) > 1 );
-
- $this->assertTrue( strlen( $pair1['privateKey'] ) > 1 );
-
-
- $crypted = Encryption\Crypt::multiKeyEncrypt( $this->dataUrl, array( $pair1['publicKey'] ) );
-
- $this->assertNotEquals( $this->dataUrl, $crypted['encrypted'] );
-
-
- $decrypt = Encryption\Crypt::multiKeyDecrypt( $crypted['encrypted'], $crypted['keys'][0], $pair1['privateKey'] );
-
- $this->assertEquals( $this->dataUrl, $decrypt );
-
- }
-
- function testKeyEncrypt() {
-
- // Generate keypair
- $pair1 = Encryption\Crypt::createKeypair();
-
- // Encrypt data
- $crypted = Encryption\Crypt::keyEncrypt( $this->dataUrl, $pair1['publicKey'] );
-
- $this->assertNotEquals( $this->dataUrl, $crypted );
-
- // Decrypt data
- $decrypt = Encryption\Crypt::keyDecrypt( $crypted, $pair1['privateKey'] );
-
- $this->assertEquals( $this->dataUrl, $decrypt );
-
- }
-
- // What is the point of this test? It doesn't use keyEncryptKeyfile()
- function testKeyEncryptKeyfile() {
-
- # TODO: Don't repeat encryption from previous tests, use PHPUnit test interdependency instead
-
- // Generate keypair
- $pair1 = Encryption\Crypt::createKeypair();
-
- // Encrypt plain data, generate keyfile & encrypted file
- $cryptedData = Encryption\Crypt::symmetricEncryptFileContentKeyfile( $this->dataUrl );
-
- // Encrypt keyfile
- $cryptedKey = Encryption\Crypt::keyEncrypt( $cryptedData['key'], $pair1['publicKey'] );
-
- // Decrypt keyfile
- $decryptKey = Encryption\Crypt::keyDecrypt( $cryptedKey, $pair1['privateKey'] );
-
- // Decrypt encrypted file
- $decryptData = Encryption\Crypt::symmetricDecryptFileContent( $cryptedData['encrypted'], $decryptKey );
-
- $this->assertEquals( $this->dataUrl, $decryptData );
-
- }
-
- /**
- * @brief test functionality of keyEncryptKeyfile() and
- * keyDecryptKeyfile()
- */
- function testKeyDecryptKeyfile() {
-
- $encrypted = Encryption\Crypt::keyEncryptKeyfile( $this->dataShort, $this->genPublicKey );
-
- $this->assertNotEquals( $encrypted['data'], $this->dataShort );
-
- $decrypted = Encryption\Crypt::keyDecryptKeyfile( $encrypted['data'], $encrypted['key'], $this->genPrivateKey );
-
- $this->assertEquals( $decrypted, $this->dataShort );
-
- }
-
-
- /**
- * @brief test encryption using legacy blowfish method
- */
- function testLegacyEncryptShort() {
-
- $crypted = Encryption\Crypt::legacyEncrypt( $this->dataShort, $this->pass );
-
- $this->assertNotEquals( $this->dataShort, $crypted );
-
- # TODO: search inencrypted text for actual content to ensure it
- # genuine transformation
-
- return $crypted;
-
- }
-
- /**
- * @brief test decryption using legacy blowfish method
- * @depends testLegacyEncryptShort
- */
- function testLegacyDecryptShort( $crypted ) {
-
- $decrypted = Encryption\Crypt::legacyDecrypt( $crypted, $this->pass );
-
- $this->assertEquals( $this->dataShort, $decrypted );
-
- }
-
- /**
- * @brief test encryption using legacy blowfish method
- */
- function testLegacyEncryptLong() {
-
- $crypted = Encryption\Crypt::legacyEncrypt( $this->dataLong, $this->pass );
-
- $this->assertNotEquals( $this->dataLong, $crypted );
-
- # TODO: search inencrypted text for actual content to ensure it
- # genuine transformation
-
- return $crypted;
-
- }
-
- /**
- * @brief test decryption using legacy blowfish method
- * @depends testLegacyEncryptLong
- */
- function testLegacyDecryptLong( $crypted ) {
-
- $decrypted = Encryption\Crypt::legacyDecrypt( $crypted, $this->pass );
-
- $this->assertEquals( $this->dataLong, $decrypted );
-
- }
-
- /**
- * @brief test generation of legacy encryption key
- * @depends testLegacyDecryptShort
- */
- function testLegacyCreateKey() {
-
- // Create encrypted key
- $encKey = Encryption\Crypt::legacyCreateKey( $this->pass );
-
- // Decrypt key
- $key = Encryption\Crypt::legacyDecrypt( $encKey, $this->pass );
-
- $this->assertTrue( is_numeric( $key ) );
-
- // Check that key is correct length
- $this->assertEquals( 20, strlen( $key ) );
-
- }
-
- /**
- * @brief test decryption using legacy blowfish method
- * @depends testLegacyEncryptLong
- */
- function testLegacyKeyRecryptKeyfileEncrypt( $crypted ) {
-
- $recrypted = Encryption\Crypt::LegacyKeyRecryptKeyfile( $crypted, $this->pass, $this->genPublicKey, $this->pass );
-
- $this->assertNotEquals( $this->dataLong, $recrypted['data'] );
-
- return $recrypted;
-
- # TODO: search inencrypted text for actual content to ensure it
- # genuine transformation
-
- }
-
-// function testEncryption(){
-//
-// $key=uniqid();
-// $file=OC::$SERVERROOT.'/3rdparty/MDB2.php';
-// $source=file_get_contents($file); //nice large text file
-// $encrypted=OC_Encryption\Crypt::encrypt($source,$key);
-// $decrypted=OC_Encryption\Crypt::decrypt($encrypted,$key);
-// $decrypted=rtrim($decrypted, "\0");
-// $this->assertNotEquals($encrypted,$source);
-// $this->assertEquals($decrypted,$source);
-//
-// $chunk=substr($source,0,8192);
-// $encrypted=OC_Encryption\Crypt::encrypt($chunk,$key);
-// $this->assertEquals(strlen($chunk),strlen($encrypted));
-// $decrypted=OC_Encryption\Crypt::decrypt($encrypted,$key);
-// $decrypted=rtrim($decrypted, "\0");
-// $this->assertEquals($decrypted,$chunk);
-//
-// $encrypted=OC_Encryption\Crypt::blockEncrypt($source,$key);
-// $decrypted=OC_Encryption\Crypt::blockDecrypt($encrypted,$key);
-// $this->assertNotEquals($encrypted,$source);
-// $this->assertEquals($decrypted,$source);
-//
-// $tmpFileEncrypted=OCP\Files::tmpFile();
-// OC_Encryption\Crypt::encryptfile($file,$tmpFileEncrypted,$key);
-// $encrypted=file_get_contents($tmpFileEncrypted);
-// $decrypted=OC_Encryption\Crypt::blockDecrypt($encrypted,$key);
-// $this->assertNotEquals($encrypted,$source);
-// $this->assertEquals($decrypted,$source);
-//
-// $tmpFileDecrypted=OCP\Files::tmpFile();
-// OC_Encryption\Crypt::decryptfile($tmpFileEncrypted,$tmpFileDecrypted,$key);
-// $decrypted=file_get_contents($tmpFileDecrypted);
-// $this->assertEquals($decrypted,$source);
-//
-// $file=OC::$SERVERROOT.'/core/img/weather-clear.png';
-// $source=file_get_contents($file); //binary file
-// $encrypted=OC_Encryption\Crypt::encrypt($source,$key);
-// $decrypted=OC_Encryption\Crypt::decrypt($encrypted,$key);
-// $decrypted=rtrim($decrypted, "\0");
-// $this->assertEquals($decrypted,$source);
-//
-// $encrypted=OC_Encryption\Crypt::blockEncrypt($source,$key);
-// $decrypted=OC_Encryption\Crypt::blockDecrypt($encrypted,$key);
-// $this->assertEquals($decrypted,$source);
-//
-// }
-//
-// function testBinary(){
-// $key=uniqid();
-//
-// $file=__DIR__.'/binary';
-// $source=file_get_contents($file); //binary file
-// $encrypted=OC_Encryption\Crypt::encrypt($source,$key);
-// $decrypted=OC_Encryption\Crypt::decrypt($encrypted,$key);
-//
-// $decrypted=rtrim($decrypted, "\0");
-// $this->assertEquals($decrypted,$source);
-//
-// $encrypted=OC_Encryption\Crypt::blockEncrypt($source,$key);
-// $decrypted=OC_Encryption\Crypt::blockDecrypt($encrypted,$key,strlen($source));
-// $this->assertEquals($decrypted,$source);
-// }
-
-}
diff --git a/apps/files_encryption/test/keymanager.php b/apps/files_encryption/test/keymanager.php
deleted file mode 100644
index bf453fe3163b8455136fc5b501beb451ba54c251..0000000000000000000000000000000000000000
--- a/apps/files_encryption/test/keymanager.php
+++ /dev/null
@@ -1,130 +0,0 @@
-
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-
-//require_once "PHPUnit/Framework/TestCase.php";
-require_once realpath( dirname(__FILE__).'/../../../lib/base.php' );
-require_once realpath( dirname(__FILE__).'/../lib/crypt.php' );
-require_once realpath( dirname(__FILE__).'/../lib/keymanager.php' );
-require_once realpath( dirname(__FILE__).'/../lib/proxy.php' );
-require_once realpath( dirname(__FILE__).'/../lib/stream.php' );
-require_once realpath( dirname(__FILE__).'/../lib/util.php' );
-require_once realpath( dirname(__FILE__).'/../appinfo/app.php' );
-
-use OCA\Encryption;
-
-// This has to go here because otherwise session errors arise, and the private
-// encryption key needs to be saved in the session
-\OC_User::login( 'admin', 'admin' );
-
-class Test_Keymanager extends \PHPUnit_Framework_TestCase {
-
- function setUp() {
-
- \OC_FileProxy::$enabled = false;
-
- // set content for encrypting / decrypting in tests
- $this->dataLong = file_get_contents( realpath( dirname(__FILE__).'/../lib/crypt.php' ) );
- $this->dataShort = 'hats';
- $this->dataUrl = realpath( dirname(__FILE__).'/../lib/crypt.php' );
- $this->legacyData = realpath( dirname(__FILE__).'/legacy-text.txt' );
- $this->legacyEncryptedData = realpath( dirname(__FILE__).'/legacy-encrypted-text.txt' );
- $this->randomKey = Encryption\Crypt::generateKey();
-
- $keypair = Encryption\Crypt::createKeypair();
- $this->genPublicKey = $keypair['publicKey'];
- $this->genPrivateKey = $keypair['privateKey'];
-
- $this->view = new \OC_FilesystemView( '/' );
-
- \OC_User::setUserId( 'admin' );
- $this->userId = 'admin';
- $this->pass = 'admin';
-
- \OC_Filesystem::init( '/' );
- \OC_Filesystem::mount( 'OC_Filestorage_Local', array('datadir' => \OC_User::getHome($this->userId)), '/' );
-
- }
-
- function tearDown(){
-
- \OC_FileProxy::$enabled = true;
-
- }
-
- function testGetPrivateKey() {
-
- $key = Encryption\Keymanager::getPrivateKey( $this->view, $this->userId );
-
- // Will this length vary? Perhaps we should use a range instead
- $this->assertEquals( 2296, strlen( $key ) );
-
- }
-
- function testGetPublicKey() {
-
- $key = Encryption\Keymanager::getPublicKey( $this->view, $this->userId );
-
- $this->assertEquals( 451, strlen( $key ) );
-
- $this->assertEquals( '-----BEGIN PUBLIC KEY-----', substr( $key, 0, 26 ) );
- }
-
- function testSetFileKey() {
-
- # NOTE: This cannot be tested until we are able to break out
- # of the FileSystemView data directory root
-
- $key = Encryption\Crypt::symmetricEncryptFileContentKeyfile( $this->randomKey, 'hat' );
-
- $path = 'unittest-'.time().'txt';
-
- //$view = new \OC_FilesystemView( '/' . $this->userId . '/files_encryption/keyfiles' );
-
- Encryption\Keymanager::setFileKey( $this->view, $path, $this->userId, $key['key'] );
-
- }
-
-// /**
-// * @depends testGetPrivateKey
-// */
-// function testGetPrivateKey_decrypt() {
-//
-// $key = Encryption\Keymanager::getPrivateKey( $this->view, $this->userId );
-//
-// # TODO: replace call to Crypt with a mock object?
-// $decrypted = Encryption\Crypt::symmetricDecryptFileContent( $key, $this->passphrase );
-//
-// $this->assertEquals( 1704, strlen( $decrypted ) );
-//
-// $this->assertEquals( '-----BEGIN PRIVATE KEY-----', substr( $decrypted, 0, 27 ) );
-//
-// }
-
- function testGetUserKeys() {
-
- $keys = Encryption\Keymanager::getUserKeys( $this->view, $this->userId );
-
- $this->assertEquals( 451, strlen( $keys['publicKey'] ) );
- $this->assertEquals( '-----BEGIN PUBLIC KEY-----', substr( $keys['publicKey'], 0, 26 ) );
- $this->assertEquals( 2296, strlen( $keys['privateKey'] ) );
-
- }
-
- function testGetPublicKeys() {
-
- # TODO: write me
-
- }
-
- function testGetFileKey() {
-
-// Encryption\Keymanager::getFileKey( $this->view, $this->userId, $this->filePath );
-
- }
-
-}
diff --git a/apps/files_encryption/test/legacy-encrypted-text.txt b/apps/files_encryption/test/legacy-encrypted-text.txt
deleted file mode 100644
index cb5bf50550d91842c8a0bd214edf9569daeadc48..0000000000000000000000000000000000000000
Binary files a/apps/files_encryption/test/legacy-encrypted-text.txt and /dev/null differ
diff --git a/apps/files_encryption/test/stream.php b/apps/files_encryption/test/stream.php
deleted file mode 100644
index ba82ac80eabb17dc16d01dce0d61d0f042c8a1b0..0000000000000000000000000000000000000000
--- a/apps/files_encryption/test/stream.php
+++ /dev/null
@@ -1,226 +0,0 @@
-//
-// * This file is licensed under the Affero General Public License version 3 or
-// * later.
-// * See the COPYING-README file.
-// */
-//
-// namespace OCA\Encryption;
-//
-// class Test_Stream extends \PHPUnit_Framework_TestCase {
-//
-// function setUp() {
-//
-// \OC_Filesystem::mount( 'OC_Filestorage_Local', array(), '/' );
-//
-// $this->empty = '';
-//
-// $this->stream = new Stream();
-//
-// $this->dataLong = file_get_contents( realpath( dirname(__FILE__).'/../lib/crypt.php' ) );
-// $this->dataShort = 'hats';
-//
-// $this->emptyTmpFilePath = \OCP\Files::tmpFile();
-//
-// $this->dataTmpFilePath = \OCP\Files::tmpFile();
-//
-// file_put_contents( $this->dataTmpFilePath, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est." );
-//
-// }
-//
-// function testStreamOpen() {
-//
-// $stream1 = new Stream();
-//
-// $handle1 = $stream1->stream_open( $this->emptyTmpFilePath, 'wb', array(), $this->empty );
-//
-// // Test that resource was returned successfully
-// $this->assertTrue( $handle1 );
-//
-// // Test that file has correct size
-// $this->assertEquals( 0, $stream1->size );
-//
-// // Test that path is correct
-// $this->assertEquals( $this->emptyTmpFilePath, $stream1->rawPath );
-//
-// $stream2 = new Stream();
-//
-// $handle2 = $stream2->stream_open( 'crypt://' . $this->emptyTmpFilePath, 'wb', array(), $this->empty );
-//
-// // Test that protocol identifier is removed from path
-// $this->assertEquals( $this->emptyTmpFilePath, $stream2->rawPath );
-//
-// // "Stat failed error" prevents this test from executing
-// // $stream3 = new Stream();
-// //
-// // $handle3 = $stream3->stream_open( $this->dataTmpFilePath, 'r', array(), $this->empty );
-// //
-// // $this->assertEquals( 0, $stream3->size );
-//
-// }
-//
-// function testStreamWrite() {
-//
-// $stream1 = new Stream();
-//
-// $handle1 = $stream1->stream_open( $this->emptyTmpFilePath, 'r+b', array(), $this->empty );
-//
-// # what about the keymanager? there is no key for the newly created temporary file!
-//
-// $stream1->stream_write( $this->dataShort );
-//
-// }
-//
-// // function getStream( $id, $mode, $size ) {
-// //
-// // if ( $id === '' ) {
-// //
-// // $id = uniqid();
-// // }
-// //
-// //
-// // if ( !isset( $this->tmpFiles[$id] ) ) {
-// //
-// // // If tempfile with given name does not already exist, create it
-// //
-// // $file = OCP\Files::tmpFile();
-// //
-// // $this->tmpFiles[$id] = $file;
-// //
-// // } else {
-// //
-// // $file = $this->tmpFiles[$id];
-// //
-// // }
-// //
-// // $stream = fopen( $file, $mode );
-// //
-// // Stream::$sourceStreams[$id] = array( 'path' => 'dummy' . $id, 'stream' => $stream, 'size' => $size );
-// //
-// // return fopen( 'crypt://streams/'.$id, $mode );
-// //
-// // }
-// //
-// // function testStream( ){
-// //
-// // $stream = $this->getStream( 'test1', 'w', strlen( 'foobar' ) );
-// //
-// // fwrite( $stream, 'foobar' );
-// //
-// // fclose( $stream );
-// //
-// //
-// // $stream = $this->getStream( 'test1', 'r', strlen( 'foobar' ) );
-// //
-// // $data = fread( $stream, 6 );
-// //
-// // fclose( $stream );
-// //
-// // $this->assertEquals( 'foobar', $data );
-// //
-// //
-// // $file = OC::$SERVERROOT.'/3rdparty/MDB2.php';
-// //
-// // $source = fopen( $file, 'r' );
-// //
-// // $target = $this->getStream( 'test2', 'w', 0 );
-// //
-// // OCP\Files::streamCopy( $source, $target );
-// //
-// // fclose( $target );
-// //
-// // fclose( $source );
-// //
-// //
-// // $stream = $this->getStream( 'test2', 'r', filesize( $file ) );
-// //
-// // $data = stream_get_contents( $stream );
-// //
-// // $original = file_get_contents( $file );
-// //
-// // $this->assertEquals( strlen( $original ), strlen( $data ) );
-// //
-// // $this->assertEquals( $original, $data );
-// //
-// // }
-//
-// }
-//
-// // class Test_CryptStream extends PHPUnit_Framework_TestCase {
-// // private $tmpFiles=array();
-// //
-// // function testStream(){
-// // $stream=$this->getStream('test1','w',strlen('foobar'));
-// // fwrite($stream,'foobar');
-// // fclose($stream);
-// //
-// // $stream=$this->getStream('test1','r',strlen('foobar'));
-// // $data=fread($stream,6);
-// // fclose($stream);
-// // $this->assertEquals('foobar',$data);
-// //
-// // $file=OC::$SERVERROOT.'/3rdparty/MDB2.php';
-// // $source=fopen($file,'r');
-// // $target=$this->getStream('test2','w',0);
-// // OCP\Files::streamCopy($source,$target);
-// // fclose($target);
-// // fclose($source);
-// //
-// // $stream=$this->getStream('test2','r',filesize($file));
-// // $data=stream_get_contents($stream);
-// // $original=file_get_contents($file);
-// // $this->assertEquals(strlen($original),strlen($data));
-// // $this->assertEquals($original,$data);
-// // }
-// //
-// // /**
-// // * get a cryptstream to a temporary file
-// // * @param string $id
-// // * @param string $mode
-// // * @param int size
-// // * @return resource
-// // */
-// // function getStream($id,$mode,$size){
-// // if($id===''){
-// // $id=uniqid();
-// // }
-// // if(!isset($this->tmpFiles[$id])){
-// // $file=OCP\Files::tmpFile();
-// // $this->tmpFiles[$id]=$file;
-// // }else{
-// // $file=$this->tmpFiles[$id];
-// // }
-// // $stream=fopen($file,$mode);
-// // OC_CryptStream::$sourceStreams[$id]=array('path'=>'dummy'.$id,'stream'=>$stream,'size'=>$size);
-// // return fopen('crypt://streams/'.$id,$mode);
-// // }
-// //
-// // function testBinary(){
-// // $file=__DIR__.'/binary';
-// // $source=file_get_contents($file);
-// //
-// // $stream=$this->getStream('test','w',strlen($source));
-// // fwrite($stream,$source);
-// // fclose($stream);
-// //
-// // $stream=$this->getStream('test','r',strlen($source));
-// // $data=stream_get_contents($stream);
-// // fclose($stream);
-// // $this->assertEquals(strlen($data),strlen($source));
-// // $this->assertEquals($source,$data);
-// //
-// // $file=__DIR__.'/zeros';
-// // $source=file_get_contents($file);
-// //
-// // $stream=$this->getStream('test2','w',strlen($source));
-// // fwrite($stream,$source);
-// // fclose($stream);
-// //
-// // $stream=$this->getStream('test2','r',strlen($source));
-// // $data=stream_get_contents($stream);
-// // fclose($stream);
-// // $this->assertEquals(strlen($data),strlen($source));
-// // $this->assertEquals($source,$data);
-// // }
-// // }
diff --git a/apps/files_encryption/test/util.php b/apps/files_encryption/test/util.php
deleted file mode 100755
index 1cdeff8008df2417e7e09c6cdbbb11b9e414c065..0000000000000000000000000000000000000000
--- a/apps/files_encryption/test/util.php
+++ /dev/null
@@ -1,225 +0,0 @@
-
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-
-//require_once "PHPUnit/Framework/TestCase.php";
-require_once realpath( dirname(__FILE__).'/../../../lib/base.php' );
-require_once realpath( dirname(__FILE__).'/../lib/crypt.php' );
-require_once realpath( dirname(__FILE__).'/../lib/keymanager.php' );
-require_once realpath( dirname(__FILE__).'/../lib/proxy.php' );
-require_once realpath( dirname(__FILE__).'/../lib/stream.php' );
-require_once realpath( dirname(__FILE__).'/../lib/util.php' );
-require_once realpath( dirname(__FILE__).'/../appinfo/app.php' );
-
-// Load mockery files
-require_once 'Mockery/Loader.php';
-require_once 'Hamcrest/Hamcrest.php';
-$loader = new \Mockery\Loader;
-$loader->register();
-
-use \Mockery as m;
-use OCA\Encryption;
-
-class Test_Enc_Util extends \PHPUnit_Framework_TestCase {
-
- function setUp() {
-
- \OC_Filesystem::mount( 'OC_Filestorage_Local', array(), '/' );
-
- // set content for encrypting / decrypting in tests
- $this->dataUrl = realpath( dirname(__FILE__).'/../lib/crypt.php' );
- $this->dataShort = 'hats';
- $this->dataLong = file_get_contents( realpath( dirname(__FILE__).'/../lib/crypt.php' ) );
- $this->legacyData = realpath( dirname(__FILE__).'/legacy-text.txt' );
- $this->legacyEncryptedData = realpath( dirname(__FILE__).'/legacy-encrypted-text.txt' );
-
- $this->userId = 'admin';
- $this->pass = 'admin';
-
- $keypair = Encryption\Crypt::createKeypair();
-
- $this->genPublicKey = $keypair['publicKey'];
- $this->genPrivateKey = $keypair['privateKey'];
-
- $this->publicKeyDir = '/' . 'public-keys';
- $this->encryptionDir = '/' . $this->userId . '/' . 'files_encryption';
- $this->keyfilesPath = $this->encryptionDir . '/' . 'keyfiles';
- $this->publicKeyPath = $this->publicKeyDir . '/' . $this->userId . '.public.key'; // e.g. data/public-keys/admin.public.key
- $this->privateKeyPath = $this->encryptionDir . '/' . $this->userId . '.private.key'; // e.g. data/admin/admin.private.key
-
- $this->view = new \OC_FilesystemView( '/' );
-
- $this->mockView = m::mock('OC_FilesystemView');
- $this->util = new Encryption\Util( $this->mockView, $this->userId );
-
- }
-
- function tearDown(){
-
- m::close();
-
- }
-
- /**
- * @brief test that paths set during User construction are correct
- */
- function testKeyPaths() {
-
- $mockView = m::mock('OC_FilesystemView');
-
- $util = new Encryption\Util( $mockView, $this->userId );
-
- $this->assertEquals( $this->publicKeyDir, $util->getPath( 'publicKeyDir' ) );
- $this->assertEquals( $this->encryptionDir, $util->getPath( 'encryptionDir' ) );
- $this->assertEquals( $this->keyfilesPath, $util->getPath( 'keyfilesPath' ) );
- $this->assertEquals( $this->publicKeyPath, $util->getPath( 'publicKeyPath' ) );
- $this->assertEquals( $this->privateKeyPath, $util->getPath( 'privateKeyPath' ) );
-
- }
-
- /**
- * @brief test setup of encryption directories when they don't yet exist
- */
- function testSetupServerSideNotSetup() {
-
- $mockView = m::mock('OC_FilesystemView');
-
- $mockView->shouldReceive( 'file_exists' )->times(5)->andReturn( false );
- $mockView->shouldReceive( 'mkdir' )->times(4)->andReturn( true );
- $mockView->shouldReceive( 'file_put_contents' )->withAnyArgs();
-
- $util = new Encryption\Util( $mockView, $this->userId );
-
- $this->assertEquals( true, $util->setupServerSide( $this->pass ) );
-
- }
-
- /**
- * @brief test setup of encryption directories when they already exist
- */
- function testSetupServerSideIsSetup() {
-
- $mockView = m::mock('OC_FilesystemView');
-
- $mockView->shouldReceive( 'file_exists' )->times(6)->andReturn( true );
- $mockView->shouldReceive( 'file_put_contents' )->withAnyArgs();
-
- $util = new Encryption\Util( $mockView, $this->userId );
-
- $this->assertEquals( true, $util->setupServerSide( $this->pass ) );
-
- }
-
- /**
- * @brief test checking whether account is ready for encryption, when it isn't ready
- */
- function testReadyNotReady() {
-
- $mockView = m::mock('OC_FilesystemView');
-
- $mockView->shouldReceive( 'file_exists' )->times(1)->andReturn( false );
-
- $util = new Encryption\Util( $mockView, $this->userId );
-
- $this->assertEquals( false, $util->ready() );
-
- # TODO: Add more tests here to check that if any of the dirs are
- # then false will be returned. Use strict ordering?
-
- }
-
- /**
- * @brief test checking whether account is ready for encryption, when it is ready
- */
- function testReadyIsReady() {
-
- $mockView = m::mock('OC_FilesystemView');
-
- $mockView->shouldReceive( 'file_exists' )->times(3)->andReturn( true );
-
- $util = new Encryption\Util( $mockView, $this->userId );
-
- $this->assertEquals( true, $util->ready() );
-
- # TODO: Add more tests here to check that if any of the dirs are
- # then false will be returned. Use strict ordering?
-
- }
-
- function testFindFiles() {
-
-// $this->view->chroot( "/data/{$this->userId}/files" );
-
- $util = new Encryption\Util( $this->view, $this->userId );
-
- $files = $util->findFiles( '/', 'encrypted' );
-
- var_dump( $files );
-
- # TODO: Add more tests here to check that if any of the dirs are
- # then false will be returned. Use strict ordering?
-
- }
-
-// /**
-// * @brief test decryption using legacy blowfish method
-// * @depends testLegacyEncryptLong
-// */
-// function testLegacyKeyRecryptKeyfileDecrypt( $recrypted ) {
-//
-// $decrypted = Encryption\Crypt::keyDecryptKeyfile( $recrypted['data'], $recrypted['key'], $this->genPrivateKey );
-//
-// $this->assertEquals( $this->dataLong, $decrypted );
-//
-// }
-
-// // Cannot use this test for now due to hidden dependencies in OC_FileCache
-// function testIsLegacyEncryptedContent() {
-//
-// $keyfileContent = OCA\Encryption\Crypt::symmetricEncryptFileContent( $this->legacyEncryptedData, 'hat' );
-//
-// $this->assertFalse( OCA\Encryption\Crypt::isLegacyEncryptedContent( $keyfileContent, '/files/admin/test.txt' ) );
-//
-// OC_FileCache::put( '/admin/files/legacy-encrypted-test.txt', $this->legacyEncryptedData );
-//
-// $this->assertTrue( OCA\Encryption\Crypt::isLegacyEncryptedContent( $this->legacyEncryptedData, '/files/admin/test.txt' ) );
-//
-// }
-
-// // Cannot use this test for now due to need for different root in OC_Filesystem_view class
-// function testGetLegacyKey() {
-//
-// $c = new \OCA\Encryption\Util( $view, false );
-//
-// $bool = $c->getLegacyKey( 'admin' );
-//
-// $this->assertTrue( $bool );
-//
-// $this->assertTrue( $c->legacyKey );
-//
-// $this->assertTrue( is_int( $c->legacyKey ) );
-//
-// $this->assertTrue( strlen( $c->legacyKey ) == 20 );
-//
-// }
-
-// // Cannot use this test for now due to need for different root in OC_Filesystem_view class
-// function testLegacyDecrypt() {
-//
-// $c = new OCA\Encryption\Util( $this->view, false );
-//
-// $bool = $c->getLegacyKey( 'admin' );
-//
-// $encrypted = $c->legacyEncrypt( $this->data, $c->legacyKey );
-//
-// $decrypted = $c->legacyDecrypt( $encrypted, $c->legacyKey );
-//
-// $this->assertEquals( $decrypted, $this->data );
-//
-// }
-
-}
\ No newline at end of file
diff --git a/apps/files_encryption/test/binary b/apps/files_encryption/tests/binary
similarity index 100%
rename from apps/files_encryption/test/binary
rename to apps/files_encryption/tests/binary
diff --git a/apps/files_encryption/tests/crypt.php b/apps/files_encryption/tests/crypt.php
new file mode 100755
index 0000000000000000000000000000000000000000..9b97df22d1685932a7afba2db881b3c78a745dd8
--- /dev/null
+++ b/apps/files_encryption/tests/crypt.php
@@ -0,0 +1,874 @@
+, and
+ * Robin Appelman
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+require_once realpath(dirname(__FILE__) . '/../3rdparty/Crypt_Blowfish/Blowfish.php');
+require_once realpath(dirname(__FILE__) . '/../../../lib/base.php');
+require_once realpath(dirname(__FILE__) . '/../lib/crypt.php');
+require_once realpath(dirname(__FILE__) . '/../lib/keymanager.php');
+require_once realpath(dirname(__FILE__) . '/../lib/proxy.php');
+require_once realpath(dirname(__FILE__) . '/../lib/stream.php');
+require_once realpath(dirname(__FILE__) . '/../lib/util.php');
+require_once realpath(dirname(__FILE__) . '/../lib/helper.php');
+require_once realpath(dirname(__FILE__) . '/../appinfo/app.php');
+require_once realpath(dirname(__FILE__) . '/util.php');
+
+use OCA\Encryption;
+
+/**
+ * Class Test_Encryption_Crypt
+ */
+class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
+
+ const TEST_ENCRYPTION_CRYPT_USER1 = "test-crypt-user1";
+
+ public $userId;
+ public $pass;
+ public $stateFilesTrashbin;
+ public $dataLong;
+ public $dataUrl;
+ public $dataShort;
+ /**
+ * @var OC_FilesystemView
+ */
+ public $view;
+ public $legacyEncryptedData;
+ public $genPrivateKey;
+ public $genPublicKey;
+
+ public static function setUpBeforeClass() {
+ // reset backend
+ \OC_User::clearBackends();
+ \OC_User::useBackend('database');
+
+ // Filesystem related hooks
+ \OCA\Encryption\Helper::registerFilesystemHooks();
+
+ // Filesystem related hooks
+ \OCA\Encryption\Helper::registerUserHooks();
+
+ // clear and register hooks
+ \OC_FileProxy::clearProxies();
+ \OC_FileProxy::register(new OCA\Encryption\Proxy());
+
+ // create test user
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Crypt::TEST_ENCRYPTION_CRYPT_USER1, true);
+ }
+
+ function setUp() {
+ // set user id
+ \OC_User::setUserId(\Test_Encryption_Crypt::TEST_ENCRYPTION_CRYPT_USER1);
+ $this->userId = \Test_Encryption_Crypt::TEST_ENCRYPTION_CRYPT_USER1;
+ $this->pass = \Test_Encryption_Crypt::TEST_ENCRYPTION_CRYPT_USER1;
+
+ // set content for encrypting / decrypting in tests
+ $this->dataLong = file_get_contents(realpath(dirname(__FILE__) . '/../lib/crypt.php'));
+ $this->dataShort = 'hats';
+ $this->dataUrl = realpath(dirname(__FILE__) . '/../lib/crypt.php');
+ $this->legacyData = realpath(dirname(__FILE__) . '/legacy-text.txt');
+ $this->legacyEncryptedData = realpath(dirname(__FILE__) . '/legacy-encrypted-text.txt');
+ $this->legacyEncryptedDataKey = realpath(dirname(__FILE__) . '/encryption.key');
+ $this->randomKey = Encryption\Crypt::generateKey();
+
+ $keypair = Encryption\Crypt::createKeypair();
+ $this->genPublicKey = $keypair['publicKey'];
+ $this->genPrivateKey = $keypair['privateKey'];
+
+ $this->view = new \OC_FilesystemView('/');
+
+ // remember files_trashbin state
+ $this->stateFilesTrashbin = OC_App::isEnabled('files_trashbin');
+
+ // we don't want to tests with app files_trashbin enabled
+ \OC_App::disable('files_trashbin');
+ }
+
+ function tearDown() {
+ // reset app files_trashbin
+ if ($this->stateFilesTrashbin) {
+ OC_App::enable('files_trashbin');
+ } else {
+ OC_App::disable('files_trashbin');
+ }
+ }
+
+ public static function tearDownAfterClass() {
+ // cleanup test user
+ \OC_User::deleteUser(\Test_Encryption_Crypt::TEST_ENCRYPTION_CRYPT_USER1);
+ }
+
+ /**
+ * @medium
+ */
+ function testGenerateKey() {
+
+ # TODO: use more accurate (larger) string length for test confirmation
+
+ $key = Encryption\Crypt::generateKey();
+
+ $this->assertTrue(strlen($key) > 16);
+
+ }
+
+ /**
+ * @large
+ * @return String
+ */
+ function testGenerateIv() {
+
+ $iv = Encryption\Crypt::generateIv();
+
+ $this->assertEquals(16, strlen($iv));
+
+ return $iv;
+
+ }
+
+ /**
+ * @large
+ * @depends testGenerateIv
+ */
+ function testConcatIv($iv) {
+
+ $catFile = Encryption\Crypt::concatIv($this->dataLong, $iv);
+
+ // Fetch encryption metadata from end of file
+ $meta = substr($catFile, -22);
+
+ $identifier = substr($meta, 0, 6);
+
+ // Fetch IV from end of file
+ $foundIv = substr($meta, 6);
+
+ $this->assertEquals('00iv00', $identifier);
+
+ $this->assertEquals($iv, $foundIv);
+
+ // Remove IV and IV identifier text to expose encrypted content
+ $data = substr($catFile, 0, -22);
+
+ $this->assertEquals($this->dataLong, $data);
+
+ return array(
+ 'iv' => $iv
+ ,
+ 'catfile' => $catFile
+ );
+
+ }
+
+ /**
+ * @medium
+ * @depends testConcatIv
+ */
+ function testSplitIv($testConcatIv) {
+
+ // Split catfile into components
+ $splitCatfile = Encryption\Crypt::splitIv($testConcatIv['catfile']);
+
+ // Check that original IV and split IV match
+ $this->assertEquals($testConcatIv['iv'], $splitCatfile['iv']);
+
+ // Check that original data and split data match
+ $this->assertEquals($this->dataLong, $splitCatfile['encrypted']);
+
+ }
+
+ /**
+ * @medium
+ * @return string padded
+ */
+ function testAddPadding() {
+
+ $padded = Encryption\Crypt::addPadding($this->dataLong);
+
+ $padding = substr($padded, -2);
+
+ $this->assertEquals('xx', $padding);
+
+ return $padded;
+
+ }
+
+ /**
+ * @medium
+ * @depends testAddPadding
+ */
+ function testRemovePadding($padded) {
+
+ $noPadding = Encryption\Crypt::RemovePadding($padded);
+
+ $this->assertEquals($this->dataLong, $noPadding);
+
+ }
+
+ /**
+ * @medium
+ */
+ function testEncrypt() {
+
+ $random = openssl_random_pseudo_bytes(13);
+
+ $iv = substr(base64_encode($random), 0, -4); // i.e. E5IG033j+mRNKrht
+
+ $crypted = Encryption\Crypt::encrypt($this->dataUrl, $iv, 'hat');
+
+ $this->assertNotEquals($this->dataUrl, $crypted);
+
+ }
+
+ /**
+ * @medium
+ */
+ function testDecrypt() {
+
+ $random = openssl_random_pseudo_bytes(13);
+
+ $iv = substr(base64_encode($random), 0, -4); // i.e. E5IG033j+mRNKrht
+
+ $crypted = Encryption\Crypt::encrypt($this->dataUrl, $iv, 'hat');
+
+ $decrypt = Encryption\Crypt::decrypt($crypted, $iv, 'hat');
+
+ $this->assertEquals($this->dataUrl, $decrypt);
+
+ }
+
+ function testDecryptPrivateKey() {
+
+ // test successful decrypt
+ $crypted = Encryption\Crypt::symmetricEncryptFileContent($this->genPrivateKey, 'hat');
+
+ $decrypted = Encryption\Crypt::decryptPrivateKey($crypted, 'hat');
+
+ $this->assertEquals($this->genPrivateKey, $decrypted);
+
+ //test private key decrypt with wrong password
+ $wrongPasswd = Encryption\Crypt::decryptPrivateKey($crypted, 'hat2');
+
+ $this->assertEquals(false, $wrongPasswd);
+
+ }
+
+
+ /**
+ * @medium
+ */
+ function testSymmetricEncryptFileContent() {
+
+ # TODO: search in keyfile for actual content as IV will ensure this test always passes
+
+ $crypted = Encryption\Crypt::symmetricEncryptFileContent($this->dataShort, 'hat');
+
+ $this->assertNotEquals($this->dataShort, $crypted);
+
+
+ $decrypt = Encryption\Crypt::symmetricDecryptFileContent($crypted, 'hat');
+
+ $this->assertEquals($this->dataShort, $decrypt);
+
+ }
+
+ /**
+ * @medium
+ */
+ function testSymmetricStreamEncryptShortFileContent() {
+
+ $filename = 'tmp-' . time() . '.test';
+
+ $cryptedFile = file_put_contents('crypt://' . $filename, $this->dataShort);
+
+ // Test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ // Get file contents without using any wrapper to get it's actual contents on disk
+ $retreivedCryptedFile = $this->view->file_get_contents($this->userId . '/files/' . $filename);
+
+ // Re-enable proxy - our work is done
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ // Check that the file was encrypted before being written to disk
+ $this->assertNotEquals($this->dataShort, $retreivedCryptedFile);
+
+ // Get the encrypted keyfile
+ $encKeyfile = Encryption\Keymanager::getFileKey($this->view, $this->userId, $filename);
+
+ // Attempt to fetch the user's shareKey
+ $shareKey = Encryption\Keymanager::getShareKey($this->view, $this->userId, $filename);
+
+ // get session
+ $session = new \OCA\Encryption\Session($this->view);
+
+ // get private key
+ $privateKey = $session->getPrivateKey($this->userId);
+
+ // Decrypt keyfile with shareKey
+ $plainKeyfile = Encryption\Crypt::multiKeyDecrypt($encKeyfile, $shareKey, $privateKey);
+
+ // Manually decrypt
+ $manualDecrypt = Encryption\Crypt::symmetricDecryptFileContent($retreivedCryptedFile, $plainKeyfile);
+
+ // Check that decrypted data matches
+ $this->assertEquals($this->dataShort, $manualDecrypt);
+
+ // Teardown
+ $this->view->unlink($this->userId . '/files/' . $filename);
+
+ Encryption\Keymanager::deleteFileKey($this->view, $this->userId, $filename);
+ }
+
+ /**
+ * @medium
+ * @brief Test that data that is written by the crypto stream wrapper
+ * @note Encrypted data is manually prepared and decrypted here to avoid dependency on success of stream_read
+ * @note If this test fails with truncate content, check that enough array slices are being rejoined to form $e, as the crypt.php file may have gotten longer and broken the manual
+ * reassembly of its data
+ */
+ function testSymmetricStreamEncryptLongFileContent() {
+
+ // Generate a a random filename
+ $filename = 'tmp-' . time() . '.test';
+
+ // Save long data as encrypted file using stream wrapper
+ $cryptedFile = file_put_contents('crypt://' . $filename, $this->dataLong . $this->dataLong);
+
+ // Test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ // Get file contents without using any wrapper to get it's actual contents on disk
+ $retreivedCryptedFile = $this->view->file_get_contents($this->userId . '/files/' . $filename);
+
+ // Re-enable proxy - our work is done
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+
+ // Check that the file was encrypted before being written to disk
+ $this->assertNotEquals($this->dataLong . $this->dataLong, $retreivedCryptedFile);
+
+ // Manuallly split saved file into separate IVs and encrypted chunks
+ $r = preg_split('/(00iv00.{16,18})/', $retreivedCryptedFile, NULL, PREG_SPLIT_DELIM_CAPTURE);
+
+ //print_r($r);
+
+ // Join IVs and their respective data chunks
+ $e = array(
+ $r[0] . $r[1],
+ $r[2] . $r[3],
+ $r[4] . $r[5],
+ $r[6] . $r[7],
+ $r[8] . $r[9],
+ $r[10] . $r[11]
+ ); //.$r[11], $r[12].$r[13], $r[14] );
+
+ //print_r($e);
+
+ // Get the encrypted keyfile
+ $encKeyfile = Encryption\Keymanager::getFileKey($this->view, $this->userId, $filename);
+
+ // Attempt to fetch the user's shareKey
+ $shareKey = Encryption\Keymanager::getShareKey($this->view, $this->userId, $filename);
+
+ // get session
+ $session = new \OCA\Encryption\Session($this->view);
+
+ // get private key
+ $privateKey = $session->getPrivateKey($this->userId);
+
+ // Decrypt keyfile with shareKey
+ $plainKeyfile = Encryption\Crypt::multiKeyDecrypt($encKeyfile, $shareKey, $privateKey);
+
+ // Set var for reassembling decrypted content
+ $decrypt = '';
+
+ // Manually decrypt chunk
+ foreach ($e as $chunk) {
+
+ $chunkDecrypt = Encryption\Crypt::symmetricDecryptFileContent($chunk, $plainKeyfile);
+
+ // Assemble decrypted chunks
+ $decrypt .= $chunkDecrypt;
+
+ }
+
+ $this->assertEquals($this->dataLong . $this->dataLong, $decrypt);
+
+ // Teardown
+
+ $this->view->unlink($this->userId . '/files/' . $filename);
+
+ Encryption\Keymanager::deleteFileKey($this->view, $this->userId, $filename);
+
+ }
+
+ /**
+ * @medium
+ * @brief Test that data that is read by the crypto stream wrapper
+ */
+ function testSymmetricStreamDecryptShortFileContent() {
+
+ $filename = 'tmp-' . time();
+
+ // Save long data as encrypted file using stream wrapper
+ $cryptedFile = file_put_contents('crypt://' . $filename, $this->dataShort);
+
+ // Test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ $this->assertTrue(Encryption\Crypt::isEncryptedMeta($filename));
+
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ // Get file decrypted contents
+ $decrypt = file_get_contents('crypt://' . $filename);
+
+ $this->assertEquals($this->dataShort, $decrypt);
+
+ // tear down
+ $this->view->unlink($this->userId . '/files/' . $filename);
+ }
+
+ /**
+ * @medium
+ */
+ function testSymmetricStreamDecryptLongFileContent() {
+
+ $filename = 'tmp-' . time();
+
+ // Save long data as encrypted file using stream wrapper
+ $cryptedFile = file_put_contents('crypt://' . $filename, $this->dataLong);
+
+ // Test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ // Get file decrypted contents
+ $decrypt = file_get_contents('crypt://' . $filename);
+
+ $this->assertEquals($this->dataLong, $decrypt);
+
+ // tear down
+ $this->view->unlink($this->userId . '/files/' . $filename);
+ }
+
+ /**
+ * @medium
+ */
+ function testSymmetricEncryptFileContentKeyfile() {
+
+ # TODO: search in keyfile for actual content as IV will ensure this test always passes
+
+ $crypted = Encryption\Crypt::symmetricEncryptFileContentKeyfile($this->dataUrl);
+
+ $this->assertNotEquals($this->dataUrl, $crypted['encrypted']);
+
+
+ $decrypt = Encryption\Crypt::symmetricDecryptFileContent($crypted['encrypted'], $crypted['key']);
+
+ $this->assertEquals($this->dataUrl, $decrypt);
+
+ }
+
+ /**
+ * @medium
+ */
+ function testIsEncryptedContent() {
+
+ $this->assertFalse(Encryption\Crypt::isCatfileContent($this->dataUrl));
+
+ $this->assertFalse(Encryption\Crypt::isCatfileContent($this->legacyEncryptedData));
+
+ $keyfileContent = Encryption\Crypt::symmetricEncryptFileContent($this->dataUrl, 'hat');
+
+ $this->assertTrue(Encryption\Crypt::isCatfileContent($keyfileContent));
+
+ }
+
+ /**
+ * @large
+ */
+ function testMultiKeyEncrypt() {
+
+ # TODO: search in keyfile for actual content as IV will ensure this test always passes
+
+ $pair1 = Encryption\Crypt::createKeypair();
+
+ $this->assertEquals(2, count($pair1));
+
+ $this->assertTrue(strlen($pair1['publicKey']) > 1);
+
+ $this->assertTrue(strlen($pair1['privateKey']) > 1);
+
+
+ $crypted = Encryption\Crypt::multiKeyEncrypt($this->dataShort, array($pair1['publicKey']));
+
+ $this->assertNotEquals($this->dataShort, $crypted['data']);
+
+
+ $decrypt = Encryption\Crypt::multiKeyDecrypt($crypted['data'], $crypted['keys'][0], $pair1['privateKey']);
+
+ $this->assertEquals($this->dataShort, $decrypt);
+
+ }
+
+ /**
+ * @medium
+ */
+ function testKeyEncrypt() {
+
+ // Generate keypair
+ $pair1 = Encryption\Crypt::createKeypair();
+
+ // Encrypt data
+ $crypted = Encryption\Crypt::keyEncrypt($this->dataUrl, $pair1['publicKey']);
+
+ $this->assertNotEquals($this->dataUrl, $crypted);
+
+ // Decrypt data
+ $decrypt = Encryption\Crypt::keyDecrypt($crypted, $pair1['privateKey']);
+
+ $this->assertEquals($this->dataUrl, $decrypt);
+
+ }
+
+ /**
+ * @medium
+ * @brief test encryption using legacy blowfish method
+ */
+ function testLegacyEncryptShort() {
+
+ $crypted = Encryption\Crypt::legacyEncrypt($this->dataShort, $this->pass);
+
+ $this->assertNotEquals($this->dataShort, $crypted);
+
+ # TODO: search inencrypted text for actual content to ensure it
+ # genuine transformation
+
+ return $crypted;
+
+ }
+
+ /**
+ * @medium
+ * @brief test decryption using legacy blowfish method
+ * @depends testLegacyEncryptShort
+ */
+ function testLegacyDecryptShort($crypted) {
+
+ $decrypted = Encryption\Crypt::legacyBlockDecrypt($crypted, $this->pass);
+
+ $this->assertEquals($this->dataShort, $decrypted);
+
+ }
+
+ /**
+ * @medium
+ * @brief test encryption using legacy blowfish method
+ */
+ function testLegacyEncryptLong() {
+
+ $crypted = Encryption\Crypt::legacyEncrypt($this->dataLong, $this->pass);
+
+ $this->assertNotEquals($this->dataLong, $crypted);
+
+ # TODO: search inencrypted text for actual content to ensure it
+ # genuine transformation
+
+ return $crypted;
+
+ }
+
+ /**
+ * @medium
+ * @brief test decryption using legacy blowfish method
+ * @depends testLegacyEncryptLong
+ */
+ function testLegacyDecryptLong($crypted) {
+
+ $decrypted = Encryption\Crypt::legacyBlockDecrypt($crypted, $this->pass);
+
+ $this->assertEquals($this->dataLong, $decrypted);
+
+ $this->assertFalse(Encryption\Crypt::getBlowfish(''));
+ }
+
+ /**
+ * @medium
+ * @brief test generation of legacy encryption key
+ * @depends testLegacyDecryptShort
+ */
+ function testLegacyCreateKey() {
+
+ // Create encrypted key
+ $encKey = Encryption\Crypt::legacyCreateKey($this->pass);
+
+ // Decrypt key
+ $key = Encryption\Crypt::legacyBlockDecrypt($encKey, $this->pass);
+
+ $this->assertTrue(is_numeric($key));
+
+ // Check that key is correct length
+ $this->assertEquals(20, strlen($key));
+
+ }
+
+ /**
+ * @medium
+ */
+ function testRenameFile() {
+
+ $filename = 'tmp-' . time();
+
+ // Save long data as encrypted file using stream wrapper
+ $cryptedFile = file_put_contents('crypt://' . $filename, $this->dataLong);
+
+ // Test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ // Get file decrypted contents
+ $decrypt = file_get_contents('crypt://' . $filename);
+
+ $this->assertEquals($this->dataLong, $decrypt);
+
+ $newFilename = 'tmp-new-' . time();
+ $view = new \OC\Files\View('/' . $this->userId . '/files');
+ $view->rename($filename, $newFilename);
+
+ // Get file decrypted contents
+ $newDecrypt = file_get_contents('crypt://' . $newFilename);
+
+ $this->assertEquals($this->dataLong, $newDecrypt);
+
+ // tear down
+ $view->unlink($newFilename);
+ }
+
+ /**
+ * @medium
+ */
+ function testMoveFileIntoFolder() {
+
+ $filename = 'tmp-' . time();
+
+ // Save long data as encrypted file using stream wrapper
+ $cryptedFile = file_put_contents('crypt://' . $filename, $this->dataLong);
+
+ // Test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ // Get file decrypted contents
+ $decrypt = file_get_contents('crypt://' . $filename);
+
+ $this->assertEquals($this->dataLong, $decrypt);
+
+ $newFolder = '/newfolder' . time();
+ $newFilename = 'tmp-new-' . time();
+ $view = new \OC\Files\View('/' . $this->userId . '/files');
+ $view->mkdir($newFolder);
+ $view->rename($filename, $newFolder . '/' . $newFilename);
+
+ // Get file decrypted contents
+ $newDecrypt = file_get_contents('crypt://' . $newFolder . '/' . $newFilename);
+
+ $this->assertEquals($this->dataLong, $newDecrypt);
+
+ // tear down
+ $view->unlink($newFolder);
+ }
+
+ /**
+ * @medium
+ */
+ function testMoveFolder() {
+
+ $view = new \OC\Files\View('/' . $this->userId . '/files');
+
+ $filename = '/tmp-' . time();
+ $folder = '/folder' . time();
+
+ $view->mkdir($folder);
+
+ // Save long data as encrypted file using stream wrapper
+ $cryptedFile = file_put_contents('crypt://' . $folder . $filename, $this->dataLong);
+
+ // Test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ // Get file decrypted contents
+ $decrypt = file_get_contents('crypt://' . $folder . $filename);
+
+ $this->assertEquals($this->dataLong, $decrypt);
+
+ $newFolder = '/newfolder/subfolder' . time();
+ $view->mkdir('/newfolder');
+
+ $view->rename($folder, $newFolder);
+
+ // Get file decrypted contents
+ $newDecrypt = file_get_contents('crypt://' . $newFolder . $filename);
+
+ $this->assertEquals($this->dataLong, $newDecrypt);
+
+ // tear down
+ $view->unlink($newFolder);
+ $view->unlink('/newfolder');
+ }
+
+ /**
+ * @medium
+ */
+ function testChangePassphrase() {
+ $filename = 'tmp-' . time();
+
+ // Save long data as encrypted file using stream wrapper
+ $cryptedFile = file_put_contents('crypt://' . $filename, $this->dataLong);
+
+ // Test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ // Get file decrypted contents
+ $decrypt = file_get_contents('crypt://' . $filename);
+
+ $this->assertEquals($this->dataLong, $decrypt);
+
+ // change password
+ \OC_User::setPassword($this->userId, 'test', null);
+
+ // relogin
+ $params['uid'] = $this->userId;
+ $params['password'] = 'test';
+ OCA\Encryption\Hooks::login($params);
+
+ // Get file decrypted contents
+ $newDecrypt = file_get_contents('crypt://' . $filename);
+
+ $this->assertEquals($this->dataLong, $newDecrypt);
+
+ // tear down
+ // change password back
+ \OC_User::setPassword($this->userId, $this->pass);
+ $view = new \OC\Files\View('/' . $this->userId . '/files');
+ $view->unlink($filename);
+ }
+
+ /**
+ * @medium
+ */
+ function testViewFilePutAndGetContents() {
+
+ $filename = '/tmp-' . time();
+ $view = new \OC\Files\View('/' . $this->userId . '/files');
+
+ // Save short data as encrypted file using stream wrapper
+ $cryptedFile = $view->file_put_contents($filename, $this->dataShort);
+
+ // Test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ // Get file decrypted contents
+ $decrypt = $view->file_get_contents($filename);
+
+ $this->assertEquals($this->dataShort, $decrypt);
+
+ // Save long data as encrypted file using stream wrapper
+ $cryptedFileLong = $view->file_put_contents($filename, $this->dataLong);
+
+ // Test that data was successfully written
+ $this->assertTrue(is_int($cryptedFileLong));
+
+ // Get file decrypted contents
+ $decryptLong = $view->file_get_contents($filename);
+
+ $this->assertEquals($this->dataLong, $decryptLong);
+
+ // tear down
+ $view->unlink($filename);
+ }
+
+ /**
+ * @large
+ */
+ function testTouchExistingFile() {
+ $filename = '/tmp-' . time();
+ $view = new \OC\Files\View('/' . $this->userId . '/files');
+
+ // Save short data as encrypted file using stream wrapper
+ $cryptedFile = $view->file_put_contents($filename, $this->dataShort);
+
+ // Test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ $view->touch($filename);
+
+ // Get file decrypted contents
+ $decrypt = $view->file_get_contents($filename);
+
+ $this->assertEquals($this->dataShort, $decrypt);
+
+ // tear down
+ $view->unlink($filename);
+ }
+
+ /**
+ * @medium
+ */
+ function testTouchFile() {
+ $filename = '/tmp-' . time();
+ $view = new \OC\Files\View('/' . $this->userId . '/files');
+
+ $view->touch($filename);
+
+ // Save short data as encrypted file using stream wrapper
+ $cryptedFile = $view->file_put_contents($filename, $this->dataShort);
+
+ // Test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ // Get file decrypted contents
+ $decrypt = $view->file_get_contents($filename);
+
+ $this->assertEquals($this->dataShort, $decrypt);
+
+ // tear down
+ $view->unlink($filename);
+ }
+
+ /**
+ * @medium
+ */
+ function testFopenFile() {
+ $filename = '/tmp-' . time();
+ $view = new \OC\Files\View('/' . $this->userId . '/files');
+
+ // Save short data as encrypted file using stream wrapper
+ $cryptedFile = $view->file_put_contents($filename, $this->dataShort);
+
+ // Test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ $handle = $view->fopen($filename, 'r');
+
+ // Get file decrypted contents
+ $decrypt = fgets($handle);
+
+ $this->assertEquals($this->dataShort, $decrypt);
+
+ // tear down
+ $view->unlink($filename);
+ }
+}
diff --git a/apps/files_encryption/tests/encryption.key b/apps/files_encryption/tests/encryption.key
new file mode 100644
index 0000000000000000000000000000000000000000..4ee962145c247ee03538aa70a2ff0da216c5c51c
Binary files /dev/null and b/apps/files_encryption/tests/encryption.key differ
diff --git a/apps/files_encryption/tests/keymanager.php b/apps/files_encryption/tests/keymanager.php
new file mode 100644
index 0000000000000000000000000000000000000000..19ba9a8117f1ce509304408afe2dd9c73c44e060
--- /dev/null
+++ b/apps/files_encryption/tests/keymanager.php
@@ -0,0 +1,263 @@
+
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+require_once realpath(dirname(__FILE__) . '/../../../lib/base.php');
+require_once realpath(dirname(__FILE__) . '/../lib/crypt.php');
+require_once realpath(dirname(__FILE__) . '/../lib/keymanager.php');
+require_once realpath(dirname(__FILE__) . '/../lib/proxy.php');
+require_once realpath(dirname(__FILE__) . '/../lib/stream.php');
+require_once realpath(dirname(__FILE__) . '/../lib/util.php');
+require_once realpath(dirname(__FILE__) . '/../lib/helper.php');
+require_once realpath(dirname(__FILE__) . '/../appinfo/app.php');
+
+use OCA\Encryption;
+
+/**
+ * Class Test_Encryption_Keymanager
+ */
+class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase {
+
+ public $userId;
+ public $pass;
+ public $stateFilesTrashbin;
+ /**
+ * @var OC_FilesystemView
+ */
+ public $view;
+ public $randomKey;
+ public $dataShort;
+
+ public static function setUpBeforeClass() {
+ // reset backend
+ \OC_User::clearBackends();
+ \OC_User::useBackend('database');
+
+ // Filesystem related hooks
+ \OCA\Encryption\Helper::registerFilesystemHooks();
+
+ // clear and register hooks
+ \OC_FileProxy::clearProxies();
+ \OC_FileProxy::register(new OCA\Encryption\Proxy());
+
+ // disable file proxy by default
+ \OC_FileProxy::$enabled = false;
+
+ // setup filesystem
+ \OC_Util::tearDownFS();
+ \OC_User::setUserId('');
+ \OC\Files\Filesystem::tearDown();
+ \OC_Util::setupFS('admin');
+ \OC_User::setUserId('admin');
+
+ // login admin
+ $params['uid'] = 'admin';
+ $params['password'] = 'admin';
+ OCA\Encryption\Hooks::login($params);
+ }
+
+ function setUp() {
+ // set content for encrypting / decrypting in tests
+ $this->dataLong = file_get_contents(realpath(dirname(__FILE__) . '/../lib/crypt.php'));
+ $this->dataShort = 'hats';
+ $this->dataUrl = realpath(dirname(__FILE__) . '/../lib/crypt.php');
+ $this->legacyData = realpath(dirname(__FILE__) . '/legacy-text.txt');
+ $this->legacyEncryptedData = realpath(dirname(__FILE__) . '/legacy-encrypted-text.txt');
+ $this->randomKey = Encryption\Crypt::generateKey();
+
+ $keypair = Encryption\Crypt::createKeypair();
+ $this->genPublicKey = $keypair['publicKey'];
+ $this->genPrivateKey = $keypair['privateKey'];
+
+ $this->view = new \OC_FilesystemView('/');
+
+ \OC_User::setUserId('admin');
+ $this->userId = 'admin';
+ $this->pass = 'admin';
+
+ $userHome = \OC_User::getHome($this->userId);
+ $this->dataDir = str_replace('/' . $this->userId, '', $userHome);
+
+ // remember files_trashbin state
+ $this->stateFilesTrashbin = OC_App::isEnabled('files_trashbin');
+
+ // we don't want to tests with app files_trashbin enabled
+ \OC_App::disable('files_trashbin');
+ }
+
+ function tearDown() {
+ // reset app files_trashbin
+ if ($this->stateFilesTrashbin) {
+ OC_App::enable('files_trashbin');
+ }
+ else {
+ OC_App::disable('files_trashbin');
+ }
+ }
+
+ public static function tearDownAfterClass() {
+ \OC_FileProxy::$enabled = true;
+ }
+
+ /**
+ * @medium
+ */
+ function testGetPrivateKey() {
+
+ $key = Encryption\Keymanager::getPrivateKey($this->view, $this->userId);
+
+ $privateKey = Encryption\Crypt::symmetricDecryptFileContent($key, $this->pass);
+
+ $res = openssl_pkey_get_private($privateKey);
+
+ $this->assertTrue(is_resource($res));
+
+ $sslInfo = openssl_pkey_get_details($res);
+
+ $this->assertArrayHasKey('key', $sslInfo);
+
+ }
+
+ /**
+ * @medium
+ */
+ function testGetPublicKey() {
+
+ $publiceKey = Encryption\Keymanager::getPublicKey($this->view, $this->userId);
+
+ $res = openssl_pkey_get_public($publiceKey);
+
+ $this->assertTrue(is_resource($res));
+
+ $sslInfo = openssl_pkey_get_details($res);
+
+ $this->assertArrayHasKey('key', $sslInfo);
+ }
+
+ /**
+ * @medium
+ */
+ function testSetFileKey() {
+
+ # NOTE: This cannot be tested until we are able to break out
+ # of the FileSystemView data directory root
+
+ $key = Encryption\Crypt::symmetricEncryptFileContentKeyfile($this->randomKey, 'hat');
+
+ $file = 'unittest-' . time() . '.txt';
+
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ $this->view->file_put_contents($this->userId . '/files/' . $file, $key['encrypted']);
+
+ // Re-enable proxy - our work is done
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ //$view = new \OC_FilesystemView( '/' . $this->userId . '/files_encryption/keyfiles' );
+ Encryption\Keymanager::setFileKey($this->view, $file, $this->userId, $key['key']);
+
+ // enable encryption proxy
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = true;
+
+ // cleanup
+ $this->view->unlink('/' . $this->userId . '/files/' . $file);
+
+ // change encryption proxy to previous state
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ }
+
+ /**
+ * @medium
+ */
+ function testGetUserKeys() {
+
+ $keys = Encryption\Keymanager::getUserKeys($this->view, $this->userId);
+
+ $resPublic = openssl_pkey_get_public($keys['publicKey']);
+
+ $this->assertTrue(is_resource($resPublic));
+
+ $sslInfoPublic = openssl_pkey_get_details($resPublic);
+
+ $this->assertArrayHasKey('key', $sslInfoPublic);
+
+ $privateKey = Encryption\Crypt::symmetricDecryptFileContent($keys['privateKey'], $this->pass);
+
+ $resPrivate = openssl_pkey_get_private($privateKey);
+
+ $this->assertTrue(is_resource($resPrivate));
+
+ $sslInfoPrivate = openssl_pkey_get_details($resPrivate);
+
+ $this->assertArrayHasKey('key', $sslInfoPrivate);
+ }
+
+ /**
+ * @medium
+ */
+ function testFixPartialFilePath() {
+
+ $partFilename = 'testfile.txt.part';
+ $filename = 'testfile.txt';
+
+ $this->assertTrue(Encryption\Keymanager::isPartialFilePath($partFilename));
+
+ $this->assertEquals('testfile.txt', Encryption\Keymanager::fixPartialFilePath($partFilename));
+
+ $this->assertFalse(Encryption\Keymanager::isPartialFilePath($filename));
+
+ $this->assertEquals('testfile.txt', Encryption\Keymanager::fixPartialFilePath($filename));
+ }
+
+ /**
+ * @medium
+ */
+ function testRecursiveDelShareKeys() {
+
+ // generate filename
+ $filename = '/tmp-' . time() . '.txt';
+
+ // create folder structure
+ $this->view->mkdir('/admin/files/folder1');
+ $this->view->mkdir('/admin/files/folder1/subfolder');
+ $this->view->mkdir('/admin/files/folder1/subfolder/subsubfolder');
+
+ // enable encryption proxy
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = true;
+
+ // save file with content
+ $cryptedFile = file_put_contents('crypt:///folder1/subfolder/subsubfolder/' . $filename, $this->dataShort);
+
+ // test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ // change encryption proxy to previous state
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ // recursive delete keys
+ Encryption\Keymanager::delShareKey($this->view, array('admin'), '/folder1/');
+
+ // check if share key not exists
+ $this->assertFalse($this->view->file_exists(
+ '/admin/files_encryption/share-keys/folder1/subfolder/subsubfolder/' . $filename . '.admin.shareKey'));
+
+ // enable encryption proxy
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = true;
+
+ // cleanup
+ $this->view->unlink('/admin/files/folder1');
+
+ // change encryption proxy to previous state
+ \OC_FileProxy::$enabled = $proxyStatus;
+ }
+}
diff --git a/apps/files_encryption/tests/legacy-encrypted-text.txt b/apps/files_encryption/tests/legacy-encrypted-text.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1f5087178cd1b4829abb3483f65322296d2235f0
--- /dev/null
+++ b/apps/files_encryption/tests/legacy-encrypted-text.txt
@@ -0,0 +1 @@
+5ǡiZgESlF=
\ No newline at end of file
diff --git a/apps/files_encryption/test/proxy.php b/apps/files_encryption/tests/proxy.php
similarity index 98%
rename from apps/files_encryption/test/proxy.php
rename to apps/files_encryption/tests/proxy.php
index 709730f7609ca2464a1faa2c410569b50fa80c19..5a2d851ff7c1019144c132875d94ddc28506ab07 100644
--- a/apps/files_encryption/test/proxy.php
+++ b/apps/files_encryption/tests/proxy.php
@@ -52,7 +52,7 @@
// $this->userId = 'admin';
// $this->pass = 'admin';
//
-// $this->session = new Encryption\Session();
+// $this->session = new Encryption\Session( $view ); // FIXME: Provide a $view object for use here
//
// $this->session->setPrivateKey(
// '-----BEGIN PRIVATE KEY-----
diff --git a/apps/files_encryption/tests/share.php b/apps/files_encryption/tests/share.php
new file mode 100755
index 0000000000000000000000000000000000000000..6b5303158595974fb815fa1435663535b7e8c1fb
--- /dev/null
+++ b/apps/files_encryption/tests/share.php
@@ -0,0 +1,920 @@
+
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library 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 along with this library. If not, see .
+ *
+ */
+
+require_once realpath(dirname(__FILE__) . '/../3rdparty/Crypt_Blowfish/Blowfish.php');
+require_once realpath(dirname(__FILE__) . '/../../../lib/base.php');
+require_once realpath(dirname(__FILE__) . '/../lib/crypt.php');
+require_once realpath(dirname(__FILE__) . '/../lib/keymanager.php');
+require_once realpath(dirname(__FILE__) . '/../lib/proxy.php');
+require_once realpath(dirname(__FILE__) . '/../lib/stream.php');
+require_once realpath(dirname(__FILE__) . '/../lib/util.php');
+require_once realpath(dirname(__FILE__) . '/../lib/helper.php');
+require_once realpath(dirname(__FILE__) . '/../appinfo/app.php');
+require_once realpath(dirname(__FILE__) . '/util.php');
+
+use OCA\Encryption;
+
+/**
+ * Class Test_Encryption_Share
+ */
+class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
+
+ const TEST_ENCRYPTION_SHARE_USER1 = "test-share-user1";
+ const TEST_ENCRYPTION_SHARE_USER2 = "test-share-user2";
+ const TEST_ENCRYPTION_SHARE_USER3 = "test-share-user3";
+ const TEST_ENCRYPTION_SHARE_USER4 = "test-share-user4";
+ const TEST_ENCRYPTION_SHARE_GROUP1 = "test-share-group1";
+
+ public $stateFilesTrashbin;
+ public $filename;
+ public $dataShort;
+ /**
+ * @var OC_FilesystemView
+ */
+ public $view;
+ public $folder1;
+ public $subfolder;
+ public $subsubfolder;
+
+ public static function setUpBeforeClass() {
+ // reset backend
+ \OC_User::clearBackends();
+ \OC_User::useBackend('database');
+
+ // enable resharing
+ \OC_Appconfig::setValue('core', 'shareapi_allow_resharing', 'yes');
+
+ // clear share hooks
+ \OC_Hook::clear('OCP\\Share');
+ \OC::registerShareHooks();
+ \OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup');
+
+ // Sharing related hooks
+ \OCA\Encryption\Helper::registerShareHooks();
+
+ // Filesystem related hooks
+ \OCA\Encryption\Helper::registerFilesystemHooks();
+
+ // clear and register hooks
+ \OC_FileProxy::clearProxies();
+ \OC_FileProxy::register(new OCA\Encryption\Proxy());
+
+ // create users
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1, true);
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, true);
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3, true);
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4, true);
+
+ // create group and assign users
+ \OC_Group::createGroup(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_GROUP1);
+ \OC_Group::addToGroup(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_GROUP1);
+ \OC_Group::addToGroup(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_GROUP1);
+ }
+
+ function setUp() {
+ $this->dataShort = 'hats';
+ $this->view = new \OC_FilesystemView('/');
+
+ $this->folder1 = '/folder1';
+ $this->subfolder = '/subfolder1';
+ $this->subsubfolder = '/subsubfolder1';
+
+ $this->filename = 'share-tmp.test';
+
+ // we don't want to tests with app files_trashbin enabled
+ \OC_App::disable('files_trashbin');
+
+ // remember files_trashbin state
+ $this->stateFilesTrashbin = OC_App::isEnabled('files_trashbin');
+ }
+
+ function tearDown() {
+ // reset app files_trashbin
+ if ($this->stateFilesTrashbin) {
+ OC_App::enable('files_trashbin');
+ } else {
+ OC_App::disable('files_trashbin');
+ }
+ }
+
+ public static function tearDownAfterClass() {
+ // clean group
+ \OC_Group::deleteGroup(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_GROUP1);
+
+ // cleanup users
+ \OC_User::deleteUser(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+ \OC_User::deleteUser(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2);
+ \OC_User::deleteUser(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3);
+ \OC_User::deleteUser(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4);
+ }
+
+ /**
+ * @medium
+ * @param bool $withTeardown
+ */
+ function testShareFile($withTeardown = true) {
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ // save file with content
+ $cryptedFile = file_put_contents('crypt://' . $this->filename, $this->dataShort);
+
+ // test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ // disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ // get the file info from previous created file
+ $fileInfo = $this->view->getFileInfo(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename);
+
+ // check if we have a valid file info
+ $this->assertTrue(is_array($fileInfo));
+
+ // check if the unencrypted file size is stored
+ $this->assertGreaterThan(0, $fileInfo['unencrypted_size']);
+
+ // re-enable the file proxy
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ // share the file
+ \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, OCP\PERMISSION_ALL);
+
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ // check if share key for user1 exists
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey'));
+
+ // login as user1
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2);
+
+ // get file contents
+ $retrievedCryptedFile = $this->view->file_get_contents(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/Shared/' . $this->filename);
+
+ // check if data is the same as we previously written
+ $this->assertEquals($this->dataShort, $retrievedCryptedFile);
+
+ // cleanup
+ if ($withTeardown) {
+
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ // unshare the file
+ \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2);
+
+ // check if share key not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey'));
+
+ // cleanup
+ $this->view->unlink(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename);
+
+ // check if share key not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '.shareKey'));
+ }
+ }
+
+ /**
+ * @medium
+ * @param bool $withTeardown
+ */
+ function testReShareFile($withTeardown = true) {
+ $this->testShareFile(false);
+
+ // login as user1
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2);
+
+ // get the file info
+ $fileInfo = $this->view->getFileInfo(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/Shared/' . $this->filename);
+
+ // share the file with user2
+ \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3, OCP\PERMISSION_ALL);
+
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ // check if share key for user2 exists
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.shareKey'));
+
+ // login as user2
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3);
+
+ // get file contents
+ $retrievedCryptedFile = $this->view->file_get_contents(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '/files/Shared/' . $this->filename);
+
+ // check if data is the same as previously written
+ $this->assertEquals($this->dataShort, $retrievedCryptedFile);
+
+ // cleanup
+ if ($withTeardown) {
+
+ // login as user1
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2);
+
+ // unshare the file with user2
+ \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3);
+
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ // check if share key not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.shareKey'));
+
+ // unshare the file with user1
+ \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2);
+
+ // check if share key not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey'));
+
+ // cleanup
+ $this->view->unlink(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename);
+
+ // check if share key not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '.shareKey'));
+ }
+ }
+
+ /**
+ * @medium
+ * @param bool $withTeardown
+ * @return array
+ */
+ function testShareFolder($withTeardown = true) {
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ // create folder structure
+ $this->view->mkdir('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files' . $this->folder1);
+ $this->view->mkdir(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files' . $this->folder1 . $this->subfolder);
+ $this->view->mkdir(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files' . $this->folder1 . $this->subfolder
+ . $this->subsubfolder);
+
+ // save file with content
+ $cryptedFile = file_put_contents('crypt://' . $this->folder1 . $this->subfolder . $this->subsubfolder . '/'
+ . $this->filename, $this->dataShort);
+
+ // test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ // disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ // get the file info from previous created folder
+ $fileInfo = $this->view->getFileInfo(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files' . $this->folder1);
+
+ // check if we have a valid file info
+ $this->assertTrue(is_array($fileInfo));
+
+ // re-enable the file proxy
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ // share the folder with user1
+ \OCP\Share::shareItem('folder', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, OCP\PERMISSION_ALL);
+
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ // check if share key for user1 exists
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys' . $this->folder1
+ . $this->subfolder . $this->subsubfolder . '/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey'));
+
+ // login as user1
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2);
+
+ // get file contents
+ $retrievedCryptedFile = $this->view->file_get_contents(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/Shared' . $this->folder1
+ . $this->subfolder . $this->subsubfolder . '/' . $this->filename);
+
+ // check if data is the same
+ $this->assertEquals($this->dataShort, $retrievedCryptedFile);
+
+ // cleanup
+ if ($withTeardown) {
+
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ // unshare the folder with user1
+ \OCP\Share::unshare('folder', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2);
+
+ // check if share key not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys'
+ . $this->folder1 . $this->subfolder . $this->subsubfolder . '/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey'));
+
+ // cleanup
+ $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files' . $this->folder1);
+
+ // check if share key not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys'
+ . $this->folder1 . $this->subfolder . $this->subsubfolder . '/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '.shareKey'));
+ }
+
+ return $fileInfo;
+ }
+
+ /**
+ * @medium
+ * @param bool $withTeardown
+ */
+ function testReShareFolder($withTeardown = true) {
+ $fileInfoFolder1 = $this->testShareFolder(false);
+
+ // login as user1
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2);
+
+ // disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ // get the file info from previous created folder
+ $fileInfoSubFolder = $this->view->getFileInfo(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/Shared' . $this->folder1
+ . $this->subfolder);
+
+ // check if we have a valid file info
+ $this->assertTrue(is_array($fileInfoSubFolder));
+
+ // re-enable the file proxy
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ // share the file with user2
+ \OCP\Share::shareItem('folder', $fileInfoSubFolder['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3, OCP\PERMISSION_ALL);
+
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ // check if share key for user2 exists
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys' . $this->folder1
+ . $this->subfolder . $this->subsubfolder . '/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.shareKey'));
+
+ // login as user2
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3);
+
+ // get file contents
+ $retrievedCryptedFile = $this->view->file_get_contents(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '/files/Shared' . $this->subfolder
+ . $this->subsubfolder . '/' . $this->filename);
+
+ // check if data is the same
+ $this->assertEquals($this->dataShort, $retrievedCryptedFile);
+
+ // get the file info
+ $fileInfo = $this->view->getFileInfo(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '/files/Shared' . $this->subfolder
+ . $this->subsubfolder . '/' . $this->filename);
+
+ // check if we have fileInfos
+ $this->assertTrue(is_array($fileInfo));
+
+ // share the file with user3
+ \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4, OCP\PERMISSION_ALL);
+
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ // check if share key for user3 exists
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys' . $this->folder1
+ . $this->subfolder . $this->subsubfolder . '/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4 . '.shareKey'));
+
+ // login as user3
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4);
+
+ // get file contents
+ $retrievedCryptedFile = $this->view->file_get_contents(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4 . '/files/Shared/' . $this->filename);
+
+ // check if data is the same
+ $this->assertEquals($this->dataShort, $retrievedCryptedFile);
+
+ // cleanup
+ if ($withTeardown) {
+
+ // login as user2
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3);
+
+ // unshare the file with user3
+ \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4);
+
+ // check if share key not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys'
+ . $this->folder1 . $this->subfolder . $this->subsubfolder . '/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4 . '.shareKey'));
+
+ // login as user1
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2);
+
+ // unshare the folder with user2
+ \OCP\Share::unshare('folder', $fileInfoSubFolder['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3);
+
+ // check if share key not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys'
+ . $this->folder1 . $this->subfolder . $this->subsubfolder . '/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.shareKey'));
+
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ // unshare the folder1 with user1
+ \OCP\Share::unshare('folder', $fileInfoFolder1['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2);
+
+ // check if share key not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys'
+ . $this->folder1 . $this->subfolder . $this->subsubfolder . '/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey'));
+
+ // cleanup
+ $this->view->unlink(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files' . $this->folder1 . $this->subfolder
+ . $this->subsubfolder . '/' . $this->filename);
+
+ // check if share key not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys'
+ . $this->folder1 . $this->subfolder . $this->subsubfolder . '/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '.shareKey'));
+ }
+ }
+
+ function testPublicShareFile() {
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ // save file with content
+ $cryptedFile = file_put_contents('crypt://' . $this->filename, $this->dataShort);
+
+ // test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ // disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ // get the file info from previous created file
+ $fileInfo = $this->view->getFileInfo(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename);
+
+ // check if we have a valid file info
+ $this->assertTrue(is_array($fileInfo));
+
+ // check if the unencrypted file size is stored
+ $this->assertGreaterThan(0, $fileInfo['unencrypted_size']);
+
+ // re-enable the file proxy
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ // share the file
+ \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, false, OCP\PERMISSION_ALL);
+
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ $publicShareKeyId = \OC_Appconfig::getValue('files_encryption', 'publicShareKeyId');
+
+ // check if share key for public exists
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . $publicShareKeyId . '.shareKey'));
+
+ // some hacking to simulate public link
+ $GLOBALS['app'] = 'files_sharing';
+ $GLOBALS['fileOwner'] = \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1;
+ \OC_User::setUserId(false);
+
+ // get file contents
+ $retrievedCryptedFile = file_get_contents('crypt://' . $this->filename);
+
+ // check if data is the same as we previously written
+ $this->assertEquals($this->dataShort, $retrievedCryptedFile);
+
+ // tear down
+
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ // unshare the file
+ \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, null);
+
+ // check if share key not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . $publicShareKeyId . '.shareKey'));
+
+ // cleanup
+ $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename);
+
+ // check if share key not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '.shareKey'));
+ }
+
+ /**
+ * @medium
+ */
+ function testShareFileWithGroup() {
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ // save file with content
+ $cryptedFile = file_put_contents('crypt://' . $this->filename, $this->dataShort);
+
+ // test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ // disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ // get the file info from previous created file
+ $fileInfo = $this->view->getFileInfo(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename);
+
+ // check if we have a valid file info
+ $this->assertTrue(is_array($fileInfo));
+
+ // check if the unencrypted file size is stored
+ $this->assertGreaterThan(0, $fileInfo['unencrypted_size']);
+
+ // re-enable the file proxy
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ // share the file
+ \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_GROUP1, OCP\PERMISSION_ALL);
+
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ // check if share key for user2 and user3 exists
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.shareKey'));
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4 . '.shareKey'));
+
+ // login as user1
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3);
+
+ // get file contents
+ $retrievedCryptedFile = $this->view->file_get_contents(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '/files/Shared/' . $this->filename);
+
+ // check if data is the same as we previously written
+ $this->assertEquals($this->dataShort, $retrievedCryptedFile);
+
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ // unshare the file
+ \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_GROUP1);
+
+ // check if share key not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.shareKey'));
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4 . '.shareKey'));
+
+ // cleanup
+ $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename);
+
+ // check if share key not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '.shareKey'));
+
+ }
+
+ /**
+ * @large
+ */
+ function testRecoveryFile() {
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ \OCA\Encryption\Helper::adminEnableRecovery(null, 'test123');
+ $recoveryKeyId = OC_Appconfig::getValue('files_encryption', 'recoveryKeyId');
+
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ // check if recovery password match
+ $this->assertTrue($util->checkRecoveryPassword('test123'));
+
+ // enable recovery for admin
+ $this->assertTrue($util->setRecoveryForUser(1));
+
+ // create folder structure
+ $this->view->mkdir('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files' . $this->folder1);
+ $this->view->mkdir(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files' . $this->folder1 . $this->subfolder);
+ $this->view->mkdir(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files' . $this->folder1 . $this->subfolder
+ . $this->subsubfolder);
+
+ // save file with content
+ $cryptedFile1 = file_put_contents('crypt://' . $this->filename, $this->dataShort);
+ $cryptedFile2 = file_put_contents('crypt://' . $this->folder1 . $this->subfolder . $this->subsubfolder . '/'
+ . $this->filename, $this->dataShort);
+
+ // test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile1));
+ $this->assertTrue(is_int($cryptedFile2));
+
+ // check if share key for admin and recovery exists
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '.shareKey'));
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . $recoveryKeyId . '.shareKey'));
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/' . $this->folder1
+ . $this->subfolder . $this->subsubfolder . '/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '.shareKey'));
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/' . $this->folder1
+ . $this->subfolder . $this->subsubfolder . '/'
+ . $this->filename . '.' . $recoveryKeyId . '.shareKey'));
+
+ // disable recovery for admin
+ $this->assertTrue($util->setRecoveryForUser(0));
+
+ // remove all recovery keys
+ $util->removeRecoveryKeys('/');
+
+ // check if share key for recovery not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . $recoveryKeyId . '.shareKey'));
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/' . $this->folder1
+ . $this->subfolder . $this->subsubfolder . '/'
+ . $this->filename . '.' . $recoveryKeyId . '.shareKey'));
+
+ // enable recovery for admin
+ $this->assertTrue($util->setRecoveryForUser(1));
+
+ // remove all recovery keys
+ $util->addRecoveryKeys('/');
+
+ // check if share key for admin and recovery exists
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . $recoveryKeyId . '.shareKey'));
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/' . $this->folder1
+ . $this->subfolder . $this->subsubfolder . '/'
+ . $this->filename . '.' . $recoveryKeyId . '.shareKey'));
+
+ // cleanup
+ $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename);
+ $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->folder1);
+
+ // check if share key for recovery not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . $recoveryKeyId . '.shareKey'));
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/' . $this->folder1
+ . $this->subfolder . $this->subsubfolder . '/'
+ . $this->filename . '.' . $recoveryKeyId . '.shareKey'));
+
+ $this->assertTrue(\OCA\Encryption\Helper::adminEnableRecovery(null, 'test123'));
+ $this->assertTrue(\OCA\Encryption\Helper::adminDisableRecovery('test123'));
+ $this->assertEquals(0, \OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled'));
+ }
+
+ /**
+ * @large
+ */
+ function testRecoveryForUser() {
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ \OCA\Encryption\Helper::adminEnableRecovery(null, 'test123');
+ $recoveryKeyId = OC_Appconfig::getValue('files_encryption', 'recoveryKeyId');
+
+ // login as user1
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2);
+
+ $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2);
+
+ // enable recovery for admin
+ $this->assertTrue($util->setRecoveryForUser(1));
+
+ // create folder structure
+ $this->view->mkdir('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files' . $this->folder1);
+ $this->view->mkdir(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files' . $this->folder1 . $this->subfolder);
+ $this->view->mkdir(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files' . $this->folder1 . $this->subfolder
+ . $this->subsubfolder);
+
+ // save file with content
+ $cryptedFile1 = file_put_contents('crypt://' . $this->filename, $this->dataShort);
+ $cryptedFile2 = file_put_contents('crypt://' . $this->folder1 . $this->subfolder . $this->subsubfolder . '/'
+ . $this->filename, $this->dataShort);
+
+ // test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile1));
+ $this->assertTrue(is_int($cryptedFile2));
+
+ // check if share key for user and recovery exists
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey'));
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . $recoveryKeyId . '.shareKey'));
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/' . $this->folder1
+ . $this->subfolder . $this->subsubfolder . '/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey'));
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/' . $this->folder1
+ . $this->subfolder . $this->subsubfolder . '/'
+ . $this->filename . '.' . $recoveryKeyId . '.shareKey'));
+
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ // change password
+ \OC_User::setPassword(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, 'test', 'test123');
+
+ // login as user1
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, false, 'test');
+
+ // get file contents
+ $retrievedCryptedFile1 = file_get_contents('crypt://' . $this->filename);
+ $retrievedCryptedFile2 = file_get_contents(
+ 'crypt://' . $this->folder1 . $this->subfolder . $this->subsubfolder . '/' . $this->filename);
+
+ // check if data is the same as we previously written
+ $this->assertEquals($this->dataShort, $retrievedCryptedFile1);
+ $this->assertEquals($this->dataShort, $retrievedCryptedFile2);
+
+ // cleanup
+ $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files' . $this->folder1);
+ $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files' . $this->filename);
+
+ // check if share key for user and recovery exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey'));
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . $recoveryKeyId . '.shareKey'));
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/' . $this->folder1
+ . $this->subfolder . $this->subsubfolder . '/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey'));
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/' . $this->folder1
+ . $this->subfolder . $this->subsubfolder . '/'
+ . $this->filename . '.' . $recoveryKeyId . '.shareKey'));
+
+ // enable recovery for admin
+ $this->assertTrue($util->setRecoveryForUser(0));
+
+ \OCA\Encryption\Helper::adminDisableRecovery('test123');
+ $this->assertEquals(0, \OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled'));
+ }
+
+ /**
+ * @medium
+ */
+ function testFailShareFile() {
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ // save file with content
+ $cryptedFile = file_put_contents('crypt://' . $this->filename, $this->dataShort);
+
+ // test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ // disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ // get the file info from previous created file
+ $fileInfo = $this->view->getFileInfo(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename);
+
+ // check if we have a valid file info
+ $this->assertTrue(is_array($fileInfo));
+
+ // check if the unencrypted file size is stored
+ $this->assertGreaterThan(0, $fileInfo['unencrypted_size']);
+
+ // break users public key
+ $this->view->rename('/public-keys/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.public.key',
+ '/public-keys/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.public.key_backup');
+
+ // re-enable the file proxy
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ // share the file
+ \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_GROUP1, OCP\PERMISSION_ALL);
+
+ // login as admin
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
+
+ // check if share key for user1 not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.shareKey'));
+
+ // disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ // break user1 public key
+ $this->view->rename(
+ '/public-keys/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.public.key_backup',
+ '/public-keys/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.public.key');
+
+ // remove share file
+ $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3
+ . '.shareKey');
+
+ // re-enable the file proxy
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ // unshare the file with user1
+ \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_GROUP1);
+
+ // check if share key not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/'
+ . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.shareKey'));
+
+ // cleanup
+ $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename);
+ }
+
+}
diff --git a/apps/files_encryption/tests/stream.php b/apps/files_encryption/tests/stream.php
new file mode 100644
index 0000000000000000000000000000000000000000..50ac41e4536ff6129f1806fc348c33b3845a1e14
--- /dev/null
+++ b/apps/files_encryption/tests/stream.php
@@ -0,0 +1,183 @@
+
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library 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 along with this library. If not, see .
+ *
+ */
+
+require_once realpath(dirname(__FILE__) . '/../../../lib/base.php');
+require_once realpath(dirname(__FILE__) . '/../lib/crypt.php');
+require_once realpath(dirname(__FILE__) . '/../lib/keymanager.php');
+require_once realpath(dirname(__FILE__) . '/../lib/proxy.php');
+require_once realpath(dirname(__FILE__) . '/../lib/stream.php');
+require_once realpath(dirname(__FILE__) . '/../lib/util.php');
+require_once realpath(dirname(__FILE__) . '/../appinfo/app.php');
+require_once realpath(dirname(__FILE__) . '/util.php');
+
+use OCA\Encryption;
+
+/**
+ * Class Test_Encryption_Stream
+ * @brief this class provide basic stream tests
+ */
+class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase {
+
+ const TEST_ENCRYPTION_STREAM_USER1 = "test-stream-user1";
+
+ public $userId;
+ public $pass;
+ /**
+ * @var \OC_FilesystemView
+ */
+ public $view;
+ public $dataShort;
+ public $stateFilesTrashbin;
+
+ public static function setUpBeforeClass() {
+ // reset backend
+ \OC_User::clearBackends();
+ \OC_User::useBackend('database');
+
+ // Filesystem related hooks
+ \OCA\Encryption\Helper::registerFilesystemHooks();
+
+ // clear and register hooks
+ \OC_FileProxy::clearProxies();
+ \OC_FileProxy::register(new OCA\Encryption\Proxy());
+
+ // create test user
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Stream::TEST_ENCRYPTION_STREAM_USER1, true);
+ }
+
+ function setUp() {
+ // set user id
+ \OC_User::setUserId(\Test_Encryption_Stream::TEST_ENCRYPTION_STREAM_USER1);
+ $this->userId = \Test_Encryption_Stream::TEST_ENCRYPTION_STREAM_USER1;
+ $this->pass = \Test_Encryption_Stream::TEST_ENCRYPTION_STREAM_USER1;
+
+ // init filesystem view
+ $this->view = new \OC_FilesystemView('/');
+
+ // init short data
+ $this->dataShort = 'hats';
+
+ // remember files_trashbin state
+ $this->stateFilesTrashbin = OC_App::isEnabled('files_trashbin');
+
+ // we don't want to tests with app files_trashbin enabled
+ \OC_App::disable('files_trashbin');
+ }
+
+ function tearDown() {
+ // reset app files_trashbin
+ if ($this->stateFilesTrashbin) {
+ OC_App::enable('files_trashbin');
+ }
+ else {
+ OC_App::disable('files_trashbin');
+ }
+ }
+
+ public static function tearDownAfterClass() {
+ // cleanup test user
+ \OC_User::deleteUser(\Test_Encryption_Stream::TEST_ENCRYPTION_STREAM_USER1);
+ }
+
+ function testStreamOptions() {
+ $filename = '/tmp-' . time();
+ $view = new \OC\Files\View('/' . $this->userId . '/files');
+
+ // Save short data as encrypted file using stream wrapper
+ $cryptedFile = $view->file_put_contents($filename, $this->dataShort);
+
+ // Test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ $handle = $view->fopen($filename, 'r');
+
+ // check if stream is at position zero
+ $this->assertEquals(0, ftell($handle));
+
+ // set stream options
+ $this->assertTrue(flock($handle, LOCK_SH));
+ $this->assertTrue(flock($handle, LOCK_UN));
+
+ // tear down
+ $view->unlink($filename);
+ }
+
+ function testStreamSetBlocking() {
+ $filename = '/tmp-' . time();
+ $view = new \OC\Files\View('/' . $this->userId . '/files');
+
+ // Save short data as encrypted file using stream wrapper
+ $cryptedFile = $view->file_put_contents($filename, $this->dataShort);
+
+ // Test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ $handle = $view->fopen($filename, 'r');
+
+ // set stream options
+ $this->assertTrue(stream_set_blocking($handle, 1));
+
+ // tear down
+ $view->unlink($filename);
+ }
+
+ /**
+ * @medium
+ */
+ function testStreamSetTimeout() {
+ $filename = '/tmp-' . time();
+ $view = new \OC\Files\View('/' . $this->userId . '/files');
+
+ // Save short data as encrypted file using stream wrapper
+ $cryptedFile = $view->file_put_contents($filename, $this->dataShort);
+
+ // Test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ $handle = $view->fopen($filename, 'r');
+
+ // set stream options
+ $this->assertFalse(stream_set_timeout($handle, 1));
+
+ // tear down
+ $view->unlink($filename);
+ }
+
+ function testStreamSetWriteBuffer() {
+ $filename = '/tmp-' . time();
+ $view = new \OC\Files\View('/' . $this->userId . '/files');
+
+ // Save short data as encrypted file using stream wrapper
+ $cryptedFile = $view->file_put_contents($filename, $this->dataShort);
+
+ // Test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ $handle = $view->fopen($filename, 'r');
+
+ // set stream options
+ $this->assertEquals(0, stream_set_write_buffer($handle, 1024));
+
+ // tear down
+ $view->unlink($filename);
+ }
+}
\ No newline at end of file
diff --git a/apps/files_encryption/tests/trashbin.php b/apps/files_encryption/tests/trashbin.php
new file mode 100755
index 0000000000000000000000000000000000000000..ade968fbece43f931b02a65c29ef30280de59ea7
--- /dev/null
+++ b/apps/files_encryption/tests/trashbin.php
@@ -0,0 +1,303 @@
+
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library 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 along with this library. If not, see .
+ *
+ */
+
+require_once realpath(dirname(__FILE__) . '/../../../lib/base.php');
+require_once realpath(dirname(__FILE__) . '/../lib/crypt.php');
+require_once realpath(dirname(__FILE__) . '/../lib/keymanager.php');
+require_once realpath(dirname(__FILE__) . '/../lib/proxy.php');
+require_once realpath(dirname(__FILE__) . '/../lib/stream.php');
+require_once realpath(dirname(__FILE__) . '/../lib/util.php');
+require_once realpath(dirname(__FILE__) . '/../appinfo/app.php');
+require_once realpath(dirname(__FILE__) . '/../../files_trashbin/appinfo/app.php');
+require_once realpath(dirname(__FILE__) . '/util.php');
+
+use OCA\Encryption;
+
+/**
+ * Class Test_Encryption_Trashbin
+ * @brief this class provide basic trashbin app tests
+ */
+class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase {
+
+ const TEST_ENCRYPTION_TRASHBIN_USER1 = "test-trashbin-user1";
+
+ public $userId;
+ public $pass;
+ /**
+ * @var \OC_FilesystemView
+ */
+ public $view;
+ public $dataShort;
+ public $stateFilesTrashbin;
+ public $folder1;
+ public $subfolder;
+ public $subsubfolder;
+
+ public static function setUpBeforeClass() {
+ // reset backend
+ \OC_User::clearBackends();
+ \OC_User::useBackend('database');
+
+ \OC_Hook::clear('OC_Filesystem');
+ \OC_Hook::clear('OC_User');
+
+ // trashbin hooks
+ \OCA\Files_Trashbin\Trashbin::registerHooks();
+
+ // Filesystem related hooks
+ \OCA\Encryption\Helper::registerFilesystemHooks();
+
+ // clear and register hooks
+ \OC_FileProxy::clearProxies();
+ \OC_FileProxy::register(new OCA\Encryption\Proxy());
+
+ // create test user
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1, true);
+ }
+
+ function setUp() {
+ // set user id
+ \OC_User::setUserId(\Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1);
+ $this->userId = \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1;
+ $this->pass = \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1;
+
+ // init filesystem view
+ $this->view = new \OC_FilesystemView('/');
+
+ // init short data
+ $this->dataShort = 'hats';
+
+ $this->folder1 = '/folder1';
+ $this->subfolder = '/subfolder1';
+ $this->subsubfolder = '/subsubfolder1';
+
+ // remember files_trashbin state
+ $this->stateFilesTrashbin = OC_App::isEnabled('files_trashbin');
+
+ // we want to tests with app files_trashbin enabled
+ \OC_App::enable('files_trashbin');
+ }
+
+ function tearDown() {
+ // reset app files_trashbin
+ if ($this->stateFilesTrashbin) {
+ OC_App::enable('files_trashbin');
+ }
+ else {
+ OC_App::disable('files_trashbin');
+ }
+ }
+
+ public static function tearDownAfterClass() {
+ // cleanup test user
+ \OC_User::deleteUser(\Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1);
+ }
+
+ /**
+ * @medium
+ * @brief test delete file
+ */
+ function testDeleteFile() {
+
+ // generate filename
+ $filename = 'tmp-' . time() . '.txt';
+
+ // save file with content
+ $cryptedFile = file_put_contents('crypt:///' . $filename, $this->dataShort);
+
+ // test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ // check if key for admin exists
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keyfiles/' . $filename
+ . '.key'));
+
+ // check if share key for admin exists
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/share-keys/'
+ . $filename . '.' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey'));
+
+ // delete file
+ \OC\FIles\Filesystem::unlink($filename);
+
+ // check if file not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename));
+
+ // check if key for admin not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keyfiles/' . $filename
+ . '.key'));
+
+ // check if share key for admin not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/share-keys/'
+ . $filename . '.' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey'));
+
+ // get files
+ $trashFiles = $this->view->getDirectoryContent(
+ '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/files/');
+
+ $trashFileSuffix = null;
+ // find created file with timestamp
+ foreach ($trashFiles as $file) {
+ if (strncmp($file['path'], $filename, strlen($filename))) {
+ $path_parts = pathinfo($file['name']);
+ $trashFileSuffix = $path_parts['extension'];
+ }
+ }
+
+ // check if we found the file we created
+ $this->assertNotNull($trashFileSuffix);
+
+ // check if key for admin not exists
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keyfiles/' . $filename
+ . '.key.' . $trashFileSuffix));
+
+ // check if share key for admin not exists
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/share-keys/' . $filename
+ . '.' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey.' . $trashFileSuffix));
+
+ // return filename for next test
+ return $filename . '.' . $trashFileSuffix;
+ }
+
+ /**
+ * @medium
+ * @brief test restore file
+ *
+ * @depends testDeleteFile
+ */
+ function testRestoreFile($filename) {
+
+ // prepare file information
+ $path_parts = pathinfo($filename);
+ $trashFileSuffix = $path_parts['extension'];
+ $timestamp = str_replace('d', '', $trashFileSuffix);
+ $fileNameWithoutSuffix = str_replace('.' . $trashFileSuffix, '', $filename);
+
+ // restore file
+ $this->assertTrue(\OCA\Files_Trashbin\Trashbin::restore($filename, $fileNameWithoutSuffix, $timestamp));
+
+ // check if file exists
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $fileNameWithoutSuffix));
+
+ // check if key for admin exists
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keyfiles/'
+ . $fileNameWithoutSuffix . '.key'));
+
+ // check if share key for admin exists
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/share-keys/'
+ . $fileNameWithoutSuffix . '.' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey'));
+ }
+
+ /**
+ * @medium
+ * @brief test delete file forever
+ */
+ function testPermanentDeleteFile() {
+
+ // generate filename
+ $filename = 'tmp-' . time() . '.txt';
+
+ // save file with content
+ $cryptedFile = file_put_contents('crypt:///' . $filename, $this->dataShort);
+
+ // test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile));
+
+ // check if key for admin exists
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keyfiles/' . $filename
+ . '.key'));
+
+ // check if share key for admin exists
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/share-keys/'
+ . $filename . '.' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey'));
+
+ // delete file
+ \OC\FIles\Filesystem::unlink($filename);
+
+ // check if file not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename));
+
+ // check if key for admin not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keyfiles/' . $filename
+ . '.key'));
+
+ // check if share key for admin not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/share-keys/'
+ . $filename . '.' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey'));
+
+ // find created file with timestamp
+ $query = \OC_DB::prepare('SELECT `timestamp`,`type` FROM `*PREFIX*files_trash`'
+ . ' WHERE `id`=?');
+ $result = $query->execute(array($filename))->fetchRow();
+
+ $this->assertTrue(is_array($result));
+
+ // build suffix
+ $trashFileSuffix = 'd' . $result['timestamp'];
+
+ // check if key for admin exists
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keyfiles/' . $filename
+ . '.key.' . $trashFileSuffix));
+
+ // check if share key for admin exists
+ $this->assertTrue($this->view->file_exists(
+ '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/share-keys/' . $filename
+ . '.' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey.' . $trashFileSuffix));
+
+ // get timestamp from file
+ $timestamp = str_replace('d', '', $trashFileSuffix);
+
+ // delete file forever
+ $this->assertGreaterThan(0, \OCA\Files_Trashbin\Trashbin::delete($filename, $timestamp));
+
+ // check if key for admin not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/files/' . $filename . '.'
+ . $trashFileSuffix));
+
+ // check if key for admin not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keyfiles/' . $filename
+ . '.key.' . $trashFileSuffix));
+
+ // check if share key for admin not exists
+ $this->assertFalse($this->view->file_exists(
+ '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/share-keys/' . $filename
+ . '.' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey.' . $trashFileSuffix));
+ }
+
+}
\ No newline at end of file
diff --git a/apps/files_encryption/tests/util.php b/apps/files_encryption/tests/util.php
new file mode 100755
index 0000000000000000000000000000000000000000..368b7b3dc3f2a02427fc07d42db7955104463ee4
--- /dev/null
+++ b/apps/files_encryption/tests/util.php
@@ -0,0 +1,356 @@
+
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+require_once realpath(dirname(__FILE__) . '/../../../lib/base.php');
+require_once realpath(dirname(__FILE__) . '/../lib/crypt.php');
+require_once realpath(dirname(__FILE__) . '/../lib/keymanager.php');
+require_once realpath(dirname(__FILE__) . '/../lib/proxy.php');
+require_once realpath(dirname(__FILE__) . '/../lib/stream.php');
+require_once realpath(dirname(__FILE__) . '/../lib/util.php');
+require_once realpath(dirname(__FILE__) . '/../appinfo/app.php');
+
+use OCA\Encryption;
+
+/**
+ * Class Test_Encryption_Util
+ */
+class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
+
+ const TEST_ENCRYPTION_UTIL_USER1 = "test-util-user1";
+ const TEST_ENCRYPTION_UTIL_LEGACY_USER = "test-legacy-user";
+
+ public $userId;
+ public $encryptionDir;
+ public $publicKeyDir;
+ public $pass;
+ /**
+ * @var OC_FilesystemView
+ */
+ public $view;
+ public $keyfilesPath;
+ public $publicKeyPath;
+ public $privateKeyPath;
+ /**
+ * @var \OCA\Encryption\Util
+ */
+ public $util;
+ public $dataShort;
+ public $legacyEncryptedData;
+ public $legacyEncryptedDataKey;
+ public $legacyKey;
+ public $stateFilesTrashbin;
+
+ public static function setUpBeforeClass() {
+ // reset backend
+ \OC_User::clearBackends();
+ \OC_User::useBackend('database');
+
+ // Filesystem related hooks
+ \OCA\Encryption\Helper::registerFilesystemHooks();
+
+ // clear and register hooks
+ \OC_FileProxy::clearProxies();
+ \OC_FileProxy::register(new OCA\Encryption\Proxy());
+
+ // create test user
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1, true);
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER, true);
+ }
+
+
+ function setUp() {
+ \OC_User::setUserId(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1);
+ $this->userId = \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1;
+ $this->pass = \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1;
+
+ // set content for encrypting / decrypting in tests
+ $this->dataUrl = realpath(dirname(__FILE__) . '/../lib/crypt.php');
+ $this->dataShort = 'hats';
+ $this->dataLong = file_get_contents(realpath(dirname(__FILE__) . '/../lib/crypt.php'));
+ $this->legacyData = realpath(dirname(__FILE__) . '/legacy-text.txt');
+ $this->legacyEncryptedData = realpath(dirname(__FILE__) . '/legacy-encrypted-text.txt');
+ $this->legacyEncryptedDataKey = realpath(dirname(__FILE__) . '/encryption.key');
+ $this->legacyKey = "30943623843030686906\0\0\0\0";
+
+ $keypair = Encryption\Crypt::createKeypair();
+
+ $this->genPublicKey = $keypair['publicKey'];
+ $this->genPrivateKey = $keypair['privateKey'];
+
+ $this->publicKeyDir = '/' . 'public-keys';
+ $this->encryptionDir = '/' . $this->userId . '/' . 'files_encryption';
+ $this->keyfilesPath = $this->encryptionDir . '/' . 'keyfiles';
+ $this->publicKeyPath =
+ $this->publicKeyDir . '/' . $this->userId . '.public.key'; // e.g. data/public-keys/admin.public.key
+ $this->privateKeyPath =
+ $this->encryptionDir . '/' . $this->userId . '.private.key'; // e.g. data/admin/admin.private.key
+
+ $this->view = new \OC_FilesystemView('/');
+
+ $this->util = new Encryption\Util($this->view, $this->userId);
+
+ // remember files_trashbin state
+ $this->stateFilesTrashbin = OC_App::isEnabled('files_trashbin');
+
+ // we don't want to tests with app files_trashbin enabled
+ \OC_App::disable('files_trashbin');
+ }
+
+ function tearDown() {
+ // reset app files_trashbin
+ if ($this->stateFilesTrashbin) {
+ OC_App::enable('files_trashbin');
+ }
+ else {
+ OC_App::disable('files_trashbin');
+ }
+ }
+
+ public static function tearDownAfterClass() {
+ // cleanup test user
+ \OC_User::deleteUser(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1);
+ \OC_User::deleteUser(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER);
+ }
+
+ /**
+ * @medium
+ * @brief test that paths set during User construction are correct
+ */
+ function testKeyPaths() {
+ $util = new Encryption\Util($this->view, $this->userId);
+
+ $this->assertEquals($this->publicKeyDir, $util->getPath('publicKeyDir'));
+ $this->assertEquals($this->encryptionDir, $util->getPath('encryptionDir'));
+ $this->assertEquals($this->keyfilesPath, $util->getPath('keyfilesPath'));
+ $this->assertEquals($this->publicKeyPath, $util->getPath('publicKeyPath'));
+ $this->assertEquals($this->privateKeyPath, $util->getPath('privateKeyPath'));
+
+ }
+
+ /**
+ * @medium
+ * @brief test setup of encryption directories
+ */
+ function testSetupServerSide() {
+ $this->assertEquals(true, $this->util->setupServerSide($this->pass));
+ }
+
+ /**
+ * @medium
+ * @brief test checking whether account is ready for encryption,
+ */
+ function testUserIsReady() {
+ $this->assertEquals(true, $this->util->ready());
+ }
+
+ /**
+ * @brief test checking whether account is not ready for encryption,
+ */
+// function testUserIsNotReady() {
+// $this->view->unlink($this->publicKeyDir);
+//
+// $params['uid'] = $this->userId;
+// $params['password'] = $this->pass;
+// $this->assertFalse(OCA\Encryption\Hooks::login($params));
+//
+// $this->view->unlink($this->privateKeyPath);
+// }
+
+ /**
+ * @medium
+ * @brief test checking whether account is not ready for encryption,
+ */
+ function testIsLegacyUser() {
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER);
+
+ $userView = new \OC_FilesystemView('/' . \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER);
+
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ $encryptionKeyContent = file_get_contents($this->legacyEncryptedDataKey);
+ $userView->file_put_contents('/encryption.key', $encryptionKeyContent);
+
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ $params['uid'] = \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER;
+ $params['password'] = \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER;
+
+ $this->setMigrationStatus(0, \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER);
+
+ $this->assertTrue(OCA\Encryption\Hooks::login($params));
+
+ $this->assertEquals($this->legacyKey, \OC::$session->get('legacyKey'));
+ }
+
+ /**
+ * @medium
+ */
+ function testRecoveryEnabledForUser() {
+
+ $util = new Encryption\Util($this->view, $this->userId);
+
+ // Record the value so we can return it to it's original state later
+ $enabled = $util->recoveryEnabledForUser();
+
+ $this->assertTrue($util->setRecoveryForUser(1));
+
+ $this->assertEquals(1, $util->recoveryEnabledForUser());
+
+ $this->assertTrue($util->setRecoveryForUser(0));
+
+ $this->assertEquals(0, $util->recoveryEnabledForUser());
+
+ // Return the setting to it's previous state
+ $this->assertTrue($util->setRecoveryForUser($enabled));
+
+ }
+
+ /**
+ * @medium
+ */
+ function testGetUidAndFilename() {
+
+ \OC_User::setUserId(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1);
+
+ $filename = '/tmp-' . time() . '.test';
+
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ $this->view->file_put_contents($this->userId . '/files/' . $filename, $this->dataShort);
+
+ // Re-enable proxy - our work is done
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ $util = new Encryption\Util($this->view, $this->userId);
+
+ list($fileOwnerUid, $file) = $util->getUidAndFilename($filename);
+
+ $this->assertEquals(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1, $fileOwnerUid);
+
+ $this->assertEquals($file, $filename);
+
+ $this->view->unlink($this->userId . '/files/' . $filename);
+ }
+
+ /**
+ * @medium
+ */
+ function testIsSharedPath() {
+ $sharedPath = '/user1/files/Shared/test';
+ $path = '/user1/files/test';
+
+ $this->assertTrue($this->util->isSharedPath($sharedPath));
+
+ $this->assertFalse($this->util->isSharedPath($path));
+ }
+
+ /**
+ * @large
+ */
+ function testEncryptLegacyFiles() {
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER);
+
+ $userView = new \OC_FilesystemView('/' . \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER);
+ $view = new \OC_FilesystemView('/' . \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER . '/files');
+
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ $encryptionKeyContent = file_get_contents($this->legacyEncryptedDataKey);
+ $userView->file_put_contents('/encryption.key', $encryptionKeyContent);
+
+ $legacyEncryptedData = file_get_contents($this->legacyEncryptedData);
+ $view->mkdir('/test/');
+ $view->mkdir('/test/subtest/');
+ $view->file_put_contents('/test/subtest/legacy-encrypted-text.txt', $legacyEncryptedData);
+
+ $fileInfo = $view->getFileInfo('/test/subtest/legacy-encrypted-text.txt');
+ $fileInfo['encrypted'] = true;
+ $view->putFileInfo('/test/subtest/legacy-encrypted-text.txt', $fileInfo);
+
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ $params['uid'] = \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER;
+ $params['password'] = \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER;
+
+ $util = new Encryption\Util($this->view, \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER);
+ $this->setMigrationStatus(0, \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER);
+
+ $this->assertTrue(OCA\Encryption\Hooks::login($params));
+
+ $this->assertEquals($this->legacyKey, \OC::$session->get('legacyKey'));
+
+ $files = $util->findEncFiles('/' . \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER . '/files/');
+
+ $this->assertTrue(is_array($files));
+
+ $found = false;
+ foreach ($files['encrypted'] as $encryptedFile) {
+ if ($encryptedFile['name'] === 'legacy-encrypted-text.txt') {
+ $found = true;
+ break;
+ }
+ }
+
+ $this->assertTrue($found);
+ }
+
+ /**
+ * @param $user
+ * @param bool $create
+ * @param bool $password
+ */
+ public static function loginHelper($user, $create = false, $password = false) {
+ if ($create) {
+ \OC_User::createUser($user, $user);
+ }
+
+ if ($password === false) {
+ $password = $user;
+ }
+
+ \OC_Util::tearDownFS();
+ \OC_User::setUserId('');
+ \OC\Files\Filesystem::tearDown();
+ \OC_Util::setupFS($user);
+ \OC_User::setUserId($user);
+
+ $params['uid'] = $user;
+ $params['password'] = $password;
+ OCA\Encryption\Hooks::login($params);
+ }
+
+ /**
+ * helper function to set migration status to the right value
+ * to be able to test the migration path
+ *
+ * @param $status needed migration status for test
+ * @param $user for which user the status should be set
+ * @return boolean
+ */
+ private function setMigrationStatus($status, $user) {
+ $sql = 'UPDATE `*PREFIX*encryption` SET `migration_status` = ? WHERE `uid` = ?';
+ $args = array(
+ $status,
+ $user
+ );
+
+ $query = \OCP\DB::prepare($sql);
+ if ($query->execute($args)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+}
diff --git a/apps/files_encryption/tests/webdav.php b/apps/files_encryption/tests/webdav.php
new file mode 100755
index 0000000000000000000000000000000000000000..1d406789f0c1ac0b1bc1aa9a4d5c8d9efbae4d5e
--- /dev/null
+++ b/apps/files_encryption/tests/webdav.php
@@ -0,0 +1,262 @@
+
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library 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 along with this library. If not, see .
+ *
+ */
+
+require_once realpath(dirname(__FILE__) . '/../../../lib/base.php');
+require_once realpath(dirname(__FILE__) . '/../lib/crypt.php');
+require_once realpath(dirname(__FILE__) . '/../lib/keymanager.php');
+require_once realpath(dirname(__FILE__) . '/../lib/proxy.php');
+require_once realpath(dirname(__FILE__) . '/../lib/stream.php');
+require_once realpath(dirname(__FILE__) . '/../lib/util.php');
+require_once realpath(dirname(__FILE__) . '/../appinfo/app.php');
+require_once realpath(dirname(__FILE__) . '/util.php');
+
+use OCA\Encryption;
+
+/**
+ * Class Test_Encryption_Webdav
+ * @brief this class provide basic webdav tests for PUT,GET and DELETE
+ */
+class Test_Encryption_Webdav extends \PHPUnit_Framework_TestCase {
+
+ const TEST_ENCRYPTION_WEBDAV_USER1 = "test-webdav-user1";
+
+ public $userId;
+ public $pass;
+ /**
+ * @var \OC_FilesystemView
+ */
+ public $view;
+ public $dataShort;
+ public $stateFilesTrashbin;
+
+ public static function setUpBeforeClass() {
+ // reset backend
+ \OC_User::clearBackends();
+ \OC_User::useBackend('database');
+
+ // Filesystem related hooks
+ \OCA\Encryption\Helper::registerFilesystemHooks();
+
+ // Filesystem related hooks
+ \OCA\Encryption\Helper::registerUserHooks();
+
+ // clear and register hooks
+ \OC_FileProxy::clearProxies();
+ \OC_FileProxy::register(new OCA\Encryption\Proxy());
+
+ // create test user
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Webdav::TEST_ENCRYPTION_WEBDAV_USER1, true);
+ }
+
+ function setUp() {
+ // reset backend
+ \OC_User::useBackend('database');
+
+ // set user id
+ \OC_User::setUserId(\Test_Encryption_Webdav::TEST_ENCRYPTION_WEBDAV_USER1);
+ $this->userId = \Test_Encryption_Webdav::TEST_ENCRYPTION_WEBDAV_USER1;
+ $this->pass = \Test_Encryption_Webdav::TEST_ENCRYPTION_WEBDAV_USER1;
+
+ // init filesystem view
+ $this->view = new \OC_FilesystemView('/');
+
+ // init short data
+ $this->dataShort = 'hats';
+
+ // remember files_trashbin state
+ $this->stateFilesTrashbin = OC_App::isEnabled('files_trashbin');
+
+ // we don't want to tests with app files_trashbin enabled
+ \OC_App::disable('files_trashbin');
+
+ // create test user
+ \Test_Encryption_Util::loginHelper(\Test_Encryption_Webdav::TEST_ENCRYPTION_WEBDAV_USER1);
+ }
+
+ function tearDown() {
+ // reset app files_trashbin
+ if ($this->stateFilesTrashbin) {
+ OC_App::enable('files_trashbin');
+ }
+ else {
+ OC_App::disable('files_trashbin');
+ }
+ }
+
+ public static function tearDownAfterClass() {
+ // cleanup test user
+ \OC_User::deleteUser(\Test_Encryption_Webdav::TEST_ENCRYPTION_WEBDAV_USER1);
+ }
+
+ /**
+ * @brief test webdav put random file
+ */
+ function testWebdavPUT() {
+
+ // generate filename
+ $filename = '/tmp-' . time() . '.txt';
+
+ // set server vars
+ $_SERVER['REQUEST_METHOD'] = 'OPTIONS';
+
+ $_SERVER['REQUEST_METHOD'] = 'PUT';
+ $_SERVER['REQUEST_URI'] = '/remote.php/webdav' . $filename;
+ $_SERVER['HTTP_AUTHORIZATION'] = 'Basic dGVzdC13ZWJkYXYtdXNlcjE6dGVzdC13ZWJkYXYtdXNlcjE=';
+ $_SERVER['CONTENT_TYPE'] = 'application/octet-stream';
+ $_SERVER['PATH_INFO'] = '/webdav' . $filename;
+ $_SERVER['CONTENT_LENGTH'] = strlen($this->dataShort);
+
+ // handle webdav request
+ $this->handleWebdavRequest($this->dataShort);
+
+ // check if file was created
+ $this->assertTrue($this->view->file_exists('/' . $this->userId . '/files' . $filename));
+
+ // check if key-file was created
+ $this->assertTrue($this->view->file_exists(
+ '/' . $this->userId . '/files_encryption/keyfiles/' . $filename . '.key'));
+
+ // check if shareKey-file was created
+ $this->assertTrue($this->view->file_exists(
+ '/' . $this->userId . '/files_encryption/share-keys/' . $filename . '.' . $this->userId . '.shareKey'));
+
+ // disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ // get encrypted file content
+ $encryptedContent = $this->view->file_get_contents('/' . $this->userId . '/files' . $filename);
+
+ // restore proxy state
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ // check if encrypted content is valid
+ $this->assertTrue(Encryption\Crypt::isCatfileContent($encryptedContent));
+
+ // get decrypted file contents
+ $decrypt = file_get_contents('crypt://' . $filename);
+
+ // check if file content match with the written content
+ $this->assertEquals($this->dataShort, $decrypt);
+
+ // return filename for next test
+ return $filename;
+ }
+
+ /**
+ * @brief test webdav get random file
+ *
+ * @depends testWebdavPUT
+ */
+ function testWebdavGET($filename) {
+
+ // set server vars
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+ $_SERVER['REQUEST_URI'] = '/remote.php/webdav' . $filename;
+ $_SERVER['HTTP_AUTHORIZATION'] = 'Basic dGVzdC13ZWJkYXYtdXNlcjE6dGVzdC13ZWJkYXYtdXNlcjE=';
+ $_SERVER['PATH_INFO'] = '/webdav' . $filename;
+
+ // handle webdav request
+ $content = $this->handleWebdavRequest();
+
+ // check if file content match with the written content
+ $this->assertEquals($this->dataShort, $content);
+
+ // return filename for next test
+ return $filename;
+ }
+
+ /**
+ * @brief test webdav delete random file
+ * @depends testWebdavGET
+ */
+ function testWebdavDELETE($filename) {
+ // set server vars
+ $_SERVER['REQUEST_METHOD'] = 'DELETE';
+ $_SERVER['REQUEST_URI'] = '/remote.php/webdav' . $filename;
+ $_SERVER['HTTP_AUTHORIZATION'] = 'Basic dGVzdC13ZWJkYXYtdXNlcjE6dGVzdC13ZWJkYXYtdXNlcjE=';
+ $_SERVER['PATH_INFO'] = '/webdav' . $filename;
+
+ // handle webdav request
+ $content = $this->handleWebdavRequest();
+
+ // check if file was removed
+ $this->assertFalse($this->view->file_exists('/' . $this->userId . '/files' . $filename));
+
+ // check if key-file was removed
+ $this->assertFalse($this->view->file_exists(
+ '/' . $this->userId . '/files_encryption/keyfiles' . $filename . '.key'));
+
+ // check if shareKey-file was removed
+ $this->assertFalse($this->view->file_exists(
+ '/' . $this->userId . '/files_encryption/share-keys' . $filename . '.' . $this->userId . '.shareKey'));
+ }
+
+ /**
+ * @brief handle webdav request
+ *
+ * @param bool $body
+ *
+ * @note this init procedure is copied from /apps/files/appinfo/remote.php
+ */
+ function handleWebdavRequest($body = false) {
+ // Backends
+ $authBackend = new OC_Connector_Sabre_Auth();
+ $lockBackend = new OC_Connector_Sabre_Locks();
+ $requestBackend = new OC_Connector_Sabre_Request();
+
+ // Create ownCloud Dir
+ $publicDir = new OC_Connector_Sabre_Directory('');
+
+ // Fire up server
+ $server = new Sabre_DAV_Server($publicDir);
+ $server->httpRequest = $requestBackend;
+ $server->setBaseUri('/remote.php/webdav/');
+
+ // Load plugins
+ $server->addPlugin(new Sabre_DAV_Auth_Plugin($authBackend, 'ownCloud'));
+ $server->addPlugin(new Sabre_DAV_Locks_Plugin($lockBackend));
+ $server->addPlugin(new Sabre_DAV_Browser_Plugin(false)); // Show something in the Browser, but no upload
+ $server->addPlugin(new OC_Connector_Sabre_QuotaPlugin());
+ $server->addPlugin(new OC_Connector_Sabre_MaintenancePlugin());
+
+ // And off we go!
+ if ($body) {
+ $server->httpRequest->setBody($body);
+ }
+
+ // turn on output buffering
+ ob_start();
+
+ // handle request
+ $server->exec();
+
+ // file content is written in the output buffer
+ $content = ob_get_contents();
+
+ // flush the output buffer and turn off output buffering
+ ob_end_clean();
+
+ // return captured content
+ return $content;
+ }
+}
\ No newline at end of file
diff --git a/apps/files_encryption/test/zeros b/apps/files_encryption/tests/zeros
similarity index 100%
rename from apps/files_encryption/test/zeros
rename to apps/files_encryption/tests/zeros
diff --git a/apps/files_external/ajax/addRootCertificate.php b/apps/files_external/ajax/addRootCertificate.php
index 43fd6752c4ae9a1d85d4a95f4362a47cd05fcb1f..ae349bfcd3a5b18499a59b4c20d2f1e96a7c048f 100644
--- a/apps/files_external/ajax/addRootCertificate.php
+++ b/apps/files_external/ajax/addRootCertificate.php
@@ -29,8 +29,12 @@ if ($isValid == false) {
// add the certificate if it could be verified
if ( $isValid ) {
+ // disable proxy to prevent multiple fopen calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
$view->file_put_contents($filename, $data);
OC_Mount_Config::createCertificateBundle();
+ \OC_FileProxy::$enabled = $proxyStatus;
} else {
OCP\Util::writeLog('files_external',
'Couldn\'t import SSL root certificate ('.$filename.'), allowed formats: PEM and DER',
diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js
index ac408786ff6271a4088530927f2141075e495e63..3e605c59a9304491635a5b24094e3af9e6774b39 100644
--- a/apps/files_external/js/settings.js
+++ b/apps/files_external/js/settings.js
@@ -88,7 +88,7 @@ OC.MountConfig={
url: OC.filePath('files_external', 'ajax', 'removeMountPoint.php'),
data: {
mountPoint: mountPoint,
- class: backendClass,
+ 'class': backendClass,
classOptions: classOptions,
mountType: mountType,
applicable: applicable,
@@ -103,7 +103,7 @@ OC.MountConfig={
url: OC.filePath('files_external', 'ajax', 'removeMountPoint.php'),
data: {
mountPoint: mountPoint,
- class: backendClass,
+ 'class': backendClass,
classOptions: classOptions,
mountType: mountType,
applicable: applicable,
@@ -247,15 +247,18 @@ $(document).ready(function() {
OC.MountConfig.saveStorage($(this).parent().parent());
});
+ $('#sslCertificate').on('click', 'td.remove>img', function() {
+ var $tr = $(this).parent().parent();
+ var row = this.parentNode.parentNode;
+ $.post(OC.filePath('files_external', 'ajax', 'removeRootCertificate.php'), {cert: row.id});
+ $tr.remove();
+ return true;
+ });
+
$('#externalStorage').on('click', 'td.remove>img', function() {
var tr = $(this).parent().parent();
var mountPoint = $(tr).find('.mountPoint input').val();
- if ( ! mountPoint) {
- var row=this.parentNode.parentNode;
- $.post(OC.filePath('files_external', 'ajax', 'removeRootCertificate.php'), { cert: row.id });
- $(tr).remove();
- return true;
- }
+
if ($('#externalStorage').data('admin') === true) {
var isPersonal = false;
var multiselect = $(tr).find('.chzn-select').val();
diff --git a/apps/files_external/l10n/ar.php b/apps/files_external/l10n/ar.php
index 06837d5085c7e2607125d7b42be994a6812ae0cc..a53bfe48bc3c82a5f1659537d337390903c6f136 100644
--- a/apps/files_external/l10n/ar.php
+++ b/apps/files_external/l10n/ar.php
@@ -1,5 +1,5 @@
"مجموعات",
"Users" => "المستخدمين",
-"Delete" => "حذف"
+"Delete" => "إلغاء"
);
diff --git a/apps/files_external/l10n/bg_BG.php b/apps/files_external/l10n/bg_BG.php
index 66ad4a879d441a038c6c5f79359fccc22a613024..fcb01152bf83135b17bf3821c411c4a70cf38bfb 100644
--- a/apps/files_external/l10n/bg_BG.php
+++ b/apps/files_external/l10n/bg_BG.php
@@ -2,6 +2,7 @@
"Access granted" => "Достъпът е даден",
"Grant access" => "Даване на достъп",
"External Storage" => "Външно хранилище",
+"Folder name" => "Име на папката",
"Configuration" => "Конфигурация",
"Options" => "Опции",
"Applicable" => "Приложимо",
diff --git a/apps/files_external/l10n/bn_BD.php b/apps/files_external/l10n/bn_BD.php
index 07ccd50074667723f638cc89f7c04d82f9246cfe..0f032df9f05782566bf6f92f82a3dcb02a6fe6c9 100644
--- a/apps/files_external/l10n/bn_BD.php
+++ b/apps/files_external/l10n/bn_BD.php
@@ -12,7 +12,7 @@
"All Users" => "সমস্ত ব্যবহারকারী",
"Groups" => "গোষ্ঠীসমূহ",
"Users" => "ব্যবহারকারী",
-"Delete" => "মুছে ফেল",
+"Delete" => "মুছে",
"Enable User External Storage" => "ব্যবহারকারীর বাহ্যিক সংরক্ষণাগার সক্রিয় কর",
"Allow users to mount their own external storage" => "ব্যবহারকারীদেরকে তাদের নিজস্ব বাহ্যিক সংরক্ষনাগার সাউন্ট করতে অনুমোদন দাও",
"SSL root certificates" => "SSL রুট সনদপত্র",
diff --git a/apps/files_external/l10n/ca.php b/apps/files_external/l10n/ca.php
index aa9304d3301a234835b4cdf0291e8a31a0682632..90ac954301f827110222c7abf00c5187e97c00fb 100644
--- a/apps/files_external/l10n/ca.php
+++ b/apps/files_external/l10n/ca.php
@@ -6,6 +6,7 @@
"Error configuring Google Drive storage" => "Error en configurar l'emmagatzemament Google Drive",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Avís: \"smbclient\" no està instal·lat. No es pot muntar la compartició CIFS/SMB. Demaneu a l'administrador del sistema que l'instal·li.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Avís: El suport FTP per PHP no està activat o no està instal·lat. No es pot muntar la compartició FTP. Demaneu a l'administrador del sistema que l'instal·li.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Avís:El suport Curl de PHP no està activat o instal·lat. No es pot muntar ownCloud / WebDAV o GoogleDrive. Demaneu a l'administrador que l'instal·li.",
"External Storage" => "Emmagatzemament extern",
"Folder name" => "Nom de la carpeta",
"External storage" => "Emmagatzemament extern",
@@ -17,7 +18,7 @@
"All Users" => "Tots els usuaris",
"Groups" => "Grups",
"Users" => "Usuaris",
-"Delete" => "Elimina",
+"Delete" => "Esborra",
"Enable User External Storage" => "Habilita l'emmagatzemament extern d'usuari",
"Allow users to mount their own external storage" => "Permet als usuaris muntar el seu emmagatzemament extern propi",
"SSL root certificates" => "Certificats SSL root",
diff --git a/apps/files_external/l10n/cs_CZ.php b/apps/files_external/l10n/cs_CZ.php
index 20bbe8acbaaf42d5b7f3e35b1f92481fcd14bbe1..12603044d63ee36907d3bf21af1829eec5084957 100644
--- a/apps/files_external/l10n/cs_CZ.php
+++ b/apps/files_external/l10n/cs_CZ.php
@@ -6,6 +6,7 @@
"Error configuring Google Drive storage" => "Chyba při nastavení úložiště Google Drive",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Varování: není nainstalován program \"smbclient\". Není možné připojení oddílů CIFS/SMB. Prosím požádejte svého správce systému ať jej nainstaluje.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Varování: není nainstalována, nebo povolena, podpora FTP v PHP. Není možné připojení oddílů FTP. Prosím požádejte svého správce systému ať ji nainstaluje.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Varování: není nainstalována, nebo povolena, podpora Curl v PHP. Není možné připojení oddílů ownCloud, WebDAV, či GoogleDrive. Prosím požádejte svého správce systému ať ji nainstaluje.",
"External Storage" => "Externí úložiště",
"Folder name" => "Název složky",
"External storage" => "Externí úložiště",
diff --git a/apps/files_external/l10n/cy_GB.php b/apps/files_external/l10n/cy_GB.php
new file mode 100644
index 0000000000000000000000000000000000000000..78bbb987eb89093f6cd7b433b0db498071696f8e
--- /dev/null
+++ b/apps/files_external/l10n/cy_GB.php
@@ -0,0 +1,5 @@
+ "Grwpiau",
+"Users" => "Defnyddwyr",
+"Delete" => "Dileu"
+);
diff --git a/apps/files_external/l10n/da.php b/apps/files_external/l10n/da.php
index 0c9c6c390443c5a789b73dad88908215cf08f4e4..f2c1e45778d34c42f15eb8c7ac220c73025cee0d 100644
--- a/apps/files_external/l10n/da.php
+++ b/apps/files_external/l10n/da.php
@@ -6,11 +6,14 @@
"Error configuring Google Drive storage" => "Fejl ved konfiguration af Google Drive plads",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => " Advarsel: b> \"smbclient\" ikke er installeret. Montering af CIFS / SMB delinger er ikke muligt. Spørg din systemadministrator om at installere det.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => " Advarsel: b> FTP-understøttelse i PHP ikke er aktiveret eller installeret. Montering af FTP delinger er ikke muligt. Spørg din systemadministrator om at installere det.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Advarsel: Understøttelsen for Curl i PHP er enten ikke aktiveret eller ikke installeret. Det er ikke muligt, at montere ownCloud / WebDAV eller GoogleDrive. Spørg din system administrator om at installere det. ",
"External Storage" => "Ekstern opbevaring",
"Folder name" => "Mappenavn",
+"External storage" => "Eksternt lager",
"Configuration" => "Opsætning",
"Options" => "Valgmuligheder",
"Applicable" => "Kan anvendes",
+"Add storage" => "Tilføj lager",
"None set" => "Ingen sat",
"All Users" => "Alle brugere",
"Groups" => "Grupper",
diff --git a/apps/files_external/l10n/de.php b/apps/files_external/l10n/de.php
index 24183772217a0d59ce1b14f7569b5ac653319aef..8dfa0eafbb4b037fa9910a93f0223bb1651f2ee4 100644
--- a/apps/files_external/l10n/de.php
+++ b/apps/files_external/l10n/de.php
@@ -6,6 +6,7 @@
"Error configuring Google Drive storage" => "Fehler beim Einrichten von Google Drive",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Warnung: \"smbclient\" ist nicht installiert. Das Einhängen von CIFS/SMB-Freigaben ist nicht möglich. Bitte Deinen System-Administrator, dies zu installieren.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Warnung:: Die FTP Unterstützung von PHP ist nicht aktiviert oder installiert. Bitte wende Dich an Deinen Systemadministrator.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Warnung: Die Curl-Unterstützung in PHP ist nicht aktiviert oder installiert. Das Einbinden von ownCloud / WebDav der GoogleDrive-Freigaben ist nicht möglich. Bitte Deinen Systemadminstrator um die Installation. ",
"External Storage" => "Externer Speicher",
"Folder name" => "Ordnername",
"External storage" => "Externer Speicher",
diff --git a/apps/files_external/l10n/de_DE.php b/apps/files_external/l10n/de_DE.php
index d55c0c6909de06d2c5b26b5fe74ef97e4c4ee181..9b7ab4d53ca80523d2dee4b7f998aa83e14c14f7 100644
--- a/apps/files_external/l10n/de_DE.php
+++ b/apps/files_external/l10n/de_DE.php
@@ -6,6 +6,7 @@
"Error configuring Google Drive storage" => "Fehler beim Einrichten von Google Drive",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Warnung: \"smbclient\" ist nicht installiert. Das Einhängen von CIFS/SMB-Freigaben ist nicht möglich. Bitten Sie Ihren Systemadministrator, dies zu installieren.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Warnung:: Die FTP Unterstützung von PHP ist nicht aktiviert oder installiert. Bitte wenden Sie sich an Ihren Systemadministrator.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Achtung: Die Curl-Unterstützung von PHP ist nicht aktiviert oder installiert. Das Laden von ownCloud / WebDAV oder GoogleDrive Freigaben ist nicht möglich. Bitte Sie Ihren Systemadministrator, das Modul zu installieren.",
"External Storage" => "Externer Speicher",
"Folder name" => "Ordnername",
"External storage" => "Externer Speicher",
@@ -19,7 +20,7 @@
"Users" => "Benutzer",
"Delete" => "Löschen",
"Enable User External Storage" => "Externen Speicher für Benutzer aktivieren",
-"Allow users to mount their own external storage" => "Erlaubt Benutzern ihre eigenen externen Speicher einzubinden",
+"Allow users to mount their own external storage" => "Erlaubt Benutzern, ihre eigenen externen Speicher einzubinden",
"SSL root certificates" => "SSL-Root-Zertifikate",
"Import Root Certificate" => "Root-Zertifikate importieren"
);
diff --git a/apps/files_external/l10n/el.php b/apps/files_external/l10n/el.php
index 38b5a098f6266fe169329cde07322dff6e65f3e6..62703b08fbc1422f2b7b9b95bd65643009da7825 100644
--- a/apps/files_external/l10n/el.php
+++ b/apps/files_external/l10n/el.php
@@ -6,11 +6,14 @@
"Error configuring Google Drive storage" => "Σφάλμα ρυθμίζωντας αποθήκευση Google Drive ",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Προσοχή: Ο \"smbclient\" δεν εγκαταστάθηκε. Δεν είναι δυνατή η προσάρτηση CIFS/SMB. Παρακαλώ ενημερώστε τον διαχειριστή συστήματος να το εγκαταστήσει.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Προσοχή: Η υποστήριξη FTP στην PHP δεν ενεργοποιήθηκε ή εγκαταστάθηκε. Δεν είναι δυνατή η προσάρτηση FTP. Παρακαλώ ενημερώστε τον διαχειριστή συστήματος να το εγκαταστήσει.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "<Προειδοποίηση Η υποστήριξη του συστήματος Curl στο PHP δεν είναι ενεργοποιημένη ή εγκαταστημένη. Η αναπαραγωγή του ownCloud/WebDAV ή GoogleDrive δεν είναι δυνατή. Παρακαλώ ρωτήστε τον διαχειριστλη του συστήματος για την εγκατάσταση. ",
"External Storage" => "Εξωτερικό Αποθηκευτικό Μέσο",
"Folder name" => "Όνομα φακέλου",
+"External storage" => "Εξωτερική αποθήκευση",
"Configuration" => "Ρυθμίσεις",
"Options" => "Επιλογές",
"Applicable" => "Εφαρμόσιμο",
+"Add storage" => "Προσθηκη αποθηκευσης",
"None set" => "Κανένα επιλεγμένο",
"All Users" => "Όλοι οι Χρήστες",
"Groups" => "Ομάδες",
diff --git a/apps/files_external/l10n/es.php b/apps/files_external/l10n/es.php
index da22f41032070f52d6f585874e05fe778d487319..d145a176f7191e13985e8d0f95a26fe91db096c3 100644
--- a/apps/files_external/l10n/es.php
+++ b/apps/files_external/l10n/es.php
@@ -1,11 +1,12 @@
"Acceso garantizado",
+"Access granted" => "Acceso concedido",
"Error configuring Dropbox storage" => "Error configurando el almacenamiento de Dropbox",
-"Grant access" => "Garantizar acceso",
-"Please provide a valid Dropbox app key and secret." => "Por favor , proporcione un secreto y una contraseña válida de la app Dropbox.",
+"Grant access" => "Conceder acceso",
+"Please provide a valid Dropbox app key and secret." => "Por favor, proporcione un una clave válida de la app Dropbox y una clave secreta.",
"Error configuring Google Drive storage" => "Error configurando el almacenamiento de Google Drive",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Advertencia: El cliente smb (smbclient) no se encuentra instalado. El montado de archivos o ficheros CIFS/SMB no es posible. Por favor pida al administrador de su sistema que lo instale.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Advertencia: El soporte de FTP en PHP no se encuentra instalado. El montado de archivos o ficheros FTP no es posible. Por favor pida al administrador de su sistema que lo instale.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Advertencia: El soporte de Curl en PHP no está activado ni instalado. El montado de ownCloud, WebDAV o GoogleDrive no es posible. Pida al administrador de su sistema que lo instale.",
"External Storage" => "Almacenamiento externo",
"Folder name" => "Nombre de la carpeta",
"External storage" => "Almacenamiento externo",
@@ -17,9 +18,9 @@
"All Users" => "Todos los usuarios",
"Groups" => "Grupos",
"Users" => "Usuarios",
-"Delete" => "Eliiminar",
-"Enable User External Storage" => "Habilitar almacenamiento de usuario externo",
+"Delete" => "Eliminar",
+"Enable User External Storage" => "Habilitar almacenamiento externo de usuario",
"Allow users to mount their own external storage" => "Permitir a los usuarios montar su propio almacenamiento externo",
-"SSL root certificates" => "Raíz de certificados SSL ",
+"SSL root certificates" => "Certificados raíz SSL",
"Import Root Certificate" => "Importar certificado raíz"
);
diff --git a/apps/files_external/l10n/es_AR.php b/apps/files_external/l10n/es_AR.php
index 6706aa43a311ffde100251e5f4d1bdb1b840bb65..c1b3ac63886b5a166f43f6f09d36176629e5a508 100644
--- a/apps/files_external/l10n/es_AR.php
+++ b/apps/files_external/l10n/es_AR.php
@@ -4,8 +4,9 @@
"Grant access" => "Permitir acceso",
"Please provide a valid Dropbox app key and secret." => "Por favor, proporcioná un secreto y una contraseña válida para la aplicación Dropbox.",
"Error configuring Google Drive storage" => "Error al configurar el almacenamiento de Google Drive",
-"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Advertencia: El cliente smb (smbclient) no se encuentra instalado. El montado de archivos o ficheros CIFS/SMB no es posible. Por favor pida al administrador de su sistema que lo instale.",
-"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Advertencia: El soporte de FTP en PHP no se encuentra instalado. El montado de archivos o ficheros FTP no es posible. Por favor pida al administrador de su sistema que lo instale.",
+"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Advertencia: El cliente smb \"smbclient\" no está instalado. Montar archivos CIFS/SMB no es posible. Por favor, pedile al administrador de tu sistema que lo instale.",
+"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Advertencia: El soporte de FTP en PHP no está instalado. Montar archivos FTP no es posible. Por favor, pedile al administrador de tu sistema que lo instale.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Advertencia: El soporte de Curl de PHP no está activo ni instalado. Montar servicios ownCloud, WebDAV y/o GoogleDrive no será posible. Pedile al administrador del sistema que lo instale.",
"External Storage" => "Almacenamiento externo",
"Folder name" => "Nombre de la carpeta",
"External storage" => "Almacenamiento externo",
diff --git a/apps/files_external/l10n/et_EE.php b/apps/files_external/l10n/et_EE.php
index fd0cdefd347cd7bfb232ebc93777c66aeb847390..465201df4dd3834a40f41c088ca9f7a2c1ce1199 100644
--- a/apps/files_external/l10n/et_EE.php
+++ b/apps/files_external/l10n/et_EE.php
@@ -4,11 +4,16 @@
"Grant access" => "Anna ligipääs",
"Please provide a valid Dropbox app key and secret." => "Palun sisesta korrektne Dropboxi rakenduse võti ja salasõna.",
"Error configuring Google Drive storage" => "Viga Google Drive'i salvestusruumi seadistamisel",
+"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Hoiatus: \"smbclient\" pole paigaldatud. Jagatud CIFS/SMB hoidlate ühendamine pole võimalik. Palu oma süsteemihalduril paigaldata SAMBA tugi.",
+"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Hoiatus: PHP-s puudub FTP tugi. Jagatud FTP hoidlate ühendamine pole võimalik. Palu oma süsteemihalduril paigaldata FTP tugi.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Hoiatus: PHP-s puudub Curl tugi. Jagatud ownCloud / WebDAV või GoogleDrive ühendamine pole võimalik. Palu oma süsteemihalduril see paigaldada.",
"External Storage" => "Väline salvestuskoht",
"Folder name" => "Kausta nimi",
+"External storage" => "Väline andmehoidla",
"Configuration" => "Seadistamine",
"Options" => "Valikud",
"Applicable" => "Rakendatav",
+"Add storage" => "Lisa andmehoidla",
"None set" => "Pole määratud",
"All Users" => "Kõik kasutajad",
"Groups" => "Grupid",
diff --git a/apps/files_external/l10n/eu.php b/apps/files_external/l10n/eu.php
index 83be50deb00e2cbdffcc7b460c62222dd82bdb43..9dc1f3e9c033a63d70988cc672be544ee2812f14 100644
--- a/apps/files_external/l10n/eu.php
+++ b/apps/files_external/l10n/eu.php
@@ -6,6 +6,7 @@
"Error configuring Google Drive storage" => "Errore bat egon da Google Drive biltegiratzea konfiguratzean",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Abisua: \"smbclient\" ez dago instalatuta. CIFS/SMB partekatutako karpetak montatzea ez da posible. Mesedez eskatu zure sistema kudeatzaileari instalatzea.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Abisua: PHPren FTP modulua ez dago instalatuta edo gaitua. FTP partekatutako karpetak montatzea ez da posible. Mesedez eskatu zure sistema kudeatzaileari instalatzea.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Abisua: Curl euskarri PHP modulua ez dago instalatuta edo gaitua. Ezinezko da ownCloud /WebDAV GoogleDrive-n muntatzea. Mesedez eskatu sistema kudeatzaileari instala dezan. ",
"External Storage" => "Kanpoko Biltegiratzea",
"Folder name" => "Karpetaren izena",
"External storage" => "Kanpoko biltegiratzea",
diff --git a/apps/files_external/l10n/fa.php b/apps/files_external/l10n/fa.php
index a7eac596b04925a0c0c636fc751356180857a65a..82d3676e17ce9a769ad83338b7b4fd7d8f03a2be 100644
--- a/apps/files_external/l10n/fa.php
+++ b/apps/files_external/l10n/fa.php
@@ -1,11 +1,20 @@
"مجوز دسترسی صادر شد",
+"Error configuring Dropbox storage" => "خطا به هنگام تنظیم فضای دراپ باکس",
+"Grant access" => " مجوز اعطا دسترسی",
+"Please provide a valid Dropbox app key and secret." => "لطفا یک کلید و کد امنیتی صحیح دراپ باکس وارد کنید.",
+"Error configuring Google Drive storage" => "خطا به هنگام تنظیم فضای Google Drive",
+"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "خطا: \"smbclient\" نصب نشده است. نصب و راه اندازی سهام CIFS/SMB امکان پذیر نمیباشد. لطفا از مدیریت سازمان خود برای راه اندازی آن درخواست نمایید.",
"External Storage" => "حافظه خارجی",
+"Folder name" => "نام پوشه",
"Configuration" => "پیکربندی",
"Options" => "تنظیمات",
"Applicable" => "قابل اجرا",
+"None set" => "تنظیم نشده",
"All Users" => "تمام کاربران",
"Groups" => "گروه ها",
"Users" => "کاربران",
"Delete" => "حذف",
-"Enable User External Storage" => "فعال سازی حافظه خارجی کاربر"
+"Enable User External Storage" => "فعال سازی حافظه خارجی کاربر",
+"Allow users to mount their own external storage" => "اجازه به کاربران برای متصل کردن منابع ذخیره ی خارجی خودشان"
);
diff --git a/apps/files_external/l10n/fi_FI.php b/apps/files_external/l10n/fi_FI.php
index 4cf97f2fc35db8e525376a5be388b119e831133b..ba39d140fbc87f922ee3e02fd645ac34168fa6f8 100644
--- a/apps/files_external/l10n/fi_FI.php
+++ b/apps/files_external/l10n/fi_FI.php
@@ -6,11 +6,14 @@
"Error configuring Google Drive storage" => "Virhe Google Drive levyn asetuksia tehtäessä",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Varoitus: \"smbclient\" ei ole asennettuna. CIFS-/SMB-jakojen liittäminen ei ole mahdollista. Pyydä järjestelmän ylläpitäjää asentamaan smbclient.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Varoitus: PHP:n FTP-tuki ei ole käytössä tai sitä ei ole asennettu. FTP-jakojen liittäminen ei ole mahdollista. Pyydä järjestelmän ylläpitäjää ottamaan FTP-tuki käyttöön.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Varoitus: PHP:n Curl-tuki ei ole käytössä tai sitä ei ole lainkaan asennettu. ownCloudin, WebDAV:in tai Google Driven liittäminen ei ole mahdollista. Pyydä järjestelmän ylläpitäjää ottamaan Curl-tuki käyttöön.",
"External Storage" => "Erillinen tallennusväline",
"Folder name" => "Kansion nimi",
+"External storage" => "Ulkoinen tallennustila",
"Configuration" => "Asetukset",
"Options" => "Valinnat",
"Applicable" => "Sovellettavissa",
+"Add storage" => "Lisää tallennustila",
"None set" => "Ei asetettu",
"All Users" => "Kaikki käyttäjät",
"Groups" => "Ryhmät",
diff --git a/apps/files_external/l10n/fr.php b/apps/files_external/l10n/fr.php
index c42c89f8572e6eaec912951b5a872cccba978146..5006133a7b688cc4e59bb84d097a777acc5ac7ec 100644
--- a/apps/files_external/l10n/fr.php
+++ b/apps/files_external/l10n/fr.php
@@ -6,6 +6,7 @@
"Error configuring Google Drive storage" => "Erreur lors de la configuration du support de stockage Google Drive",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Attention : \"smbclient\" n'est pas installé. Le montage des partages CIFS/SMB n'est pas disponible. Contactez votre administrateur système pour l'installer.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Attention : Le support FTP de PHP n'est pas activé ou installé. Le montage des partages FTP n'est pas disponible. Contactez votre administrateur système pour l'installer.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Attention : Le support de Curl n'est pas activé ou installé dans PHP. Le montage de ownCloud / WebDAV ou GoogleDrive n'est pas possible. Contactez votre administrateur système pour l'installer.",
"External Storage" => "Stockage externe",
"Folder name" => "Nom du dossier",
"External storage" => "Stockage externe",
diff --git a/apps/files_external/l10n/gl.php b/apps/files_external/l10n/gl.php
index 715417e25a0d96dde674f0cec29d1ce6fbe24bb6..77f23c39bc3f95b1c37bd7c5cfc2b4d6708f7559 100644
--- a/apps/files_external/l10n/gl.php
+++ b/apps/files_external/l10n/gl.php
@@ -6,6 +6,7 @@
"Error configuring Google Drive storage" => "Produciuse un erro ao configurar o almacenamento en Google Drive",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Aviso: «smbclient» non está instalado. Non é posibel a montaxe de comparticións CIFS/SMB. Consulte co administrador do sistema para instalalo.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Aviso: A compatibilidade de FTP en PHP non está activada ou instalada. Non é posibel a montaxe de comparticións FTP. Consulte co administrador do sistema para instalalo.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Aviso: b> A compatibilidade de Curl en PHP non está activada ou instalada. Non é posíbel a montaxe de ownCloud / WebDAV ou GoogleDrive. Consulte co administrador do sistema para instalala.",
"External Storage" => "Almacenamento externo",
"Folder name" => "Nome do cartafol",
"External storage" => "Almacenamento externo",
diff --git a/apps/files_external/l10n/hu_HU.php b/apps/files_external/l10n/hu_HU.php
index 9ecd2d1088b7a0d348409b470ee196c2d4c52309..b88737a19abde8df8d97c60f132795cc2f4c8d30 100644
--- a/apps/files_external/l10n/hu_HU.php
+++ b/apps/files_external/l10n/hu_HU.php
@@ -6,6 +6,7 @@
"Error configuring Google Drive storage" => "A Google Drive tárolót nem sikerült beállítani",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Figyelem: az \"smbclient\" nincs telepítve a kiszolgálón. Emiatt nem lehet CIFS/SMB megosztásokat fölcsatolni. Kérje meg a rendszergazdát, hogy telepítse a szükséges programot.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Figyelem: a PHP FTP támogatása vagy nincs telepítve, vagy nincs engedélyezve a kiszolgálón. Emiatt nem lehetséges FTP-tárolókat fölcsatolni. Kérje meg a rendszergazdát, hogy telepítse a szükséges programot.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Figyelmeztetés: A PHP-ben nincs telepítve vagy engedélyezve a Curl támogatás. Nem lehetséges ownCloud / WebDAV ill. GoogleDrive tárolók becsatolása. Kérje meg a rendszergazdát, hogy telepítse a szükséges programot!",
"External Storage" => "Külső tárolási szolgáltatások becsatolása",
"Folder name" => "Mappanév",
"External storage" => "Külső tárolók",
diff --git a/apps/files_external/l10n/id.php b/apps/files_external/l10n/id.php
index 647220706bae67ec6469ea2ae3c8c6e0ff100e71..30cd28bba1c91fb9f70fcd6809a12040c796f830 100644
--- a/apps/files_external/l10n/id.php
+++ b/apps/files_external/l10n/id.php
@@ -1,22 +1,25 @@
"Akses diberikan",
-"Error configuring Dropbox storage" => "Kesalahan dalam mengkonfigurasi penyimpanan Dropbox",
+"Error configuring Dropbox storage" => "Kesalahan dalam mengonfigurasi penyimpanan Dropbox",
"Grant access" => "Berikan hak akses",
"Please provide a valid Dropbox app key and secret." => "Masukkan kunci dan sandi aplikasi Dropbox yang benar.",
"Error configuring Google Drive storage" => "Kesalahan dalam mengkonfigurasi penyimpanan Google Drive",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Peringatan: \"smbclient\" tidak terpasang. Mount direktori CIFS/SMB tidak dapat dilakukan. Silakan minta administrator sistem untuk memasangnya.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Peringatan: Dukungan FTP di PHP tidak aktif atau tidak terpasang. Mount direktori FTP tidak dapat dilakukan. Silakan minta administrator sistem untuk memasangnya.",
"External Storage" => "Penyimpanan Eksternal",
+"Folder name" => "Nama folder",
+"External storage" => "Penyimpanan eksternal",
"Configuration" => "Konfigurasi",
-"Options" => "Pilihan",
+"Options" => "Opsi",
"Applicable" => "Berlaku",
+"Add storage" => "Tambahkan penyimpanan",
"None set" => "Tidak satupun di set",
"All Users" => "Semua Pengguna",
"Groups" => "Grup",
"Users" => "Pengguna",
"Delete" => "Hapus",
"Enable User External Storage" => "Aktifkan Penyimpanan Eksternal Pengguna",
-"Allow users to mount their own external storage" => "Ijinkan pengguna untuk me-mount penyimpanan eksternal mereka",
+"Allow users to mount their own external storage" => "Izinkan pengguna untuk mengaitkan penyimpanan eksternal mereka",
"SSL root certificates" => "Sertifikat root SSL",
"Import Root Certificate" => "Impor Sertifikat Root"
);
diff --git a/apps/files_external/l10n/it.php b/apps/files_external/l10n/it.php
index d7e0c81a0b0b6e0f23f4fbb9c2e4dea96774d88a..4c70a04022ecba70b8b9845d10047a256a8c5dcb 100644
--- a/apps/files_external/l10n/it.php
+++ b/apps/files_external/l10n/it.php
@@ -6,6 +6,7 @@
"Error configuring Google Drive storage" => "Errore durante la configurazione dell'archivio Google Drive",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Avviso: \"smbclient\" non è installato. Impossibile montare condivisioni CIFS/SMB. Chiedi all'amministratore di sistema di installarlo.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Avviso: il supporto FTP di PHP non è abilitato o non è installato. Impossibile montare condivisioni FTP. Chiedi all'amministratore di sistema di installarlo.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Avviso: il supporto Curl di PHP non è abilitato o non è installato. Impossibile montare condivisioni ownCloud / WebDAV o GoogleDrive. Chiedi all'amministratore di sistema di installarlo.",
"External Storage" => "Archiviazione esterna",
"Folder name" => "Nome della cartella",
"External storage" => "Archiviazione esterna",
diff --git a/apps/files_external/l10n/ja_JP.php b/apps/files_external/l10n/ja_JP.php
index 12a0b30938a5e668377371ead59d07e9005451fa..97dd4e119d4d9fdecdbe1bc41dfac60d830bdcfd 100644
--- a/apps/files_external/l10n/ja_JP.php
+++ b/apps/files_external/l10n/ja_JP.php
@@ -6,6 +6,7 @@
"Error configuring Google Drive storage" => "Googleドライブストレージの設定エラー",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "警告: \"smbclient\" はインストールされていません。CIFS/SMB 共有のマウントはできません。システム管理者にインストールをお願いして下さい。",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "警告: PHPのFTPサポートは無効もしくはインストールされていません。FTP共有のマウントはできません。システム管理者にインストールをお願いして下さい。",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "警告: PHP の Curl サポートは無効もしくはインストールされていません。ownCloud / WebDAV もしくは GoogleDrive のマウントはできません。システム管理者にインストールをお願いして下さい。",
"External Storage" => "外部ストレージ",
"Folder name" => "フォルダ名",
"External storage" => "外部ストレージ",
diff --git a/apps/files_external/l10n/ka_GE.php b/apps/files_external/l10n/ka_GE.php
index efccca9fd782b119528d5b037f8ac194d41338e3..b0845555b4b41d6d46b76cffb628dd6b61ee37af 100644
--- a/apps/files_external/l10n/ka_GE.php
+++ b/apps/files_external/l10n/ka_GE.php
@@ -1,5 +1,26 @@
"დაშვება მინიჭებულია",
+"Error configuring Dropbox storage" => "შეცდომა Dropbox საცავის კონფიგურირების დროს",
+"Grant access" => "დაშვების მინიჭება",
+"Please provide a valid Dropbox app key and secret." => "გთხოვთ მიუთითოთ Dropbox აპლიკაციის გასაღები და კოდი.",
+"Error configuring Google Drive storage" => "შეცდომა Google Drive საცავის კონფიგურირების დროს",
+"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "გაფრთხილება: \"smbclient\" არ არის ინსტალირებული. CIFS/SMB ზიარების მონტირება შეუძლებელია. გთხოვთ თხოვოთ თქვენს სისტემურ ადმინისტრატორებს დააინსტალიროს ის.",
+"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "გაფრთხილება: FTP მხარდაჭერა არ არის აქტიური ან დაინსტალირებული. FTP ზიარის მონტირება შეუძლებელია. გთხოვთ თხოვოთ თქვენს სისტემურ ადმინისტრატორებს დააინსტალიროს ის.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "გაფრთხილება:PHP–ის Curl მხარდაჭერა არ არის ჩართული ან ინსტალირებული. ownCloud / WebDAV ან GoogleDrive–ის მონტირება შეუძლებელია. თხოვეთ თქვენს ადმინისტრატორს დააინსტალიროს ის.",
+"External Storage" => "ექსტერნალ საცავი",
+"Folder name" => "ფოლდერის სახელი",
+"External storage" => "ექსტერნალ საცავი",
+"Configuration" => "კონფიგურაცია",
+"Options" => "ოფცია",
+"Applicable" => "მიღებადი",
+"Add storage" => "საცავის დამატება",
+"None set" => "არაფერია მითითებული",
+"All Users" => "ყველა მომხმარებელი",
"Groups" => "ჯგუფები",
"Users" => "მომხმარებელი",
-"Delete" => "წაშლა"
+"Delete" => "წაშლა",
+"Enable User External Storage" => "მომხმარებლის ექსტერნალ საცავის აქტივირება",
+"Allow users to mount their own external storage" => "მიეცით მომხმარებლებს თავისი ექსტერნალ საცავის მონტირების უფლება",
+"SSL root certificates" => "SSL root სერთიფიკატები",
+"Import Root Certificate" => "Root სერთიფიკატის იმპორტირება"
);
diff --git a/apps/files_external/l10n/ko.php b/apps/files_external/l10n/ko.php
index 47de9aad5e0ff566e4812e0f00be6136605133d6..803b489c218313cae5ce99d463eebee15e753d59 100644
--- a/apps/files_external/l10n/ko.php
+++ b/apps/files_external/l10n/ko.php
@@ -6,11 +6,14 @@
"Error configuring Google Drive storage" => "Google 드라이브 저장소 설정 오류",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "경고: \"smbclient\"가 설치되지 않았습니다. CIFS/SMB 공유 자원에 연결할 수 없습니다. 시스템 관리자에게 설치를 요청하십시오.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "경고: PHP FTP 지원이 비활성화되어 있거나 설치되지 않았습니다. FTP 공유를 마운트할 수 없습니다. 시스템 관리자에게 설치를 요청하십시오.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "경고: PHP Curl 지원이 비활성화되어 있거나 설치되지 않았습니다. 다른 ownCloud, WebDAV, Google 드라이브 공유를 마운트할 수 없습니다. 시스템 관리자에게 설치를 요청하십시오.",
"External Storage" => "외부 저장소",
"Folder name" => "폴더 이름",
+"External storage" => "외부 저장소",
"Configuration" => "설정",
"Options" => "옵션",
"Applicable" => "적용 가능",
+"Add storage" => "저장소 추가",
"None set" => "설정되지 않음",
"All Users" => "모든 사용자",
"Groups" => "그룹",
diff --git a/apps/files_external/l10n/lb.php b/apps/files_external/l10n/lb.php
index 2a62cad3fe90c3a6e2e97a7de790f5faf8ef0958..4e78227ec4854d4d7281a9fc69199347bde8c6f1 100644
--- a/apps/files_external/l10n/lb.php
+++ b/apps/files_external/l10n/lb.php
@@ -1,5 +1,6 @@
"Dossiers Numm:",
"Groups" => "Gruppen",
+"Users" => "Benotzer",
"Delete" => "Läschen"
);
diff --git a/apps/files_external/l10n/lt_LT.php b/apps/files_external/l10n/lt_LT.php
index f7dca99ef654bb245aaf65135c2e4977990c4e3b..29c962d9a8057b2898921ce6113494c5b9b5ac76 100644
--- a/apps/files_external/l10n/lt_LT.php
+++ b/apps/files_external/l10n/lt_LT.php
@@ -4,11 +4,16 @@
"Grant access" => "Suteikti priėjimą",
"Please provide a valid Dropbox app key and secret." => "Prašome įvesti teisingus Dropbox \"app key\" ir \"secret\".",
"Error configuring Google Drive storage" => "Klaida nustatinėjant Google Drive talpyklą",
+"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Įspėjimas: \"smbclient\" nėra įdiegtas. CIFS/SMB dalinimasis nėra galimas. Prašome susisiekti su sistemos administratoriumi kad būtų įdiegtas \"smbclient\"",
+"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Įspėjimas: FTP palaikymas PHP sistemoje nėra įjungtas arba nėra įdiegtas. FTP dalinimosi įjungimas nėra galimas. Prašome susisiekti su sistemos administratoriumi kad būtų įdiegtas FTP palaikymas. ",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Įspėjimas: \"Curl\" palaikymas PHP terpėje nėra įjungtas arba įdiegtas. ownCloud/WebDAV ar GoogleDrive įjungimas nebus įmanomas. Prašome susisiekti su sistemos administratoriumi kad būtų įdiegtas arba įjungtas \"Curl\" palaikymas.",
"External Storage" => "Išorinės saugyklos",
"Folder name" => "Katalogo pavadinimas",
+"External storage" => "Išorinė saugykla",
"Configuration" => "Konfigūracija",
"Options" => "Nustatymai",
"Applicable" => "Pritaikyti",
+"Add storage" => "Pridėti saugyklą",
"None set" => "Nieko nepasirinkta",
"All Users" => "Visi vartotojai",
"Groups" => "Grupės",
diff --git a/apps/files_external/l10n/nb_NO.php b/apps/files_external/l10n/nb_NO.php
index 961ef2b1046bb8833751b47be4a337f77c761371..ea8648303d1be23bec5c75f626e4f1f5ccaf63ec 100644
--- a/apps/files_external/l10n/nb_NO.php
+++ b/apps/files_external/l10n/nb_NO.php
@@ -2,6 +2,11 @@
"Access granted" => "Tilgang innvilget",
"Error configuring Dropbox storage" => "Feil ved konfigurering av Dropbox-lagring",
"Grant access" => "Gi tilgang",
+"Please provide a valid Dropbox app key and secret." => "Vær vennlig å oppgi gyldig Dropbox appnøkkel og hemmelighet.",
+"Error configuring Google Drive storage" => "Feil med konfigurering av Google Drive",
+"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Advarsel: \"smbclient\" er ikke installert. Kan ikke montere CIFS/SMB mapper. Ta kontakt med din systemadministrator for å installere det.",
+"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Advarsel: FTP støtte i PHP er ikke slått på eller innstallert. Kan ikke montere FTP mapper. Ta kontakt med din systemadministrator for å innstallere det.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Advarsel: Curl støtte i PHP er ikke aktivert eller innstallert. Kan ikke montere owncloud/WebDAV eller Googledrive. Ta kontakt med din systemadministrator for å innstallerer det.",
"External Storage" => "Ekstern lagring",
"Folder name" => "Mappenavn",
"External storage" => "Ekstern lagringsplass",
diff --git a/apps/files_external/l10n/nl.php b/apps/files_external/l10n/nl.php
index ad3eda9747fe44c0dda8ef59b8e433a807598ee1..ded5a861a8b50ca0509b0dce2ceb65b97c96715e 100644
--- a/apps/files_external/l10n/nl.php
+++ b/apps/files_external/l10n/nl.php
@@ -6,6 +6,7 @@
"Error configuring Google Drive storage" => "Fout tijdens het configureren van Google Drive opslag",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Waarschuwing: \"smbclient\" is niet geïnstalleerd. Mounten van CIFS/SMB shares is niet mogelijk. Vraag uw beheerder om smbclient te installeren.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Waarschuwing: FTP ondersteuning in PHP is niet geactiveerd of geïnstalleerd. Mounten van FTP shares is niet mogelijk. Vraag uw beheerder FTP ondersteuning te installeren.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Waarschuwing: Curl ondersteuning in PHP is niet geactiveerd of geïnstalleerd. Mounten van ownCloud / WebDAV of GoogleDrive is niet mogelijk. Vraag uw systeembeheerder dit te installeren.",
"External Storage" => "Externe opslag",
"Folder name" => "Mapnaam",
"External storage" => "Externe opslag",
diff --git a/apps/files_external/l10n/nn_NO.php b/apps/files_external/l10n/nn_NO.php
index 4b4b6167d88628cfae7ace8305001b3a06cc31b7..998c3f824578b5d2553d84eecd777aff27a8c4ff 100644
--- a/apps/files_external/l10n/nn_NO.php
+++ b/apps/files_external/l10n/nn_NO.php
@@ -1,4 +1,5 @@
"Innstillingar",
"Groups" => "Grupper",
"Users" => "Brukarar",
"Delete" => "Slett"
diff --git a/apps/files_external/l10n/pl.php b/apps/files_external/l10n/pl.php
index cd1b1fe84a1f4145a50bd3ba44a5b9d7c68c11f3..e03ded1e70a222268880990d6d7fc2339755e9e4 100644
--- a/apps/files_external/l10n/pl.php
+++ b/apps/files_external/l10n/pl.php
@@ -6,6 +6,7 @@
"Error configuring Google Drive storage" => "Wystąpił błąd podczas konfigurowania zasobu Google Drive",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Ostrzeżenie: \"smbclient\" nie jest zainstalowany. Zamontowanie katalogów CIFS/SMB nie jest możliwe. Skontaktuj sie z administratorem w celu zainstalowania.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Ostrzeżenie: Wsparcie dla FTP w PHP nie jest zainstalowane lub włączone. Skontaktuj sie z administratorem w celu zainstalowania lub włączenia go.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Ostrzeżenie: Wsparcie dla Curl w PHP nie jest zainstalowane lub włączone. Montowanie WebDAV lub GoogleDrive nie będzie możliwe. Skontaktuj się z administratorem w celu zainstalowania lub włączenia tej opcji.",
"External Storage" => "Zewnętrzna zasoby dyskowe",
"Folder name" => "Nazwa folderu",
"External storage" => "Zewnętrzne zasoby dyskowe",
diff --git a/apps/files_external/l10n/pt_BR.php b/apps/files_external/l10n/pt_BR.php
index a358d56913916cff5bdeddc883acf765aba20a30..bc3c356a5175f89f4d93437da084f4b67376aa4b 100644
--- a/apps/files_external/l10n/pt_BR.php
+++ b/apps/files_external/l10n/pt_BR.php
@@ -6,6 +6,7 @@
"Error configuring Google Drive storage" => "Erro ao configurar armazenamento do Google Drive",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Aviso: \"smbclient\" não está instalado. Impossível montar compartilhamentos de CIFS/SMB. Por favor, peça ao seu administrador do sistema para instalá-lo.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Aviso: O suporte para FTP do PHP não está ativado ou instalado. Impossível montar compartilhamentos FTP. Por favor, peça ao seu administrador do sistema para instalá-lo.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => " Aviso: O suport a Curl em PHP não está habilitado ou instalado. A montagem do ownCloud / WebDAV ou GoogleDrive não é possível. Por favor, solicite ao seu administrador do sistema instalá-lo.",
"External Storage" => "Armazenamento Externo",
"Folder name" => "Nome da pasta",
"External storage" => "Armazenamento Externo",
@@ -17,7 +18,7 @@
"All Users" => "Todos os Usuários",
"Groups" => "Grupos",
"Users" => "Usuários",
-"Delete" => "Remover",
+"Delete" => "Excluir",
"Enable User External Storage" => "Habilitar Armazenamento Externo do Usuário",
"Allow users to mount their own external storage" => "Permitir usuários a montar seus próprios armazenamentos externos",
"SSL root certificates" => "Certificados SSL raíz",
diff --git a/apps/files_external/l10n/pt_PT.php b/apps/files_external/l10n/pt_PT.php
index aac3c1c2ca0779e1ca00f13a17a6d3fd986e82e0..0a05d1f8825fb3654dae7470c8b54616aa82dcf6 100644
--- a/apps/files_external/l10n/pt_PT.php
+++ b/apps/files_external/l10n/pt_PT.php
@@ -6,6 +6,7 @@
"Error configuring Google Drive storage" => "Erro ao configurar o armazenamento do Google Drive",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Atenção: O cliente \"smbclient\" não está instalado. Não é possível montar as partilhas CIFS/SMB . Peça ao seu administrador para instalar.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Aviso: O suporte FTP no PHP não está activate ou instalado. Não é possível montar as partilhas FTP. Peça ao seu administrador para instalar.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Atenção: O suporte PHP para o Curl não está activado ou instalado. A montagem do ownCloud/WebDav ou GoolgeDriver não é possível. Por favor contacte o administrador para o instalar.",
"External Storage" => "Armazenamento Externo",
"Folder name" => "Nome da pasta",
"External storage" => "Armazenamento Externo",
diff --git a/apps/files_external/l10n/ro.php b/apps/files_external/l10n/ro.php
index 5747205dc0590730806b6e5a0bff56918f86dc26..ed23b4cca8f7c52266f92e96603956a8bd59eb9b 100644
--- a/apps/files_external/l10n/ro.php
+++ b/apps/files_external/l10n/ro.php
@@ -6,11 +6,14 @@
"Error configuring Google Drive storage" => "Eroare la configurarea mediului de stocare Google Drive",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Atenție: \"smbclient\" nu este instalat. Montarea mediilor CIFS/SMB partajate nu este posibilă. Solicită administratorului sistemului tău să îl instaleaze.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Atenție: suportul pentru FTP în PHP nu este activat sau instalat. Montarea mediilor FPT partajate nu este posibilă. Solicită administratorului sistemului tău să îl instaleze.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Atentie: Suportul Curl nu este pornit / instalat in configuratia PHP! Montarea ownCloud / WebDAV / GoogleDrive nu este posibila! Intrebati administratorul sistemului despre aceasta problema!",
"External Storage" => "Stocare externă",
"Folder name" => "Denumire director",
+"External storage" => "Stocare externă",
"Configuration" => "Configurație",
"Options" => "Opțiuni",
"Applicable" => "Aplicabil",
+"Add storage" => "Adauga stocare",
"None set" => "Niciunul",
"All Users" => "Toți utilizatorii",
"Groups" => "Grupuri",
diff --git a/apps/files_external/l10n/ru.php b/apps/files_external/l10n/ru.php
index 46b73a67f046d8bc53d8eaf4c29d0e5500821ff7..d2c5292bac414da45f92ca36d928ff3ff087d238 100644
--- a/apps/files_external/l10n/ru.php
+++ b/apps/files_external/l10n/ru.php
@@ -6,6 +6,7 @@
"Error configuring Google Drive storage" => "Ошибка при настройке хранилища Google Drive",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Внимание: \"smbclient\" не установлен. Подключение по CIFS/SMB невозможно. Пожалуйста, обратитесь к системному администратору, чтобы установить его.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Внимание: Поддержка FTP не включена в PHP. Подключение по FTP невозможно. Пожалуйста, обратитесь к системному администратору, чтобы включить.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Внимание: Поддержка Curl в PHP не включена или не установлена. Подключение ownCloud / WebDAV или GoogleDrive невозможно. Попросите вашего системного администратора установить его.",
"External Storage" => "Внешний носитель",
"Folder name" => "Имя папки",
"External storage" => "Внешний носитель данных",
diff --git a/apps/files_external/l10n/ru_RU.php b/apps/files_external/l10n/ru_RU.php
index 406e284b2781734bdcdde8fb67bf3c99845057a9..a43417dfbc1a134a783914c108680fa888d81f06 100644
--- a/apps/files_external/l10n/ru_RU.php
+++ b/apps/files_external/l10n/ru_RU.php
@@ -1,23 +1,4 @@
"Доступ разрешен",
-"Error configuring Dropbox storage" => "Ошибка при конфигурировании хранилища Dropbox",
-"Grant access" => "Предоставить доступ",
-"Please provide a valid Dropbox app key and secret." => "Пожалуйста представьте допустимый ключ приложения Dropbox и пароль.",
-"Error configuring Google Drive storage" => "Ошибка настройки хранилища Google Drive",
-"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Предупреждение: \"smbclient\" не установлен. Подключение общих папок CIFS/SMB невозможно. Пожалуйста, обратитесь к системному администратору, чтобы установить его.",
-"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Предупреждение: Поддержка FTP в PHP не включена или не установлена. Подключение по FTP невозможно. Пожалуйста, обратитесь к системному администратору, чтобы установить ее.",
-"External Storage" => "Внешние системы хранения данных",
-"Folder name" => "Имя папки",
-"Configuration" => "Конфигурация",
-"Options" => "Опции",
-"Applicable" => "Применимый",
-"None set" => "Не задан",
-"All Users" => "Все пользователи",
"Groups" => "Группы",
-"Users" => "Пользователи",
-"Delete" => "Удалить",
-"Enable User External Storage" => "Включить пользовательскую внешнюю систему хранения данных",
-"Allow users to mount their own external storage" => "Разрешить пользователям монтировать их собственную внешнюю систему хранения данных",
-"SSL root certificates" => "Корневые сертификаты SSL",
-"Import Root Certificate" => "Импортировать корневые сертификаты"
+"Delete" => "Удалить"
);
diff --git a/apps/files_external/l10n/sk_SK.php b/apps/files_external/l10n/sk_SK.php
index af6b7b4ae6e2bb3fd4a6489735f0c7fda3ca8b4d..33edcb9d4c8c112202b001263ff202486b01156e 100644
--- a/apps/files_external/l10n/sk_SK.php
+++ b/apps/files_external/l10n/sk_SK.php
@@ -6,6 +6,7 @@
"Error configuring Google Drive storage" => "Chyba pri konfigurácii úložiska Google drive",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Upozornenie: \"smbclient\" nie je nainštalovaný. Nie je možné pripojenie oddielov CIFS/SMB. Požiadajte administrátora systému, nech ho nainštaluje.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Upozornenie: Podpora FTP v PHP nie je povolená alebo nainštalovaná. Nie je možné pripojenie oddielov FTP. Požiadajte administrátora systému, nech ho nainštaluje.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Varovanie: nie je nainštalovaná, alebo povolená, podpora Curl v PHP. Nie je možné pripojenie oddielov ownCloud, WebDAV, či GoogleDrive. Prosím požiadajte svojho administrátora systému, nech ju nainštaluje.",
"External Storage" => "Externé úložisko",
"Folder name" => "Meno priečinka",
"External storage" => "Externé úložisko",
@@ -17,7 +18,7 @@
"All Users" => "Všetci používatelia",
"Groups" => "Skupiny",
"Users" => "Používatelia",
-"Delete" => "Odstrániť",
+"Delete" => "Zmazať",
"Enable User External Storage" => "Povoliť externé úložisko",
"Allow users to mount their own external storage" => "Povoliť používateľom pripojiť ich vlastné externé úložisko",
"SSL root certificates" => "Koreňové SSL certifikáty",
diff --git a/apps/files_external/l10n/sl.php b/apps/files_external/l10n/sl.php
index 4ff2eed3bf0de9dc2ae984ce7ff2ddd182438331..09b91b913e9a796899b1b8b96d7756939b5e8814 100644
--- a/apps/files_external/l10n/sl.php
+++ b/apps/files_external/l10n/sl.php
@@ -5,7 +5,8 @@
"Please provide a valid Dropbox app key and secret." => "Vpisati je treba veljaven ključ programa in kodo za Dropbox",
"Error configuring Google Drive storage" => "Napaka nastavljanja shrambe Google Drive",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Opozorilo: paket \"smbclient\" ni nameščen. Priklapljanje pogonov CIFS/SMB ne bo mogoče.",
-"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Opozorilo: podpora FTP v PHP ni omogočena ali pa ni nameščena. Priklapljanje pogonov FTP zato ni mogoče.",
+"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Opozorilo: podpora FTP v PHP ni omogočena ali pa ni nameščena. Priklapljanje pogonov FTP zato ne bo mogoče.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Opozorilo: podpora za Curl v PHP ni omogočena ali pa ni nameščena. Priklapljanje točke ownCloud / WebDAV ali GoogleDrive zato ne bo mogoče. Zahtevane pakete je treba pred uporabo namestiti.",
"External Storage" => "Zunanja podatkovna shramba",
"Folder name" => "Ime mape",
"External storage" => "Zunanja shramba",
@@ -18,7 +19,7 @@
"Groups" => "Skupine",
"Users" => "Uporabniki",
"Delete" => "Izbriši",
-"Enable User External Storage" => "Omogoči uporabniško zunanjo podatkovno shrambo",
+"Enable User External Storage" => "Omogoči zunanjo uporabniško podatkovno shrambo",
"Allow users to mount their own external storage" => "Dovoli uporabnikom priklop lastne zunanje podatkovne shrambe",
"SSL root certificates" => "Korenska potrdila SSL",
"Import Root Certificate" => "Uvozi korensko potrdilo"
diff --git a/apps/files_external/l10n/sq.php b/apps/files_external/l10n/sq.php
new file mode 100644
index 0000000000000000000000000000000000000000..d5393aa38527a242df701d3002ca1c60335c346c
--- /dev/null
+++ b/apps/files_external/l10n/sq.php
@@ -0,0 +1,4 @@
+ "Përdoruesit",
+"Delete" => "Elimino"
+);
diff --git a/apps/files_external/l10n/sv.php b/apps/files_external/l10n/sv.php
index 45d3589228f614f483049cbd0faa2a3c102af7f2..80e68ab6e0645305d0440d03cd8c17372b5fb4d8 100644
--- a/apps/files_external/l10n/sv.php
+++ b/apps/files_external/l10n/sv.php
@@ -6,6 +6,7 @@
"Error configuring Google Drive storage" => "Fel vid konfigurering av Google Drive",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Varning: \"smb-klienten\" är inte installerad. Montering av CIFS/SMB delningar är inte möjligt. Kontakta din systemadministratör för att få den installerad.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Varning: Stöd för FTP i PHP är inte aktiverat eller installerat. Montering av FTP-delningar är inte möjligt. Kontakta din systemadministratör för att få det installerat.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Varning: Curl-stöd i PHP är inte aktiverat eller installerat. Montering av ownCloud / WebDAV eller GoogleDrive är inte möjligt. Vänligen be din administratör att installera det.",
"External Storage" => "Extern lagring",
"Folder name" => "Mappnamn",
"External storage" => "Extern lagring",
diff --git a/apps/files_external/l10n/te.php b/apps/files_external/l10n/te.php
new file mode 100644
index 0000000000000000000000000000000000000000..3d31f6438f586ab936a37a0dca4cf1cc7ccc8e40
--- /dev/null
+++ b/apps/files_external/l10n/te.php
@@ -0,0 +1,5 @@
+ "సంచయం పేరు",
+"Users" => "వాడుకరులు",
+"Delete" => "తొలగించు"
+);
diff --git a/apps/files_external/l10n/tr.php b/apps/files_external/l10n/tr.php
index cddb2b35e03e4ca2d1311a9d5c65d33f39a9a0e0..3c3c0c24f97ad6baa6c8529f8272b5aed44ff0b1 100644
--- a/apps/files_external/l10n/tr.php
+++ b/apps/files_external/l10n/tr.php
@@ -1,12 +1,19 @@
"Giriş kabul edildi",
+"Error configuring Dropbox storage" => "Dropbox depo yapılandırma hatası",
"Grant access" => "Erişim sağlandı",
"Please provide a valid Dropbox app key and secret." => "Lütfen Dropbox app key ve secret temin ediniz",
+"Error configuring Google Drive storage" => "Google Drive depo yapılandırma hatası",
+"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Uyari.''smbclient''yüklü değil. Mont etme CIFS/SMB hissenin mümkün değildir. Lutfen kullanici sistemin sormak onu yuklemek ici, ",
+"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => ". Sistem FTP PHPden aktif degil veya yuklemedi. Monte etme hissenin FTP mumkun degildir. Lutfen kullaniici sistemin sormak onu yuklemek icin.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => " Ihbar . Dayanma Curl PHPden aktif veya yuklemedi degil. Monte ownClouden/WebDay veya GoogleDrive mumkun degil. Lutfen sistm yonetici sormak yuklemek icin. ",
"External Storage" => "Harici Depolama",
"Folder name" => "Dizin ismi",
+"External storage" => "Harici Depolama",
"Configuration" => "Yapılandırma",
"Options" => "Seçenekler",
"Applicable" => "Uygulanabilir",
+"Add storage" => "Depo ekle",
"None set" => "Hiçbiri",
"All Users" => "Tüm Kullanıcılar",
"Groups" => "Gruplar",
diff --git a/apps/files_external/l10n/ug.php b/apps/files_external/l10n/ug.php
new file mode 100644
index 0000000000000000000000000000000000000000..2d1dea989063c0cc93a38882d4c7303f60e6ae1e
--- /dev/null
+++ b/apps/files_external/l10n/ug.php
@@ -0,0 +1,9 @@
+ "قىسقۇچ ئاتى",
+"External storage" => "سىرتقى ساقلىغۇچ",
+"Configuration" => "سەپلىمە",
+"Options" => "تاللانما",
+"Groups" => "گۇرۇپپا",
+"Users" => "ئىشلەتكۈچىلەر",
+"Delete" => "ئۆچۈر"
+);
diff --git a/apps/files_external/l10n/vi.php b/apps/files_external/l10n/vi.php
index 84f31e88924a8fafd610a0e98f68077b778406ad..769f9e2a0976aa443ffda271da4e10fe6de52959 100644
--- a/apps/files_external/l10n/vi.php
+++ b/apps/files_external/l10n/vi.php
@@ -6,11 +6,14 @@
"Error configuring Google Drive storage" => "Lỗi cấu hình lưu trữ Google Drive",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "Cảnh báo: \"smbclient\" chưa được cài đặt. Mount CIFS/SMB shares là không thể thực hiện được. Hãy hỏi người quản trị hệ thống để cài đặt nó.",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "Cảnh báo: FTP trong PHP chưa được cài đặt hoặc chưa được mở. Mount FTP shares là không thể. Xin hãy yêu cầu quản trị hệ thống của bạn cài đặt nó.",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "Cảnh báo: Tính năng Curl trong PHP chưa được kích hoạt hoặc cài đặt. Việc gắn kết ownCloud / WebDAV hay GoogleDrive không thực hiện được. Vui lòng liên hệ người quản trị để cài đặt nó.",
"External Storage" => "Lưu trữ ngoài",
"Folder name" => "Tên thư mục",
+"External storage" => "Lưu trữ ngoài",
"Configuration" => "Cấu hình",
"Options" => "Tùy chọn",
"Applicable" => "Áp dụng",
+"Add storage" => "Thêm bộ nhớ",
"None set" => "không",
"All Users" => "Tất cả người dùng",
"Groups" => "Nhóm",
diff --git a/apps/files_external/l10n/zh_CN.GB2312.php b/apps/files_external/l10n/zh_CN.GB2312.php
index 74b9e3cad8134419b79993227992135b41cf5e93..47298f8007dbfc9b2fa59ceed1e90334347f357f 100644
--- a/apps/files_external/l10n/zh_CN.GB2312.php
+++ b/apps/files_external/l10n/zh_CN.GB2312.php
@@ -4,11 +4,16 @@
"Grant access" => "授予权限",
"Please provide a valid Dropbox app key and secret." => "请提供一个有效的 Dropbox app key 和 secret。",
"Error configuring Google Drive storage" => "配置 Google Drive 存储失败",
+"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "注意:“SMB客户端”未安装。CIFS/SMB分享不可用。请向您的系统管理员请求安装该客户端。",
+"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "注意:PHP的FTP支持尚未启用或未安装。FTP分享不可用。请向您的系统管理员请求安装。",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "警告: PHP 的 Curl 支持没有安装或打开。挂载 ownCloud、WebDAV 或 Google Drive 的功能将不可用。请询问您的系统管理员去安装它。",
"External Storage" => "外部存储",
"Folder name" => "文件夹名",
+"External storage" => "外部存储",
"Configuration" => "配置",
"Options" => "选项",
"Applicable" => "可应用",
+"Add storage" => "扩容",
"None set" => "未设置",
"All Users" => "所有用户",
"Groups" => "群组",
diff --git a/apps/files_external/l10n/zh_CN.php b/apps/files_external/l10n/zh_CN.php
index 7f95320511f99a165e7d3c8cbbf60465e4c502ef..8157923183cc92a1909a3b06cb7c28b1c8ec2089 100644
--- a/apps/files_external/l10n/zh_CN.php
+++ b/apps/files_external/l10n/zh_CN.php
@@ -6,6 +6,7 @@
"Error configuring Google Drive storage" => "配置Google Drive存储时出错",
"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "警告:“smbclient” 尚未安装。CIFS/SMB 分享挂载无法实现。请咨询系统管理员进行安装。",
"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "警告:PHP中尚未启用或安装FTP。FTP 分享挂载无法实现。请咨询系统管理员进行安装。",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "警告: PHP中未启用或未安装Curl支持。ownCloud / WebDAV 或 GoogleDrive 不能挂载。请请求您的系统管理员安装该它。",
"External Storage" => "外部存储",
"Folder name" => "目录名称",
"External storage" => "外部存储",
diff --git a/apps/files_external/l10n/zh_TW.php b/apps/files_external/l10n/zh_TW.php
index 512a151a3c88b3c9756f725f832564419a0b2513..a8314dcef03660b8b3ecd734b66c340f5fb3c610 100644
--- a/apps/files_external/l10n/zh_TW.php
+++ b/apps/files_external/l10n/zh_TW.php
@@ -1,10 +1,26 @@
"外部儲存裝置",
+"Access granted" => "允許存取",
+"Error configuring Dropbox storage" => "設定 Dropbox 儲存時發生錯誤",
+"Grant access" => "允許存取",
+"Please provide a valid Dropbox app key and secret." => "請提供有效的 Dropbox app key 和 app secret 。",
+"Error configuring Google Drive storage" => "設定 Google Drive 儲存時發生錯誤",
+"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "警告:未安裝 \"smbclient\" ,因此無法掛載 CIFS/SMB 分享,請洽您的系統管理員將其安裝。",
+"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "警告:PHP 並未啓用 FTP 的支援,因此無法掛載 FTP 分享,請洽您的系統管理員將其安裝並啓用。",
+"Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "警告:PHP 並未啓用 Curl 的支援,因此無法掛載 ownCloud/WebDAV 或 Google Drive 分享,請洽您的系統管理員將其安裝並啓用。",
+"External Storage" => "外部儲存",
"Folder name" => "資料夾名稱",
+"External storage" => "外部儲存",
+"Configuration" => "設定",
+"Options" => "選項",
+"Applicable" => "可用的",
+"Add storage" => "增加儲存區",
"None set" => "尚未設定",
"All Users" => "所有使用者",
"Groups" => "群組",
"Users" => "使用者",
"Delete" => "刪除",
+"Enable User External Storage" => "啓用使用者外部儲存",
+"Allow users to mount their own external storage" => "允許使用者自行掛載他們的外部儲存",
+"SSL root certificates" => "SSL 根憑證",
"Import Root Certificate" => "匯入根憑證"
);
diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php
index 11d24045fd9012fc76dbd53e5bff837c61b5b780..4cb9b7c8ecdc4751b24a3828a5b9b1bd769a740c 100755
--- a/apps/files_external/lib/config.php
+++ b/apps/files_external/lib/config.php
@@ -70,7 +70,7 @@ class OC_Mount_Config {
'root' => '&Root',
'secure' => '!Secure ftps://'));
- $backends['\OC\Files\Storage\Google']=array(
+ if(OC_Mount_Config::checkcurl()) $backends['\OC\Files\Storage\Google']=array(
'backend' => 'Google Drive',
'configuration' => array(
'configured' => '#configured',
@@ -96,7 +96,7 @@ class OC_Mount_Config {
'share' => 'Share',
'root' => '&Root'));
- $backends['\OC\Files\Storage\DAV']=array(
+ if(OC_Mount_Config::checkcurl()) $backends['\OC\Files\Storage\DAV']=array(
'backend' => 'ownCloud / WebDAV',
'configuration' => array(
'host' => 'URL',
@@ -339,6 +339,7 @@ class OC_Mount_Config {
}
$content = json_encode($data);
@file_put_contents($file, $content);
+ @chmod($file, 0640);
}
/**
@@ -413,6 +414,13 @@ class OC_Mount_Config {
}
}
+ /**
+ * check if curl is installed
+ */
+ public static function checkcurl() {
+ return (function_exists('curl_init'));
+ }
+
/**
* check dependencies
*/
@@ -425,6 +433,9 @@ class OC_Mount_Config {
if(!OC_Mount_Config::checkphpftp()) {
$txt.=$l->t('Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it.').' ';
}
+ if(!OC_Mount_Config::checkcurl()) {
+ $txt.=$l->t('Warning: The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it.').' ';
+ }
return($txt);
}
diff --git a/apps/files_external/lib/dropbox.php b/apps/files_external/lib/dropbox.php
index cb04e557f8a6b2b3c01a26e0a32330bd3c04cd65..081c54788814788ba2d7cd63142dbb08ba103543 100755
--- a/apps/files_external/lib/dropbox.php
+++ b/apps/files_external/lib/dropbox.php
@@ -45,7 +45,6 @@ class Dropbox extends \OC\Files\Storage\Common {
$oauth = new \Dropbox_OAuth_Curl($params['app_key'], $params['app_secret']);
$oauth->setToken($params['token'], $params['token_secret']);
$this->dropbox = new \Dropbox_API($oauth, 'dropbox');
- $this->mkdir('');
} else {
throw new \Exception('Creating \OC\Files\Storage\Dropbox storage failed');
}
diff --git a/apps/files_external/lib/ftp.php b/apps/files_external/lib/ftp.php
index 8a7375ebe38730a270ba74ea1f275543e100fffd..ca6c635eb2b802812e8a3ef43d5dca6538e3760c 100644
--- a/apps/files_external/lib/ftp.php
+++ b/apps/files_external/lib/ftp.php
@@ -35,10 +35,6 @@ class FTP extends \OC\Files\Storage\StreamWrapper{
if ( ! $this->root || $this->root[0]!='/') {
$this->root='/'.$this->root;
}
- //create the root folder if necessary
- if ( ! $this->is_dir('')) {
- $this->mkdir('');
- }
} else {
throw new \Exception();
}
@@ -63,7 +59,6 @@ class FTP extends \OC\Files\Storage\StreamWrapper{
return $url;
}
public function fopen($path,$mode) {
- $this->init();
switch($mode) {
case 'r':
case 'rb':
@@ -100,7 +95,6 @@ class FTP extends \OC\Files\Storage\StreamWrapper{
}
public function writeBack($tmpFile) {
- $this->init();
if (isset(self::$tempFiles[$tmpFile])) {
$this->uploadFile($tmpFile, self::$tempFiles[$tmpFile]);
unlink($tmpFile);
diff --git a/apps/files_external/lib/sftp.php b/apps/files_external/lib/sftp.php
index ede6c251fd9e18463590b04ff7ee72a725c5f536..4fd360964631d652372d454d2097700d2b68d6cf 100644
--- a/apps/files_external/lib/sftp.php
+++ b/apps/files_external/lib/sftp.php
@@ -50,10 +50,6 @@ class SFTP extends \OC\Files\Storage\Common {
$host_keys[$this->host] = $current_host_key;
$this->write_host_keys($host_keys);
}
-
- if(!$this->file_exists('')){
- $this->mkdir('');
- }
}
public function test() {
diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php
index 961efb1a50a43123a43d299296cbb30d305875c7..81a6c95638591115d7740496e313571fb35bbcf6 100644
--- a/apps/files_external/lib/smb.php
+++ b/apps/files_external/lib/smb.php
@@ -57,12 +57,22 @@ class SMB extends \OC\Files\Storage\StreamWrapper{
public function stat($path) {
if ( ! $path and $this->root=='/') {//mtime doesn't work for shares
- $mtime=$this->shareMTime();
$stat=stat($this->constructUrl($path));
+ if (empty($stat)) {
+ return false;
+ }
+ $mtime=$this->shareMTime();
$stat['mtime']=$mtime;
return $stat;
} else {
- return stat($this->constructUrl($path));
+ $stat = stat($this->constructUrl($path));
+
+ // smb4php can return an empty array if the connection could not be established
+ if (empty($stat)) {
+ return false;
+ }
+
+ return $stat;
}
}
@@ -73,7 +83,6 @@ class SMB extends \OC\Files\Storage\StreamWrapper{
* @return bool
*/
public function hasUpdated($path,$time) {
- $this->init();
if(!$path and $this->root=='/') {
// mtime doesn't work for shares, but giving the nature of the backend,
// doing a full update is still just fast enough
diff --git a/apps/files_external/lib/streamwrapper.php b/apps/files_external/lib/streamwrapper.php
index 4685877f26b7ea0bb0d7266bfceb897afa08f809..09041f335b46517a6076edb15f2db942a53aa9fc 100644
--- a/apps/files_external/lib/streamwrapper.php
+++ b/apps/files_external/lib/streamwrapper.php
@@ -8,46 +8,28 @@
namespace OC\Files\Storage;
-abstract class StreamWrapper extends \OC\Files\Storage\Common{
- private $ready = false;
-
- protected function init(){
- if($this->ready) {
- return;
- }
- $this->ready = true;
-
- //create the root folder if necesary
- if(!$this->is_dir('')) {
- $this->mkdir('');
- }
- }
-
+abstract class StreamWrapper extends Common{
abstract public function constructUrl($path);
public function mkdir($path) {
- $this->init();
return mkdir($this->constructUrl($path));
}
public function rmdir($path) {
- $this->init();
if($this->file_exists($path)) {
- $succes = rmdir($this->constructUrl($path));
+ $success = rmdir($this->constructUrl($path));
clearstatcache();
- return $succes;
+ return $success;
} else {
return false;
}
}
public function opendir($path) {
- $this->init();
return opendir($this->constructUrl($path));
}
public function filetype($path) {
- $this->init();
return filetype($this->constructUrl($path));
}
@@ -60,24 +42,20 @@ abstract class StreamWrapper extends \OC\Files\Storage\Common{
}
public function file_exists($path) {
- $this->init();
return file_exists($this->constructUrl($path));
}
public function unlink($path) {
- $this->init();
- $succes = unlink($this->constructUrl($path));
+ $success = unlink($this->constructUrl($path));
clearstatcache();
- return $succes;
+ return $success;
}
public function fopen($path, $mode) {
- $this->init();
return fopen($this->constructUrl($path), $mode);
}
public function touch($path, $mtime=null) {
- $this->init();
if(is_null($mtime)) {
$fh = $this->fopen($path, 'a');
fwrite($fh, '');
@@ -88,22 +66,18 @@ abstract class StreamWrapper extends \OC\Files\Storage\Common{
}
public function getFile($path, $target) {
- $this->init();
return copy($this->constructUrl($path), $target);
}
public function uploadFile($path, $target) {
- $this->init();
return copy($path, $this->constructUrl($target));
}
public function rename($path1, $path2) {
- $this->init();
return rename($this->constructUrl($path1), $this->constructUrl($path2));
}
public function stat($path) {
- $this->init();
return stat($this->constructUrl($path));
}
diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php
index 68c4b48f17c18ae41562bc9a3f44122517bb10ac..a9cfe5bd20f69807f21a59f4920a38f25a656e80 100644
--- a/apps/files_external/lib/swift.php
+++ b/apps/files_external/lib/swift.php
@@ -287,6 +287,7 @@ class SWIFT extends \OC\Files\Storage\Common{
if ( ! $this->root || $this->root[0]!='/') {
$this->root='/'.$this->root;
}
+ $this->id = 'swift:' . $this->host . ':'.$this->root . ':' . $this->user;
} else {
throw new \Exception();
}
diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php
index 3ba7c48cd5742adcabbb94bc831364ee4c2f2ae2..c2fe7c67b582e994f65e60215d797590327665a0 100644
--- a/apps/files_external/lib/webdav.php
+++ b/apps/files_external/lib/webdav.php
@@ -73,8 +73,6 @@ class DAV extends \OC\Files\Storage\Common{
$this->client->addTrustedCertificates($certPath);
}
}
- //create the root folder if necessary
- $this->mkdir('');
}
public function getId(){
diff --git a/apps/files_external/settings.php b/apps/files_external/settings.php
index 1a39affe2e6606e0d9cf439a8eaff63b139d578d..31183409e3965b5c2b73cac6066fb38be171ce96 100644
--- a/apps/files_external/settings.php
+++ b/apps/files_external/settings.php
@@ -32,6 +32,7 @@ $tmpl->assign('mounts', OC_Mount_Config::getSystemMountPoints());
$tmpl->assign('backends', OC_Mount_Config::getBackends());
$tmpl->assign('groups', OC_Group::getGroups());
$tmpl->assign('users', OCP\User::getUsers());
+$tmpl->assign('userDisplayNames', OC_User::getDisplayNames());
$tmpl->assign('dependencies', OC_Mount_Config::checkDependencies());
$tmpl->assign('allowUserMounting', OCP\Config::getAppValue('files_external', 'allow_user_mounting', 'yes'));
return $tmpl->fetchPage();
diff --git a/apps/files_external/templates/settings.php b/apps/files_external/templates/settings.php
index b3b94a1dafd8dd19a8673d2bffed221ba63e0c68..b3c08e212251da025bc621e314158ed4a7fd7a13 100644
--- a/apps/files_external/templates/settings.php
+++ b/apps/files_external/templates/settings.php
@@ -102,7 +102,7 @@
+ >
diff --git a/apps/files_external/tests/config.php b/apps/files_external/tests/config.php
index 1d4f30c713dd00e098172da16be1a81453f0754f..bac594b485f36d25017f8cdea63ba72c30de6990 100644
--- a/apps/files_external/tests/config.php
+++ b/apps/files_external/tests/config.php
@@ -1,4 +1,13 @@
use them
+$privateConfigFile = $_SERVER['HOME'] . '/owncloud-extfs-test-config.php';
+if (file_exists($privateConfigFile)) {
+ $config = include($privateConfigFile);
+ return $config;
+}
+
+// this is now more a template now for your private configurations
return array(
'ftp'=>array(
'run'=>false,
diff --git a/apps/files_external/tests/ftp.php b/apps/files_external/tests/ftp.php
index 923b5e39681bd144a4adb3952d94ee17a92a1276..e146725473ac2bfb3444090a03ebfde58db86836 100644
--- a/apps/files_external/tests/ftp.php
+++ b/apps/files_external/tests/ftp.php
@@ -19,6 +19,7 @@ class FTP extends Storage {
}
$this->config['ftp']['root'] .= '/' . $id; //make sure we have an new empty folder to work in
$this->instance = new \OC\Files\Storage\FTP($this->config['ftp']);
+ $this->instance->mkdir('/');
}
public function tearDown() {
diff --git a/apps/files_external/tests/sftp.php b/apps/files_external/tests/sftp.php
index 16964e208781c34b4d8ecce4d90230496b51c2fe..efea7f075ff20d48d19d4b49a5e68448a023d423 100644
--- a/apps/files_external/tests/sftp.php
+++ b/apps/files_external/tests/sftp.php
@@ -33,6 +33,7 @@ class SFTP extends Storage {
}
$this->config['sftp']['root'] .= '/' . $id; //make sure we have an new empty folder to work in
$this->instance = new \OC\Files\Storage\SFTP($this->config['sftp']);
+ $this->instance->mkdir('/');
}
public function tearDown() {
@@ -40,4 +41,4 @@ class SFTP extends Storage {
$this->instance->rmdir('/');
}
}
-}
\ No newline at end of file
+}
diff --git a/apps/files_external/tests/smb.php b/apps/files_external/tests/smb.php
index be3ea5a8308baed4a36ecfd70dfce9a04f28ca2e..ca2a93c894449f5584be40d6b996cc339b3aec89 100644
--- a/apps/files_external/tests/smb.php
+++ b/apps/files_external/tests/smb.php
@@ -20,6 +20,7 @@ class SMB extends Storage {
}
$this->config['smb']['root'] .= $id; //make sure we have an new empty folder to work in
$this->instance = new \OC\Files\Storage\SMB($this->config['smb']);
+ $this->instance->mkdir('/');
}
public function tearDown() {
diff --git a/apps/files_external/tests/webdav.php b/apps/files_external/tests/webdav.php
index 1702898045e772f34da117641a5038a8264dc753..1f9b767eca69d24ca1fff865471972f7c6a79eb6 100644
--- a/apps/files_external/tests/webdav.php
+++ b/apps/files_external/tests/webdav.php
@@ -20,6 +20,7 @@ class DAV extends Storage {
}
$this->config['webdav']['root'] .= '/' . $id; //make sure we have an new empty folder to work in
$this->instance = new \OC\Files\Storage\DAV($this->config['webdav']);
+ $this->instance->mkdir('/');
}
public function tearDown() {
diff --git a/apps/files_sharing/css/public.css b/apps/files_sharing/css/public.css
index 13298f113f8f767f707374bffe612f37aa455624..b6511cb57cca2791f5d5eda73a5d01d2004fcdd4 100644
--- a/apps/files_sharing/css/public.css
+++ b/apps/files_sharing/css/public.css
@@ -17,14 +17,29 @@ body {
#details {
color:#fff;
+ float: left;
}
-#header #download {
+#public_upload,
+#download {
font-weight:700;
- margin-left:2em;
+ margin: 0 0.4em 0 0;
+ padding: 0 5px;
+ height: 27px;
+ float: left;
+
+}
+
+.header-right #details {
+ margin-right: 2em;
+}
+
+#public_upload {
+ margin-left: 0.3em;
}
-#header #download img {
+#public_upload img,
+#download img {
padding-left:.1em;
padding-right:.3em;
vertical-align:text-bottom;
@@ -73,3 +88,49 @@ thead{
background-color: white;
padding-left:0 !important; /* fixes multiselect bar offset on shared page */
}
+
+#data-upload-form {
+ position: relative;
+ right: 0;
+ height: 27px;
+ overflow: hidden;
+ padding: 0;
+ float: right;
+ display: inline;
+ margin: 0;
+}
+
+#file_upload_start {
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
+ filter: alpha(opacity=0);
+ opacity: 0;
+ z-index: 20;
+ position: absolute !important;
+ top: 0;
+ left: 0;
+ width: 100% !important;
+}
+
+#download span {
+ position: relative;
+ bottom: 3px;
+}
+
+#publicUploadButtonMock {
+ position:relative;
+ display:block;
+ width:100%;
+ height:27px;
+ cursor:pointer;
+ z-index:10;
+ background-image:url('%webroot%/core/img/actions/upload.svg');
+ background-repeat:no-repeat;
+ background-position:7px 6px;
+}
+
+#publicUploadButtonMock span {
+ margin: 0 5px 0 28px;
+ position: relative;
+ top: -2px;
+ color: #555;
+}
diff --git a/apps/files_sharing/js/public.js b/apps/files_sharing/js/public.js
index 916e35419c1b4aec563d8ba070d3fde7f3408cf7..294223aa094844640debf983731e83820dfae26f 100644
--- a/apps/files_sharing/js/public.js
+++ b/apps/files_sharing/js/public.js
@@ -7,8 +7,12 @@ function fileDownloadPath(dir, file) {
return url;
}
+var form_data;
+
$(document).ready(function() {
+ $('#data-upload-form').tipsy({gravity:'ne', fade:true});
+
if (typeof FileActions !== 'undefined') {
var mimetype = $('#mimetype').val();
// Show file preview if previewer is available, images are already handled by the template
@@ -46,4 +50,19 @@ $(document).ready(function() {
});
}
-});
\ No newline at end of file
+ // Add some form data to the upload handler
+ file_upload_param.formData = {
+ MAX_FILE_SIZE: $('#uploadMaxFilesize').val(),
+ requesttoken: $('#publicUploadRequestToken').val(),
+ dirToken: $('#dirToken').val(),
+ appname: 'files_sharing',
+ subdir: $('input#dir').val()
+ };
+
+ // Add Uploadprogress Wrapper to controls bar
+ $('#controls').append($('#additional_controls div#uploadprogresswrapper'));
+
+ // Cancel upload trigger
+ $('#cancel_upload_button').click(Files.cancelUploads);
+
+});
diff --git a/apps/files_sharing/l10n/af_ZA.php b/apps/files_sharing/l10n/af_ZA.php
index 344585a62fc16076649abc43618c0ad75195994e..04e194530b1579dd85e08b1ccdacee1964f70d0e 100644
--- a/apps/files_sharing/l10n/af_ZA.php
+++ b/apps/files_sharing/l10n/af_ZA.php
@@ -1,4 +1,3 @@
"Wagwoord",
-"web services under your control" => "webdienste onder jou beheer"
+"Password" => "Wagwoord"
);
diff --git a/apps/files_sharing/l10n/ar.php b/apps/files_sharing/l10n/ar.php
index 4cf3f8c092061fc4b8f842b4faa4bb35c41f7d73..043c7ee1b27781ea5ceb5be6fa4eec1430a0cd3b 100644
--- a/apps/files_sharing/l10n/ar.php
+++ b/apps/files_sharing/l10n/ar.php
@@ -4,6 +4,7 @@
"%s shared the folder %s with you" => "%s شارك المجلد %s معك",
"%s shared the file %s with you" => "%s شارك الملف %s معك",
"Download" => "تحميل",
-"No preview available for" => "لا يوجد عرض مسبق لـ",
-"web services under your control" => "خدمات الشبكة تحت سيطرتك"
+"Upload" => "رفع",
+"Cancel upload" => "إلغاء رفع الملفات",
+"No preview available for" => "لا يوجد عرض مسبق لـ"
);
diff --git a/apps/files_sharing/l10n/bg_BG.php b/apps/files_sharing/l10n/bg_BG.php
index ac94358c4f9690de89281d20a58ece3202fe2500..8e719ba23562924b2b957067e2416d615b9e1d0f 100644
--- a/apps/files_sharing/l10n/bg_BG.php
+++ b/apps/files_sharing/l10n/bg_BG.php
@@ -4,6 +4,7 @@
"%s shared the folder %s with you" => "%s сподели папката %s с Вас",
"%s shared the file %s with you" => "%s сподели файла %s с Вас",
"Download" => "Изтегляне",
-"No preview available for" => "Няма наличен преглед за",
-"web services under your control" => "уеб услуги под Ваш контрол"
+"Upload" => "Качване",
+"Cancel upload" => "Спри качването",
+"No preview available for" => "Няма наличен преглед за"
);
diff --git a/apps/files_sharing/l10n/bn_BD.php b/apps/files_sharing/l10n/bn_BD.php
index c3af434ee2934d590c2467400afb792661c9cbc0..baa0c5c707c8af76dc77ab4de89a2cbcc53093f5 100644
--- a/apps/files_sharing/l10n/bn_BD.php
+++ b/apps/files_sharing/l10n/bn_BD.php
@@ -1,9 +1,10 @@
"কূটশব্দ",
-"Submit" => "জমা দাও",
+"Submit" => "জমা দিন",
"%s shared the folder %s with you" => "%s আপনার সাথে %s ফোল্ডারটি ভাগাভাগি করেছেন",
"%s shared the file %s with you" => "%s আপনার সাথে %s ফাইলটি ভাগাভাগি করেছেন",
"Download" => "ডাউনলোড",
-"No preview available for" => "এর জন্য কোন প্রাকবীক্ষণ সুলভ নয়",
-"web services under your control" => "ওয়েব সার্ভিস আপনার হাতের মুঠোয়"
+"Upload" => "আপলোড",
+"Cancel upload" => "আপলোড বাতিল কর",
+"No preview available for" => "এর জন্য কোন প্রাকবীক্ষণ সুলভ নয়"
);
diff --git a/apps/files_sharing/l10n/ca.php b/apps/files_sharing/l10n/ca.php
index 223495455f0e3fad598dd0a967602b3675da0c03..9d2ab5031c13825586b84f108a69cc2b01812ce7 100644
--- a/apps/files_sharing/l10n/ca.php
+++ b/apps/files_sharing/l10n/ca.php
@@ -1,9 +1,11 @@
"la contrasenya és incorrecta. Intenteu-ho de nou.",
"Password" => "Contrasenya",
"Submit" => "Envia",
"%s shared the folder %s with you" => "%s ha compartit la carpeta %s amb vós",
"%s shared the file %s with you" => "%s ha compartit el fitxer %s amb vós",
"Download" => "Baixa",
-"No preview available for" => "No hi ha vista prèvia disponible per a",
-"web services under your control" => "controleu els vostres serveis web"
+"Upload" => "Puja",
+"Cancel upload" => "Cancel·la la pujada",
+"No preview available for" => "No hi ha vista prèvia disponible per a"
);
diff --git a/apps/files_sharing/l10n/cs_CZ.php b/apps/files_sharing/l10n/cs_CZ.php
index 9889fae488ab838432fe2a464ddff73759d01495..a57764a18bc49a646370a74e12197b5486914a15 100644
--- a/apps/files_sharing/l10n/cs_CZ.php
+++ b/apps/files_sharing/l10n/cs_CZ.php
@@ -4,6 +4,7 @@
"%s shared the folder %s with you" => "%s s Vámi sdílí složku %s",
"%s shared the file %s with you" => "%s s Vámi sdílí soubor %s",
"Download" => "Stáhnout",
-"No preview available for" => "Náhled není dostupný pro",
-"web services under your control" => "služby webu pod Vaší kontrolou"
+"Upload" => "Odeslat",
+"Cancel upload" => "Zrušit odesílání",
+"No preview available for" => "Náhled není dostupný pro"
);
diff --git a/apps/files_sharing/l10n/cy_GB.php b/apps/files_sharing/l10n/cy_GB.php
new file mode 100644
index 0000000000000000000000000000000000000000..6ff3e274c39af1ceaaf70d0ea43178bcb3ac90c5
--- /dev/null
+++ b/apps/files_sharing/l10n/cy_GB.php
@@ -0,0 +1,10 @@
+ "Cyfrinair",
+"Submit" => "Cyflwyno",
+"%s shared the folder %s with you" => "Rhannodd %s blygell %s â chi",
+"%s shared the file %s with you" => "Rhannodd %s ffeil %s â chi",
+"Download" => "Llwytho i lawr",
+"Upload" => "Llwytho i fyny",
+"Cancel upload" => "Diddymu llwytho i fyny",
+"No preview available for" => "Does dim rhagolwg ar gael ar gyfer"
+);
diff --git a/apps/files_sharing/l10n/da.php b/apps/files_sharing/l10n/da.php
index 75fbdabe16f0f20070e72022a8201b13658a87b1..e3e469a4e51bce6edd12fc221806345b09873091 100644
--- a/apps/files_sharing/l10n/da.php
+++ b/apps/files_sharing/l10n/da.php
@@ -4,6 +4,7 @@
"%s shared the folder %s with you" => "%s delte mappen %s med dig",
"%s shared the file %s with you" => "%s delte filen %s med dig",
"Download" => "Download",
-"No preview available for" => "Forhåndsvisning ikke tilgængelig for",
-"web services under your control" => "Webtjenester under din kontrol"
+"Upload" => "Upload",
+"Cancel upload" => "Fortryd upload",
+"No preview available for" => "Forhåndsvisning ikke tilgængelig for"
);
diff --git a/apps/files_sharing/l10n/de.php b/apps/files_sharing/l10n/de.php
index 7f4cbb1adad59c2c2792ea1856ad692b1ced313d..ad2d171aa9f2a0607eff9125550af65e0b94bb50 100644
--- a/apps/files_sharing/l10n/de.php
+++ b/apps/files_sharing/l10n/de.php
@@ -1,9 +1,11 @@
"Bitte überprüfen sie Ihr Passwort und versuchen Sie es erneut.",
"Password" => "Passwort",
"Submit" => "Absenden",
"%s shared the folder %s with you" => "%s hat den Ordner %s mit Dir geteilt",
"%s shared the file %s with you" => "%s hat die Datei %s mit Dir geteilt",
"Download" => "Download",
-"No preview available for" => "Es ist keine Vorschau verfügbar für",
-"web services under your control" => "Web-Services unter Deiner Kontrolle"
+"Upload" => "Hochladen",
+"Cancel upload" => "Upload abbrechen",
+"No preview available for" => "Es ist keine Vorschau verfügbar für"
);
diff --git a/apps/files_sharing/l10n/de_DE.php b/apps/files_sharing/l10n/de_DE.php
index b92d6d478c9ae99203a0e7fa377742a85a54d067..cac7b7591d66f560cca368112db490c8c812310d 100644
--- a/apps/files_sharing/l10n/de_DE.php
+++ b/apps/files_sharing/l10n/de_DE.php
@@ -1,9 +1,11 @@
"Das Passwort ist falsch. Bitte versuchen Sie es erneut.",
"Password" => "Passwort",
-"Submit" => "Absenden",
+"Submit" => "Bestätigen",
"%s shared the folder %s with you" => "%s hat den Ordner %s mit Ihnen geteilt",
"%s shared the file %s with you" => "%s hat die Datei %s mit Ihnen geteilt",
-"Download" => "Download",
-"No preview available for" => "Es ist keine Vorschau verfügbar für",
-"web services under your control" => "Web-Services unter Ihrer Kontrolle"
+"Download" => "Herunterladen",
+"Upload" => "Hochladen",
+"Cancel upload" => "Upload abbrechen",
+"No preview available for" => "Es ist keine Vorschau verfügbar für"
);
diff --git a/apps/files_sharing/l10n/el.php b/apps/files_sharing/l10n/el.php
index 5305eedd484476a7c1f5ab5cb90d50ffb64ebffc..b7b893537186f831731d6491ee43e00c1a9b17bd 100644
--- a/apps/files_sharing/l10n/el.php
+++ b/apps/files_sharing/l10n/el.php
@@ -4,6 +4,7 @@
"%s shared the folder %s with you" => "%s μοιράστηκε τον φάκελο %s μαζί σας",
"%s shared the file %s with you" => "%s μοιράστηκε το αρχείο %s μαζί σας",
"Download" => "Λήψη",
-"No preview available for" => "Δεν υπάρχει διαθέσιμη προεπισκόπηση για",
-"web services under your control" => "υπηρεσίες δικτύου υπό τον έλεγχό σας"
+"Upload" => "Μεταφόρτωση",
+"Cancel upload" => "Ακύρωση αποστολής",
+"No preview available for" => "Δεν υπάρχει διαθέσιμη προεπισκόπηση για"
);
diff --git a/apps/files_sharing/l10n/en@pirate.php b/apps/files_sharing/l10n/en@pirate.php
new file mode 100644
index 0000000000000000000000000000000000000000..cb40c5a168088bf194258df39224b23268a651ee
--- /dev/null
+++ b/apps/files_sharing/l10n/en@pirate.php
@@ -0,0 +1,8 @@
+ "Secret Code",
+"Submit" => "Submit",
+"%s shared the folder %s with you" => "%s shared the folder %s with you",
+"%s shared the file %s with you" => "%s shared the file %s with you",
+"Download" => "Download",
+"No preview available for" => "No preview available for"
+);
diff --git a/apps/files_sharing/l10n/eo.php b/apps/files_sharing/l10n/eo.php
index c598d3aa2c4ac84a3bde24f6ce48d28c377fbb36..d3ca5370a2c7947efa339341143c66b2d8ecbcf6 100644
--- a/apps/files_sharing/l10n/eo.php
+++ b/apps/files_sharing/l10n/eo.php
@@ -4,6 +4,7 @@
"%s shared the folder %s with you" => "%s kunhavigis la dosierujon %s kun vi",
"%s shared the file %s with you" => "%s kunhavigis la dosieron %s kun vi",
"Download" => "Elŝuti",
-"No preview available for" => "Ne haveblas antaŭvido por",
-"web services under your control" => "TTT-servoj regataj de vi"
+"Upload" => "Alŝuti",
+"Cancel upload" => "Nuligi alŝuton",
+"No preview available for" => "Ne haveblas antaŭvido por"
);
diff --git a/apps/files_sharing/l10n/es.php b/apps/files_sharing/l10n/es.php
index 2023d35903e81e7760651cc3de6db93ca61e7d7f..1b65cf0c1903b13b8df0c056805fc1c55ff51207 100644
--- a/apps/files_sharing/l10n/es.php
+++ b/apps/files_sharing/l10n/es.php
@@ -1,9 +1,11 @@
"La contraseña introducida es errónea. Inténtelo de nuevo.",
"Password" => "Contraseña",
"Submit" => "Enviar",
"%s shared the folder %s with you" => "%s compartió la carpeta %s contigo",
"%s shared the file %s with you" => "%s compartió el fichero %s contigo",
"Download" => "Descargar",
-"No preview available for" => "No hay vista previa disponible para",
-"web services under your control" => "Servicios web bajo su control"
+"Upload" => "Subir",
+"Cancel upload" => "Cancelar subida",
+"No preview available for" => "No hay vista previa disponible para"
);
diff --git a/apps/files_sharing/l10n/es_AR.php b/apps/files_sharing/l10n/es_AR.php
index a2d6e232f2077d17fefd6c91a21148ded48937e2..90bfe704d22a8d102ba53af9d325c1dfa20e1c46 100644
--- a/apps/files_sharing/l10n/es_AR.php
+++ b/apps/files_sharing/l10n/es_AR.php
@@ -1,9 +1,11 @@
"La contraseña no es correcta. Probá de nuevo.",
"Password" => "Contraseña",
"Submit" => "Enviar",
"%s shared the folder %s with you" => "%s compartió la carpeta %s con vos",
"%s shared the file %s with you" => "%s compartió el archivo %s con vos",
"Download" => "Descargar",
-"No preview available for" => "La vista preliminar no está disponible para",
-"web services under your control" => "servicios web controlados por vos"
+"Upload" => "Subir",
+"Cancel upload" => "Cancelar subida",
+"No preview available for" => "La vista preliminar no está disponible para"
);
diff --git a/apps/files_sharing/l10n/et_EE.php b/apps/files_sharing/l10n/et_EE.php
index 36290ad2787e366e63a12568595dff734dd3648f..78fe436398c7d652a5b07c69a85eaaee173ca1a7 100644
--- a/apps/files_sharing/l10n/et_EE.php
+++ b/apps/files_sharing/l10n/et_EE.php
@@ -1,9 +1,11 @@
"Parool on vale. Proovi uuesti.",
"Password" => "Parool",
"Submit" => "Saada",
"%s shared the folder %s with you" => "%s jagas sinuga kausta %s",
"%s shared the file %s with you" => "%s jagas sinuga faili %s",
"Download" => "Lae alla",
-"No preview available for" => "Eelvaadet pole saadaval",
-"web services under your control" => "veebitenused sinu kontrolli all"
+"Upload" => "Lae üles",
+"Cancel upload" => "Tühista üleslaadimine",
+"No preview available for" => "Eelvaadet pole saadaval"
);
diff --git a/apps/files_sharing/l10n/eu.php b/apps/files_sharing/l10n/eu.php
index ebef0f445edf2d6526cb4aaa8f3e4a85310468f0..7a4559cb6556582498caa6127dda0e24fa5b6fb2 100644
--- a/apps/files_sharing/l10n/eu.php
+++ b/apps/files_sharing/l10n/eu.php
@@ -4,6 +4,7 @@
"%s shared the folder %s with you" => "%sk zurekin %s karpeta elkarbanatu du",
"%s shared the file %s with you" => "%sk zurekin %s fitxategia elkarbanatu du",
"Download" => "Deskargatu",
-"No preview available for" => "Ez dago aurrebista eskuragarririk hauentzat ",
-"web services under your control" => "web zerbitzuak zure kontrolpean"
+"Upload" => "Igo",
+"Cancel upload" => "Ezeztatu igoera",
+"No preview available for" => "Ez dago aurrebista eskuragarririk hauentzat "
);
diff --git a/apps/files_sharing/l10n/fa.php b/apps/files_sharing/l10n/fa.php
index 4313acae1ade0b40194270336fcd1ffe16eb0aee..7a744c8463d5cfd44fc1f9b553ad12f46699102f 100644
--- a/apps/files_sharing/l10n/fa.php
+++ b/apps/files_sharing/l10n/fa.php
@@ -1,9 +1,11 @@
"رمزعبور اشتباه می باشد. دوباره امتحان کنید.",
"Password" => "گذرواژه",
"Submit" => "ثبت",
"%s shared the folder %s with you" => "%sپوشه %s را با شما به اشتراک گذاشت",
"%s shared the file %s with you" => "%sفایل %s را با شما به اشتراک گذاشت",
"Download" => "دانلود",
-"No preview available for" => "هیچگونه پیش نمایشی موجود نیست",
-"web services under your control" => "سرویس های تحت وب در کنترل شما"
+"Upload" => "بارگزاری",
+"Cancel upload" => "متوقف کردن بار گذاری",
+"No preview available for" => "هیچگونه پیش نمایشی موجود نیست"
);
diff --git a/apps/files_sharing/l10n/fi_FI.php b/apps/files_sharing/l10n/fi_FI.php
index 6c441342133e171f691816548ce73e13e7c77b5f..03931bf29868ed13bd8f95c2998fce8c4e609bca 100644
--- a/apps/files_sharing/l10n/fi_FI.php
+++ b/apps/files_sharing/l10n/fi_FI.php
@@ -4,6 +4,7 @@
"%s shared the folder %s with you" => "%s jakoi kansion %s kanssasi",
"%s shared the file %s with you" => "%s jakoi tiedoston %s kanssasi",
"Download" => "Lataa",
-"No preview available for" => "Ei esikatselua kohteelle",
-"web services under your control" => "verkkopalvelut hallinnassasi"
+"Upload" => "Lähetä",
+"Cancel upload" => "Peru lähetys",
+"No preview available for" => "Ei esikatselua kohteelle"
);
diff --git a/apps/files_sharing/l10n/fr.php b/apps/files_sharing/l10n/fr.php
index 1038d819330557bf3082562b67ffbba0bb39acdf..32aa6e0065aeadee4a74256d1a34503ddd4dd616 100644
--- a/apps/files_sharing/l10n/fr.php
+++ b/apps/files_sharing/l10n/fr.php
@@ -1,9 +1,11 @@
"Le mot de passe est incorrect. Veuillez réessayer.",
"Password" => "Mot de passe",
"Submit" => "Envoyer",
"%s shared the folder %s with you" => "%s a partagé le répertoire %s avec vous",
"%s shared the file %s with you" => "%s a partagé le fichier %s avec vous",
"Download" => "Télécharger",
-"No preview available for" => "Pas d'aperçu disponible pour",
-"web services under your control" => "services web sous votre contrôle"
+"Upload" => "Envoyer",
+"Cancel upload" => "Annuler l'envoi",
+"No preview available for" => "Pas d'aperçu disponible pour"
);
diff --git a/apps/files_sharing/l10n/gl.php b/apps/files_sharing/l10n/gl.php
index d03f1a5005f49542b65b8637c6bc71221687e4b2..2d8de8e101972f8928909d8be11db12962e2da47 100644
--- a/apps/files_sharing/l10n/gl.php
+++ b/apps/files_sharing/l10n/gl.php
@@ -1,9 +1,11 @@
"O contrasinal é incorrecto. Ténteo de novo.",
"Password" => "Contrasinal",
"Submit" => "Enviar",
"%s shared the folder %s with you" => "%s compartiu o cartafol %s con vostede",
"%s shared the file %s with you" => "%s compartiu o ficheiro %s con vostede",
"Download" => "Descargar",
-"No preview available for" => "Sen vista previa dispoñíbel para",
-"web services under your control" => "servizos web baixo o seu control"
+"Upload" => "Enviar",
+"Cancel upload" => "Cancelar o envío",
+"No preview available for" => "Sen vista previa dispoñíbel para"
);
diff --git a/apps/files_sharing/l10n/he.php b/apps/files_sharing/l10n/he.php
index ff7be88af87ed7de04c0303ebe1476584e1d9b2f..41fc314f3c2c07bd266f116cc773b812dd7c26ab 100644
--- a/apps/files_sharing/l10n/he.php
+++ b/apps/files_sharing/l10n/he.php
@@ -1,9 +1,10 @@
"ססמה",
+"Password" => "סיסמא",
"Submit" => "שליחה",
"%s shared the folder %s with you" => "%s שיתף עמך את התיקייה %s",
"%s shared the file %s with you" => "%s שיתף עמך את הקובץ %s",
"Download" => "הורדה",
-"No preview available for" => "אין תצוגה מקדימה זמינה עבור",
-"web services under your control" => "שירותי רשת תחת השליטה שלך"
+"Upload" => "העלאה",
+"Cancel upload" => "ביטול ההעלאה",
+"No preview available for" => "אין תצוגה מקדימה זמינה עבור"
);
diff --git a/apps/files_sharing/l10n/hi.php b/apps/files_sharing/l10n/hi.php
new file mode 100644
index 0000000000000000000000000000000000000000..560df54fc94879dc4a36194c970aa8fc1400a6a7
--- /dev/null
+++ b/apps/files_sharing/l10n/hi.php
@@ -0,0 +1,3 @@
+ "पासवर्ड"
+);
diff --git a/apps/files_sharing/l10n/hr.php b/apps/files_sharing/l10n/hr.php
new file mode 100644
index 0000000000000000000000000000000000000000..d5763a8ddb8f9ef48be2a8cac0016a7f484c9987
--- /dev/null
+++ b/apps/files_sharing/l10n/hr.php
@@ -0,0 +1,7 @@
+ "Lozinka",
+"Submit" => "Pošalji",
+"Download" => "Preuzimanje",
+"Upload" => "Učitaj",
+"Cancel upload" => "Prekini upload"
+);
diff --git a/apps/files_sharing/l10n/hu_HU.php b/apps/files_sharing/l10n/hu_HU.php
index f8ca541260d10676aaf4c2733d4e59aae2e7f8ba..15ff6ff3c2bd90c9c4ed3d2a70ab687e339d1325 100644
--- a/apps/files_sharing/l10n/hu_HU.php
+++ b/apps/files_sharing/l10n/hu_HU.php
@@ -1,9 +1,11 @@
"A megadott jelszó nem megfelelő. Próbálja újra!",
"Password" => "Jelszó",
"Submit" => "Elküld",
"%s shared the folder %s with you" => "%s megosztotta Önnel ezt a mappát: %s",
"%s shared the file %s with you" => "%s megosztotta Önnel ezt az állományt: %s",
"Download" => "Letöltés",
-"No preview available for" => "Nem áll rendelkezésre előnézet ehhez: ",
-"web services under your control" => "webszolgáltatások saját kézben"
+"Upload" => "Feltöltés",
+"Cancel upload" => "A feltöltés megszakítása",
+"No preview available for" => "Nem áll rendelkezésre előnézet ehhez: "
);
diff --git a/apps/files_sharing/l10n/hy.php b/apps/files_sharing/l10n/hy.php
new file mode 100644
index 0000000000000000000000000000000000000000..438e8a7433cfde7ccdab2b0e2a3c466fb56a415f
--- /dev/null
+++ b/apps/files_sharing/l10n/hy.php
@@ -0,0 +1,4 @@
+ "Հաստատել",
+"Download" => "Բեռնել"
+);
diff --git a/apps/files_sharing/l10n/ia.php b/apps/files_sharing/l10n/ia.php
new file mode 100644
index 0000000000000000000000000000000000000000..01acba5108a1826f84e46f9b971c566bec173b33
--- /dev/null
+++ b/apps/files_sharing/l10n/ia.php
@@ -0,0 +1,6 @@
+ "Contrasigno",
+"Submit" => "Submitter",
+"Download" => "Discargar",
+"Upload" => "Incargar"
+);
diff --git a/apps/files_sharing/l10n/id.php b/apps/files_sharing/l10n/id.php
index 8897269d989ea4bafc894d8f2919b510e0653852..cc6e591834ca19ec3db0aafa8ca420422d73bd4e 100644
--- a/apps/files_sharing/l10n/id.php
+++ b/apps/files_sharing/l10n/id.php
@@ -1,9 +1,10 @@
"kata kunci",
-"Submit" => "kirim",
-"%s shared the folder %s with you" => "%s membagikan folder %s dengan anda",
-"%s shared the file %s with you" => "%s membagikan file %s dengan anda",
-"Download" => "unduh",
-"No preview available for" => "tidak ada pratinjau tersedia untuk",
-"web services under your control" => "servis web dibawah kendali anda"
+"Password" => "Sandi",
+"Submit" => "Kirim",
+"%s shared the folder %s with you" => "%s membagikan folder %s dengan Anda",
+"%s shared the file %s with you" => "%s membagikan file %s dengan Anda",
+"Download" => "Unduh",
+"Upload" => "Unggah",
+"Cancel upload" => "Batal pengunggahan",
+"No preview available for" => "Tidak ada pratinjau tersedia untuk"
);
diff --git a/apps/files_sharing/l10n/is.php b/apps/files_sharing/l10n/is.php
index bf1975c54ae271bb86a7b6b3b7ee0d4d08fd05a2..222459f7a00aa366f407b6de219db6cf52f2cfd4 100644
--- a/apps/files_sharing/l10n/is.php
+++ b/apps/files_sharing/l10n/is.php
@@ -4,6 +4,7 @@
"%s shared the folder %s with you" => "%s deildi möppunni %s með þér",
"%s shared the file %s with you" => "%s deildi skránni %s með þér",
"Download" => "Niðurhal",
-"No preview available for" => "Yfirlit ekki í boði fyrir",
-"web services under your control" => "vefþjónusta undir þinni stjórn"
+"Upload" => "Senda inn",
+"Cancel upload" => "Hætta við innsendingu",
+"No preview available for" => "Yfirlit ekki í boði fyrir"
);
diff --git a/apps/files_sharing/l10n/it.php b/apps/files_sharing/l10n/it.php
index f83ca1446d604b45fc54381999ded0cfdb84d37b..cf25c53ca388923aedaa8fa4d1e37c6f5cbf7613 100644
--- a/apps/files_sharing/l10n/it.php
+++ b/apps/files_sharing/l10n/it.php
@@ -1,9 +1,11 @@
"La password è errata. Prova ancora.",
"Password" => "Password",
"Submit" => "Invia",
"%s shared the folder %s with you" => "%s ha condiviso la cartella %s con te",
"%s shared the file %s with you" => "%s ha condiviso il file %s con te",
"Download" => "Scarica",
-"No preview available for" => "Nessuna anteprima disponibile per",
-"web services under your control" => "servizi web nelle tue mani"
+"Upload" => "Carica",
+"Cancel upload" => "Annulla il caricamento",
+"No preview available for" => "Nessuna anteprima disponibile per"
);
diff --git a/apps/files_sharing/l10n/ja_JP.php b/apps/files_sharing/l10n/ja_JP.php
index 02142e2879a98de6b3836b94d8097f1c0e49439d..d2bc2d11245a5c17f1f0470efd9a42db7ee9180f 100644
--- a/apps/files_sharing/l10n/ja_JP.php
+++ b/apps/files_sharing/l10n/ja_JP.php
@@ -1,9 +1,11 @@
"パスワードが間違っています。再試行してください。",
"Password" => "パスワード",
"Submit" => "送信",
"%s shared the folder %s with you" => "%s はフォルダー %s をあなたと共有中です",
"%s shared the file %s with you" => "%s はファイル %s をあなたと共有中です",
"Download" => "ダウンロード",
-"No preview available for" => "プレビューはありません",
-"web services under your control" => "管理下のウェブサービス"
+"Upload" => "アップロード",
+"Cancel upload" => "アップロードをキャンセル",
+"No preview available for" => "プレビューはありません"
);
diff --git a/apps/files_sharing/l10n/ka_GE.php b/apps/files_sharing/l10n/ka_GE.php
index ef42196d2cbf8cc38384b2b9100f433cb4808bec..c88cc59cf8dc88127a32640577f206814af037d3 100644
--- a/apps/files_sharing/l10n/ka_GE.php
+++ b/apps/files_sharing/l10n/ka_GE.php
@@ -1,6 +1,10 @@
"პაროლი",
"Submit" => "გაგზავნა",
+"%s shared the folder %s with you" => "%s–მა გაგიზიარათ ფოლდერი %s",
+"%s shared the file %s with you" => "%s–მა გაგიზიარათ ფაილი %s",
"Download" => "ჩამოტვირთვა",
-"web services under your control" => "web services under your control"
+"Upload" => "ატვირთვა",
+"Cancel upload" => "ატვირთვის გაუქმება",
+"No preview available for" => "წინასწარი დათვალიერება შეუძლებელია"
);
diff --git a/apps/files_sharing/l10n/ko.php b/apps/files_sharing/l10n/ko.php
index 600168d9bfa86e73c16ea8ed44fd88383cf30e13..d2cf52447f17cdd8f0fc02fa32c02e66cb65ebcb 100644
--- a/apps/files_sharing/l10n/ko.php
+++ b/apps/files_sharing/l10n/ko.php
@@ -4,6 +4,7 @@
"%s shared the folder %s with you" => "%s 님이 폴더 %s을(를) 공유하였습니다",
"%s shared the file %s with you" => "%s 님이 파일 %s을(를) 공유하였습니다",
"Download" => "다운로드",
-"No preview available for" => "다음 항목을 미리 볼 수 없음:",
-"web services under your control" => "내가 관리하는 웹 서비스"
+"Upload" => "업로드",
+"Cancel upload" => "업로드 취소",
+"No preview available for" => "다음 항목을 미리 볼 수 없음:"
);
diff --git a/apps/files_sharing/l10n/ku_IQ.php b/apps/files_sharing/l10n/ku_IQ.php
index f139b0a06438f16c8ae797d1bee15cf9b221ddd2..576671aaa754d8749db5f7ffdab06fdf49f0d660 100644
--- a/apps/files_sharing/l10n/ku_IQ.php
+++ b/apps/files_sharing/l10n/ku_IQ.php
@@ -1,9 +1,9 @@
"تێپهڕهوشه",
+"Password" => "وشەی تێپەربو",
"Submit" => "ناردن",
"%s shared the folder %s with you" => "%s دابهشی کردووه بوخچهی %s لهگهڵ تۆ",
"%s shared the file %s with you" => "%s دابهشی کردووه پهڕگهیی %s لهگهڵ تۆ",
"Download" => "داگرتن",
-"No preview available for" => "هیچ پێشبینیهك ئاماده نیه بۆ",
-"web services under your control" => "ڕاژهی وێب لهژێر چاودێریت دایه"
+"Upload" => "بارکردن",
+"No preview available for" => "هیچ پێشبینیهك ئاماده نیه بۆ"
);
diff --git a/apps/files_sharing/l10n/lb.php b/apps/files_sharing/l10n/lb.php
index 8aba5806aa03c9ece3e8630f7e065da5a293c302..a604affee64501a4c0ee7a60c36534e2e80a9eb9 100644
--- a/apps/files_sharing/l10n/lb.php
+++ b/apps/files_sharing/l10n/lb.php
@@ -1,3 +1,11 @@
"Passwuert"
+"The password is wrong. Try again." => "Den Passwuert ass incorrect. Probeier ed nach eng keier.",
+"Password" => "Passwuert",
+"Submit" => "Fortschécken",
+"%s shared the folder %s with you" => "%s huet den Dossier %s mad der gedeelt",
+"%s shared the file %s with you" => "%s deelt den Fichier %s mad dir",
+"Download" => "Download",
+"Upload" => "Eroplueden",
+"Cancel upload" => "Upload ofbriechen",
+"No preview available for" => "Keeng Preview do fir"
);
diff --git a/apps/files_sharing/l10n/lt_LT.php b/apps/files_sharing/l10n/lt_LT.php
index d21a3c14f4044e594080241e97a200c247df5fcf..0f9347377c9176dc60fc5a4ae288481ee6151a15 100644
--- a/apps/files_sharing/l10n/lt_LT.php
+++ b/apps/files_sharing/l10n/lt_LT.php
@@ -1,6 +1,10 @@
"Dydis",
-"Modified" => "Pakeista",
-"Delete all" => "Ištrinti viską",
-"Delete" => "Ištrinti"
+"Password" => "Slaptažodis",
+"Submit" => "Išsaugoti",
+"%s shared the folder %s with you" => "%s pasidalino su jumis %s aplanku",
+"%s shared the file %s with you" => "%s pasidalino su jumis %s failu",
+"Download" => "Atsisiųsti",
+"Upload" => "Įkelti",
+"Cancel upload" => "Atšaukti siuntimą",
+"No preview available for" => "Peržiūra nėra galima"
);
diff --git a/apps/files_sharing/l10n/lv.php b/apps/files_sharing/l10n/lv.php
index 0b22486708959b12614f26618fcf016001261683..be021b8e7a04720373b1f22d676136194cb45bb3 100644
--- a/apps/files_sharing/l10n/lv.php
+++ b/apps/files_sharing/l10n/lv.php
@@ -4,6 +4,7 @@
"%s shared the folder %s with you" => "%s ar jums dalījās ar mapi %s",
"%s shared the file %s with you" => "%s ar jums dalījās ar datni %s",
"Download" => "Lejupielādēt",
-"No preview available for" => "Nav pieejams priekšskatījums priekš",
-"web services under your control" => "jūsu vadībā esošie tīmekļa servisi"
+"Upload" => "Augšupielādēt",
+"Cancel upload" => "Atcelt augšupielādi",
+"No preview available for" => "Nav pieejams priekšskatījums priekš"
);
diff --git a/apps/files_sharing/l10n/mk.php b/apps/files_sharing/l10n/mk.php
index 16c7ee0eb04e6563db792422483bf61f56133262..ed04035ea5da9d6610efc80f1dd962c6d9cd0b96 100644
--- a/apps/files_sharing/l10n/mk.php
+++ b/apps/files_sharing/l10n/mk.php
@@ -4,6 +4,7 @@
"%s shared the folder %s with you" => "%s ја сподели папката %s со Вас",
"%s shared the file %s with you" => "%s ја сподели датотеката %s со Вас",
"Download" => "Преземи",
-"No preview available for" => "Нема достапно преглед за",
-"web services under your control" => "веб сервиси под Ваша контрола"
+"Upload" => "Подигни",
+"Cancel upload" => "Откажи прикачување",
+"No preview available for" => "Нема достапно преглед за"
);
diff --git a/apps/files_sharing/l10n/ms_MY.php b/apps/files_sharing/l10n/ms_MY.php
new file mode 100644
index 0000000000000000000000000000000000000000..0a6a05b77815f008a1d80f28248182829b7fec5d
--- /dev/null
+++ b/apps/files_sharing/l10n/ms_MY.php
@@ -0,0 +1,7 @@
+ "Kata laluan",
+"Submit" => "Hantar",
+"Download" => "Muat turun",
+"Upload" => "Muat naik",
+"Cancel upload" => "Batal muat naik"
+);
diff --git a/apps/files_sharing/l10n/my_MM.php b/apps/files_sharing/l10n/my_MM.php
index dc7ec17e9c58249113282639cac8aa27f1c2b42a..4b37ab8b48a75365370546eab07a0037df38d5f8 100644
--- a/apps/files_sharing/l10n/my_MM.php
+++ b/apps/files_sharing/l10n/my_MM.php
@@ -1,6 +1,5 @@
"စကားဝှက်",
"Submit" => "ထည့်သွင်းမည်",
-"Download" => "ဒေါင်းလုတ်",
-"web services under your control" => "သင်၏ထိန်းချုပ်မှု့အောက်တွင်ရှိသော Web services"
+"Download" => "ဒေါင်းလုတ်"
);
diff --git a/apps/files_sharing/l10n/nb_NO.php b/apps/files_sharing/l10n/nb_NO.php
index 4934c3410674c405f4ea58e4dcc9c3113e0a183c..65eadd3ccaec4477e5c2f59a755830d1c6c19c1b 100644
--- a/apps/files_sharing/l10n/nb_NO.php
+++ b/apps/files_sharing/l10n/nb_NO.php
@@ -1,9 +1,11 @@
"Passordet er feil. Prøv på nytt.",
"Password" => "Passord",
"Submit" => "Send inn",
"%s shared the folder %s with you" => "%s delte mappen %s med deg",
"%s shared the file %s with you" => "%s delte filen %s med deg",
"Download" => "Last ned",
-"No preview available for" => "Forhåndsvisning ikke tilgjengelig for",
-"web services under your control" => "web tjenester du kontrollerer"
+"Upload" => "Last opp",
+"Cancel upload" => "Avbryt opplasting",
+"No preview available for" => "Forhåndsvisning ikke tilgjengelig for"
);
diff --git a/apps/files_sharing/l10n/nl.php b/apps/files_sharing/l10n/nl.php
index 2cef02543983744447bd92397d32038b22fcfcbe..6c1bf7a53f3682888d3bc4028d9050a3ba4b6c5a 100644
--- a/apps/files_sharing/l10n/nl.php
+++ b/apps/files_sharing/l10n/nl.php
@@ -4,6 +4,7 @@
"%s shared the folder %s with you" => "%s deelt de map %s met u",
"%s shared the file %s with you" => "%s deelt het bestand %s met u",
"Download" => "Downloaden",
-"No preview available for" => "Geen voorbeeldweergave beschikbaar voor",
-"web services under your control" => "Webdiensten in eigen beheer"
+"Upload" => "Uploaden",
+"Cancel upload" => "Upload afbreken",
+"No preview available for" => "Geen voorbeeldweergave beschikbaar voor"
);
diff --git a/apps/files_sharing/l10n/nn_NO.php b/apps/files_sharing/l10n/nn_NO.php
new file mode 100644
index 0000000000000000000000000000000000000000..afa3eabe8cf3dafc4af74a89cf6063d533bfc5a8
--- /dev/null
+++ b/apps/files_sharing/l10n/nn_NO.php
@@ -0,0 +1,10 @@
+ "Passord",
+"Submit" => "Send",
+"%s shared the folder %s with you" => "%s delte mappa %s med deg",
+"%s shared the file %s with you" => "%s delte fila %s med deg",
+"Download" => "Last ned",
+"Upload" => "Last opp",
+"Cancel upload" => "Avbryt opplasting",
+"No preview available for" => "Inga førehandsvising tilgjengeleg for"
+);
diff --git a/apps/files_sharing/l10n/oc.php b/apps/files_sharing/l10n/oc.php
new file mode 100644
index 0000000000000000000000000000000000000000..4ec48b151a83a8809c00edb4e4dbbd712f485d18
--- /dev/null
+++ b/apps/files_sharing/l10n/oc.php
@@ -0,0 +1,7 @@
+ "Senhal",
+"Submit" => "Sosmetre",
+"Download" => "Avalcarga",
+"Upload" => "Amontcarga",
+"Cancel upload" => " Anulla l'amontcargar"
+);
diff --git a/apps/files_sharing/l10n/pl.php b/apps/files_sharing/l10n/pl.php
index 9db5e87c9ba907f9e81e8f8ec09ad8a82cf9e415..39039da77b6d73f8165c466b4f3b61b0b1dfde45 100644
--- a/apps/files_sharing/l10n/pl.php
+++ b/apps/files_sharing/l10n/pl.php
@@ -4,6 +4,7 @@
"%s shared the folder %s with you" => "%s współdzieli folder z tobą %s",
"%s shared the file %s with you" => "%s współdzieli z tobą plik %s",
"Download" => "Pobierz",
-"No preview available for" => "Podgląd nie jest dostępny dla",
-"web services under your control" => "Kontrolowane serwisy"
+"Upload" => "Wyślij",
+"Cancel upload" => "Anuluj wysyłanie",
+"No preview available for" => "Podgląd nie jest dostępny dla"
);
diff --git a/apps/files_sharing/l10n/pt_BR.php b/apps/files_sharing/l10n/pt_BR.php
index 4dde4bb5ad5b380daa58c4bd6b7bd267fe78f6ea..c82989857a9965b2958fc8672e54c88e3bcb2924 100644
--- a/apps/files_sharing/l10n/pt_BR.php
+++ b/apps/files_sharing/l10n/pt_BR.php
@@ -1,9 +1,11 @@
"Senha incorreta. Tente novamente.",
"Password" => "Senha",
"Submit" => "Submeter",
"%s shared the folder %s with you" => "%s compartilhou a pasta %s com você",
"%s shared the file %s with you" => "%s compartilhou o arquivo %s com você",
"Download" => "Baixar",
-"No preview available for" => "Nenhuma visualização disponível para",
-"web services under your control" => "web services sob seu controle"
+"Upload" => "Upload",
+"Cancel upload" => "Cancelar upload",
+"No preview available for" => "Nenhuma visualização disponível para"
);
diff --git a/apps/files_sharing/l10n/pt_PT.php b/apps/files_sharing/l10n/pt_PT.php
index b8e700e3802dfc0cc89f2defa750a05cdc249dfc..2f41abca1f5fcc648097a27946ab18b70cd24c7d 100644
--- a/apps/files_sharing/l10n/pt_PT.php
+++ b/apps/files_sharing/l10n/pt_PT.php
@@ -1,9 +1,10 @@
"Palavra-Passe",
+"Password" => "Password",
"Submit" => "Submeter",
"%s shared the folder %s with you" => "%s partilhou a pasta %s consigo",
"%s shared the file %s with you" => "%s partilhou o ficheiro %s consigo",
-"Download" => "Descarregar",
-"No preview available for" => "Não há pré-visualização para",
-"web services under your control" => "serviços web sob o seu controlo"
+"Download" => "Transferir",
+"Upload" => "Carregar",
+"Cancel upload" => "Cancelar envio",
+"No preview available for" => "Não há pré-visualização para"
);
diff --git a/apps/files_sharing/l10n/ro.php b/apps/files_sharing/l10n/ro.php
index eb9977dc585ce0efafa7fac2e50d1b96a401322a..3197068cdd131f6ce16903f717915e1bb6e21572 100644
--- a/apps/files_sharing/l10n/ro.php
+++ b/apps/files_sharing/l10n/ro.php
@@ -1,9 +1,11 @@
"Parola este incorectă. Încercaţi din nou.",
"Password" => "Parolă",
"Submit" => "Trimite",
"%s shared the folder %s with you" => "%s a partajat directorul %s cu tine",
"%s shared the file %s with you" => "%s a partajat fișierul %s cu tine",
"Download" => "Descarcă",
-"No preview available for" => "Nici o previzualizare disponibilă pentru ",
-"web services under your control" => "servicii web controlate de tine"
+"Upload" => "Încărcare",
+"Cancel upload" => "Anulează încărcarea",
+"No preview available for" => "Nici o previzualizare disponibilă pentru "
);
diff --git a/apps/files_sharing/l10n/ru.php b/apps/files_sharing/l10n/ru.php
index 7fd116e0aae8cca19012b1635167289966c18ca4..77332c183f64a75bbf3de9151c7c3cb6f8b9788d 100644
--- a/apps/files_sharing/l10n/ru.php
+++ b/apps/files_sharing/l10n/ru.php
@@ -1,9 +1,11 @@
"Неверный пароль. Попробуйте еще раз.",
"Password" => "Пароль",
"Submit" => "Отправить",
"%s shared the folder %s with you" => "%s открыл доступ к папке %s для Вас",
"%s shared the file %s with you" => "%s открыл доступ к файлу %s для Вас",
"Download" => "Скачать",
-"No preview available for" => "Предпросмотр недоступен для",
-"web services under your control" => "веб-сервисы под вашим управлением"
+"Upload" => "Загрузка",
+"Cancel upload" => "Отмена загрузки",
+"No preview available for" => "Предпросмотр недоступен для"
);
diff --git a/apps/files_sharing/l10n/ru_RU.php b/apps/files_sharing/l10n/ru_RU.php
index 36e4b2fd0e1fceccc83a859368d0a7a9d6d189e2..2cadd163462aaa92e781eb415cde248d47a4d088 100644
--- a/apps/files_sharing/l10n/ru_RU.php
+++ b/apps/files_sharing/l10n/ru_RU.php
@@ -1,9 +1,3 @@
"Пароль",
-"Submit" => "Передать",
-"%s shared the folder %s with you" => "%s имеет общий с Вами доступ к папке %s ",
-"%s shared the file %s with you" => "%s имеет общий с Вами доступ к файлу %s ",
-"Download" => "Загрузка",
-"No preview available for" => "Предварительный просмотр недоступен",
-"web services under your control" => "веб-сервисы под Вашим контролем"
+"Download" => "Загрузка"
);
diff --git a/apps/files_sharing/l10n/si_LK.php b/apps/files_sharing/l10n/si_LK.php
index 1c69c608178673c4f6bd4ca5aae050b4df68f17d..27b9d649a0af5bccde4812ff61a83ce4b353d43a 100644
--- a/apps/files_sharing/l10n/si_LK.php
+++ b/apps/files_sharing/l10n/si_LK.php
@@ -1,9 +1,10 @@
"මුරපදය",
+"Password" => "මුර පදය",
"Submit" => "යොමු කරන්න",
"%s shared the folder %s with you" => "%s ඔබව %s ෆෝල්ඩරයට හවුල් කරගත්තේය",
"%s shared the file %s with you" => "%s ඔබ සමඟ %s ගොනුව බෙදාහදාගත්තේය",
-"Download" => "භාගත කරන්න",
-"No preview available for" => "පූර්වදර්ශනයක් නොමැත",
-"web services under your control" => "ඔබට පාලනය කළ හැකි වෙබ් සේවාවන්"
+"Download" => "බාන්න",
+"Upload" => "උඩුගත කරන්න",
+"Cancel upload" => "උඩුගත කිරීම අත් හරින්න",
+"No preview available for" => "පූර්වදර්ශනයක් නොමැත"
);
diff --git a/apps/files_sharing/l10n/sk_SK.php b/apps/files_sharing/l10n/sk_SK.php
index 2e781f76f385540606664e20a8a67876b1a2d37e..77173b44345c5f3d6def6067d7a45e146f25e879 100644
--- a/apps/files_sharing/l10n/sk_SK.php
+++ b/apps/files_sharing/l10n/sk_SK.php
@@ -3,7 +3,8 @@
"Submit" => "Odoslať",
"%s shared the folder %s with you" => "%s zdieľa s vami priečinok %s",
"%s shared the file %s with you" => "%s zdieľa s vami súbor %s",
-"Download" => "Stiahnuť",
-"No preview available for" => "Žiaden náhľad k dispozícii pre",
-"web services under your control" => "webové služby pod Vašou kontrolou"
+"Download" => "Sťahovanie",
+"Upload" => "Odoslať",
+"Cancel upload" => "Zrušiť odosielanie",
+"No preview available for" => "Žiaden náhľad k dispozícii pre"
);
diff --git a/apps/files_sharing/l10n/sl.php b/apps/files_sharing/l10n/sl.php
index 6bcbb0070b35239b8093856433c3c92c8cb2dc79..39d2fca81cb25ca3fcb6aa55b5065edecccaf21f 100644
--- a/apps/files_sharing/l10n/sl.php
+++ b/apps/files_sharing/l10n/sl.php
@@ -4,6 +4,7 @@
"%s shared the folder %s with you" => "Oseba %s je določila mapo %s za souporabo",
"%s shared the file %s with you" => "Oseba %s je določila datoteko %s za souporabo",
"Download" => "Prejmi",
-"No preview available for" => "Predogled ni na voljo za",
-"web services under your control" => "spletne storitve pod vašim nadzorom"
+"Upload" => "Pošlji",
+"Cancel upload" => "Prekliči pošiljanje",
+"No preview available for" => "Predogled ni na voljo za"
);
diff --git a/apps/files_sharing/l10n/sq.php b/apps/files_sharing/l10n/sq.php
new file mode 100644
index 0000000000000000000000000000000000000000..1c0e0aa2bd138347c466a4aa7b026201dce73744
--- /dev/null
+++ b/apps/files_sharing/l10n/sq.php
@@ -0,0 +1,10 @@
+ "Kodi",
+"Submit" => "Parashtro",
+"%s shared the folder %s with you" => "%s ndau me ju dosjen %s",
+"%s shared the file %s with you" => "%s ndau me ju skedarin %s",
+"Download" => "Shkarko",
+"Upload" => "Ngarko",
+"Cancel upload" => "Anulo ngarkimin",
+"No preview available for" => "Shikimi paraprak nuk është i mundur për"
+);
diff --git a/apps/files_sharing/l10n/sr.php b/apps/files_sharing/l10n/sr.php
index 6e277f677119ce3b1f1373b57267142b73463d4c..f893ec0ab422f3139a249a2630a69577481dc8ea 100644
--- a/apps/files_sharing/l10n/sr.php
+++ b/apps/files_sharing/l10n/sr.php
@@ -1,5 +1,7 @@
"Лозинка",
"Submit" => "Пошаљи",
-"Download" => "Преузми"
+"Download" => "Преузми",
+"Upload" => "Отпреми",
+"Cancel upload" => "Прекини отпремање"
);
diff --git a/apps/files_sharing/l10n/sr@latin.php b/apps/files_sharing/l10n/sr@latin.php
new file mode 100644
index 0000000000000000000000000000000000000000..c45f711e15f559c362bcfe68c2dd093695a067b7
--- /dev/null
+++ b/apps/files_sharing/l10n/sr@latin.php
@@ -0,0 +1,6 @@
+ "Lozinka",
+"Submit" => "Pošalji",
+"Download" => "Preuzmi",
+"Upload" => "Pošalji"
+);
diff --git a/apps/files_sharing/l10n/sv.php b/apps/files_sharing/l10n/sv.php
index d1c9afff07cf362bb5b2c4c26b424a2e6a4a64a9..21e4e542d8e4066690321c83949f84b94d3f148c 100644
--- a/apps/files_sharing/l10n/sv.php
+++ b/apps/files_sharing/l10n/sv.php
@@ -4,6 +4,7 @@
"%s shared the folder %s with you" => "%s delade mappen %s med dig",
"%s shared the file %s with you" => "%s delade filen %s med dig",
"Download" => "Ladda ner",
-"No preview available for" => "Ingen förhandsgranskning tillgänglig för",
-"web services under your control" => "webbtjänster under din kontroll"
+"Upload" => "Ladda upp",
+"Cancel upload" => "Avbryt uppladdning",
+"No preview available for" => "Ingen förhandsgranskning tillgänglig för"
);
diff --git a/apps/files_sharing/l10n/ta_LK.php b/apps/files_sharing/l10n/ta_LK.php
index 6cf6f6236b7ac0adf86cf4d62278b41441938a35..6e69855be11d34e8d84940ee5c410e4458bda74c 100644
--- a/apps/files_sharing/l10n/ta_LK.php
+++ b/apps/files_sharing/l10n/ta_LK.php
@@ -4,6 +4,7 @@
"%s shared the folder %s with you" => "%s கோப்புறையானது %s உடன் பகிரப்பட்டது",
"%s shared the file %s with you" => "%s கோப்பானது %s உடன் பகிரப்பட்டது",
"Download" => "பதிவிறக்குக",
-"No preview available for" => "அதற்கு முன்னோக்கு ஒன்றும் இல்லை",
-"web services under your control" => "வலைய சேவைகள் உங்களுடைய கட்டுப்பாட்டின் கீழ் உள்ளது"
+"Upload" => "பதிவேற்றுக",
+"Cancel upload" => "பதிவேற்றலை இரத்து செய்க",
+"No preview available for" => "அதற்கு முன்னோக்கு ஒன்றும் இல்லை"
);
diff --git a/apps/files_sharing/l10n/te.php b/apps/files_sharing/l10n/te.php
new file mode 100644
index 0000000000000000000000000000000000000000..1e2eedc684412607f66fba52489aef0edf896b6b
--- /dev/null
+++ b/apps/files_sharing/l10n/te.php
@@ -0,0 +1,3 @@
+ "సంకేతపదం"
+);
diff --git a/apps/files_sharing/l10n/th_TH.php b/apps/files_sharing/l10n/th_TH.php
index 9d53d65f8ab607351a539fbed0c45faeae2ac748..608c86d586a872640075786bb72dfc601a870ed4 100644
--- a/apps/files_sharing/l10n/th_TH.php
+++ b/apps/files_sharing/l10n/th_TH.php
@@ -4,6 +4,7 @@
"%s shared the folder %s with you" => "%s ได้แชร์โฟลเดอร์ %s ให้กับคุณ",
"%s shared the file %s with you" => "%s ได้แชร์ไฟล์ %s ให้กับคุณ",
"Download" => "ดาวน์โหลด",
-"No preview available for" => "ไม่สามารถดูตัวอย่างได้สำหรับ",
-"web services under your control" => "เว็บเซอร์วิสที่คุณควบคุมการใช้งานได้"
+"Upload" => "อัพโหลด",
+"Cancel upload" => "ยกเลิกการอัพโหลด",
+"No preview available for" => "ไม่สามารถดูตัวอย่างได้สำหรับ"
);
diff --git a/apps/files_sharing/l10n/tr.php b/apps/files_sharing/l10n/tr.php
index f2e6e5697d629b473966dda9fb59438f7cea5f0d..4da9c17c7e8b72783b842cf9ddc2bafc92d55d5d 100644
--- a/apps/files_sharing/l10n/tr.php
+++ b/apps/files_sharing/l10n/tr.php
@@ -1,9 +1,10 @@
"Şifre",
+"Password" => "Parola",
"Submit" => "Gönder",
"%s shared the folder %s with you" => "%s sizinle paylaşılan %s klasör",
"%s shared the file %s with you" => "%s sizinle paylaşılan %s klasör",
"Download" => "İndir",
-"No preview available for" => "Kullanılabilir önizleme yok",
-"web services under your control" => "Bilgileriniz güvenli ve şifreli"
+"Upload" => "Yükle",
+"Cancel upload" => "Yüklemeyi iptal et",
+"No preview available for" => "Kullanılabilir önizleme yok"
);
diff --git a/apps/files_sharing/l10n/ug.php b/apps/files_sharing/l10n/ug.php
new file mode 100644
index 0000000000000000000000000000000000000000..9f9c7beb4105911ac014b4588e7a1c49421e0008
--- /dev/null
+++ b/apps/files_sharing/l10n/ug.php
@@ -0,0 +1,7 @@
+ "ئىم",
+"Submit" => "تاپشۇر",
+"Download" => "چۈشۈر",
+"Upload" => "يۈكلە",
+"Cancel upload" => "يۈكلەشتىن ۋاز كەچ"
+);
diff --git a/apps/files_sharing/l10n/uk.php b/apps/files_sharing/l10n/uk.php
index cdc103ad465be0e0c5dec0df6655bb5a5ca5ed9a..8ef7f1bd8adb32a0dd10bae742eac0d6722bdfba 100644
--- a/apps/files_sharing/l10n/uk.php
+++ b/apps/files_sharing/l10n/uk.php
@@ -1,9 +1,10 @@
"Пароль",
-"Submit" => "Submit",
+"Submit" => "Передати",
"%s shared the folder %s with you" => "%s опублікував каталог %s для Вас",
"%s shared the file %s with you" => "%s опублікував файл %s для Вас",
"Download" => "Завантажити",
-"No preview available for" => "Попередній перегляд недоступний для",
-"web services under your control" => "підконтрольні Вам веб-сервіси"
+"Upload" => "Вивантажити",
+"Cancel upload" => "Перервати завантаження",
+"No preview available for" => "Попередній перегляд недоступний для"
);
diff --git a/apps/files_sharing/l10n/ur_PK.php b/apps/files_sharing/l10n/ur_PK.php
index f68b714350f8a7b318978c7110586c8c58bdae4d..745f2f930d193b6c5ab9142a040ea800afa902a1 100644
--- a/apps/files_sharing/l10n/ur_PK.php
+++ b/apps/files_sharing/l10n/ur_PK.php
@@ -1,4 +1,3 @@
"پاسورڈ",
-"web services under your control" => "آپ کے اختیار میں ویب سروسیز"
+"Password" => "پاسورڈ"
);
diff --git a/apps/files_sharing/l10n/vi.php b/apps/files_sharing/l10n/vi.php
index afeec5c648132a26106ecd7e9d805e378f7edfe0..d75fb1dc53f0e5223899b3c1ff4324ceaf9703e9 100644
--- a/apps/files_sharing/l10n/vi.php
+++ b/apps/files_sharing/l10n/vi.php
@@ -4,6 +4,7 @@
"%s shared the folder %s with you" => "%s đã chia sẻ thư mục %s với bạn",
"%s shared the file %s with you" => "%s đã chia sẻ tập tin %s với bạn",
"Download" => "Tải về",
-"No preview available for" => "Không có xem trước cho",
-"web services under your control" => "dịch vụ web dưới sự kiểm soát của bạn"
+"Upload" => "Tải lên",
+"Cancel upload" => "Hủy upload",
+"No preview available for" => "Không có xem trước cho"
);
diff --git a/apps/files_sharing/l10n/zh_CN.GB2312.php b/apps/files_sharing/l10n/zh_CN.GB2312.php
index 117ec8f4065b819699067223bb57fc2fe24e6447..2dd79ec38d4fb8a3cf3255f36c286eceb9076d2d 100644
--- a/apps/files_sharing/l10n/zh_CN.GB2312.php
+++ b/apps/files_sharing/l10n/zh_CN.GB2312.php
@@ -4,6 +4,7 @@
"%s shared the folder %s with you" => "%s 与您分享了文件夹 %s",
"%s shared the file %s with you" => "%s 与您分享了文件 %s",
"Download" => "下载",
-"No preview available for" => "没有预览可用于",
-"web services under your control" => "您控制的网络服务"
+"Upload" => "上传",
+"Cancel upload" => "取消上传",
+"No preview available for" => "没有预览可用于"
);
diff --git a/apps/files_sharing/l10n/zh_CN.php b/apps/files_sharing/l10n/zh_CN.php
index 64e7af3e0cdc1bd4f8301ff4334c7c45b9713486..c7fa08b81f03277826543f42b244743c931087e9 100644
--- a/apps/files_sharing/l10n/zh_CN.php
+++ b/apps/files_sharing/l10n/zh_CN.php
@@ -4,6 +4,7 @@
"%s shared the folder %s with you" => "%s与您共享了%s文件夹",
"%s shared the file %s with you" => "%s与您共享了%s文件",
"Download" => "下载",
-"No preview available for" => "没有预览",
-"web services under your control" => "您控制的web服务"
+"Upload" => "上传",
+"Cancel upload" => "取消上传",
+"No preview available for" => "没有预览"
);
diff --git a/apps/files_sharing/l10n/zh_HK.php b/apps/files_sharing/l10n/zh_HK.php
index 7ef0f19ca435e0ae17be1f4112bb4fdef1133c0c..8f9b7900c2ccf2f839d665ec778b14d67121370c 100644
--- a/apps/files_sharing/l10n/zh_HK.php
+++ b/apps/files_sharing/l10n/zh_HK.php
@@ -1,4 +1,5 @@
"密碼",
-"Download" => "下載"
+"Download" => "下載",
+"Upload" => "上傳"
);
diff --git a/apps/files_sharing/l10n/zh_TW.php b/apps/files_sharing/l10n/zh_TW.php
index f1d28731a7fc78f11f3f48033e64cbd4423d63ba..b172879469fe1dffd90f686829d2a38b79d2782d 100644
--- a/apps/files_sharing/l10n/zh_TW.php
+++ b/apps/files_sharing/l10n/zh_TW.php
@@ -1,9 +1,10 @@
"密碼",
"Submit" => "送出",
-"%s shared the folder %s with you" => "%s 分享了資料夾 %s 給您",
-"%s shared the file %s with you" => "%s 分享了檔案 %s 給您",
+"%s shared the folder %s with you" => "%s 和您分享了資料夾 %s ",
+"%s shared the file %s with you" => "%s 和您分享了檔案 %s",
"Download" => "下載",
-"No preview available for" => "無法預覽",
-"web services under your control" => "在您掌控之下的網路服務"
+"Upload" => "上傳",
+"Cancel upload" => "取消上傳",
+"No preview available for" => "無法預覽"
);
diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php
index 9fccd0b46f32481684e993d66b081cd4580b5cf0..2160fe9a393bb366a1e4fd0c6d3bf415684e2a1a 100644
--- a/apps/files_sharing/lib/cache.php
+++ b/apps/files_sharing/lib/cache.php
@@ -44,9 +44,9 @@ class Shared_Cache extends Cache {
$source = \OC_Share_Backend_File::getSource($target);
if (isset($source['path']) && isset($source['fileOwner'])) {
\OC\Files\Filesystem::initMountPoints($source['fileOwner']);
- $mount = \OC\Files\Mount::findByNumericId($source['storage']);
- if ($mount) {
- $fullPath = $mount->getMountPoint().$source['path'];
+ $mount = \OC\Files\Filesystem::getMountByNumericId($source['storage']);
+ if (is_array($mount)) {
+ $fullPath = $mount[key($mount)]->getMountPoint().$source['path'];
list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($fullPath);
if ($storage) {
$this->files[$target] = $internalPath;
@@ -60,6 +60,14 @@ class Shared_Cache extends Cache {
return false;
}
+ public function getNumericStorageId() {
+ if (isset($this->numericId)) {
+ return $this->numericId;
+ } else {
+ return false;
+ }
+ }
+
/**
* get the stored metadata of a file or folder
*
@@ -182,12 +190,10 @@ class Shared_Cache extends Cache {
*/
public function move($source, $target) {
if ($cache = $this->getSourceCache($source)) {
- $targetPath = \OC_Share_Backend_File::getSourcePath(dirname($target));
- if ($targetPath) {
- $targetPath .= '/' . basename($target);
- $cache->move($this->files[$source], $targetPath);
+ $file = \OC_Share_Backend_File::getSource($target);
+ if ($file && isset($file['path'])) {
+ $cache->move($this->files[$source], $file['path']);
}
-
}
}
@@ -269,4 +275,17 @@ class Shared_Cache extends Cache {
return \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_GET_ALL);
}
-}
+ /**
+ * find a folder in the cache which has not been fully scanned
+ *
+ * If multiply incomplete folders are in the cache, the one with the highest id will be returned,
+ * use the one with the highest id gives the best result with the background scanner, since that is most
+ * likely the folder where we stopped scanning previously
+ *
+ * @return string|bool the path of the folder or false when no folder matched
+ */
+ public function getIncomplete() {
+ return false;
+ }
+
+}
\ No newline at end of file
diff --git a/apps/files_sharing/lib/permissions.php b/apps/files_sharing/lib/permissions.php
index 6747faa4d4313269cbf1649774e625cbfd1f26f5..b6638564cd82c343070f6be07da1b3235d7f8747 100644
--- a/apps/files_sharing/lib/permissions.php
+++ b/apps/files_sharing/lib/permissions.php
@@ -70,6 +70,28 @@ class Shared_Permissions extends Permissions {
return $filePermissions;
}
+ /**
+ * get the permissions for all files in a folder
+ *
+ * @param int $parentId
+ * @param string $user
+ * @return int[]
+ */
+ public function getDirectoryPermissions($parentId, $user) {
+ // Root of the Shared folder
+ if ($parentId === -1) {
+ return \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_PERMISSIONS);
+ }
+ $permissions = $this->get($parentId, $user);
+ $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `parent` = ?');
+ $result = $query->execute(array($parentId));
+ $filePermissions = array();
+ while ($row = $result->fetchRow()) {
+ $filePermissions[$row['fileid']] = $permissions;
+ }
+ return $filePermissions;
+ }
+
/**
* remove the permissions for a file
*
@@ -83,4 +105,5 @@ class Shared_Permissions extends Permissions {
public function removeMultiple($fileIds, $user) {
// Not a valid action for Shared Permissions
}
-}
+
+}
\ No newline at end of file
diff --git a/apps/files_sharing/lib/share/file.php b/apps/files_sharing/lib/share/file.php
index 62948651806fdde14b0d28b67d64dcaa57567cc5..07e7a4ca0c5ccaa1c26d6acb55141abbf351b47a 100644
--- a/apps/files_sharing/lib/share/file.php
+++ b/apps/files_sharing/lib/share/file.php
@@ -26,6 +26,7 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent {
const FORMAT_FILE_APP_ROOT = 2;
const FORMAT_OPENDIR = 3;
const FORMAT_GET_ALL = 4;
+ const FORMAT_PERMISSIONS = 5;
private $path;
@@ -125,6 +126,12 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent {
$ids[] = $item['file_source'];
}
return $ids;
+ } else if ($format === self::FORMAT_PERMISSIONS) {
+ $filePermissions = array();
+ foreach ($items as $item) {
+ $filePermissions[$item['file_source']] = $item['permissions'];
+ }
+ return $filePermissions;
}
return array();
}
diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php
index ffd4e5ced22bdd1264b2898b6b62bbe646f4be07..5c23a9eb0d0a69a0c1001786538c624790a718c6 100644
--- a/apps/files_sharing/lib/sharedstorage.php
+++ b/apps/files_sharing/lib/sharedstorage.php
@@ -71,9 +71,9 @@ class Shared extends \OC\Files\Storage\Common {
if ($source) {
if (!isset($source['fullPath'])) {
\OC\Files\Filesystem::initMountPoints($source['fileOwner']);
- $mount = \OC\Files\Mount::findByNumericId($source['storage']);
- if ($mount) {
- $this->files[$target]['fullPath'] = $mount->getMountPoint().$source['path'];
+ $mount = \OC\Files\Filesystem::getMountByNumericId($source['storage']);
+ if (is_array($mount)) {
+ $this->files[$target]['fullPath'] = $mount[key($mount)]->getMountPoint().$source['path'];
} else {
$this->files[$target]['fullPath'] = false;
}
diff --git a/apps/files_sharing/lib/updater.php b/apps/files_sharing/lib/updater.php
index 73e7808f24a08625fa50246dec64063935bd05a5..a43ab2e2a0a5e07ad5188b96b3e481e99c60d69e 100644
--- a/apps/files_sharing/lib/updater.php
+++ b/apps/files_sharing/lib/updater.php
@@ -38,10 +38,12 @@ class Shared_Updater {
while (!empty($users)) {
$reshareUsers = array();
foreach ($users as $user) {
- $etag = \OC\Files\Filesystem::getETag('');
- \OCP\Config::setUserValue($user, 'files_sharing', 'etag', $etag);
- // Look for reshares
- $reshareUsers = array_merge($reshareUsers, \OCP\Share::getUsersItemShared('file', $info['fileid'], $user, true));
+ if ( $user !== $uidOwner ) {
+ $etag = \OC\Files\Filesystem::getETag('');
+ \OCP\Config::setUserValue($user, 'files_sharing', 'etag', $etag);
+ // Look for reshares
+ $reshareUsers = array_merge($reshareUsers, \OCP\Share::getUsersItemShared('file', $info['fileid'], $user, true));
+ }
}
$users = $reshareUsers;
}
@@ -66,8 +68,8 @@ class Shared_Updater {
* @param array $params
*/
static public function renameHook($params) {
- self::correctFolders($params['oldpath']);
self::correctFolders($params['newpath']);
+ self::correctFolders(pathinfo($params['oldpath'], PATHINFO_DIRNAME));
}
/**
@@ -88,10 +90,12 @@ class Shared_Updater {
while (!empty($users)) {
$reshareUsers = array();
foreach ($users as $user) {
- $etag = \OC\Files\Filesystem::getETag('');
- \OCP\Config::setUserValue($user, 'files_sharing', 'etag', $etag);
- // Look for reshares
- $reshareUsers = array_merge($reshareUsers, \OCP\Share::getUsersItemShared('file', $params['fileSource'], $user, true));
+ if ($user !== $uidOwner) {
+ $etag = \OC\Files\Filesystem::getETag('');
+ \OCP\Config::setUserValue($user, 'files_sharing', 'etag', $etag);
+ // Look for reshares
+ $reshareUsers = array_merge($reshareUsers, \OCP\Share::getUsersItemShared('file', $params['fileSource'], $user, true));
+ }
}
$users = $reshareUsers;
}
diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php
index 1da972ad7e3fd295053a4b419de74cb1bdf2c501..9462844a82b7be7db8a54876744fc6fd57059f2c 100644
--- a/apps/files_sharing/public.php
+++ b/apps/files_sharing/public.php
@@ -1,8 +1,14 @@
printPage();
+ exit();
+}
+
function fileCmp($a, $b) {
if ($a['type'] == 'dir' and $b['type'] != 'dir') {
return -1;
@@ -21,24 +27,11 @@ if (isset($_GET['t'])) {
$type = $linkItem['item_type'];
$fileSource = $linkItem['file_source'];
$shareOwner = $linkItem['uid_owner'];
- $fileOwner = null;
$path = null;
- if (isset($linkItem['parent'])) {
- $parent = $linkItem['parent'];
- while (isset($parent)) {
- $query = \OC_DB::prepare('SELECT `parent`, `uid_owner` FROM `*PREFIX*share` WHERE `id` = ?', 1);
- $item = $query->execute(array($parent))->fetchRow();
- if (isset($item['parent'])) {
- $parent = $item['parent'];
- } else {
- $fileOwner = $item['uid_owner'];
- break;
- }
- }
- } else {
- $fileOwner = $shareOwner;
- }
+ $rootLinkItem = OCP\Share::resolveReShare($linkItem);
+ $fileOwner = $rootLinkItem['uid_owner'];
if (isset($fileOwner)) {
+ OC_Util::tearDownFS();
OC_Util::setupFS($fileOwner);
$path = \OC\Files\Filesystem::getPath($linkItem['file_source']);
}
@@ -72,12 +65,12 @@ if (isset($path)) {
$linkItem['share_with']))) {
$tmpl = new OCP\Template('files_sharing', 'authenticate', 'guest');
$tmpl->assign('URL', $url);
- $tmpl->assign('error', true);
+ $tmpl->assign('wrongpw', true);
$tmpl->printPage();
exit();
} else {
// Save item id in session for future requests
- $_SESSION['public_link_authenticated'] = $linkItem['id'];
+ \OC::$session->set('public_link_authenticated', $linkItem['id']);
}
} else {
OCP\Util::writeLog('share', 'Unknown share type '.$linkItem['share_type']
@@ -90,8 +83,8 @@ if (isset($path)) {
} else {
// Check if item id is set in session
- if (!isset($_SESSION['public_link_authenticated'])
- || $_SESSION['public_link_authenticated'] !== $linkItem['id']
+ if ( ! \OC::$session->exists('public_link_authenticated')
+ || \OC::$session->get('public_link_authenticated') !== $linkItem['id']
) {
// Prompt for password
$tmpl = new OCP\Template('files_sharing', 'authenticate', 'guest');
@@ -113,21 +106,44 @@ if (isset($path)) {
// Download the file
if (isset($_GET['download'])) {
if (isset($_GET['files'])) { // download selected files
- OC_Files::get($path, $_GET['files'], $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false);
+ $files = urldecode($_GET['files']);
+ $files_list = json_decode($files);
+ // in case we get only a single file
+ if ($files_list === NULL ) {
+ $files_list = array($files);
+ }
+ OC_Files::get($path, $files_list, $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false);
} else {
OC_Files::get($dir, $file, $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false);
}
exit();
} else {
+ OCP\Util::addScript('files', 'file-upload');
OCP\Util::addStyle('files_sharing', 'public');
OCP\Util::addScript('files_sharing', 'public');
OCP\Util::addScript('files', 'fileactions');
+ OCP\Util::addScript('files', 'jquery.iframe-transport');
+ OCP\Util::addScript('files', 'jquery.fileupload');
+ $maxUploadFilesize=OCP\Util::maxUploadFilesize($path);
$tmpl = new OCP\Template('files_sharing', 'public', 'base');
$tmpl->assign('uidOwner', $shareOwner);
$tmpl->assign('displayName', \OCP\User::getDisplayName($shareOwner));
$tmpl->assign('filename', $file);
+ $tmpl->assign('directory_path', $linkItem['file_target']);
$tmpl->assign('mimetype', \OC\Files\Filesystem::getMimeType($path));
$tmpl->assign('fileTarget', basename($linkItem['file_target']));
+ $tmpl->assign('dirToken', $linkItem['token']);
+ $allowPublicUploadEnabled = (($linkItem['permissions'] & OCP\PERMISSION_CREATE) ? true : false );
+ if (\OCP\App::isEnabled('files_encryption')) {
+ $allowPublicUploadEnabled = false;
+ }
+ if ($linkItem['item_type'] !== 'folder') {
+ $allowPublicUploadEnabled = false;
+ }
+ $tmpl->assign('allowPublicUploadEnabled', $allowPublicUploadEnabled);
+ $tmpl->assign('uploadMaxFilesize', $maxUploadFilesize);
+ $tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize));
+
$urlLinkIdentifiers= (isset($token)?'&t='.$token:'')
.(isset($_GET['dir'])?'&dir='.$_GET['dir']:'')
.(isset($_GET['file'])?'&file='.$_GET['file']:'');
@@ -178,15 +194,17 @@ if (isset($path)) {
$breadcrumbNav = new OCP\Template('files', 'part.breadcrumb', '');
$breadcrumbNav->assign('breadcrumb', $breadcrumb);
$breadcrumbNav->assign('baseURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&path=');
+ $maxUploadFilesize=OCP\Util::maxUploadFilesize($path);
$folder = new OCP\Template('files', 'index', '');
$folder->assign('fileList', $list->fetchPage());
$folder->assign('breadcrumb', $breadcrumbNav->fetchPage());
$folder->assign('dir', $getPath);
$folder->assign('isCreatable', false);
- $folder->assign('permissions', 0);
+ $folder->assign('permissions', OCP\PERMISSION_READ);
+ $folder->assign('isPublic',true);
$folder->assign('files', $files);
- $folder->assign('uploadMaxFilesize', 0);
- $folder->assign('uploadMaxHumanFilesize', 0);
+ $folder->assign('uploadMaxFilesize', $maxUploadFilesize);
+ $folder->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize));
$folder->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true)));
$folder->assign('usedSpacePercent', 0);
$tmpl->assign('folder', $folder->fetchPage());
diff --git a/apps/files_sharing/templates/authenticate.php b/apps/files_sharing/templates/authenticate.php
index 7a67b6e550343e0762bf8a5539883391e01d2c3b..fa03f41913060540c4da710336436b4f2adefa9b 100644
--- a/apps/files_sharing/templates/authenticate.php
+++ b/apps/files_sharing/templates/authenticate.php
@@ -1,5 +1,8 @@