Запрет скачивания папки zip nextcloud

Автор: | 26.08.2022

Преамбула

Однако, наступил момент, о котором я никогда не задумывался при использовании 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);
Закомментировать, после неё вставить следующий код:

if (!$shareIsFolder or $shareTmpl['nonHumanFileSize'] <= 1024**3) {
$response->setHeaderActions($responseComposer);

Должно получиться так:

			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');
после неё вставить:

if (isDir && context.$file.attr('data-size') >= Math.pow(1024,3)) {
						alert("Размер загрузки слишком велик (" + Math.round(context.$file.attr('data-size')/(1024*1024)) + "MB, лимит 1GB), воспользуйтесь другим способом скачать");
						return;
					}

Должно получиться так:

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
Находим строчку:

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;
			}

Должно получиться так:

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.

Запрет скачивания папки zip nextcloud: 2 комментария

  1. Дмитрий

    а можно как то вообще запретить скачивание одного файла и одной папки в которой файлы лежат? И разрешить скачивание только для заданной определенной группы например

  2. Дмитрий

    или может запретить скачивание только определенного типа файлов

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.