Преамбула
Однако, наступил момент, о котором я никогда не задумывался при использовании NextCloud. Один из пользователей моего облака решил всё своё забрать себе одним разом – нажал на кнопку “скачать все файлы” вверху на панели.
Учитывая слабое железо и объём папки в полтора Терабайта, сервер призадумался надолго потому что оно и понятно. Облазив всю конфигурацию и настройки, прочитав сотни форумов и документацию NextCloud, я пришёл к выводу, что разработчик не намерен добавлять какую либо функцию для ограничения скачивания папок, а сообщество до сих пор не выпустило приложения, которое помогло бы в этом. Похожая ситуация произошла и с родственником – OwnCloud. Там была административная функция управление скачиванием папок. Разработчики объясняют своё нежелание что то менять по странной причине – теперь для создания Zip архива не требуется временная папка, упаковка и отсылка данных происходит “на лету”.
Решил посмотреть “как у других”, и с удивлением обнаружил, что практически все облачные сервисы (Mega, Mail, Google, YandexDisk) позволяют скачивать сразу ВСЁ невзирая на размер, и отключить это невозможно. Единственное приложение, где можно отключить – это Seafile (через добавление строчек в конфиг).
Решение как это исправить найдено, оно “костыльное”, но работает. Суть в том, чтобы убрать в Header упоминание о скачивании, а возможность нажать “скачать” через правый клик или по нажатию в “три точки” – заблокировать Алертом. При этом, можно указать размер, при котором всё таки скачать можно.
Для реализации задуманного, нужно модифицировать три файла:
ShareController.php
fileactions.js
filelist.js
Подозреваю, что после какого то из обновлений, эти файлы могут перезаписаться. Проверялось на древних версиях и самой последней NextCloud – работает.
Правим ShareController.php
в файле apps/files_sharing/lib/Controller/ShareController.php
Найти строку:
$response->setHeaderActions($responseComposer);
Закомментировать, после неё вставить следующий код:
1 2 |
if (!$shareIsFolder or $shareTmpl['nonHumanFileSize'] <= 1024**3) { $response->setHeaderActions($responseComposer); |
Должно получиться так:
1 2 3 4 5 6 7 8 9 10 11 |
if ($this->federatedShareProvider->isOutgoingServer2serverShareEnabled()) { $responseComposer[] = $externalShare; } #$response->setHeaderActions($responseComposer); - закомментировать строку if (!$shareIsFolder or $shareTmpl['nonHumanFileSize'] <= 1024**3) { $response->setHeaderActions($responseComposer); } } $response->setContentSecurityPolicy($csp); |
Правим fileactions.js
в файле: apps/files/js/fileactions.js
Найти строку:
var downloadFileaction = $(context.$file).find('.fileactions .action-download');
после неё вставить:
1 2 3 4 |
if (isDir && context.$file.attr('data-size') >= Math.pow(1024,3)) { alert("Размер загрузки слишком велик (" + Math.round(context.$file.attr('data-size')/(1024*1024)) + "MB, лимит 1GB), воспользуйтесь другим способом скачать"); return; } |
Должно получиться так:
1 2 3 4 5 6 7 8 9 |
var downloadFileaction = $(context.$file).find('.fileactions .action-download'); if (isDir && context.$file.attr('data-size') >= Math.pow(1024,3)) { alert("Размер загрузки слишком велик (" + Math.round(context.$file.attr('data-size')/(1024*1024)) + "MB, лимит 1GB), воспользуйтесь другим способом скачать"); return; } // don't allow a second click on the download action if(downloadFileaction.hasClass('disabled')) { return; |
Правим filelist.js
В файле: apps/files/js/filelist.js
Находим строчку:
1 2 |
files = _.pluck(this.getSelectedFiles(), 'name'); } |
После неё вставляем код:
1 2 3 4 5 6 7 8 9 |
sizes = _.pluck(this.getSelectedFiles(), 'size'); const reducer = (accumulator, currentValue) => accumulator + currentValue; var size= sizes.reduce(reducer); // проверка размера файла и то, что это не одиночный файл if (size > Math.pow(1024,3) && !(files.length == 1 && this.getSelectedFiles()[0].type == 'file')) { alert("Размер загрузки слишком велик (" + Math.round(context.$file.attr('data-size')/(1024*1024)) + "MB, лимит 1GB), воспользуйтесь другим способом скачать"); return false; } |
Должно получиться так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
files = _.pluck(this.getSelectedFiles(), 'name'); } sizes = _.pluck(this.getSelectedFiles(), 'size'); const reducer = (accumulator, currentValue) => accumulator + currentValue; var size= sizes.reduce(reducer); // проверка размера файла и то, что это не одиночный файл if (size > Math.pow(1024,3) && !(files.length == 1 && this.getSelectedFiles()[0].type == 'file')) { alert("Размер загрузки слишком велик (" + Math.round(context.$file.attr('data-size')/(1024*1024)) + "MB, лимит 1GB), воспользуйтесь другим способом скачать"); return false; } // don't allow a second click on the download action if(this.fileMultiSelectMenu.isDisabled('download')) { return false; |
Сообщение alert вы можете изменить на свой вкус в строке:
" + Math.round(context.$file.attr('data-size')/(1024*1024)) + "MB, лимит 1GB), воспользуйтесь другим способом скачать"
Например, я лимит выставил в коде для js 1024,3 — на 1024,1 В коде PHP 1024**3 — 1024**1 – это лимит в 1 МБ, а код строки для alert выглядит так:
"Скачивать папки нельзя!"
Готовый результат и сами файлы
Ну, и сам результат
Кому лень ковыряться, скачать все три файла с моим вариантом alert.
а можно как то вообще запретить скачивание одного файла и одной папки в которой файлы лежат? И разрешить скачивание только для заданной определенной группы например
или может запретить скачивание только определенного типа файлов