diff options
Diffstat (limited to 'apps')
64 files changed, 793 insertions, 312 deletions
diff --git a/apps/files/command/scan.php b/apps/files/command/scan.php index 25ab70af362..3412cf80dea 100644 --- a/apps/files/command/scan.php +++ b/apps/files/command/scan.php @@ -9,6 +9,7 @@ namespace OCA\Files\Command; +use OC\ForbiddenException; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -32,28 +33,32 @@ class Scan extends Command { ->setName('files:scan') ->setDescription('rescan filesystem') ->addArgument( - 'user_id', - InputArgument::OPTIONAL | InputArgument::IS_ARRAY, - 'will rescan all files of the given user(s)' - ) + 'user_id', + InputArgument::OPTIONAL | InputArgument::IS_ARRAY, + 'will rescan all files of the given user(s)' + ) ->addOption( - 'all', - null, - InputOption::VALUE_NONE, - 'will rescan all files of all known users' - ) - ; + 'all', + null, + InputOption::VALUE_NONE, + 'will rescan all files of all known users' + ); } protected function scanFiles($user, OutputInterface $output) { $scanner = new \OC\Files\Utils\Scanner($user); - $scanner->listen('\OC\Files\Utils\Scanner', 'scanFile', function($path) use ($output) { + $scanner->listen('\OC\Files\Utils\Scanner', 'scanFile', function ($path) use ($output) { $output->writeln("Scanning <info>$path</info>"); }); - $scanner->listen('\OC\Files\Utils\Scanner', 'scanFolder', function($path) use ($output) { + $scanner->listen('\OC\Files\Utils\Scanner', 'scanFolder', function ($path) use ($output) { $output->writeln("Scanning <info>$path</info>"); }); - $scanner->scan(''); + try { + $scanner->scan(''); + } catch (ForbiddenException $e) { + $output->writeln("<error>Home storage for user $user not writable</error>"); + $output->writeln("Make sure you're running the scan command only as the user the web server runs as"); + } } protected function execute(InputInterface $input, OutputInterface $output) { @@ -63,6 +68,11 @@ class Scan extends Command { $users = $input->getArgument('user_id'); } + if (count($users) === 0) { + $output->writeln("<error>Please specify the user id to scan or \"--all\" to scan for all users</error>"); + return; + } + foreach ($users as $user) { if (is_object($user)) { $user = $user->getUID(); diff --git a/apps/files/css/files.css b/apps/files/css/files.css index e138261b9f2..bf76682f03c 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -140,9 +140,8 @@ table.multiselect th a { color: #000; } table th .columntitle { - display: inline-block; + display: block; padding: 15px; - width: 100%; height: 50px; box-sizing: border-box; -moz-box-sizing: border-box; @@ -150,8 +149,8 @@ table th .columntitle { } table th .columntitle.name { padding-left: 5px; + padding-right: 80px; margin-left: 50px; - max-width: 300px; } /* hover effect on sortable column */ table th a.columntitle:hover { @@ -165,6 +164,7 @@ table th .sort-indicator { } table th, table td { border-bottom:1px solid #ddd; text-align:left; font-weight:normal; } table td { + padding: 0 15px; border-bottom: 1px solid #eee; font-style: normal; background-position: 8px center; @@ -180,12 +180,7 @@ table th#headerName { height: 50px; } table th#headerSize, table td.filesize { - min-width: 48px; text-align: right; - padding: 0; -} -table table td.filesize { - padding: 0 16px; } table th#headerDate, table td.date, table th.column-last, table td.column-last { @@ -227,23 +222,22 @@ table td.filename a.name { box-sizing: border-box; display: block; height: 50px; - vertical-align: middle; + line-height: 50px; padding: 0; } table tr[data-type="dir"] td.filename a.name span.nametext {font-weight:bold; } table td.filename input.filename { width: 80%; font-size: 14px; - margin-top: 8px; + margin-top: 0; margin-left: 2px; cursor: text; } table td.filename a, table td.login, table td.logout, table td.download, table td.upload, table td.create, table td.delete { padding:3px 8px 8px 3px; } -table td.filename .nametext, .uploadtext, .modified, .column-last>span:first-child { float:left; padding:14px 0; } +table td.filename .nametext, .uploadtext, .modified, .column-last>span:first-child { float:left; padding:15px 0; } .modified, .column-last>span:first-child { position: relative; - padding-left: 15px; overflow: hidden; text-overflow: ellipsis; width: 90%; @@ -257,7 +251,6 @@ table td.filename .nametext, .uploadtext, .modified, .column-last>span:first-chi /* TODO fix usability bug (accidental file/folder selection) */ table td.filename .nametext { position: absolute; - top: 16px; left: 55px; padding: 0; overflow: hidden; @@ -315,7 +308,7 @@ table td.filename .nametext .innernametext { /* for smaller resolutions - see mobile.css */ table td.filename .uploadtext { font-weight:normal; margin-left:8px; } -table td.filename form { font-size:14px; margin-left:48px; margin-right:48px; } +table td.filename form { font-size:14px; margin-left:46px; height: 40px; padding-top: 10px} .ie8 input[type="checkbox"]{ padding: 0; @@ -369,7 +362,9 @@ table td.filename form { font-size:14px; margin-left:48px; margin-right:48px; } #fileList tr td.filename { - position:relative; width:100%; + position: relative; + width: 100%; + padding-left: 0; -webkit-transition:background-image 500ms; -moz-transition:background-image 500ms; -o-transition:background-image 500ms; transition:background-image 500ms; } @@ -384,7 +379,6 @@ table td.filename form { font-size:14px; margin-left:48px; margin-right:48px; } /* File actions */ .fileactions { position: absolute; - top: 14px; right: 0; font-size: 11px; } @@ -393,39 +387,49 @@ table td.filename form { font-size:14px; margin-left:48px; margin-right:48px; } #fileList a.action.delete { position: absolute; right: 0; - padding: 28px 14px 19px !important; + padding: 17px 14px; } #fileList .action.action-share-notification span, #fileList a { cursor: default !important; } -a.action>img { max-height:16px; max-width:16px; vertical-align:text-bottom; } +a.action>img { + max-height:16px; + max-width:16px; + vertical-align:text-bottom; + margin-bottom: -1px; +} /* Actions for selected files */ .selectedActions { position: absolute; - top: -1px; + top: 0; right: 0; - padding: 15px 8px; } .selectedActions a { display: inline; - padding: 17px 5px; + font-size: 11px; + line-height: 50px; + padding: 18px 5px; +} +.selectedActions a.delete-selected { + padding-right: 15px; } .selectedActions a.hidden { display: none; } .selectedActions a img { position:relative; - top:5px; + vertical-align: text-bottom; + margin-bottom: -1px; } #fileList a.action { display: inline; - margin: -8px 0; padding: 18px 8px; + line-height: 50px; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter: alpha(opacity=0); opacity: 0; diff --git a/apps/files/css/mobile.css b/apps/files/css/mobile.css index a0b92ca6949..04a9a3079e8 100644 --- a/apps/files/css/mobile.css +++ b/apps/files/css/mobile.css @@ -18,6 +18,11 @@ table td.date { display: none; } +/* remove padding to let border bottom fill the whole width*/ +table td { + padding: 0; +} + /* remove shift for multiselect bar to account for missing navigation */ table.multiselect thead { padding-left: 0; @@ -25,7 +30,7 @@ table.multiselect thead { /* restrict length of displayed filename to prevent overflow */ table td.filename .nametext { - max-width: 75% !important; + width: 100%; } /* always show actions on mobile, not only on hover */ @@ -51,7 +56,7 @@ table td.filename .nametext { /* ellipsis on file names */ table td.filename .nametext .innernametext { - max-width: 75%; + max-width: 50%; } /* proper notification area for multi line messages */ diff --git a/apps/files/l10n/eo.php b/apps/files/l10n/eo.php index 45c9ca78aad..26e2cd6f29c 100644 --- a/apps/files/l10n/eo.php +++ b/apps/files/l10n/eo.php @@ -51,6 +51,7 @@ $TRANSLATIONS = array( "Your storage is almost full ({usedSpacePercent}%)" => "Via memoro preskaŭ plenas ({usedSpacePercent}%)", "{dirs} and {files}" => "{dirs} kaj {files}", "%s could not be renamed" => "%s ne povis alinomiĝi", +"Upload (max. %s)" => "Alŝuti (maks. %s)", "File handling" => "Dosieradministro", "Maximum upload size" => "Maksimuma alŝutogrando", "max. possible: " => "maks. ebla: ", diff --git a/apps/files/l10n/ml_IN.php b/apps/files/l10n/ml_IN.php index 0157af093e9..9cf8ea034ab 100644 --- a/apps/files/l10n/ml_IN.php +++ b/apps/files/l10n/ml_IN.php @@ -1,5 +1,6 @@ <?php $TRANSLATIONS = array( +"Files" => "ഫയലുകൾ", "_%n folder_::_%n folders_" => array("",""), "_%n file_::_%n files_" => array("",""), "_Uploading %n file_::_Uploading %n files_" => array("","") diff --git a/apps/files/l10n/ru.php b/apps/files/l10n/ru.php index f63c4419302..ea47eba921f 100644 --- a/apps/files/l10n/ru.php +++ b/apps/files/l10n/ru.php @@ -53,7 +53,7 @@ $TRANSLATIONS = array( "Error deleting file." => "Ошибка при удалении файла.", "Name" => "Имя", "Size" => "Размер", -"Modified" => "Дата изменения", +"Modified" => "Изменён", "_%n folder_::_%n folders_" => array("%n каталог","%n каталога","%n каталогов"), "_%n file_::_%n files_" => array("%n файл","%n файла","%n файлов"), "_Uploading %n file_::_Uploading %n files_" => array("Закачка %n файла","Закачка %n файлов","Закачка %n файлов"), @@ -65,7 +65,7 @@ $TRANSLATIONS = array( "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Шифрование было отключено, но ваши файлы остались зашифрованными. Зайдите на страницу личных настроек для того, чтобы расшифровать их.", "{dirs} and {files}" => "{dirs} и {files}", "%s could not be renamed" => "%s не может быть переименован", -"Upload (max. %s)" => "Загружено (max. %s)", +"Upload (max. %s)" => "Загрузка (Максимум: %s)", "File handling" => "Управление файлами", "Maximum upload size" => "Максимальный размер загружаемого файла", "max. possible: " => "макс. возможно: ", diff --git a/apps/files/l10n/sl.php b/apps/files/l10n/sl.php index c155e79c211..a0238646b28 100644 --- a/apps/files/l10n/sl.php +++ b/apps/files/l10n/sl.php @@ -71,7 +71,7 @@ $TRANSLATIONS = array( "max. possible: " => "največ mogoče:", "Save" => "Shrani", "WebDAV" => "WebDAV", -"Use this address to <a href=\"%s\" target=\"_blank\">access your Files via WebDAV</a>" => "Uporabite naslov <a href=\"%s\" target=\"_blank\"> za dostop do datotek rpeko sistema WebDAV</a>.", +"Use this address to <a href=\"%s\" target=\"_blank\">access your Files via WebDAV</a>" => "Uporabite naslov <a href=\"%s\" target=\"_blank\"> za dostop do datotek peko sistema WebDAV</a>.", "New" => "Novo", "New text file" => "Nova besedilna datoteka", "Text file" => "Besedilna datoteka", @@ -85,6 +85,6 @@ $TRANSLATIONS = array( "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 ...", -"Currently scanning" => "Trenutno preverjam" +"Currently scanning" => "Poteka preverjanje" ); $PLURAL_FORMS = "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"; diff --git a/apps/files/l10n/uk.php b/apps/files/l10n/uk.php index 740c4f5c0cc..5a098561d65 100644 --- a/apps/files/l10n/uk.php +++ b/apps/files/l10n/uk.php @@ -3,8 +3,15 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Не вдалося перемістити %s - Файл з таким ім'ям вже існує", "Could not move %s" => "Не вдалося перемістити %s", "File name cannot be empty." => " Ім'я файлу не може бути порожнім.", +"\"%s\" is an invalid file name." => "\"%s\" - це некоректне ім'я файлу.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Невірне ім'я, '\\', '/', '<', '>', ':', '\"', '|', '?' та '*' не дозволені.", +"The target folder has been moved or deleted." => "Теку призначення було переміщено або видалено.", +"The name %s is already used in the folder %s. Please choose a different name." => "Файл з ім'ям %s вже є у теці %s. Оберіть інше ім'я.", +"Server is not allowed to open URLs, please check the server configuration" => "Серверу заборонено відкривати посилання, перевірте конфігурацію", +"Error while downloading %s to %s" => "Помилка завантаження %s до %s", +"Error when creating the file" => "Помилка створення файлу", "Folder name cannot be empty." => "Ім'я теки не може бути порожнім.", +"Error when creating the folder" => "Помилка створення теки", "Unable to set upload directory." => "Не вдалося встановити каталог завантаження.", "No file was uploaded. Unknown error" => "Не завантажено жодного файлу. Невідома помилка", "There is no error, the file uploaded with success" => "Файл успішно вивантажено без помилок.", @@ -15,47 +22,66 @@ $TRANSLATIONS = array( "Missing a temporary folder" => "Відсутній тимчасовий каталог", "Failed to write to disk" => "Невдалося записати на диск", "Not enough storage available" => "Місця більше немає", +"Upload failed. Could not find uploaded file" => "Завантаження не вдалося. Неможливо знайти завантажений файл.", +"Upload failed. Could not get file info." => "Завантаження не вдалося. Неможливо отримати інформацію про файл.", "Invalid directory." => "Невірний каталог.", "Files" => "Файли", +"All files" => "Усі файли", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "Неможливо завантажити {filename}, оскільки це каталог або має нульовий розмір.", +"Total file size {size1} exceeds upload limit {size2}" => "Розмір файлу {size1} перевищує обмеження {size2}", +"Not enough free space, you are uploading {size1} but only {size2} is left" => "Недостатньо вільного місця, ви завантажуєте {size1}, а залишилося лише {size2}", "Upload cancelled." => "Завантаження перервано.", +"Could not get result from server." => "Не вдалося отримати результат від сервера.", "File upload is in progress. Leaving the page now will cancel the upload." => "Виконується завантаження файлу. Закриття цієї сторінки приведе до відміни завантаження.", "URL cannot be empty" => "URL не може бути порожнім", "{new_name} already exists" => "{new_name} вже існує", "Could not create file" => "Не вдалося створити файл", "Could not create folder" => "Не вдалося створити теку", +"Error fetching URL" => "Помилка отримання URL", "Share" => "Поділитися", "Delete permanently" => "Видалити назавжди", "Delete" => "Видалити", "Rename" => "Перейменувати", "Your download is being prepared. This might take some time if the files are big." => "Ваше завантаження готується. Це може зайняти деякий час, якщо файли завеликі.", "Pending" => "Очікування", +"Error moving file." => "Помилка переміщення файлу.", "Error moving file" => "Помилка переміщення файлу", "Error" => "Помилка", "Could not rename file" => "Неможливо перейменувати файл", +"Error deleting file." => "Помилка видалення файлу.", "Name" => "Ім'я", "Size" => "Розмір", "Modified" => "Змінено", "_%n folder_::_%n folders_" => array("%n тека","%n тека","%n теки"), "_%n file_::_%n files_" => array("%n файл","%n файлів","%n файли"), -"_Uploading %n file_::_Uploading %n files_" => array("","",""), +"_Uploading %n file_::_Uploading %n files_" => array("Завантаження %n файлу","Завантаження %n файлів","Завантаження %n файлів"), +"\"{name}\" is an invalid file name." => "\"{name}\" - некоректне ім'я файлу.", "Your storage is full, files can not be updated or synced anymore!" => "Ваше сховище переповнене, файли більше не можуть бути оновлені або синхронізовані !", "Your storage is almost full ({usedSpacePercent}%)" => "Ваше сховище майже повне ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Доданок шифрування ввімкнено, але ваші ключі не ініціалізовано, вийдіть та зайдіть знову", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Невірний закритий ключ для доданку шифрування. Оновіть пароль до вашого закритого ключа в особистих налаштуваннях.", +"Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Шифрування було вимкнено, але ваші файли все ще зашифровано. Для розшифрування перейдіть до персональних налаштувань.", "%s could not be renamed" => "%s не може бути перейменований", +"Upload (max. %s)" => "Завантаження (макс. %s)", "File handling" => "Робота з файлами", "Maximum upload size" => "Максимальний розмір відвантажень", "max. possible: " => "макс.можливе:", "Save" => "Зберегти", "WebDAV" => "WebDAV", +"Use this address to <a href=\"%s\" target=\"_blank\">access your Files via WebDAV</a>" => "Для доступу до файлів через WebDAV використовуйте <a href=\"%s\" target=\"_blank\">це посилання</a>", "New" => "Створити", +"New text file" => "Новий текстовий файл", "Text file" => "Текстовий файл", "New folder" => "Нова тека", "Folder" => "Тека", "From link" => "З посилання", "Cancel upload" => "Перервати завантаження", +"You don’t have permission to upload or create files here" => "У вас недостатньо прав для завантаження або створення файлів тут", "Nothing in here. Upload something!" => "Тут нічого немає. Відвантажте що-небудь!", "Download" => "Завантажити", "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." => "Файли скануються, зачекайте, будь-ласка." +"Files are being scanned, please wait." => "Файли скануються, зачекайте, будь-ласка.", +"Currently scanning" => "Триває перевірка" ); $PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index df101acab9d..3625d5a09f3 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -464,61 +464,44 @@ class Hooks { $newShareKeyPath = $ownerNew . '/files_encryption/share-keys/' . $pathNew;
}
- // add key ext if this is not an folder
+ // create new key folders if it doesn't exists
+ if (!$view->file_exists(dirname($newShareKeyPath))) {
+ $view->mkdir(dirname($newShareKeyPath));
+ }
+ if (!$view->file_exists(dirname($newKeyfilePath))) {
+ $view->mkdir(dirname($newKeyfilePath));
+ }
+
+ // handle share keys
if (!$view->is_dir($oldKeyfilePath)) {
$oldKeyfilePath .= '.key';
$newKeyfilePath .= '.key';
// handle share-keys
- $localKeyPath = $view->getLocalFile($oldShareKeyPath);
- $escapedPath = Helper::escapeGlobPattern($localKeyPath);
- $matches = glob($escapedPath . '*.shareKey');
+ $matches = Helper::findShareKeys($oldShareKeyPath, $view);
foreach ($matches as $src) {
$dst = \OC\Files\Filesystem::normalizePath(str_replace($pathOld, $pathNew, $src));
-
- // create destination folder if not exists
- if (!file_exists(dirname($dst))) {
- mkdir(dirname($dst), 0750, true);
- }
-
- rename($src, $dst);
+ $view->rename($src, $dst);
}
} else {
// handle share-keys folders
-
- // create destination folder if not exists
- if (!$view->file_exists(dirname($newShareKeyPath))) {
- mkdir($view->getLocalFile($newShareKeyPath), 0750, true);
- }
-
$view->rename($oldShareKeyPath, $newShareKeyPath);
}
// Rename keyfile so it isn't orphaned
if ($view->file_exists($oldKeyfilePath)) {
-
- // create destination folder if not exists
- if (!$view->file_exists(dirname($newKeyfilePath))) {
- mkdir(dirname($view->getLocalFile($newKeyfilePath)), 0750, true);
- }
-
$view->rename($oldKeyfilePath, $newKeyfilePath);
}
- // build the path to the file
- $newPath = '/' . $ownerNew . '/files' . $pathNew;
+ // update share keys
+ $sharingEnabled = \OCP\Share::isEnabled();
- if ($util->fixFileSize($newPath)) {
- // get sharing app state
- $sharingEnabled = \OCP\Share::isEnabled();
-
- // get users
- $usersSharing = $util->getSharingUsersArray($sharingEnabled, $pathNew);
+ // get users
+ $usersSharing = $util->getSharingUsersArray($sharingEnabled, $pathNew);
- // update sharing-keys
- $util->setSharedFileKeyfiles($session, $usersSharing, $pathNew);
- }
+ // update sharing-keys
+ $util->setSharedFileKeyfiles($session, $usersSharing, $pathNew);
\OC_FileProxy::$enabled = $proxyStatus;
}
diff --git a/apps/files_encryption/l10n/eo.php b/apps/files_encryption/l10n/eo.php index a77ef9813a5..f66d6120964 100644 --- a/apps/files_encryption/l10n/eo.php +++ b/apps/files_encryption/l10n/eo.php @@ -11,6 +11,7 @@ $TRANSLATIONS = array( "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" +"Update Private Key Password" => "Ĝisdatigi la pasvorton de la malpublika klavo", +"Enable password recovery:" => "Kapabligi restaŭron de pasvorto:" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_encryption/l10n/es.php b/apps/files_encryption/l10n/es.php index f8bed2f720b..2c88589bf9d 100644 --- a/apps/files_encryption/l10n/es.php +++ b/apps/files_encryption/l10n/es.php @@ -17,6 +17,7 @@ $TRANSLATIONS = array( "Following users are not set up for encryption:" => "Los siguientes usuarios no han sido configurados para el cifrado:", "Initial encryption started... This can take some time. Please wait." => "Encriptación iniciada..... Esto puede tomar un tiempo. Por favor espere.", "Initial encryption running... Please try again later." => "Cifrado inicial en curso... Inténtelo más tarde.", +"Go directly to your %spersonal settings%s." => "Ir directamente a %sOpciones%s.", "Encryption" => "Cifrado", "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", diff --git a/apps/files_encryption/l10n/pl.php b/apps/files_encryption/l10n/pl.php index 7063161b20a..e134430d8d3 100644 --- a/apps/files_encryption/l10n/pl.php +++ b/apps/files_encryption/l10n/pl.php @@ -17,6 +17,7 @@ $TRANSLATIONS = array( "Following users are not set up for encryption:" => "Następujący użytkownicy nie mają skonfigurowanego szyfrowania:", "Initial encryption started... This can take some time. Please wait." => "Rozpoczęto szyfrowanie... To może chwilę potrwać. Proszę czekać.", "Initial encryption running... Please try again later." => "Trwa szyfrowanie początkowe...Spróbuj ponownie.", +"Go directly to your %spersonal settings%s." => "Przejdź bezpośrednio do %spersonal settings%s.", "Encryption" => "Szyfrowanie", "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", diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php index 2684bf7be33..fed0788028f 100755 --- a/apps/files_encryption/lib/helper.php +++ b/apps/files_encryption/lib/helper.php @@ -430,12 +430,28 @@ class Helper { } /** - * glob uses different pattern than regular expressions, escape glob pattern only - * @param string $path unescaped path - * @return string path + * find all share keys for a given file + * @param string $path to the file + * @param \OC\Files\View $view view, relative to data/ + * @return array list of files, path relative to data/ */ - public static function escapeGlobPattern($path) { - return preg_replace('/(\*|\?|\[)/', '[$1]', $path); + public static function findShareKeys($path, $view) { + $result = array(); + $pathinfo = pathinfo($path); + $dirContent = $view->opendir($pathinfo['dirname']); + + if (is_resource($dirContent)) { + while (($file = readdir($dirContent)) !== false) { + if (!\OC\Files\Filesystem::isIgnoredDir($file)) { + if (preg_match("/" . $pathinfo['filename'] . ".(.*).shareKey/", $file)) { + $result[] = $pathinfo['dirname'] . '/' . $file; + } + } + } + closedir($dirContent); + } + + return $result; } /** diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 98986d1486f..e71fec56854 100755 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -133,20 +133,7 @@ class Keymanager { $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); - - } - } + $targetPath = self::keySetPreparation($view, $filename, $basePath); // try reusing key file if part file if (Helper::isPartialFilePath($targetPath)) { @@ -281,8 +268,9 @@ class Keymanager { $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; - if (!$view->file_exists('')) + if (!$view->file_exists('')) { $view->mkdir(''); + } $result = $view->file_put_contents($user . '.private.key', $key); @@ -340,7 +328,7 @@ class Keymanager { $basePath = '/' . $owner . '/files_encryption/share-keys'; } - $shareKeyPath = self::keySetPreparation($view, $filename, $basePath, $owner); + $shareKeyPath = self::keySetPreparation($view, $filename, $basePath); $result = true; @@ -466,8 +454,7 @@ class Keymanager { if ($view->is_dir($shareKeyPath)) { - $localPath = \OC\Files\Filesystem::normalizePath($view->getLocalFolder($shareKeyPath)); - self::recursiveDelShareKeys($localPath, $userIds); + self::recursiveDelShareKeys($shareKeyPath, $userIds, $view); } else { @@ -491,23 +478,25 @@ class Keymanager { * @param string $dir directory * @param array $userIds user ids for which the share keys should be deleted */ - 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); + private static function recursiveDelShareKeys($dir, $userIds, $view) { + + $dirContent = $view->opendir($dir); + + if (is_resource($dirContent)) { + while (($file = readdir($dirContent)) !== false) { + if (!\OC\Files\Filesystem::isIgnoredDir($file)) { + if ($view->is_dir($dir . '/' . $file)) { + self::recursiveDelShareKeys($dir . '/' . $file, $userIds, $view); + } else { + foreach ($userIds as $userId) { + if (preg_match("/(.*)." . $userId . ".shareKey/", $file)) { + $view->unlink($dir . '/' . $file); + } + } + } + } } - } - $subdirs = glob($escapedDir . '/*', GLOB_ONLYDIR); - foreach ($subdirs as $subdir) { - self::recursiveDelShareKeys($subdir, $userIds); + closedir($dirContent); } } @@ -516,7 +505,7 @@ class Keymanager { * @param string|boolean $path * @param string $basePath */ - protected static function keySetPreparation(\OC\Files\View $view, $path, $basePath, $userId) { + protected static function keySetPreparation(\OC\Files\View $view, $path, $basePath) { $targetPath = ltrim($path, '/'); diff --git a/apps/files_encryption/tests/hooks.php b/apps/files_encryption/tests/hooks.php index 79699a3ef35..5eda8df01b9 100644 --- a/apps/files_encryption/tests/hooks.php +++ b/apps/files_encryption/tests/hooks.php @@ -307,7 +307,7 @@ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase { $this->assertTrue($this->rootView->is_dir('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->folder . '/' . $this->folder)); - // move the file out of the shared folder + // move the file to the sub-subfolder $root = $this->rootView->getRoot(); $this->rootView->chroot('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/'); $this->rootView->rename($this->filename, '/' . $this->folder . '/' . $this->folder . '/' . $this->filename); diff --git a/apps/files_encryption/tests/keymanager.php b/apps/files_encryption/tests/keymanager.php index 0c025443cd6..3339f8c73e6 100644 --- a/apps/files_encryption/tests/keymanager.php +++ b/apps/files_encryption/tests/keymanager.php @@ -206,55 +206,56 @@ class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase { */ function testRecursiveDelShareKeys() { - // generate filename - $filename = '/tmp-' . uniqid() . '.txt'; - // create folder structure - $this->view->mkdir('/'.Test_Encryption_Keymanager::TEST_USER.'/files/folder1'); - $this->view->mkdir('/'.Test_Encryption_Keymanager::TEST_USER.'/files/folder1/subfolder'); - $this->view->mkdir('/'.Test_Encryption_Keymanager::TEST_USER.'/files/folder1/subfolder/subsubfolder'); - - // enable encryption proxy - $proxyStatus = \OC_FileProxy::$enabled; - \OC_FileProxy::$enabled = true; - - // save file with content - $cryptedFile = file_put_contents('crypt:///'.Test_Encryption_Keymanager::TEST_USER.'/files/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->view->mkdir('/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/share-keys/folder1'); + $this->view->mkdir('/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/share-keys/folder1/subfolder'); + $this->view->mkdir('/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/share-keys/folder1/subfolder/subsubfolder'); + + // create some dummy share keys + $this->view->file_put_contents('/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/share-keys/folder1/file1.user1.shareKey', 'data'); + $this->view->file_put_contents('/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/share-keys/folder1/file2.user2.shareKey', 'data'); + $this->view->file_put_contents('/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/share-keys/folder1/file2.user3.shareKey', 'data'); + $this->view->file_put_contents('/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/share-keys/folder1/subfolder/file2.user3.shareKey', 'data'); + $this->view->file_put_contents('/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/share-keys/folder1/subfolder/subsubfolder/file1.user1.shareKey', 'data'); + $this->view->file_put_contents('/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/share-keys/folder1/subfolder/subsubfolder/file2.user2.shareKey', 'data'); + $this->view->file_put_contents('/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/share-keys/folder1/subfolder/subsubfolder/file2.user3.shareKey', 'data'); + + // recursive delete share keys from user1 and user2 + Encryption\Keymanager::delShareKey($this->view, array('user1', 'user2'), '/folder1/'); + + // check if share keys from user1 and user2 are deleted + $this->assertFalse($this->view->file_exists( + '/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/share-keys/folder1/file1.user1.shareKey')); + $this->assertFalse($this->view->file_exists( + '/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/share-keys/folder1/file2.user2.shareKey')); + $this->assertFalse($this->view->file_exists( + '/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/share-keys/folder1/subfolder/subsubfolder/file1.user1.shareKey')); $this->assertFalse($this->view->file_exists( - '/admin/files_encryption/share-keys/folder1/subfolder/subsubfolder/' . $filename . '.admin.shareKey')); + '/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/share-keys/folder1/subfolder/subsubfolder/file2.user2.shareKey')); - // enable encryption proxy - $proxyStatus = \OC_FileProxy::$enabled; - \OC_FileProxy::$enabled = true; + // check if share keys from user3 still exists + $this->assertTrue($this->view->file_exists( + '/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/share-keys/folder1/file2.user3.shareKey')); + $this->assertTrue($this->view->file_exists( + '/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/share-keys/folder1/subfolder/subsubfolder/file2.user3.shareKey')); + $this->assertTrue($this->view->file_exists( + '/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/share-keys/folder1/subfolder/file2.user3.shareKey')); // cleanup - $this->view->deleteAll('/admin/files/folder1'); + $this->view->deleteAll('/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/share-keys'); - // change encryption proxy to previous state - \OC_FileProxy::$enabled = $proxyStatus; } function testKeySetPreperation() { $basePath = '/'.Test_Encryption_Keymanager::TEST_USER.'/files'; - $path = '/folder1/subfolder/subsubfolder'; + $path = '/folder1/subfolder/subsubfolder/file.txt'; $this->assertFalse($this->view->is_dir($basePath . '/testKeySetPreperation')); $result = TestProtectedKeymanagerMethods::testKeySetPreperation($this->view, $path, $basePath); // return path without leading slash - $this->assertSame('folder1/subfolder/subsubfolder', $result); + $this->assertSame('folder1/subfolder/subsubfolder/file.txt', $result); // check if directory structure was created $this->assertTrue($this->view->is_dir($basePath . '/folder1/subfolder/subsubfolder')); @@ -283,6 +284,6 @@ class TestProtectedKeymanagerMethods extends \OCA\Encryption\Keymanager { * @param string $basePath */ public static function testKeySetPreperation($view, $path, $basePath) { - return self::keySetPreparation($view, $path, $basePath, ''); + return self::keySetPreparation($view, $path, $basePath); } } diff --git a/apps/files_external/l10n/ru.php b/apps/files_external/l10n/ru.php index 3bc71ad2709..837e48fcb90 100644 --- a/apps/files_external/l10n/ru.php +++ b/apps/files_external/l10n/ru.php @@ -5,6 +5,7 @@ $TRANSLATIONS = array( "Location" => "Местоположение", "Amazon S3" => "Amazon S3", "Key" => "Ключ", +"Secret" => "Секрет", "Access Key" => "Ключ доступа", "Secret Key" => "Секретный ключ", "Hostname (optional)" => "Хост (опц.)", @@ -31,7 +32,11 @@ $TRANSLATIONS = array( "<b>Note:</b> " => "<b>Примечание:</b> ", " and " => "и", "<b>Note:</b> The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." => "<b>Примечание:</b> Поддержка cURL в PHP не включена или не установлен модуль. Подключение %s невозможно. Обратитесь к вашему системному администратору.", +"<b>Note:</b> The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." => "<b>Обратите внимание:</b> Поддержка FTP в PHP не включена или не установлена. Монтирование %s невозможно. Пожалуйста, обратитесь к системному администратору.", +"<b>Note:</b> \"%s\" is not installed. Mounting of %s is not possible. Please ask your system administrator to install it." => "<b>Обратите внимание:</b> \"%s\" не установлен. Монтирование %s невозможно. Пожалуйста, обратитесь к системному администратору.", +"You don't have any external storages" => "У вас нет внешних хранилищ", "Name" => "Имя", +"Storage type" => "Тип хранилища", "External Storage" => "Внешний носитель", "Folder name" => "Имя папки", "Configuration" => "Конфигурация", diff --git a/apps/files_external/l10n/zh_TW.php b/apps/files_external/l10n/zh_TW.php index 0701b47bcfa..70339801f0c 100644 --- a/apps/files_external/l10n/zh_TW.php +++ b/apps/files_external/l10n/zh_TW.php @@ -3,9 +3,18 @@ $TRANSLATIONS = array( "External storage" => "外部儲存", "Local" => "本地", "Location" => "地點", +"Amazon S3" => "Amazon S3", +"Key" => "鑰", +"Secret" => "密", +"Secret Key" => "密鑰", +"Hostname (optional)" => "主機名稱 (選填)", +"Port (optional)" => "埠號 (選填)", +"Region (optional)" => "區域 (選填)", +"Enable SSL" => "啟用 SSL", "Host" => "主機", "Username" => "使用者名稱:", "Password" => "密碼", +"Username (required)" => "使用者名稱 (必填)", "Share" => "分享", "URL" => "URL", "Access granted" => "允許存取", @@ -14,18 +23,28 @@ $TRANSLATIONS = array( "Please provide a valid Dropbox app key and secret." => "請提供有效的 Dropbox app key 和 app secret 。", "Error configuring Google Drive storage" => "設定 Google Drive 儲存時發生錯誤", "Personal" => "個人", +"System" => "系統", "Saved" => "已儲存", +"<b>Note:</b> " => "<b>警告:</b> ", +" and " => "與", +"<b>Note:</b> The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." => "<b>警告:</b> PHP 並未啓用 Curl 的支援,因此無法掛載 %s 。請洽您的系統管理員將其安裝並啓用。", +"<b>Note:</b> The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." => "<b>警告</b>:PHP 並未啓用 FTP 的支援,因此無法掛載 %s,請洽您的系統管理員將其安裝並啓用。", +"<b>Note:</b> \"%s\" is not installed. Mounting of %s is not possible. Please ask your system administrator to install it." => "<b>警告</b>並未安裝 \"%s\",因此無法掛載 %s。請洽您的系統管理員將其安裝並啓用。", +"You don't have any external storages" => "您沒有任何外部儲存", "Name" => "名稱", "External Storage" => "外部儲存", "Folder name" => "資料夾名稱", "Configuration" => "設定", "Options" => "選項", +"Available for" => "可用的", "Add storage" => "增加儲存區", +"No user or group" => "沒有使用者或群組", "All Users" => "所有使用者", "Groups" => "群組", "Users" => "使用者", "Delete" => "刪除", "Enable User External Storage" => "啓用使用者外部儲存", +"Allow users to mount the following external storage" => "允許使用者自行掛載以下的外部儲存", "SSL root certificates" => "SSL 根憑證", "Import Root Certificate" => "匯入根憑證" ); diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php index a4a0a57c675..b55a80ea640 100644 --- a/apps/files_sharing/appinfo/app.php +++ b/apps/files_sharing/appinfo/app.php @@ -14,20 +14,14 @@ OC::$CLASSPATH['OCA\Files\Share\Proxy'] = 'files_sharing/lib/proxy.php'; \OCP\App::registerAdmin('files_sharing', 'settings-admin'); -OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup'); -OCP\Util::connectHook('OC_Filesystem', 'setup', '\OCA\Files_Sharing\External\Manager', 'setup'); +\OCA\Files_Sharing\Helper::registerHooks(); + OCP\Share::registerBackend('file', 'OC_Share_Backend_File'); OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file'); OCP\Util::addScript('files_sharing', 'share'); OCP\Util::addScript('files_sharing', 'external'); -\OC_Hook::connect('OC_Filesystem', 'post_write', '\OC\Files\Cache\Shared_Updater', 'writeHook'); -\OC_Hook::connect('OC_Filesystem', 'post_delete', '\OC\Files\Cache\Shared_Updater', 'postDeleteHook'); -\OC_Hook::connect('OC_Filesystem', 'delete', '\OC\Files\Cache\Shared_Updater', 'deleteHook'); -\OC_Hook::connect('OC_Filesystem', 'post_rename', '\OC\Files\Cache\Shared_Updater', 'renameHook'); -\OC_Hook::connect('OC_Appconfig', 'post_set_value', '\OCA\Files\Share\Maintainer', 'configChangeHook'); - OC_FileProxy::register(new OCA\Files\Share\Proxy()); \OCA\Files\App::getNavigationManager()->add( diff --git a/apps/files_sharing/js/external.js b/apps/files_sharing/js/external.js index 5c476b2d43d..a142819b112 100644 --- a/apps/files_sharing/js/external.js +++ b/apps/files_sharing/js/external.js @@ -8,13 +8,6 @@ * */ (function () { - var getParameterByName = function (query, name) { - name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); - var regex = new RegExp("[\\#&]" + name + "=([^&#]*)"), - results = regex.exec(query); - return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); - }; - var addExternalShare = function (remote, token, owner, name, password) { return $.post(OC.generateUrl('apps/files_sharing/external'), { remote: remote, @@ -25,7 +18,16 @@ }); }; - var showAddExternalDialog = function (remote, token, owner, name, passwordProtected) { + /** + * Shows "add external share" dialog. + * + * @param {String} remote remote server URL + * @param {String} owner owner name + * @param {String} name name of the shared folder + * @param {String} token authentication token + * @param {bool} passwordProtected true if the share is password protected + */ + OCA.Sharing.showAddExternalDialog = function (remote, token, owner, name, passwordProtected) { var remoteClean = (remote.substr(0, 8) === 'https://') ? remote.substr(8) : remote.substr(7); var callback = function (add, password) { password = password || ''; @@ -47,25 +49,23 @@ , 'Add Share', callback, true, 'Password', true); } }; - - OCA.Sharing.showAddExternalDialog = function (hash) { - var remote = getParameterByName(hash, 'remote'); - var owner = getParameterByName(hash, 'owner'); - var name = getParameterByName(hash, 'name'); - var token = getParameterByName(hash, 'token'); - var passwordProtected = parseInt(getParameterByName(hash, 'protected'), 10); - - if (remote && token && owner && name) { - showAddExternalDialog(remote, token, owner, name, passwordProtected); - } - }; })(); $(document).ready(function () { // FIXME: HACK: do not init when running unit tests, need a better way if (!window.TESTING && OCA.Files) {// only run in the files app - var hash = location.hash; - location.hash = ''; - OCA.Sharing.showAddExternalDialog(hash); + var params = OC.Util.History.parseUrlQuery(); + if (params.remote && params.token && params.owner && params.name) { + // clear hash, it is unlikely that it contain any extra parameters + location.hash = ''; + params.passwordProtected = parseInt(params.passwordProtected, 10) === 1; + OCA.Sharing.showAddExternalDialog( + params.remote, + params.token, + params.owner, + params.name, + params.passwordProtected + ); + } } }); diff --git a/apps/files_sharing/l10n/ast.php b/apps/files_sharing/l10n/ast.php index 941abe6d323..f1987ed5382 100644 --- a/apps/files_sharing/l10n/ast.php +++ b/apps/files_sharing/l10n/ast.php @@ -30,7 +30,6 @@ $TRANSLATIONS = array( "Download" => "Baxar", "Download %s" => "Descargar %s", "Direct link" => "Enllaz direutu", -"File Sharing" => "Compartición de ficheru", "Allow other instances to mount public links shared from this server" => "Permitir a otres instancies montar enllaces compartíos públicos d'esti sirvidor", "Allow users to mount public link shares" => "Permitir a los usuarios montar enllaces compartíos públicos" ); diff --git a/apps/files_sharing/l10n/ca.php b/apps/files_sharing/l10n/ca.php index a9fa0c5bad9..8de7be9a0f3 100644 --- a/apps/files_sharing/l10n/ca.php +++ b/apps/files_sharing/l10n/ca.php @@ -30,7 +30,6 @@ $TRANSLATIONS = array( "Download" => "Baixa", "Download %s" => "Baixa %s", "Direct link" => "Enllaç directe", -"File Sharing" => "Compartició de fitxers", "Allow other instances to mount public links shared from this server" => "Permet que altres instàncies muntin enllaços públics compartits des d'aqeust servidor", "Allow users to mount public link shares" => "Permet que usuaris muntin compartits amb enllaços públics" ); diff --git a/apps/files_sharing/l10n/cs_CZ.php b/apps/files_sharing/l10n/cs_CZ.php index 5fedb6d1610..914a002ac16 100644 --- a/apps/files_sharing/l10n/cs_CZ.php +++ b/apps/files_sharing/l10n/cs_CZ.php @@ -30,7 +30,6 @@ $TRANSLATIONS = array( "Download" => "Stáhnout", "Download %s" => "Stáhnout %s", "Direct link" => "Přímý odkaz", -"File Sharing" => "Sdílení Souborů", "Allow other instances to mount public links shared from this server" => "Povolit připojování veřejně sdílených odkazů z tohoto serveru", "Allow users to mount public link shares" => "Povolit uživatelům připojovat veřejně sdílené odkazy" ); diff --git a/apps/files_sharing/l10n/de.php b/apps/files_sharing/l10n/de.php index 571f4c3d665..ecf7f175800 100644 --- a/apps/files_sharing/l10n/de.php +++ b/apps/files_sharing/l10n/de.php @@ -30,7 +30,6 @@ $TRANSLATIONS = array( "Download" => "Herunterladen", "Download %s" => "Download %s", "Direct link" => "Direkter Link", -"File Sharing" => "Datei-Freigabe", "Allow other instances to mount public links shared from this server" => "Andere Instanzen zum Hinzufügen von öffentlichen Links, die über diesen Server Freigegeben werden, erlauben", "Allow users to mount public link shares" => "Erlaube Nutzern das Hinzufügen von freigegebenen öffentlichen Links" ); diff --git a/apps/files_sharing/l10n/de_DE.php b/apps/files_sharing/l10n/de_DE.php index a14a34f8dbe..c0488b4988b 100644 --- a/apps/files_sharing/l10n/de_DE.php +++ b/apps/files_sharing/l10n/de_DE.php @@ -30,7 +30,6 @@ $TRANSLATIONS = array( "Download" => "Herunterladen", "Download %s" => "Download %s", "Direct link" => "Direkte Verlinkung", -"File Sharing" => "Datei-Freigabe", "Allow other instances to mount public links shared from this server" => "Andere Instanzen zum Hinzufügen von öffentlichen Links, die über diesen Server Freigegeben werden, erlauben", "Allow users to mount public link shares" => "Erlaube Nutzern das Hinzufügen von freigegebenen öffentlichen Links" ); diff --git a/apps/files_sharing/l10n/el.php b/apps/files_sharing/l10n/el.php index d8c79f97c66..b340b677231 100644 --- a/apps/files_sharing/l10n/el.php +++ b/apps/files_sharing/l10n/el.php @@ -30,7 +30,6 @@ $TRANSLATIONS = array( "Download" => "Λήψη", "Download %s" => "Λήψη %s", "Direct link" => "Άμεσος σύνδεσμος", -"File Sharing" => "Διαμοιρασμός Αρχείων", "Allow other instances to mount public links shared from this server" => "Να επιτρέπεται σε άλλες εγκαταστάσεις να επιθέτουν δημόσιους συνδέσμους που έχουν διαμοιραστεί από αυτόν το διακομιστή", "Allow users to mount public link shares" => "Να επιτρέπεται στους χρήστες να επιθέτουν κοινόχρηστους φακέλους με δημόσιους συνδέσμους" ); diff --git a/apps/files_sharing/l10n/en_GB.php b/apps/files_sharing/l10n/en_GB.php index 674771f8b3e..04a5bb5e1b2 100644 --- a/apps/files_sharing/l10n/en_GB.php +++ b/apps/files_sharing/l10n/en_GB.php @@ -30,7 +30,6 @@ $TRANSLATIONS = array( "Download" => "Download", "Download %s" => "Download %s", "Direct link" => "Direct link", -"File Sharing" => "File Sharing", "Allow other instances to mount public links shared from this server" => "Allow other instances to mount public links shared from this server", "Allow users to mount public link shares" => "Allow users to mount public link shares" ); diff --git a/apps/files_sharing/l10n/eo.php b/apps/files_sharing/l10n/eo.php index 337a9bf8ac5..7ae7e543271 100644 --- a/apps/files_sharing/l10n/eo.php +++ b/apps/files_sharing/l10n/eo.php @@ -1,8 +1,19 @@ <?php $TRANSLATIONS = array( +"Server to server sharing is not enabled on this server" => "Interservila kunhavo ne kapabliĝis en ĉi tiu servilo", +"Shared with you" => "Kunhavata kun vi", +"Shared with others" => "Kunhavata kun aliaj", +"Shared by link" => "Kunhavata per ligilo", +"No files have been shared with you yet." => "Neniu dosiero kunhaviĝis kun vi ankoraŭ.", +"You haven't shared any files yet." => "Vi kunhavigis neniun dosieron ankoraŭ.", +"You haven't shared any files by link yet." => "Vi kunhavigis neniun dosieron per ligilo ankoraŭ.", +"Add {name} from {owner}@{remote}" => "Aldoni {name} el {owner}@{remote}", +"No ownCloud installation found at {remote}" => "Ne troviĝis instalo de ownCloud ĉe {remote}", +"Invalid ownCloud url" => "Nevalidas URL de ownCloud", "Shared by {owner}" => "Kunhavigita de {owner}", "Shared by" => "Kunhavigita de", "This share is password-protected" => "Ĉi tiu kunhavigo estas protektata per pasvorto", +"The password is wrong. Try again." => "La pasvorto malĝustas. Provu denove.", "Password" => "Pasvorto", "Name" => "Nomo", "Sorry, this link doesn’t seem to work anymore." => "Pardonu, ĉi tiu ligilo ŝajne ne plu funkcias.", @@ -11,8 +22,11 @@ $TRANSLATIONS = array( "the link expired" => "la ligilo eksvalidiĝis", "sharing is disabled" => "kunhavigo malkapablas", "For more info, please ask the person who sent this link." => "Por plia informo, bonvolu peti al la persono, kiu sendis ĉi tiun ligilon.", +"Save to ownCloud" => "Konservi en ownCloud", +"example.com/owncloud" => "example.com/owncloud", "Save" => "Konservi", "Download" => "Elŝuti", +"Download %s" => "Elŝuti %s", "Direct link" => "Direkta ligilo" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/es.php b/apps/files_sharing/l10n/es.php index 6e8d055446a..1b536db41c2 100644 --- a/apps/files_sharing/l10n/es.php +++ b/apps/files_sharing/l10n/es.php @@ -1,11 +1,14 @@ <?php $TRANSLATIONS = array( +"Server to server sharing is not enabled on this server" => "Compartir entre servidores no está habilitado en este servidor", +"Couldn't add remote share" => "No se puede añadir un compartido remoto", "Shared with you" => "Compartido contigo", "Shared with others" => "Compartido con otros", "Shared by link" => "Compartido por medio de enlaces", "No files have been shared with you yet." => "Aún no han compartido contigo ningún archivo.", "You haven't shared any files yet." => "Aún no has compartido ningún archivo.", "You haven't shared any files by link yet." => "Usted todavía no ha compartido ningún archivo por medio de enlaces.", +"Add {name} from {owner}@{remote}" => "Añadir {name} desde {owner}@{remote}", "No ownCloud installation found at {remote}" => "No se encontró una instalación de ownCloud en {remote}", "Invalid ownCloud url" => "URL de ownCloud inválido", "Shared by {owner}" => "Compartido por {owner}", @@ -27,6 +30,7 @@ $TRANSLATIONS = array( "Download" => "Descargar", "Download %s" => "Descargar %s", "Direct link" => "Enlace directo", -"File Sharing" => "Compartir archivos" +"Allow other instances to mount public links shared from this server" => "Permitir a otros montar enlaces publicos compartidos de este servidor", +"Allow users to mount public link shares" => "Permitir a los usuarios montar enlaces publicos compartidos" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/et_EE.php b/apps/files_sharing/l10n/et_EE.php index 9a9928321b1..422adf39a58 100644 --- a/apps/files_sharing/l10n/et_EE.php +++ b/apps/files_sharing/l10n/et_EE.php @@ -30,7 +30,6 @@ $TRANSLATIONS = array( "Download" => "Lae alla", "Download %s" => "Laadi alla %s", "Direct link" => "Otsene link", -"File Sharing" => "Faili jagamine", "Allow other instances to mount public links shared from this server" => "Luba teistel instantsidel ühendada sellest serverist jagatud avalikke linke", "Allow users to mount public link shares" => "Luba kasutajatel ühendada jagatud avalikke linke" ); diff --git a/apps/files_sharing/l10n/fi_FI.php b/apps/files_sharing/l10n/fi_FI.php index 4a55276fd42..16694632ec2 100644 --- a/apps/files_sharing/l10n/fi_FI.php +++ b/apps/files_sharing/l10n/fi_FI.php @@ -30,7 +30,6 @@ $TRANSLATIONS = array( "Download" => "Lataa", "Download %s" => "Lataa %s", "Direct link" => "Suora linkki", -"File Sharing" => "Tiedostonjako", "Allow other instances to mount public links shared from this server" => "Salli muiden instanssien liittää tältä palvelimelta jaettuja julkisia linkkejä", "Allow users to mount public link shares" => "Salli käyttäjien liittää julkisia linkkijakoja" ); diff --git a/apps/files_sharing/l10n/fr.php b/apps/files_sharing/l10n/fr.php index 182ad2b94ce..0d0d0567886 100644 --- a/apps/files_sharing/l10n/fr.php +++ b/apps/files_sharing/l10n/fr.php @@ -30,7 +30,6 @@ $TRANSLATIONS = array( "Download" => "Télécharger", "Download %s" => "Télécharger %s", "Direct link" => "Lien direct", -"File Sharing" => "Partage de fichiers", "Allow other instances to mount public links shared from this server" => "Autorise d'autres instances à monter des liens publiques partagés depuis ce serveur", "Allow users to mount public link shares" => "Autorise les utilisateurs à monter des liens de partages publiques" ); diff --git a/apps/files_sharing/l10n/gl.php b/apps/files_sharing/l10n/gl.php index c5fbcc6d6e2..d2f690e7729 100644 --- a/apps/files_sharing/l10n/gl.php +++ b/apps/files_sharing/l10n/gl.php @@ -30,7 +30,6 @@ $TRANSLATIONS = array( "Download" => "Descargar", "Download %s" => "Descargar %s", "Direct link" => "Ligazón directa", -"File Sharing" => "Compartir ficheiros", "Allow other instances to mount public links shared from this server" => "Permitir que outras instancias monten ligazóns públicas compartidas desde este servidor", "Allow users to mount public link shares" => "Permitirlle aos usuarios montar ligazóns públicas compartidas" ); diff --git a/apps/files_sharing/l10n/it.php b/apps/files_sharing/l10n/it.php index 710fed4b1b3..4aa95730aa1 100644 --- a/apps/files_sharing/l10n/it.php +++ b/apps/files_sharing/l10n/it.php @@ -30,7 +30,6 @@ $TRANSLATIONS = array( "Download" => "Scarica", "Download %s" => "Scarica %s", "Direct link" => "Collegamento diretto", -"File Sharing" => "Condivisione file", "Allow other instances to mount public links shared from this server" => "Permetti ad altre istanze di montare collegamenti pubblici condivisi da questo server", "Allow users to mount public link shares" => "Permetti agli utenti di montare condivisioni con collegamento pubblico" ); diff --git a/apps/files_sharing/l10n/ja.php b/apps/files_sharing/l10n/ja.php index 43c8f1c06d6..6a0b5cb3ed3 100644 --- a/apps/files_sharing/l10n/ja.php +++ b/apps/files_sharing/l10n/ja.php @@ -2,12 +2,12 @@ $TRANSLATIONS = array( "Server to server sharing is not enabled on this server" => "このサーバーでは、サーバー間の共有が有効ではありません", "Couldn't add remote share" => "リモート共有を追加できませんでした", -"Shared with you" => "あなたと共有", -"Shared with others" => "他人と共有", -"Shared by link" => "URLリンクで共有済", -"No files have been shared with you yet." => "まだ共有を行なっているファイルはありません。", -"You haven't shared any files yet." => "まだ共有を行なっているファイルはありません。", -"You haven't shared any files by link yet." => "まだURLリンクで共有を行なっているファイルはありません。", +"Shared with you" => "他ユーザーがあなたと共有中", +"Shared with others" => "他ユーザーと共有中", +"Shared by link" => "URLリンクで共有中", +"No files have been shared with you yet." => "他のユーザーがあなたと共有しているファイルはありません。", +"You haven't shared any files yet." => "他のユーザーと共有しているファイルはありません。", +"You haven't shared any files by link yet." => "URLリンクで共有しているファイルはありません。", "Add {name} from {owner}@{remote}" => "{owner}@{remote} から {name} を追加", "No ownCloud installation found at {remote}" => "{remote} には ownCloud がインストールされていません", "Invalid ownCloud url" => "無効な ownCloud URL です", @@ -22,7 +22,7 @@ $TRANSLATIONS = array( "Reasons might be:" => "理由は以下の通りと考えられます:", "the item was removed" => "アイテムが削除されました", "the link expired" => "リンクの期限が切れています", -"sharing is disabled" => "共有が無効になっています", +"sharing is disabled" => "共有は無効になっています", "For more info, please ask the person who sent this link." => "不明な点は、こちらのリンクの提供者に確認をお願いします。", "Save to ownCloud" => "ownCloud に保存", "example.com/owncloud" => "example.com/owncloud", @@ -30,8 +30,7 @@ $TRANSLATIONS = array( "Download" => "ダウンロード", "Download %s" => "%s をダウンロード", "Direct link" => "リンク", -"File Sharing" => "ファイル共有", -"Allow other instances to mount public links shared from this server" => "このサーバの公開共有リンクを他のインスタンスからマウントできるようにする", -"Allow users to mount public link shares" => "ユーザが公開共有リンクをマウントできるようにする" +"Allow other instances to mount public links shared from this server" => "このサーバにおけるURLでの共有を他のインスタンスからマウントできるようにする", +"Allow users to mount public link shares" => "ユーザーがURLでの共有をマウントできるようにする" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_sharing/l10n/nb_NO.php b/apps/files_sharing/l10n/nb_NO.php index 7ed1ee4696a..b9cc7ec90ab 100644 --- a/apps/files_sharing/l10n/nb_NO.php +++ b/apps/files_sharing/l10n/nb_NO.php @@ -30,7 +30,6 @@ $TRANSLATIONS = array( "Download" => "Last ned", "Download %s" => "Last ned %s", "Direct link" => "Direkte lenke", -"File Sharing" => "Fildeling", "Allow other instances to mount public links shared from this server" => "Tillat at andre instanser monterer offentlige lenker som er delt fra denne serveren", "Allow users to mount public link shares" => "Tillat at brukere monterer offentlige lenke-delinger" ); diff --git a/apps/files_sharing/l10n/nl.php b/apps/files_sharing/l10n/nl.php index de6644cd385..4f01b2e79d8 100644 --- a/apps/files_sharing/l10n/nl.php +++ b/apps/files_sharing/l10n/nl.php @@ -1,5 +1,7 @@ <?php $TRANSLATIONS = array( +"Server to server sharing is not enabled on this server" => "Server met server delen is niet geactiveerd op deze server", +"Couldn't add remote share" => "Kon geen externe share toevoegen", "Shared with you" => "Deelde met u", "Shared with others" => "Deelde met anderen", "Shared by link" => "Gedeeld via een link", @@ -7,6 +9,7 @@ $TRANSLATIONS = array( "You haven't shared any files yet." => "U hebt nog geen bestanden gedeeld.", "You haven't shared any files by link yet." => "U hebt nog geen bestanden via een link gedeeld.", "Add {name} from {owner}@{remote}" => "Toevoegen {name} van {owner}@{remote}", +"No ownCloud installation found at {remote}" => "Geen ownCloud installatie gevonden op {remote}", "Invalid ownCloud url" => "Ongeldige ownCloud url", "Shared by {owner}" => "Gedeeld door {owner}", "Shared by" => "Gedeeld door", @@ -27,6 +30,7 @@ $TRANSLATIONS = array( "Download" => "Downloaden", "Download %s" => "Download %s", "Direct link" => "Directe link", -"File Sharing" => "Bestand delen" +"Allow other instances to mount public links shared from this server" => "Toestaan dat andere oanClouds openbaar gedeelde links mounten vanaf deze server", +"Allow users to mount public link shares" => "Toestaan dat gebruikers openbaar gedeelde links mounten" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/pl.php b/apps/files_sharing/l10n/pl.php index 8b1bcf70399..7b0da90ac3d 100644 --- a/apps/files_sharing/l10n/pl.php +++ b/apps/files_sharing/l10n/pl.php @@ -1,11 +1,15 @@ <?php $TRANSLATIONS = array( +"Couldn't add remote share" => "Nie można dodać zdalnego folderu", "Shared with you" => "Współdzielony z Tobą", "Shared with others" => "Współdzielony z innymi", "Shared by link" => "Współdzielony linkiem", "No files have been shared with you yet." => "Nie ma jeszcze żadnych plików współdzielonych z Tobą", "You haven't shared any files yet." => "Nie współdzielisz jeszcze żadnych plików.", "You haven't shared any files by link yet." => "Nie współdzielisz jeszcze żadnych plików linkiem", +"Add {name} from {owner}@{remote}" => "Dodaj {name} z {owner}@{remote}", +"No ownCloud installation found at {remote}" => "Nie znaleziono instalacji ownCloud na {remote}", +"Invalid ownCloud url" => "Błędny adres URL", "Shared by {owner}" => "Udostępnione przez {owner}", "Shared by" => "Udostępniane przez", "This share is password-protected" => "Udział ten jest chroniony hasłem", @@ -19,9 +23,12 @@ $TRANSLATIONS = array( "the link expired" => "link wygasł", "sharing is disabled" => "Udostępnianie jest wyłączone", "For more info, please ask the person who sent this link." => "Aby uzyskać więcej informacji proszę poprosić osobę, która wysłał ten link.", +"Save to ownCloud" => "Zapis do ownCloud", +"example.com/owncloud" => "mojastrona.pl/owncloud", "Save" => "Zapisz", "Download" => "Pobierz", "Download %s" => "Pobierz %s", -"Direct link" => "Bezpośredni link" +"Direct link" => "Bezpośredni link", +"Allow users to mount public link shares" => "Zezwalaj użytkownikom na montowanie publicznych linków" ); $PLURAL_FORMS = "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/files_sharing/l10n/pt_BR.php b/apps/files_sharing/l10n/pt_BR.php index b7dac04c266..7d6f036d2a0 100644 --- a/apps/files_sharing/l10n/pt_BR.php +++ b/apps/files_sharing/l10n/pt_BR.php @@ -30,7 +30,6 @@ $TRANSLATIONS = array( "Download" => "Baixar", "Download %s" => "Baixar %s", "Direct link" => "Link direto", -"File Sharing" => "Compartilhamento de Arquivo", "Allow other instances to mount public links shared from this server" => "Permitir que outras instâncias montem links de compartilhamentos públicos a partir desde servidor", "Allow users to mount public link shares" => "Permitir aos usuários montar links públicos de compartilhamentos" ); diff --git a/apps/files_sharing/l10n/pt_PT.php b/apps/files_sharing/l10n/pt_PT.php index fd1bf232227..858d27aafa1 100644 --- a/apps/files_sharing/l10n/pt_PT.php +++ b/apps/files_sharing/l10n/pt_PT.php @@ -1,11 +1,16 @@ <?php $TRANSLATIONS = array( +"Server to server sharing is not enabled on this server" => "A partilha entre servidores não se encontra disponível", +"Couldn't add remote share" => "Ocorreu um erro ao adicionar a partilha remota", "Shared with you" => "Partilhado consigo ", "Shared with others" => "Partilhado com outros", "Shared by link" => "Partilhado pela hiperligação", "No files have been shared with you yet." => "Ainda não partilhados quaisquer ficheuiros consigo.", "You haven't shared any files yet." => "Ainda não partilhou quaisquer ficheiros.", "You haven't shared any files by link yet." => "Ainda não partilhou quaisquer ficheiros por hiperligação.", +"Add {name} from {owner}@{remote}" => "Adicionar {name} de {owner}@{remote}", +"No ownCloud installation found at {remote}" => "Não foi encontrada uma instalação em {remote}", +"Invalid ownCloud url" => "Endereço errado", "Shared by {owner}" => "Partilhado por {dono}", "Shared by" => "Partilhado por", "This share is password-protected" => "Esta partilha está protegida por senha", @@ -19,9 +24,13 @@ $TRANSLATIONS = array( "the link expired" => "A hiperligação expirou", "sharing is disabled" => "a partilha está desativada", "For more info, please ask the person who sent this link." => "Para mais informação, por favor, pergunte à pessoa que lhe enviou esta hiperligação.", +"Save to ownCloud" => "Guardar na ownCloud", +"example.com/owncloud" => "exemplo.pt/owncloud", "Save" => "Guardar", "Download" => "Transferir", "Download %s" => "Transferir %s", -"Direct link" => "Hiperligação direta" +"Direct link" => "Hiperligação direta", +"Allow other instances to mount public links shared from this server" => "Permitir que outras instâncias mapeiem endereços partilhados deste servidor", +"Allow users to mount public link shares" => "Permitir mapeamentos de endereços partilhados aos utilizadores" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/ru.php b/apps/files_sharing/l10n/ru.php index 1f38d3cf30b..a165d634e1e 100644 --- a/apps/files_sharing/l10n/ru.php +++ b/apps/files_sharing/l10n/ru.php @@ -1,11 +1,15 @@ <?php $TRANSLATIONS = array( +"Shared with you" => "Опубликованы вами", +"Shared with others" => "Опубликованы другими", +"No files have been shared with you yet." => "Вы ещё не опубликовали файлы", "Shared by {owner}" => "Доступ открыл {owner}", "Shared by" => "Опубликовано", "This share is password-protected" => "Для доступа к информации необходимо ввести пароль", "The password is wrong. Try again." => "Неверный пароль. Попробуйте еще раз.", "Password" => "Пароль", "Name" => "Имя", +"Share time" => "Дата публикации", "Sorry, this link doesn’t seem to work anymore." => "Эта ссылка устарела и более не действительна.", "Reasons might be:" => "Причиной может быть:", "the item was removed" => "объект был удалён", diff --git a/apps/files_sharing/l10n/sk_SK.php b/apps/files_sharing/l10n/sk_SK.php index 4fe89ef102b..b8471370e83 100644 --- a/apps/files_sharing/l10n/sk_SK.php +++ b/apps/files_sharing/l10n/sk_SK.php @@ -30,7 +30,6 @@ $TRANSLATIONS = array( "Download" => "Sťahovanie", "Download %s" => "Stiahnuť %s", "Direct link" => "Priama linka", -"File Sharing" => "Zdieľanie súborov", "Allow other instances to mount public links shared from this server" => "Povoliť ďalším inštanciám pripojiť verejné odkazy zdieľané z tohto servera", "Allow users to mount public link shares" => "Povoliť používateľom pripojiť sa na zdieľané verejné odkazy" ); diff --git a/apps/files_sharing/l10n/tr.php b/apps/files_sharing/l10n/tr.php index 5952704bcea..acf1620a6a1 100644 --- a/apps/files_sharing/l10n/tr.php +++ b/apps/files_sharing/l10n/tr.php @@ -30,7 +30,6 @@ $TRANSLATIONS = array( "Download" => "İndir", "Download %s" => "İndir: %s", "Direct link" => "Doğrudan bağlantı", -"File Sharing" => "Dosya Paylaşımı", "Allow other instances to mount public links shared from this server" => "Diğer örneklerin, bu sunucudan paylaşılmış herkese açık bağlantıları bağlamasına izin ver", "Allow users to mount public link shares" => "Kullanıcıların herkese açık bağlantı paylaşımlarını bağlamasına izin ver" ); diff --git a/apps/files_sharing/l10n/uk.php b/apps/files_sharing/l10n/uk.php index 8f16528c204..dc5cc41c7f0 100644 --- a/apps/files_sharing/l10n/uk.php +++ b/apps/files_sharing/l10n/uk.php @@ -14,6 +14,7 @@ $TRANSLATIONS = array( "For more info, please ask the person who sent this link." => "Для отримання додаткової інформації, будь ласка, зверніться до особи, яка надіслала це посилання.", "Save" => "Зберегти", "Download" => "Завантажити", +"Download %s" => "Завантажити %s", "Direct link" => "Пряме посилання" ); $PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 7a6b70d82b5..6bc9e131949 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -95,9 +95,9 @@ class Shared_Cache extends Cache { } $data['uid_owner'] = $this->storage->getOwner($file); if (isset($data['permissions'])) { - $data['permissions'] &= $this->storage->getPermissions(''); + $data['permissions'] &= $this->storage->getPermissions($file); } else { - $data['permissions'] = $this->storage->getPermissions(''); + $data['permissions'] = $this->storage->getPermissions($file); } return $data; } @@ -163,7 +163,7 @@ class Shared_Cache extends Cache { $sourceFolderContent[$key]['path'] = $dir . $c['name']; $sourceFolderContent[$key]['uid_owner'] = $parent['uid_owner']; $sourceFolderContent[$key]['displayname_owner'] = $parent['uid_owner']; - $sourceFolderContent[$key]['permissions'] = $sourceFolderContent[$key]['permissions'] & $this->storage->getPermissions(''); + $sourceFolderContent[$key]['permissions'] = $sourceFolderContent[$key]['permissions'] & $this->storage->getPermissions($dir . $c['name']); } return $sourceFolderContent; diff --git a/apps/files_sharing/lib/external/storage.php b/apps/files_sharing/lib/external/storage.php index cd04841bb09..2771f974614 100644 --- a/apps/files_sharing/lib/external/storage.php +++ b/apps/files_sharing/lib/external/storage.php @@ -37,9 +37,9 @@ class Storage extends DAV implements ISharedStorage { $this->remote = $options['remote']; $this->remoteUser = $options['owner']; list($protocol, $remote) = explode('://', $this->remote); - list($host, $root) = explode('/', $remote); + list($host, $root) = explode('/', $remote, 2); $secure = $protocol === 'https'; - $root .= '/public.php/webdav'; + $root = rtrim($root, '/') . '/public.php/webdav'; $this->mountPoint = $options['mountpoint']; $this->token = $options['token']; parent::__construct(array( diff --git a/apps/files_sharing/lib/helper.php b/apps/files_sharing/lib/helper.php index 34de3a915ab..0b3433576f6 100644 --- a/apps/files_sharing/lib/helper.php +++ b/apps/files_sharing/lib/helper.php @@ -7,6 +7,20 @@ use PasswordHash; class Helper { + public static function registerHooks() { + \OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup'); + \OCP\Util::connectHook('OC_Filesystem', 'setup', '\OCA\Files_Sharing\External\Manager', 'setup'); + \OCP\Util::connectHook('OC_Filesystem', 'post_write', '\OC\Files\Cache\Shared_Updater', 'writeHook'); + \OCP\Util::connectHook('OC_Filesystem', 'post_delete', '\OC\Files\Cache\Shared_Updater', 'postDeleteHook'); + \OCP\Util::connectHook('OC_Filesystem', 'delete', '\OC\Files\Cache\Shared_Updater', 'deleteHook'); + \OCP\Util::connectHook('OC_Filesystem', 'post_rename', '\OC\Files\Cache\Shared_Updater', 'renameHook'); + \OCP\Util::connectHook('OC_Appconfig', 'post_set_value', '\OCA\Files\Share\Maintainer', 'configChangeHook'); + + \OCP\Util::connectHook('OCP\Share', 'post_shared', '\OC\Files\Cache\Shared_Updater', 'postShareHook'); + \OCP\Util::connectHook('OCP\Share', 'post_unshare', '\OC\Files\Cache\Shared_Updater', 'postUnshareHook'); + \OCP\Util::connectHook('OCP\Share', 'post_unshareFromSelf', '\OC\Files\Cache\Shared_Updater', 'postUnshareFromSelfHook'); + } + /** * Sets up the filesystem and user for public sharing * @param string $token string share token diff --git a/apps/files_sharing/lib/updater.php b/apps/files_sharing/lib/updater.php index 5cb2b638e5a..e114c3ba0ac 100644 --- a/apps/files_sharing/lib/updater.php +++ b/apps/files_sharing/lib/updater.php @@ -133,6 +133,68 @@ class Shared_Updater { } /** + * update etags if a file was shared + * @param array $params + */ + static public function postShareHook($params) { + + if ($params['itemType'] === 'folder' || $params['itemType'] === 'file') { + + $shareWith = $params['shareWith']; + $shareType = $params['shareType']; + + if ($shareType === \OCP\Share::SHARE_TYPE_USER) { + self::correctUsersFolder($shareWith, '/'); + } elseif ($shareType === \OCP\Share::SHARE_TYPE_GROUP) { + foreach (\OC_Group::usersInGroup($shareWith) as $user) { + self::correctUsersFolder($user, '/'); + } + } + } + } + + /** + * update etags if a file was unshared + * + * @param array $params + */ + static public function postUnshareHook($params) { + + if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') { + + $deletedShares = isset($params['deletedShares']) ? $params['deletedShares'] : array(); + + foreach ($deletedShares as $share) { + if ($share['shareType'] === \OCP\Share::SHARE_TYPE_GROUP) { + foreach (\OC_Group::usersInGroup($share['shareWith']) as $user) { + self::correctUsersFolder($user, dirname($share['fileTarget'])); + } + } else { + self::correctUsersFolder($share['shareWith'], dirname($share['fileTarget'])); + } + } + } + } + + /** + * update etags if file was unshared from self + * @param array $params + */ + static public function postUnshareFromSelfHook($params) { + if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') { + foreach ($params['unsharedItems'] as $item) { + if ($item['shareType'] === \OCP\Share::SHARE_TYPE_GROUP) { + foreach (\OC_Group::usersInGroup($item['shareWith']) as $user) { + self::correctUsersFolder($user, dirname($item['fileTarget'])); + } + } else { + self::correctUsersFolder($item['shareWith'], dirname($item['fileTarget'])); + } + } + } + } + + /** * clean up oc_share table from files which are no longer exists * * This fixes issues from updates from files_sharing < 0.3.5.6 (ownCloud 4.5) diff --git a/apps/files_sharing/templates/settings-admin.php b/apps/files_sharing/templates/settings-admin.php index 18cf2276701..7c84f770fa6 100644 --- a/apps/files_sharing/templates/settings-admin.php +++ b/apps/files_sharing/templates/settings-admin.php @@ -1,6 +1,6 @@ <div class="section" id="fileSharingSettings" > - <h2><?php p($l->t('File Sharing'));?></h2> + <h2><?php p($l->t('Remote Shares'));?></h2> <input type="checkbox" name="outgoing_server2server_share_enabled" id="outgoingServer2serverShareEnabled" value="1" <?php if ($_['outgoingServer2serverShareEnabled']) print_unescaped('checked="checked"'); ?> /> diff --git a/apps/files_sharing/tests/externalstorage.php b/apps/files_sharing/tests/externalstorage.php new file mode 100644 index 00000000000..b7797333c10 --- /dev/null +++ b/apps/files_sharing/tests/externalstorage.php @@ -0,0 +1,91 @@ +<?php +/** + * ownCloud + * + * @author Vincent Petry + * @copyright 2014 Vincent Petry <pvince81@owncloud.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 <http://www.gnu.org/licenses/>. + * + */ + +require_once __DIR__ . '/base.php'; + +require_once __DIR__ . '/../../files_external/lib/webdav.php'; + +/** + * Tests for the external Storage class for remote shares. + */ +class Test_Files_Sharing_External_Storage extends \PHPUnit_Framework_TestCase { + + function optionsProvider() { + return array( + array( + 'http://remoteserver:8080/owncloud', + 'http://remoteserver:8080/owncloud/public.php/webdav/', + ), + // extra slash + array( + 'http://remoteserver:8080/owncloud/', + 'http://remoteserver:8080/owncloud/public.php/webdav/', + ), + // extra path + array( + 'http://remoteserver:8080/myservices/owncloud/', + 'http://remoteserver:8080/myservices/owncloud/public.php/webdav/', + ), + // root path + array( + 'http://remoteserver:8080/', + 'http://remoteserver:8080/public.php/webdav/', + ), + // without port + array( + 'http://remoteserver/oc.test', + 'http://remoteserver/oc.test/public.php/webdav/', + ), + // https + array( + 'https://remoteserver/', + 'https://remoteserver/public.php/webdav/', + ), + ); + } + + /** + * @dataProvider optionsProvider + */ + public function testStorageMountOptions($inputUri, $baseUri) { + $storage = new TestSharingExternalStorage( + array( + 'remote' => $inputUri, + 'owner' => 'testOwner', + 'mountpoint' => 'remoteshare', + 'token' => 'abcdef', + 'password' => '', + ) + ); + $this->assertEquals($baseUri, $storage->getBaseUri()); + } +} + +/** + * Dummy subclass to make it possible to access private members + */ +class TestSharingExternalStorage extends \OCA\Files_Sharing\External\Storage { + + public function getBaseUri() { + return $this->createBaseUri(); + } +} diff --git a/apps/files_sharing/tests/permissions.php b/apps/files_sharing/tests/permissions.php index 2cbc412d261..299e471a3fd 100644 --- a/apps/files_sharing/tests/permissions.php +++ b/apps/files_sharing/tests/permissions.php @@ -145,10 +145,9 @@ class Test_Files_Sharing_Permissions extends Test_Files_Sharing_Base { $this->assertEquals(27, $contents[1]['permissions']); $contents = $this->secondView->getDirectoryContent('files/shareddirrestricted'); $this->assertEquals('subdir', $contents[0]['name']); - $this->assertEquals(7 | \OCP\PERMISSION_DELETE, $contents[0]['permissions']); + $this->assertEquals(7, $contents[0]['permissions']); $this->assertEquals('textfile1.txt', $contents[1]['name']); // 3 is correct because create is reserved to folders only - // delete permissions are added since mount points can always be deleted - $this->assertEquals(3 | \OCP\PERMISSION_DELETE, $contents[1]['permissions']); + $this->assertEquals(3, $contents[1]['permissions']); } } diff --git a/apps/files_sharing/tests/sharedstorage.php b/apps/files_sharing/tests/sharedstorage.php index b80ab6b4f14..27f3b5150d5 100644 --- a/apps/files_sharing/tests/sharedstorage.php +++ b/apps/files_sharing/tests/sharedstorage.php @@ -166,4 +166,35 @@ class Test_Files_Sharing_Storage extends Test_Files_Sharing_Base { $this->assertTrue($result); } + function testGetPermissions() { + $fileinfoFolder = $this->view->getFileInfo($this->folder); + + $result = \OCP\Share::shareItem('folder', $fileinfoFolder['fileid'], \OCP\Share::SHARE_TYPE_USER, + self::TEST_FILES_SHARING_API_USER2, 1); + $this->assertTrue($result); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER2); + + $this->assertTrue(\OC\Files\Filesystem::is_dir($this->folder)); + + // for the share root we expect: + // the shared permissions (1) + // the delete permission (8), to enable unshare + // the update permission (2), to allow renaming of the mount point + $rootInfo = \OC\Files\Filesystem::getFileInfo($this->folder); + $this->assertSame(11, $rootInfo->getPermissions()); + + // for the file within the shared folder we expect: + // the shared permissions (1) + $subfileInfo = \OC\Files\Filesystem::getFileInfo($this->folder . $this->filename); + $this->assertSame(1, $subfileInfo->getPermissions()); + + + //cleanup + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + $result = \OCP\Share::unshare('folder', $fileinfoFolder['fileid'], \OCP\Share::SHARE_TYPE_USER, + self::TEST_FILES_SHARING_API_USER2); + $this->assertTrue($result); + } + } diff --git a/apps/files_sharing/tests/updater.php b/apps/files_sharing/tests/updater.php index 8183e7067a4..cdb44068254 100644 --- a/apps/files_sharing/tests/updater.php +++ b/apps/files_sharing/tests/updater.php @@ -28,14 +28,19 @@ require_once __DIR__ . '/base.php'; */ class Test_Files_Sharing_Updater extends Test_Files_Sharing_Base { - const TEST_FOLDER_NAME = '/folder_share_api_test'; + const TEST_FOLDER_NAME = '/folder_share_updater_test'; + + public static function setUpBeforeClass() { + parent::setUpBeforeClass(); + \OCA\Files_Sharing\Helper::registerHooks(); + } function setUp() { parent::setUp(); $this->folder = self::TEST_FOLDER_NAME; - $this->filename = '/share-api-test.txt'; + $this->filename = '/share-updater-test.txt'; // save file with content $this->view->file_put_contents($this->filename, $this->data); @@ -104,6 +109,112 @@ class Test_Files_Sharing_Updater extends Test_Files_Sharing_Base { if ($status === false) { \OC_App::disable('files_trashbin'); } + // cleanup + $this->loginHelper(self::TEST_FILES_SHARING_API_USER1); + $result = \OCP\Share::unshare('folder', $fileinfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2); + $this->assertTrue($result); + } + + /** + * if a file gets shared the etag for the recipients root should change + */ + function testShareFile() { + $this->loginHelper(self::TEST_FILES_SHARING_API_USER2); + + $beforeShare = \OC\Files\Filesystem::getFileInfo(''); + $etagBeforeShare = $beforeShare->getEtag(); + + $this->loginHelper(self::TEST_FILES_SHARING_API_USER1); + $fileinfo = \OC\Files\Filesystem::getFileInfo($this->folder); + $result = \OCP\Share::shareItem('folder', $fileinfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31); + $this->assertTrue($result); + + $this->loginHelper(self::TEST_FILES_SHARING_API_USER2); + + $afterShare = \OC\Files\Filesystem::getFileInfo(''); + $etagAfterShare = $afterShare->getEtag(); + + $this->assertTrue(is_string($etagBeforeShare)); + $this->assertTrue(is_string($etagAfterShare)); + $this->assertTrue($etagBeforeShare !== $etagAfterShare); + + // cleanup + $this->loginHelper(self::TEST_FILES_SHARING_API_USER1); + $result = \OCP\Share::unshare('folder', $fileinfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2); + $this->assertTrue($result); + } + + /** + * if a file gets unshared by the owner the etag for the recipients root should change + */ + function testUnshareFile() { + + $this->loginHelper(self::TEST_FILES_SHARING_API_USER1); + $fileinfo = \OC\Files\Filesystem::getFileInfo($this->folder); + $result = \OCP\Share::shareItem('folder', $fileinfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31); + $this->assertTrue($result); + + $this->loginHelper(self::TEST_FILES_SHARING_API_USER2); + + $beforeUnshare = \OC\Files\Filesystem::getFileInfo(''); + $etagBeforeUnshare = $beforeUnshare->getEtag(); + + $this->loginHelper(self::TEST_FILES_SHARING_API_USER1); + $result = \OCP\Share::unshare('folder', $fileinfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2); + $this->assertTrue($result); + + $this->loginHelper(self::TEST_FILES_SHARING_API_USER2); + + $afterUnshare = \OC\Files\Filesystem::getFileInfo(''); + $etagAfterUnshare = $afterUnshare->getEtag(); + + $this->assertTrue(is_string($etagBeforeUnshare)); + $this->assertTrue(is_string($etagAfterUnshare)); + $this->assertTrue($etagBeforeUnshare !== $etagAfterUnshare); + + } + + /** + * if a file gets unshared from self the etag for the recipients root should change + */ + function testUnshareFromSelfFile() { + $this->loginHelper(self::TEST_FILES_SHARING_API_USER1); + $fileinfo = \OC\Files\Filesystem::getFileInfo($this->folder); + $result = \OCP\Share::shareItem('folder', $fileinfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31); + $this->assertTrue($result); + + $this->loginHelper(self::TEST_FILES_SHARING_API_USER2); + + $result = \OCP\Share::shareItem('folder', $fileinfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER3, 31); + + $beforeUnshareUser2 = \OC\Files\Filesystem::getFileInfo(''); + $etagBeforeUnshareUser2 = $beforeUnshareUser2->getEtag(); + + $this->loginHelper(self::TEST_FILES_SHARING_API_USER3); + + $beforeUnshareUser3 = \OC\Files\Filesystem::getFileInfo(''); + $etagBeforeUnshareUser3 = $beforeUnshareUser3->getEtag(); + + $this->loginHelper(self::TEST_FILES_SHARING_API_USER2); + + $result = \OC\Files\Filesystem::unlink($this->folder); + $this->assertTrue($result); + + $afterUnshareUser2 = \OC\Files\Filesystem::getFileInfo(''); + $etagAfterUnshareUser2 = $afterUnshareUser2->getEtag(); + + $this->loginHelper(self::TEST_FILES_SHARING_API_USER3); + + $afterUnshareUser3 = \OC\Files\Filesystem::getFileInfo(''); + $etagAfterUnshareUser3 = $afterUnshareUser3->getEtag(); + + $this->assertTrue(is_string($etagBeforeUnshareUser2)); + $this->assertTrue(is_string($etagBeforeUnshareUser3)); + $this->assertTrue(is_string($etagAfterUnshareUser2)); + $this->assertTrue(is_string($etagAfterUnshareUser3)); + $this->assertTrue($etagBeforeUnshareUser2 !== $etagAfterUnshareUser2); + $this->assertTrue($etagBeforeUnshareUser3 !== $etagAfterUnshareUser3); + } } diff --git a/apps/files_trashbin/css/trash.css b/apps/files_trashbin/css/trash.css index 04b4a175c83..64e462e2e8a 100644 --- a/apps/files_trashbin/css/trash.css +++ b/apps/files_trashbin/css/trash.css @@ -11,3 +11,7 @@ #app-content-trashbin tbody tr[data-type="file"] td a.name span { cursor: default; } + +#app-content-trashbin .summary :last-child { + padding: 0; +} diff --git a/apps/files_trashbin/l10n/uk.php b/apps/files_trashbin/l10n/uk.php index 328e8da5e02..406bd520c29 100644 --- a/apps/files_trashbin/l10n/uk.php +++ b/apps/files_trashbin/l10n/uk.php @@ -2,7 +2,7 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Неможливо видалити %s назавжди", "Couldn't restore %s" => "Неможливо відновити %s", -"Deleted files" => "Видалено файлів", +"Deleted files" => "Видалені файли", "Restore" => "Відновити", "Error" => "Помилка", "restored" => "відновлено", diff --git a/apps/user_ldap/l10n/cs_CZ.php b/apps/user_ldap/l10n/cs_CZ.php index 254386aea7f..3a8ee2980da 100644 --- a/apps/user_ldap/l10n/cs_CZ.php +++ b/apps/user_ldap/l10n/cs_CZ.php @@ -30,11 +30,11 @@ $TRANSLATIONS = array( "Confirm Deletion" => "Potvrdit smazání", "_%s group found_::_%s groups found_" => array("nalezena %s skupina","nalezeny %s skupiny","nalezeno %s skupin"), "_%s user found_::_%s users found_" => array("nalezen %s uživatel","nalezeni %s uživatelé","nalezeno %s uživatelů"), -"Invalid Host" => "Neplatný hostitel", "Could not find the desired feature" => "Nelze nalézt požadovanou vlastnost", +"Invalid Host" => "Neplatný hostitel", "Server" => "Server", -"User Filter" => "Uživatelský Filtr", -"Login Filter" => "Přihlašovací Filtr", +"User Filter" => "Uživatelský filtr", +"Login Filter" => "Přihlašovací filtr", "Group Filter" => "Filtr skupin", "Save" => "Uložit", "Test Configuration" => "Vyzkoušet nastavení", diff --git a/apps/user_ldap/l10n/eo.php b/apps/user_ldap/l10n/eo.php index 3dccb192daf..1cab0f66b91 100644 --- a/apps/user_ldap/l10n/eo.php +++ b/apps/user_ldap/l10n/eo.php @@ -3,9 +3,13 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Malsukcesis forigo de la agordo de servilo", "Deletion failed" => "Forigo malsukcesis", "Keep settings?" => "Ĉu daŭrigi la agordon?", +"{nthServer}. Server" => "{nthServer}. Servilo", "Cannot add server configuration" => "Ne eblas aldoni agordon de servilo", "Success" => "Sukceso", "Error" => "Eraro", +"Configuration OK" => "La agordaro ĝustas", +"Configuration incorrect" => "La agordaro malĝustas", +"Configuration incomplete" => "La agordaro neplenas", "Select groups" => "Elekti grupojn", "Select object classes" => "Elekti objektoklasojn", "Select attributes" => "Elekti atribuojn", @@ -15,6 +19,9 @@ $TRANSLATIONS = array( "_%s group found_::_%s groups found_" => array("%s grupo troviĝis","%s grupoj troviĝis"), "_%s user found_::_%s users found_" => array("%s uzanto troviĝis","%s uzanto troviĝis"), "Invalid Host" => "Nevalida gastigo", +"Server" => "Servilo", +"User Filter" => "Filtrilo de uzanto", +"Login Filter" => "Ensaluta filtrilo", "Group Filter" => "Filtrilo de grupo", "Save" => "Konservi", "Test Configuration" => "Provi agordon", @@ -22,10 +29,14 @@ $TRANSLATIONS = array( "only those object classes:" => "nur tiuj objektoklasoj:", "only from those groups:" => "nur el tiuj grupoj:", "groups found" => "grupoj trovitaj", +"Users login with this attribute:" => "Uzantoj ensalutas kun ĉi tiu atributo:", "LDAP Username:" => "LDAP-uzantonomo:", "LDAP Email Address:" => "LDAP-retpoŝtadreso:", "Other Attributes:" => "Aliaj atribuoj:", +"1. Server" => "1. Servilo", +"%s. Server:" => "%s. Servilo:", "Add Server Configuration" => "Aldoni agordon de servilo", +"Delete Configuration" => "Forigi agordaron", "Host" => "Gastigo", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Vi povas neglekti la protokolon, escepte se vi bezonas SSL-on. Tiuokaze, komencu per ldaps://", "Port" => "Pordo", @@ -34,14 +45,17 @@ $TRANSLATIONS = array( "For anonymous access, leave DN and Password empty." => "Por sennoman aliron, lasu DN-on kaj Pasvorton malplenaj.", "users found" => "uzantoj trovitaj", "Back" => "Antaŭen", +"Expert" => "Sperta", "Advanced" => "Progresinta", "Connection Settings" => "Agordo de konekto", "Disable Main Server" => "Malkapabligi la ĉefan servilon", "Turn off SSL certificate validation." => "Malkapabligi validkontrolon de SSL-atestiloj.", "Cache Time-To-Live" => "Vivotempo de la kaŝmemoro", "in seconds. A change empties the cache." => "sekunde. Ajna ŝanĝo malplenigas la kaŝmemoron.", +"Directory Settings" => "Agordo de dosierujo", "User Display Name Field" => "Kampo de vidignomo de uzanto", "Base User Tree" => "Baza uzantarbo", +"User Search Attributes" => "Atributoj de serĉo de uzanto", "Group Display Name Field" => "Kampo de vidignomo de grupo", "Base Group Tree" => "Baza gruparbo", "Group Search Attributes" => "Atribuoj de gruposerĉo", diff --git a/apps/user_ldap/l10n/pt_BR.php b/apps/user_ldap/l10n/pt_BR.php index ab2cb67c596..6e5a1663e2d 100644 --- a/apps/user_ldap/l10n/pt_BR.php +++ b/apps/user_ldap/l10n/pt_BR.php @@ -11,7 +11,7 @@ $TRANSLATIONS = array( " Could not set configuration %s" => "Não foi possível definir a configuração %s", "Deletion failed" => "Remoção falhou", "Take over settings from recent server configuration?" => "Tomar parámetros de recente configuração de servidor?", -"Keep settings?" => "Manter ajustes?", +"Keep settings?" => "Manter configurações?", "{nthServer}. Server" => "Servidor {nthServer}.", "Cannot add server configuration" => "Impossível adicionar a configuração do servidor", "mappings cleared" => "mapeamentos limpos", @@ -32,18 +32,18 @@ $TRANSLATIONS = array( "Confirm Deletion" => "Confirmar Exclusão", "_%s group found_::_%s groups found_" => array("grupo% s encontrado","grupos% s encontrado"), "_%s user found_::_%s users found_" => array("usuário %s encontrado","usuários %s encontrados"), -"Invalid Host" => "Host inválido", "Could not find the desired feature" => "Não foi possível encontrar a função desejada", +"Invalid Host" => "Host Inválido", "Server" => "Servidor", "User Filter" => "Filtro de Usuário", "Login Filter" => "Filtro de Login", "Group Filter" => "Filtro de Grupo", -"Save" => "Guardar", +"Save" => "Salvar", "Test Configuration" => "Teste de Configuração", "Help" => "Ajuda", "Groups meeting these criteria are available in %s:" => "Grupos que satisfazem estes critérios estão disponíveis em %s:", "only those object classes:" => "apenas essas classes de objetos:", -"only from those groups:" => "apenas a partir dos grupos:", +"only from those groups:" => "apenas desses grupos:", "Edit raw filter instead" => "Editar filtro raw ao invéz", "Raw LDAP filter" => "Filtro LDAP Raw", "The filter specifies which LDAP groups shall have access to the %s instance." => "O filtro especifica quais grupos LDAP devem ter acesso à instância do %s.", @@ -51,13 +51,13 @@ $TRANSLATIONS = array( "Users login with this attribute:" => "Usuários entrar com este atributo:", "LDAP Username:" => "Usuário LDAP:", "LDAP Email Address:" => "LDAP Endereço de E-mail:", -"Other Attributes:" => "Outros atributos:", -"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Define o filtro a ser aplicado, o login é feito. %%uid substitui o nome do usuário na ação de login. Exemplo: \"uid=%%uid\"", +"Other Attributes:" => "Outros Atributos:", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Define o filtro a ser aplicado, quando o login for feito. %%uid substitui o nome do usuário na ação de login. Exemplo: \"uid=%%uid\"", "1. Server" => "1. Servidor", "%s. Server:" => "%s. Servidor:", "Add Server Configuration" => "Adicionar Configuração de Servidor", "Delete Configuration" => "Excluir Configuração", -"Host" => "Servidor", +"Host" => "Host", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Você pode omitir o protocolo, exceto quando requerer SSL. Então inicie com ldaps://", "Port" => "Porta", "User DN" => "DN Usuário", @@ -76,9 +76,9 @@ $TRANSLATIONS = array( "<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Aviso:</b> Os aplicativos user_ldap e user_webdavauth são incompatíveis. Você pode experimentar comportamento inesperado. Por favor, peça ao seu administrador do sistema para desabilitar um deles.", "<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Aviso:</b> O módulo PHP LDAP não está instalado, o backend não funcionará. Por favor, peça ao seu administrador do sistema para instalá-lo.", "Connection Settings" => "Configurações de Conexão", -"Configuration Active" => "Configuração ativa", +"Configuration Active" => "Configuração Ativa", "When unchecked, this configuration will be skipped." => "Quando não marcada, esta configuração será ignorada.", -"Backup (Replica) Host" => "Servidor de Backup (Réplica)", +"Backup (Replica) Host" => "Host de Backup (Réplica)", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Defina um servidor de backup opcional. Ele deverá ser uma réplica do servidor LDAP/AD principal.", "Backup (Replica) Port" => "Porta do Backup (Réplica)", "Disable Main Server" => "Desativar Servidor Principal", diff --git a/apps/user_ldap/l10n/pt_PT.php b/apps/user_ldap/l10n/pt_PT.php index e701ed0b241..20a136384fb 100644 --- a/apps/user_ldap/l10n/pt_PT.php +++ b/apps/user_ldap/l10n/pt_PT.php @@ -32,8 +32,8 @@ $TRANSLATIONS = array( "Confirm Deletion" => "Confirmar a operação de apagar", "_%s group found_::_%s groups found_" => array("%s grupo encontrado","%s grupos encontrados"), "_%s user found_::_%s users found_" => array("%s utilizador encontrado","%s utilizadores encontrados"), -"Invalid Host" => "Hospedeiro Inválido", "Could not find the desired feature" => "Não se encontrou a função desejada", +"Invalid Host" => "Hospedeiro Inválido", "Server" => "Servidor", "User Filter" => "Filtro de utilizadores", "Login Filter" => "Filtro de Login", diff --git a/apps/user_ldap/l10n/sl.php b/apps/user_ldap/l10n/sl.php index d0b6ab8fb0d..60aebba7dcc 100644 --- a/apps/user_ldap/l10n/sl.php +++ b/apps/user_ldap/l10n/sl.php @@ -28,8 +28,11 @@ $TRANSLATIONS = array( "Confirm Deletion" => "Potrdi brisanje", "_%s group found_::_%s groups found_" => array("%s najdena skupina","%s najdeni skupini","%s najdene skupine","%s najdenih skupin"), "_%s user found_::_%s users found_" => array("%s najden uporabnik","%s najdena uporabnika","%s najdeni uporabniki","%s najdenih uporabnikov"), -"Invalid Host" => "Neveljaven gostitelj", "Could not find the desired feature" => "Želene zmožnosti ni mogoče najti", +"Invalid Host" => "Neveljaven gostitelj", +"Server" => "Strežnik", +"User Filter" => "Uporabniški filter", +"Login Filter" => "Filter prijave", "Group Filter" => "Filter skupin", "Save" => "Shrani", "Test Configuration" => "Preizkusne nastavitve", @@ -45,6 +48,7 @@ $TRANSLATIONS = array( "Other Attributes:" => "Drugi atributi:", "Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Določi filter, ki bo uveljavljen ob poskusu prijave. %%uid zamenja uporabniško ime pri prijavi, na primer: \"uid=%%uid\"", "Add Server Configuration" => "Dodaj nastavitve strežnika", +"Delete Configuration" => "Izbriši nastavitve", "Host" => "Gostitelj", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Protokol je lahko izpuščen, če ni posebej zahtevan SSL. V tem primeru se mora naslov začeti z ldaps://", "Port" => "Vrata", diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php index d289627bead..ca5d1386995 100644 --- a/apps/user_ldap/lib/access.php +++ b/apps/user_ldap/lib/access.php @@ -724,10 +724,18 @@ class Access extends LDAPUtility implements user\IUserTools { } /** - * prepares and executes an LDAP search operation - * @param string $filter the LDAP filter for the search - * @param array $base an array containing the LDAP subtree(s) that shall be searched - * @param string|string[] $attr optional, array, one or more attributes that shall be + * returns the number of available groups + * @param string $filter the LDAP search filter + * @param string[] $attr optional + * @param int|null $limit + * @param int|null $offset + * @return int|bool + */ + public function countGroups($filter, $attr = array('dn'), $limit = null, $offset = null) { + return $this->count($filter, $this->connection->ldapBaseGroups, $attr, $limit, $offset); + } + + /** * retrieved. Results will according to the order in the array. * @param int $limit optional, maximum results to be counted * @param int $offset optional, a starting point @@ -827,7 +835,7 @@ class Access extends LDAPUtility implements user\IUserTools { \OCP\Util::writeLog('user_ldap', 'Count filter: '.print_r($filter, true), \OCP\Util::DEBUG); if(is_null($limit)) { - $limit = $this->connection->ldapPagingSize; + $limit = intval($this->connection->ldapPagingSize); } $counter = 0; @@ -1026,9 +1034,10 @@ class Access extends LDAPUtility implements user\IUserTools { } /** - * combines the input filters with AND + * combines the input filters with OR * @param string[] $filters the filters to connect * @return string the combined filter + * Combines Filter arguments with OR */ public function combineFilterWithOr($filters) { return $this->combineFilter($filters, '|'); diff --git a/apps/user_ldap/lib/connection.php b/apps/user_ldap/lib/connection.php index 52f6c5ceb10..bafb0e0b895 100644 --- a/apps/user_ldap/lib/connection.php +++ b/apps/user_ldap/lib/connection.php @@ -41,11 +41,13 @@ class Connection extends LDAPUtility { protected $doNotValidate = false; + protected $ignoreValidation = false; + /** * Constructor * @param ILDAPWrapper $ldap * @param string $configPrefix a string with the prefix for the configkey column (appconfig table) - * @param string $configID a string with the value for the appid column (appconfig table) or null for on-the-fly connections + * @param string|null $configID a string with the value for the appid column (appconfig table) or null for on-the-fly connections */ public function __construct(ILDAPWrapper $ldap, $configPrefix = '', $configID = 'user_ldap') { parent::__construct($ldap); @@ -117,6 +119,16 @@ class Connection extends LDAPUtility { } /** + * sets whether the result of the configuration validation shall + * be ignored when establishing the connection. Used by the Wizard + * in early configuration state. + * @param bool $state + */ + public function setIgnoreValidation($state) { + $this->ignoreValidation = (bool)$state; + } + + /** * initializes the LDAP backend * @param bool $force read the config settings no matter what */ @@ -466,7 +478,7 @@ class Connection extends LDAPUtility { if(!$phpLDAPinstalled) { return false; } - if(!$this->configured) { + if(!$this->ignoreValidation && !$this->configured) { \OCP\Util::writeLog('user_ldap', 'Configuration is invalid, cannot connect', \OCP\Util::WARN); diff --git a/apps/user_ldap/lib/wizard.php b/apps/user_ldap/lib/wizard.php index b8a0e5ad799..42d612fa736 100644 --- a/apps/user_ldap/lib/wizard.php +++ b/apps/user_ldap/lib/wizard.php @@ -64,39 +64,53 @@ class Wizard extends LDAPUtility { } /** - * @return WizardResult - * @throws \Exception + * counts entries in the LDAP directory + * @param string $filter the LDAP search filter + * @param string $type a string being either 'users' or 'groups'; + * @return int|bool */ - public function countGroups() { - if(!$this->checkRequirements(array('ldapHost', - 'ldapPort', - 'ldapBase', - ))) { - return false; + public function countEntries($filter, $type) { + $reqs = array('ldapHost', 'ldapPort', 'ldapBase'); + if($type === 'users') { + $reqs[] = 'ldapUserFilter'; + } + if(!$this->checkRequirements($reqs)) { + throw new \Exception('Requirements not met', 400); } - $base = $this->configuration->ldapBase[0]; + $ldapAccess = $this->getAccess(); + if($type === 'groups') { + $result = $ldapAccess->countGroups($filter); + } else if($type === 'users') { + $result = $ldapAccess->countUsers($filter); + } else { + throw new \Exception('internal error: invald object type', 500); + } + + return $result; + } + + public function countGroups() { $filter = $this->configuration->ldapGroupFilter; - \OCP\Util::writeLog('user_ldap', 'Wiz: g filter '. print_r($filter, true), \OCP\Util::DEBUG); - $l = \OC_L10N::get('user_ldap'); + if(empty($filter)) { - $output = $l->n('%s group found', '%s groups found', 0, array(0)); + $output = self::$l->n('%s group found', '%s groups found', 0, array(0)); $this->result->addChange('ldap_group_count', $output); return $this->result; } - $cr = $this->getConnection(); - if(!$cr) { - throw new \Exception('Could not connect to LDAP'); - } - $rr = $this->ldap->search($cr, $base, $filter, array('dn')); - if(!$this->ldap->isResource($rr)) { + + try { + $groupsTotal = $this->countEntries($filter, 'groups'); + } catch (\Exception $e) { + //400 can be ignored, 500 is forwarded + if($e->getCode() === 500) { + throw $e; + } return false; } - $entries = $this->ldap->countEntries($cr, $rr); - $entries = ($entries !== false) ? $entries : 0; - $output = $l->n('%s group found', '%s groups found', $entries, $entries); + $groupsTotal = ($groupsTotal !== false) ? $groupsTotal : 0; + $output = self::$l->n('%s group found', '%s groups found', $groupsTotal, $groupsTotal); $this->result->addChange('ldap_group_count', $output); - return $this->result; } @@ -105,31 +119,12 @@ class Wizard extends LDAPUtility { * @throws \Exception */ public function countUsers() { - if(!$this->checkRequirements(array('ldapHost', - 'ldapPort', - 'ldapBase', - 'ldapUserFilter', - ))) { - return false; - } - - $cr = $this->getConnection(); - if(!$cr) { - throw new \Exception('Could not connect to LDAP'); - } - - $base = $this->configuration->ldapBase[0]; $filter = $this->configuration->ldapUserFilter; - $rr = $this->ldap->search($cr, $base, $filter, array('dn')); - if(!$this->ldap->isResource($rr)) { - return false; - } - $entries = $this->ldap->countEntries($cr, $rr); - $entries = ($entries !== false) ? $entries : 0; - $l = \OC_L10N::get('user_ldap'); - $output = $l->n('%s user found', '%s users found', $entries, $entries); - $this->result->addChange('ldap_user_count', $output); + $usersTotal = $this->countEntries($filter, 'users'); + $usersTotal = ($usersTotal !== false) ? $usersTotal : 0; + $output = self::$l->n('%s user found', '%s users found', $usersTotal, $usersTotal); + $this->result->addChange('ldap_user_count', $output); return $this->result; } @@ -273,8 +268,7 @@ class Wizard extends LDAPUtility { throw new \Exception('Could not connect to LDAP'); } - $obClasses = array('posixGroup', 'group', 'zimbraDistributionList', '*'); - $this->determineFeature($obClasses, 'cn', $dbKey, $confKey); + $this->fetchGroups($dbKey, $confKey); if($testMemberOf) { $this->configuration->hasMemberOfFilterSupport = $this->testMemberOf(); @@ -288,9 +282,48 @@ class Wizard extends LDAPUtility { } /** - * @return bool|WizardResult - * @throws \Exception + * fetches all groups from LDAP + * @param string $dbKey + * @param string $confKey */ + public function fetchGroups($dbKey, $confKey) { + $obclasses = array('posixGroup', 'group', 'zimbraDistributionList', 'groupOfNames'); + $ldapAccess = $this->getAccess(); + + $filterParts = array(); + foreach($obclasses as $obclass) { + $filterParts[] = 'objectclass='.$obclass; + } + //we filter for everything + //- that looks like a group and + //- has the group display name set + $filter = $ldapAccess->combineFilterWithOr($filterParts); + $filter = $ldapAccess->combineFilterWithAnd(array($filter, 'cn=*')); + + $limit = 400; + $offset = 0; + do { + $result = $ldapAccess->searchGroups($filter, array('cn'), $limit, $offset); + foreach($result as $item) { + $groups[] = $item[0]; + } + $offset += $limit; + } while (count($groups) > 0 && count($groups) % $limit === 0); + + if(count($groups) > 0) { + natsort($groups); + $this->result->addOptions($dbKey, array_values($groups)); + } else { + throw new \Exception(self::$l->t('Could not find the desired feature')); + } + + $setFeatures = $this->configuration->$confKey; + if(is_array($setFeatures) && !empty($setFeatures)) { + //something is already configured? pre-select it. + $this->result->addChange($dbKey, $setFeatures); + } + } + public function determineGroupMemberAssoc() { if(!$this->checkRequirements(array('ldapHost', 'ldapPort', @@ -909,15 +942,13 @@ class Wizard extends LDAPUtility { * specified attribute * @param string[] $filters array, the filters that shall be used in the search * @param string $attr the attribute of which a list of values shall be returned - * @param bool $lfw whether the last filter is a wildcard which shall not - * be processed if there were already findings, defaults to true * @param int $dnReadLimit the amount of how many DNs should be analyzed. * The lower, the faster * @param string $maxF string. if not null, this variable will have the filter that * yields most result entries * @return array|false an array with the values on success, false otherwise */ - public function cumulativeSearchOnAttribute($filters, $attr, $lfw = true, $dnReadLimit = 3, &$maxF = null) { + public function cumulativeSearchOnAttribute($filters, $attr, $dnReadLimit = 3, &$maxF = null) { $dnRead = array(); $foundItems = array(); $maxEntries = 0; @@ -935,7 +966,7 @@ class Wizard extends LDAPUtility { $lastFilter = $filters[count($filters)-1]; } foreach($filters as $filter) { - if($lfw && $lastFilter === $filter && count($foundItems) > 0) { + if($lastFilter === $filter && count($foundItems) > 0) { //skip when the filter is a wildcard and results were found continue; } @@ -1005,16 +1036,11 @@ class Wizard extends LDAPUtility { //how deep to dig? //When looking for objectclasses, testing few entries is sufficient, - //when looking for group we need to get all names, though. - if(strtolower($attr) === 'objectclass') { - $dig = 3; - } else { - $dig = 0; - } + $dig = 3; $availableFeatures = $this->cumulativeSearchOnAttribute($objectclasses, $attr, - true, $dig, $maxEntryObjC); + $dig, $maxEntryObjC); if(is_array($availableFeatures) && count($availableFeatures) > 0) { natcasesort($availableFeatures); @@ -1073,6 +1099,27 @@ class Wizard extends LDAPUtility { } /** + * creates and returns an Access instance + * @return \OCA\user_ldap\lib\Access + */ + private function getAccess() { + $con = new Connection($this->ldap, '', null); + $con->setConfiguration($this->configuration->getConfiguration()); + $con->ldapConfigurationActive = true; + $con->setIgnoreValidation(true); + + $userManager = new user\Manager( + \OC::$server->getConfig(), + new FilesystemHelper(), + new LogWrapper(), + \OC::$server->getAvatarManager(), + new \OCP\Image()); + + $ldapAccess = new Access($con, $this->ldap, $userManager); + return $ldapAccess; + } + + /** * @return bool|mixed */ private function getConnection() { diff --git a/apps/user_ldap/tests/wizard.php b/apps/user_ldap/tests/wizard.php index 2b5cabc705d..ff5ee010b71 100644 --- a/apps/user_ldap/tests/wizard.php +++ b/apps/user_ldap/tests/wizard.php @@ -127,7 +127,7 @@ class Test_Wizard extends \PHPUnit_Framework_TestCase { # The following expectations are the real test # $filters = array('f1', 'f2', '*'); - $wizard->cumulativeSearchOnAttribute($filters, 'cn', true, 5); + $wizard->cumulativeSearchOnAttribute($filters, 'cn', 5); unset($uidnumber); } @@ -203,8 +203,8 @@ class Test_Wizard extends \PHPUnit_Framework_TestCase { # The following expectations are the real test # $filters = array('f1', 'f2', '*'); - $wizard->cumulativeSearchOnAttribute($filters, 'cn', true, 0); + $wizard->cumulativeSearchOnAttribute($filters, 'cn', 0); unset($uidnumber); } -}
\ No newline at end of file +} |